Refactor common code from the generic.c and linux.c version of

xf86ExtendedInitInt10 to xf86int10GetBiosLocationType and
xf86int10GetBiosSegment.

These changes were tested on MGA hardware on x86-64 with various
combinations of InitPrimary and BiosLocation.
This commit is contained in:
Ian Romanick 2006-07-14 15:13:35 -07:00
parent 8793c7fd4b
commit d3ee49bcba
4 changed files with 135 additions and 184 deletions

View File

@ -136,59 +136,12 @@ xf86ExtendedInitInt10(int entityIndex, int Flags)
if (xf86IsEntityPrimary(entityIndex) if (xf86IsEntityPrimary(entityIndex)
&& !(initPrimary(options))) { && !(initPrimary(options))) {
if (! xf86int10GetBiosSegment(pInt, &bios,
if (bios.bus == BUS_ISA && bios.location.legacy) { (unsigned char *)sysMem - V_BIOS)) {
xf86DrvMsg(screen, X_CONFIG, goto error1;
"Overriding BIOS location: 0x%x\n",
bios.location.legacy);
cs = bios.location.legacy >> 4;
#define CHECK_V_SEGMENT_RANGE(x) \
if (((x) << 4) < V_BIOS) {\
xf86DrvMsg(screen, X_ERROR, \
"V_BIOS address 0x%lx out of range\n", \
(unsigned long)(x) << 4); \
goto error1; \
}
CHECK_V_SEGMENT_RANGE(cs);
vbiosMem = (unsigned char *)sysMem - V_BIOS + (cs << 4);
if (!int10_check_bios(screen, cs, vbiosMem)) {
xf86DrvMsg(screen, X_ERROR,
"No V_BIOS at specified address 0x%lx\n",
(unsigned long)cs << 4);
goto error1;
}
} else {
if (bios.bus == BUS_PCI) {
xf86DrvMsg(screen, X_WARNING,
"Option BiosLocation for primary device ignored: "
"It points to PCI.\n");
xf86DrvMsg(screen, X_WARNING,
"You must set Option InitPrimary also\n");
}
cs = MEM_RW(pInt,((0x10<<2)+2));
CHECK_V_SEGMENT_RANGE(cs);
vbiosMem = (unsigned char *)sysMem - V_BIOS + (cs << 4);
if (!int10_check_bios(screen, cs, vbiosMem)) {
cs = MEM_RW(pInt, (0x42 << 2) + 2);
CHECK_V_SEGMENT_RANGE(cs);
vbiosMem = (unsigned char *)sysMem - V_BIOS + (cs << 4);
if (!int10_check_bios(screen, cs, vbiosMem)) {
cs = V_BIOS >> 4;
vbiosMem = (unsigned char *)sysMem - V_BIOS + (cs << 4);
if (!int10_check_bios(screen, cs, vbiosMem)) {
xf86DrvMsg(screen, X_ERROR, "No V_BIOS found\n");
goto error1;
}
}
}
} }
xf86DrvMsg(screen, X_INFO, "Primary V_BIOS segment is: 0x%lx\n",
(unsigned long)cs);
set_return_trap(pInt); set_return_trap(pInt);
pInt->BIOSseg = cs;
pInt->Flags = Flags & (SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH); pInt->Flags = Flags & (SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH);
if (! (pInt->Flags & SET_BIOS_SCRATCH)) if (! (pInt->Flags & SET_BIOS_SCRATCH))
@ -196,54 +149,33 @@ xf86ExtendedInitInt10(int entityIndex, int Flags)
xf86Int10SaveRestoreBIOSVars(pInt, TRUE); xf86Int10SaveRestoreBIOSVars(pInt, TRUE);
} else { } else {
BusType location_type; const BusType location_type = xf86int10GetBiosLocationType(pInt,
&bios);
int bios_location = V_BIOS; int bios_location = V_BIOS;
int pci_entity;
EntityInfoPtr pEnt = xf86GetEntityInfo(pInt->entityIndex);
reset_int_vect(pInt); reset_int_vect(pInt);
set_return_trap(pInt); set_return_trap(pInt);
if (bios.bus != BUS_NONE) {
switch (location_type = bios.bus) {
case BUS_PCI:
xf86DrvMsg(screen,X_CONFIG,"Overriding bios location: "
"PCI:%i:%i%i\n",bios.location.pci.bus,
bios.location.pci.dev,bios.location.pci.func);
break;
case BUS_ISA:
bios_location = bios.location.legacy;
if (bios.location.legacy)
xf86DrvMsg(screen,X_CONFIG,"Overriding bios location: "
"Legacy:0x%x\n",bios.location.legacy);
else
xf86DrvMsg(screen,X_CONFIG,"Overriding bios location: "
"Legacy\n");
break;
default:
break;
}
} else
location_type = pEnt->location.type;
xfree(pEnt);
switch (location_type) { switch (location_type) {
case BUS_PCI: case BUS_PCI: {
const int pci_entity = (bios.bus == BUS_PCI)
? xf86GetPciEntity(bios.location.pci.bus,
bios.location.pci.dev,
bios.location.pci.func)
: pInt->entityIndex;
vbiosMem = (unsigned char *)base + bios_location; vbiosMem = (unsigned char *)base + bios_location;
if (bios.bus == BUS_PCI)
pci_entity = xf86GetPciEntity(bios.location.pci.bus,
bios.location.pci.dev,
bios.location.pci.func);
else
pci_entity = pInt->entityIndex;
if (!(size = mapPciRom(pci_entity,(unsigned char *)(vbiosMem)))) { if (!(size = mapPciRom(pci_entity,(unsigned char *)(vbiosMem)))) {
xf86DrvMsg(screen,X_ERROR,"Cannot read V_BIOS (3)\n"); xf86DrvMsg(screen,X_ERROR,"Cannot read V_BIOS (3)\n");
goto error1; goto error1;
} }
INTPriv(pInt)->highMemory = GET_HIGH_BASE(size); INTPriv(pInt)->highMemory = GET_HIGH_BASE(size);
break; break;
}
case BUS_ISA: case BUS_ISA:
if (bios.bus == BUS_ISA) {
bios_location = bios.location.legacy;
}
vbiosMem = (unsigned char *)sysMem + bios_location; vbiosMem = (unsigned char *)sysMem + bios_location;
#if 0 #if 0
(void)memset(vbiosMem, 0, V_BIOS_SIZE); (void)memset(vbiosMem, 0, V_BIOS_SIZE);

View File

@ -336,4 +336,104 @@ xf86int10ParseBiosLocation(void* options,
} }
BusType
xf86int10GetBiosLocationType(const xf86Int10InfoPtr pInt,
const xf86int10BiosLocationPtr bios)
{
BusType location_type = bios->bus;
switch (location_type) {
case BUS_PCI:
xf86DrvMsg(pInt->scrnIndex,X_CONFIG,"Overriding bios location: "
"PCI:%i:%i%i\n",bios->location.pci.bus,
bios->location.pci.dev,bios->location.pci.func);
break;
case BUS_ISA:
if (bios->location.legacy)
xf86DrvMsg(pInt->scrnIndex,X_CONFIG,"Overriding bios location: "
"Legacy:0x%x\n",bios->location.legacy);
else
xf86DrvMsg(pInt->scrnIndex,X_CONFIG,"Overriding bios location: "
"Legacy\n");
break;
case BUS_NONE: {
EntityInfoPtr pEnt = xf86GetEntityInfo(pInt->entityIndex);
location_type = pEnt->location.type;
xfree(pEnt);
break;
}
default:
break;
}
return location_type;
}
#define CHECK_V_SEGMENT_RANGE(x) \
if (((x) << 4) < V_BIOS) { \
xf86DrvMsg(pInt->scrnIndex, X_ERROR, \
"V_BIOS address 0x%lx out of range\n", \
(unsigned long)(x) << 4); \
return FALSE; \
}
Bool
xf86int10GetBiosSegment(xf86Int10InfoPtr pInt,
const xf86int10BiosLocationPtr bios, void * base)
{
unsigned i;
int cs = ~0;
int segments[4];
const char * format;
if (bios->bus == BUS_ISA && bios->location.legacy) {
xf86DrvMsg(pInt->scrnIndex, X_CONFIG,
"Overriding BIOS location: 0x%x\n",
bios->location.legacy);
segments[0] = bios->location.legacy >> 4;
segments[1] = ~0;
format = "No V_BIOS at specified address 0x%lx\n";
} else {
if (bios->bus == BUS_PCI) {
xf86DrvMsg(pInt->scrnIndex, X_WARNING,
"Option BiosLocation for primary device ignored: "
"It points to PCI.\n");
xf86DrvMsg(pInt->scrnIndex, X_WARNING,
"You must set Option InitPrimary also\n");
}
segments[0] = MEM_RW(pInt, (0x10 << 2) + 2);
segments[1] = MEM_RW(pInt, (0x42 << 2) + 2);
segments[2] = V_BIOS >> 4;
segments[3] = ~0;
format = "No V_BIOS found\n";
}
for (i = 0; segments[i] != ~0; i++) {
unsigned char * vbiosMem;
cs = segments[i];
CHECK_V_SEGMENT_RANGE(cs);
vbiosMem = (unsigned char *)base + (cs << 4);
if (int10_check_bios(pInt->scrnIndex, cs, vbiosMem)) {
break;
}
}
if (segments[i] == ~0) {
xf86DrvMsg(pInt->scrnIndex, X_ERROR, format, (unsigned long)cs << 4);
return FALSE;
}
xf86DrvMsg(pInt->scrnIndex, X_INFO, "Primary V_BIOS segment is: 0x%lx\n",
(unsigned long)cs);
pInt->BIOSseg = cs;
return TRUE;
}

View File

@ -187,6 +187,10 @@ Bool int10_check_bios(int scrnIndex, int codeSeg, unsigned char* vbiosMem);
Bool initPrimary(void* options); Bool initPrimary(void* options);
void xf86int10ParseBiosLocation(void* options, void xf86int10ParseBiosLocation(void* options,
xf86int10BiosLocationPtr bios); xf86int10BiosLocationPtr bios);
BusType xf86int10GetBiosLocationType(const xf86Int10InfoPtr pInt,
const xf86int10BiosLocationPtr bios);
Bool xf86int10GetBiosSegment(xf86Int10InfoPtr pInt,
const xf86int10BiosLocationPtr bios, void * base);
#ifdef DEBUG #ifdef DEBUG
void dprint(unsigned long start, unsigned long size); void dprint(unsigned long start, unsigned long size);
#endif #endif

View File

@ -264,52 +264,15 @@ xf86ExtendedInitInt10(int entityIndex, int Flags)
ErrorF("done\n"); ErrorF("done\n");
#endif #endif
} }
xf86int10ParseBiosLocation(options,&bios); xf86int10ParseBiosLocation(options,&bios);
if (xf86IsEntityPrimary(entityIndex) if (xf86IsEntityPrimary(entityIndex)
&& !(initPrimary(options))) { && !(initPrimary(options))) {
if (bios.bus == BUS_ISA && bios.location.legacy) { if (! xf86int10GetBiosSegment(pInt, &bios, NULL)) {
xf86DrvMsg(screen, X_CONFIG, goto error3;
"Overriding BIOS location: 0x%x\n",
bios.location.legacy);
cs = bios.location.legacy >> 4;
bios_base = (unsigned char *)(cs << 4);
if (!int10_check_bios(screen, cs, bios_base)) {
xf86DrvMsg(screen, X_ERROR,
"No V_BIOS at specified address 0x%lx\n",cs << 4);
goto error3;
}
} else {
if (bios.bus == BUS_PCI) {
xf86DrvMsg(screen, X_WARNING,
"Option BiosLocation for primary device ignored: "
"It points to PCI.\n");
xf86DrvMsg(screen, X_WARNING,
"You must set Option InitPrimary also\n");
}
cs = ((CARD16*)0)[(0x10<<1) + 1];
bios_base = (unsigned char *)(cs << 4);
if (!int10_check_bios(screen, cs, bios_base)) {
cs = ((CARD16*)0)[(0x42 << 1) + 1];
bios_base = (unsigned char *)(cs << 4);
if (!int10_check_bios(screen, cs, bios_base)) {
cs = V_BIOS >> 4;
bios_base = (unsigned char *)(cs << 4);
if (!int10_check_bios(screen, cs, bios_base)) {
xf86DrvMsg(screen, X_ERROR, "No V_BIOS found\n");
goto error3;
}
}
}
} }
xf86DrvMsg(screen, X_INFO, "Primary V_BIOS segment is: 0x%lx\n", cs);
pInt->BIOSseg = cs;
set_return_trap(pInt); set_return_trap(pInt);
#ifdef _PC #ifdef _PC
pInt->Flags = Flags & (SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH); pInt->Flags = Flags & (SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH);
@ -318,41 +281,17 @@ xf86ExtendedInitInt10(int entityIndex, int Flags)
xf86Int10SaveRestoreBIOSVars(pInt, TRUE); xf86Int10SaveRestoreBIOSVars(pInt, TRUE);
#endif #endif
} else { } else {
EntityInfoPtr pEnt = xf86GetEntityInfo(pInt->entityIndex); const BusType location_type = xf86int10GetBiosLocationType(pInt,
BusType location_type; &bios);
if (bios.bus != BUS_NONE) {
switch (location_type = bios.bus) {
case BUS_PCI:
xf86DrvMsg(screen,X_CONFIG,"Overriding bios location: "
"PCI:%i:%i%i\n",bios.location.pci.bus,
bios.location.pci.dev,bios.location.pci.func);
break;
case BUS_ISA:
if (bios.location.legacy)
xf86DrvMsg(screen,X_CONFIG,"Overriding bios location: "
"Legacy:0x%x\n",bios.location.legacy);
else
xf86DrvMsg(screen,X_CONFIG,"Overriding bios location: "
"Legacy\n");
break;
default:
break;
}
} else
location_type = pEnt->location.type;
switch (location_type) { switch (location_type) {
case BUS_PCI: case BUS_PCI: {
{ const int pci_entity = (bios.bus == BUS_PCI)
int pci_entity; ? xf86GetPciEntity(bios.location.pci.bus,
bios.location.pci.dev,
bios.location.pci.func)
: pInt->entityIndex;
if (bios.bus == BUS_PCI)
pci_entity = xf86GetPciEntity(bios.location.pci.bus,
bios.location.pci.dev,
bios.location.pci.func);
else
pci_entity = pInt->entityIndex;
if (!mapPciRom(pci_entity, (unsigned char *)(V_BIOS))) { if (!mapPciRom(pci_entity, (unsigned char *)(V_BIOS))) {
xf86DrvMsg(screen, X_ERROR, "Cannot read V_BIOS\n"); xf86DrvMsg(screen, X_ERROR, "Cannot read V_BIOS\n");
goto error3; goto error3;
@ -361,38 +300,14 @@ xf86ExtendedInitInt10(int entityIndex, int Flags)
break; break;
} }
case BUS_ISA: case BUS_ISA:
if (bios.bus == BUS_ISA && bios.location.legacy) { if (! xf86int10GetBiosSegment(pInt, &bios, NULL)) {
cs = bios.location.legacy >> 4; goto error3;
bios_base = (unsigned char *)(cs << 4);
if (!int10_check_bios(screen, cs, bios_base)) {
xf86DrvMsg(screen,X_ERROR,"No V_BIOS found "
"on override address %p\n",bios_base);
goto error3;
}
} else {
cs = ((CARD16*)0)[(0x10<<1)+1];
bios_base = (unsigned char *)(cs << 4);
if (!int10_check_bios(screen, cs, bios_base)) {
cs = ((CARD16*)0)[(0x42<<1)+1];
bios_base = (unsigned char *)(cs << 4);
if (!int10_check_bios(screen, cs, bios_base)) {
cs = V_BIOS >> 4;
bios_base = (unsigned char *)(cs << 4);
if (!int10_check_bios(screen, cs, bios_base)) {
xf86DrvMsg(screen,X_ERROR,"No V_BIOS found\n");
goto error3;
}
}
}
} }
xf86DrvMsg(screen,X_INFO,"Primary V_BIOS segment is: 0x%lx\n",cs);
pInt->BIOSseg = cs;
break; break;
default: default:
goto error3; goto error3;
} }
xfree(pEnt);
pInt->num = 0xe6; pInt->num = 0xe6;
reset_int_vect(pInt); reset_int_vect(pInt);
set_return_trap(pInt); set_return_trap(pInt);