1
/* $XFree86: xc/programs/Xserver/hw/xfree86/int10/helper_mem.c,v 1.25 2002/09/16 18:06:08 eich Exp $ */
4
* execute BIOS int 10h calls in x86 real mode environment
5
* Copyright 1999 Egbert Eich
7
#ifdef HAVE_XORG_CONFIG_H
8
#include <xorg-config.h>
12
#include "xf86_OSproc.h"
13
#include "xf86_ansic.h"
16
#define _INT10_PRIVATE
18
#include "int10Defines.h"
20
#include "xf86int10.h"
30
static const OptionInfoRec INT10Options[] = {
31
{OPT_NOINT10, "NoINT10", OPTV_BOOLEAN, {0}, FALSE },
32
{OPT_INIT_PRIMARY, "InitPrimary", OPTV_BOOLEAN, {0}, FALSE },
33
{OPT_BIOS_LOCATION, "BiosLocation", OPTV_STRING, {0}, FALSE },
34
{ -1, NULL, OPTV_NONE, {0}, FALSE },
39
dprint(unsigned long start, unsigned long size)
42
char *c = (char *)start;
44
for (j = 0; j < (size >> 4); j++) {
46
ErrorF("\n0x%lx: ",(unsigned long)c);
47
for (i = 0; i<16; i++)
48
ErrorF("%2.2x ",(unsigned char) (*(c++)));
50
for (i = 0; i<16; i++) {
51
ErrorF("%c",((((CARD8)(*c)) > 32) && (((CARD8)(*c)) < 128)) ?
52
(unsigned char) (*(c)): '.');
62
* here we are really paranoid about faking a "real"
63
* BIOS. Most of this information was pulled from
67
setup_int_vect(xf86Int10InfoPtr pInt)
71
/* let the int vects point to the SYS_BIOS seg */
72
for (i = 0; i < 0x80; i++) {
73
MEM_WW(pInt, i << 2, 0);
74
MEM_WW(pInt, (i << 2) + 2, SYS_BIOS >> 4);
78
/* font tables default location (int 1F) */
79
MEM_WW(pInt,0x1f<<2,0xfa6e);
81
/* int 11 default location (Get Equipment Configuration) */
82
MEM_WW(pInt, 0x11 << 2, 0xf84d);
83
/* int 12 default location (Get Conventional Memory Size) */
84
MEM_WW(pInt, 0x12 << 2, 0xf841);
85
/* int 15 default location (I/O System Extensions) */
86
MEM_WW(pInt, 0x15 << 2, 0xf859);
87
/* int 1A default location (RTC, PCI and others) */
88
MEM_WW(pInt, 0x1a << 2, 0xff6e);
89
/* int 05 default location (Bound Exceeded) */
90
MEM_WW(pInt, 0x05 << 2, 0xff54);
91
/* int 08 default location (Double Fault) */
92
MEM_WW(pInt, 0x08 << 2, 0xfea5);
93
/* int 13 default location (Disk) */
94
MEM_WW(pInt, 0x13 << 2, 0xec59);
95
/* int 0E default location (Page Fault) */
96
MEM_WW(pInt, 0x0e << 2, 0xef57);
97
/* int 17 default location (Parallel Port) */
98
MEM_WW(pInt, 0x17 << 2, 0xefd2);
99
/* fdd table default location (int 1e) */
100
MEM_WW(pInt, 0x1e << 2, 0xefc7);
102
/* Set Equipment flag to VGA */
103
i = MEM_RB(pInt, 0x0410) & 0xCF;
104
MEM_WB(pInt, 0x0410, i);
105
/* XXX Perhaps setup more of the BDA here. See also int42(0x00). */
110
setup_system_bios(void *base_addr)
112
char *base = (char *) base_addr;
115
* we trap the "industry standard entry points" to the BIOS
116
* and all other locations by filling them with "hlt"
117
* TODO: implement hlt-handler for these
119
memset(base, 0xf4, 0x10000);
122
strcpy(base + 0x0FFF5, "06/11/99");
123
/* set up eisa ident string */
124
strcpy(base + 0x0FFD9, "PCI_ISA");
125
/* write system model id for IBM-AT */
126
*((unsigned char *)(base + 0x0FFFE)) = 0xfc;
132
reset_int_vect(xf86Int10InfoPtr pInt)
135
* This table is normally located at 0xF000:0xF0A4. However, int 0x42,
136
* function 0 (Mode Set) expects it (or a copy) somewhere in the bottom
137
* 64kB. Note that because this data doesn't survive POST, int 0x42 should
138
* only be used during EGA/VGA BIOS initialisation.
140
static const CARD8 VideoParms[] = {
141
/* Timing for modes 0x00 & 0x01 */
142
0x38, 0x28, 0x2d, 0x0a, 0x1f, 0x06, 0x19, 0x1c,
143
0x02, 0x07, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
144
/* Timing for modes 0x02 & 0x03 */
145
0x71, 0x50, 0x5a, 0x0a, 0x1f, 0x06, 0x19, 0x1c,
146
0x02, 0x07, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
147
/* Timing for modes 0x04, 0x05 & 0x06 */
148
0x38, 0x28, 0x2d, 0x0a, 0x7f, 0x06, 0x64, 0x70,
149
0x02, 0x01, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
150
/* Timing for mode 0x07 */
151
0x61, 0x50, 0x52, 0x0f, 0x19, 0x06, 0x19, 0x19,
152
0x02, 0x0d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00,
153
/* Display page lengths in little endian order */
154
0x00, 0x08, /* Modes 0x00 and 0x01 */
155
0x00, 0x10, /* Modes 0x02 and 0x03 */
156
0x00, 0x40, /* Modes 0x04 and 0x05 */
157
0x00, 0x40, /* Modes 0x06 and 0x07 */
158
/* Number of columns for each mode */
159
40, 40, 80, 80, 40, 40, 80, 80,
160
/* CGA Mode register value for each mode */
161
0x2c, 0x28, 0x2d, 0x29, 0x2a, 0x2e, 0x1e, 0x29,
163
0x00, 0x00, 0x00, 0x00
167
for (i = 0; i < sizeof(VideoParms); i++)
168
MEM_WB(pInt, i + (0x1000 - sizeof(VideoParms)), VideoParms[i]);
169
MEM_WW(pInt, 0x1d << 2, 0x1000 - sizeof(VideoParms));
170
MEM_WW(pInt, (0x1d << 2) + 2, 0);
172
MEM_WW(pInt, 0x10 << 2, 0xf065);
173
MEM_WW(pInt, (0x10 << 2) + 2, SYS_BIOS >> 4);
174
MEM_WW(pInt, 0x42 << 2, 0xf065);
175
MEM_WW(pInt, (0x42 << 2) + 2, SYS_BIOS >> 4);
176
MEM_WW(pInt, 0x6D << 2, 0xf065);
177
MEM_WW(pInt, (0x6D << 2) + 2, SYS_BIOS >> 4);
181
set_return_trap(xf86Int10InfoPtr pInt)
184
* Here we set the exit condition: We return when we encounter
185
* 'hlt' (=0xf4), which we locate at address 0x600 in x86 memory.
187
MEM_WB(pInt, 0x0600, 0xf4);
190
* Allocate a segment for the stack
192
xf86Int10AllocPages(pInt, 1, &pInt->stackseg);
196
xf86HandleInt10Options(ScrnInfoPtr pScrn, int entityIndex)
198
EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex);
199
OptionInfoPtr options = NULL;
202
pointer configOptions = NULL;
204
/* Check if xf86CollectOptions() has already been called */
205
if (((pEnt->index < 0) ||
207
!(configOptions = pScrn->options)) &&
209
configOptions = pEnt->device->options;
212
if (!(options = (OptionInfoPtr) xalloc(sizeof(INT10Options))))
215
(void)memcpy(options, INT10Options, sizeof(INT10Options));
216
xf86ProcessOptions(pScrn->scrnIndex, configOptions, options);
225
int10skip(void* options)
227
Bool noint10 = FALSE;
229
if (!options) return FALSE;
231
xf86GetOptValBool(options, OPT_NOINT10, &noint10);
236
int10_check_bios(int scrnIndex, int codeSeg, unsigned char* vbiosMem)
240
if ((codeSeg & 0x1f) || /* Not 512-byte aligned otherwise */
241
((codeSeg << 4) < V_BIOS) ||
242
((codeSeg << 4) >= SYS_SIZE))
248
if ((*vbiosMem != 0x55) || (*(vbiosMem+1) != 0xAA) || !*(vbiosMem+2))
251
size = *(vbiosMem + 2) * 512;
253
if ((size + (codeSeg << 4)) > SYS_SIZE)
256
if (bios_checksum(vbiosMem, size))
257
xf86DrvMsg(scrnIndex, X_WARNING, "Bad V_BIOS checksum\n");
263
initPrimary(void* options)
265
Bool initPrimary = FALSE;
267
if (!options) return FALSE;
269
xf86GetOptValBool(options, OPT_INIT_PRIMARY, &initPrimary);
274
* xf86int10ParseBiosLocation(): allows to set the location of the
275
* BIOS. One may select a BIOS of another card for posting or the
276
* legacy V_BIOS range located at 0xc0000 or an alternative address
278
* This is only useful under very special circumstances and should
279
* be used with extreme care.
282
xf86int10ParseBiosLocation(void* options,
283
xf86int10BiosLocationPtr bios)
290
str = xf86GetOptValString(options,OPT_BIOS_LOCATION);
292
bios->bus = BUS_NONE;
298
if (xf86NameCmp(p,"pci") == 0) bios->bus = BUS_PCI;
300
if (xf86NameCmp(p,"primary") == 0) bios->bus = BUS_ISA;
304
if (bios->bus == BUS_NONE) return;
312
bios->location.legacy = atoi(++p);
314
bios->location.legacy = 0;
318
bios->location.pci.bus = atoi(++p);
319
if ((p = strchr(p, ':'))) {
320
bios->location.pci.dev = atoi(++p);
321
if ((p = strchr(p, ':'))) {
322
bios->location.pci.func = atoi(++p);
328
bios->bus = BUS_NONE;