warmboot.c

来自「适合KS8695X」· C语言 代码 · 共 570 行 · 第 1/2 页

C
570
字号
	    /* Load the BIOS and interrupt vector information from disk */
	    sprintf(filename,"%s/bios.%02d",PM_getNucleusConfigPath(),device);
	    if ((f = fopen(filename,"rb")) != NULL) {
		fread(copyOfBIOS,1,FINAL_BIOSLEN,f);
		fread(VGAInfo[device].LowMem,1,sizeof(VGAInfo[device].LowMem),f);
		fclose(f);
		}
	    }

	/* Fix up all the secondary PCI base address registers */
	/* (restores them all from the values we read previously) */
	_PCI_fixupSecondaryBARs();

	/* Disable the secondary controller and AGP VGA pass-through */
	DISABLE_DEVICE(device);
	if (AGPBridge)
	    DISABLE_AGP_VGA();
	}

    /* Reenable primary display controller and reset AGP bridge control */
    if (AGPBridge)
	RESTORE_AGP_VGA();
    ENABLE_DEVICE(0);

    /* Free physical BIOS image mapping */
    PM_freePhysicalAddr(mappedBIOS,MAX_BIOSLEN-1);

    /* Restore the X86 emulator BIOS info to primary controller */
    if (!useV86)
	BE_setVGA(&VGAInfo[0]);
    return true;
}

/****************************************************************************
REMARKS:
Enumerates the PCI bus and dumps the PCI configuration information to the
log file.
****************************************************************************/
static void EnumeratePCI(void)
{
    int             i,index;
    PCIBridgeInfo   *info;

    printk("Displaying enumeration of PCI bus (%d devices, %d display devices)\n",
	NumPCI, NumDevices);
    for (index = 0; index < NumDevices; index++)
	printk("  Display device %d is PCI device %d\n",index,DeviceIndex[index]);
    printk("\n");
    printk("Bus Slot Fnc DeviceID  SubSystem Rev Class IRQ Int Cmd\n");
    for (i = 0; i < NumPCI; i++) {
	printk("%2d   %2d  %2d  %04X:%04X %04X:%04X %02X  %02X:%02X %02X  %02X  %04X   ",
	    PCI[i].slot.p.Bus,
	    PCI[i].slot.p.Device,
	    PCI[i].slot.p.Function,
	    PCI[i].VendorID,
	    PCI[i].DeviceID,
	    PCI[i].SubSystemVendorID,
	    PCI[i].SubSystemID,
	    PCI[i].RevID,
	    PCI[i].BaseClass,
	    PCI[i].SubClass,
	    PCI[i].InterruptLine,
	    PCI[i].InterruptPin,
	    PCI[i].Command);
	for (index = 0; index < NumDevices; index++) {
	    if (DeviceIndex[index] == i)
		break;
	    }
	if (index < NumDevices)
	    printk("<- %d\n", index);
	else
	    printk("\n");
	}
    printk("\n");
    printk("DeviceID  Stat Ifc Cch Lat Hdr BIST\n");
    for (i = 0; i < NumPCI; i++) {
	printk("%04X:%04X %04X  %02X  %02X  %02X  %02X  %02X   ",
	    PCI[i].VendorID,
	    PCI[i].DeviceID,
	    PCI[i].Status,
	    PCI[i].Interface,
	    PCI[i].CacheLineSize,
	    PCI[i].LatencyTimer,
	    PCI[i].HeaderType,
	    PCI[i].BIST);
	for (index = 0; index < NumDevices; index++) {
	    if (DeviceIndex[index] == i)
		break;
	    }
	if (index < NumDevices)
	    printk("<- %d\n", index);
	else
	    printk("\n");
	}
    printk("\n");
    printk("DeviceID  Base10h  Base14h  Base18h  Base1Ch  Base20h  Base24h  ROMBase\n");
    for (i = 0; i < NumPCI; i++) {
	printk("%04X:%04X %08X %08X %08X %08X %08X %08X %08X ",
	    PCI[i].VendorID,
	    PCI[i].DeviceID,
	    PCI[i].BaseAddress10,
	    PCI[i].BaseAddress14,
	    PCI[i].BaseAddress18,
	    PCI[i].BaseAddress1C,
	    PCI[i].BaseAddress20,
	    PCI[i].BaseAddress24,
	    PCI[i].ROMBaseAddress);
	for (index = 0; index < NumDevices; index++) {
	    if (DeviceIndex[index] == i)
		break;
	    }
	if (index < NumDevices)
	    printk("<- %d\n", index);
	else
	    printk("\n");
	}
    printk("\n");
    printk("DeviceID  BAR10Len BAR14Len BAR18Len BAR1CLen BAR20Len BAR24Len ROMLen\n");
    for (i = 0; i < NumPCI; i++) {
	printk("%04X:%04X %08X %08X %08X %08X %08X %08X %08X ",
	    PCI[i].VendorID,
	    PCI[i].DeviceID,
	    PCI[i].BaseAddress10Len,
	    PCI[i].BaseAddress14Len,
	    PCI[i].BaseAddress18Len,
	    PCI[i].BaseAddress1CLen,
	    PCI[i].BaseAddress20Len,
	    PCI[i].BaseAddress24Len,
	    PCI[i].ROMBaseAddressLen);
	for (index = 0; index < NumDevices; index++) {
	    if (DeviceIndex[index] == i)
		break;
	    }
	if (index < NumDevices)
	    printk("<- %d\n", index);
	else
	    printk("\n");
	}
    printk("\n");
    printk("Displaying enumeration of %d bridge devices\n",NumBridges);
    printk("\n");
    printk("DeviceID  P# S# B# IOB  IOL  MemBase  MemLimit PreBase  PreLimit Ctrl\n");
    for (i = 0; i < NumBridges; i++) {
	info = (PCIBridgeInfo*)&PCI[BridgeIndex[i]];
	printk("%04X:%04X %02X %02X %02X %04X %04X %08X %08X %08X %08X %04X\n",
	    info->VendorID,
	    info->DeviceID,
	    info->PrimaryBusNumber,
	    info->SecondayBusNumber,
	    info->SubordinateBusNumber,
	    ((u16)info->IOBase << 8) & 0xF000,
	    info->IOLimit ?
		((u16)info->IOLimit << 8) | 0xFFF : 0,
	    ((u32)info->MemoryBase << 16) & 0xFFF00000,
	    info->MemoryLimit ?
		((u32)info->MemoryLimit << 16) | 0xFFFFF : 0,
	    ((u32)info->PrefetchableMemoryBase << 16) & 0xFFF00000,
	    info->PrefetchableMemoryLimit ?
		((u32)info->PrefetchableMemoryLimit << 16) | 0xFFFFF : 0,
	    info->BridgeControl);
	}
    printk("\n");
}

/****************************************************************************
RETURNS:
Number of display devices found.

REMARKS:
This function enumerates the number of available display devices on the
PCI bus, and returns the number found.
****************************************************************************/
static int PCI_enumerateDevices(void)
{
    int             i,j;
    PCIBridgeInfo   *info;

    /* If this is the first time we have been called, enumerate all */
    /* devices on the PCI bus. */
    if (NumPCI == -1) {
	for (i = 0; i < MAX_PCI_DEVICES; i++)
	    PCI[i].dwSize = sizeof(PCI[i]);
	if ((NumPCI = PCI_enumerate(PCI,MAX_PCI_DEVICES)) == 0)
	    return -1;

	/* Build a list of all PCI bridge devices */
	for (i = 0,NumBridges = 0,BridgeIndex[0] = -1; i < NumPCI; i++) {
	    if (PCI[i].BaseClass == PCI_BRIDGE_CLASS) {
		if (NumBridges < MAX_PCI_DEVICES)
		    BridgeIndex[NumBridges++] = i;
		}
	    }

	/* Now build a list of all display class devices */
	for (i = 0,NumDevices = 1,DeviceIndex[0] = -1; i < NumPCI; i++) {
	    if (PCI_IS_DISPLAY_CLASS(&PCI[i])) {
		if ((PCI[i].Command & 0x3) == 0x3) {
		    DeviceIndex[0] = i;
		    }
		else {
		    if (NumDevices < MAX_PCI_DEVICES)
			DeviceIndex[NumDevices++] = i;
		    }
		if (PCI[i].slot.p.Bus != 0) {
		    /* This device is on a different bus than the primary */
		    /* PCI bus, so it is probably an AGP device. Find the */
		    /* AGP bus device that controls that bus so we can */
		    /* control it. */
		    for (j = 0; j < NumBridges; j++) {
			info = (PCIBridgeInfo*)&PCI[BridgeIndex[j]];
			if (info->SecondayBusNumber == PCI[i].slot.p.Bus) {
			    AGPBridge = info;
			    break;
			    }
			}
		    }
		}
	    }

	/* Enumerate all PCI and bridge devices to log file */
	EnumeratePCI();
	}
    return NumDevices;
}

FILE *logfile;

void printk(const char *fmt, ...)
{
    va_list argptr;
    va_start(argptr, fmt);
    vfprintf(logfile, fmt, argptr);
    fflush(logfile);
    va_end(argptr);
}

int main(int argc,char *argv[])
{
    while (argc > 1) {
	if (stricmp(argv[1],"-usev86") == 0) {
	    useV86 = true;
	    }
	else if (stricmp(argv[1],"-force") == 0) {
	    forcePost = true;
	    }
#ifdef  DEBUG
	else if (stricmp(argv[1],"-decode") == 0) {
	    debugFlags |= DEBUG_DECODE_F;
	    }
	else if (stricmp(argv[1],"-iotrace") == 0) {
	    debugFlags |= DEBUG_IO_TRACE_F;
	    }
#endif
	else {
	    printf("Usage: warmboot [-usev86] [-force] [-decode] [-iotrace]\n");
	    exit(-1);
	    }
	argc--;
	argv++;
	}
    if ((logfile = fopen("warmboot.log","w")) == NULL)
	exit(1);

    PM_init();
    if (!useV86) {
	/* Initialise the x86 BIOS emulator */
	BE_init(false,debugFlags,65536,&VGAInfo[0]);
	}

    /* Enumerate all devices (which POST's them at the same time) */
    if (PCI_enumerateDevices() < 1) {
	printk("No PCI display devices found!\n");
	return -1;
	}

    /* Post all the display controller BIOS'es */
    PCI_postControllers();

    /* Cleanup and exit the emulator */
    if (!useV86)
	BE_exit();
    fclose(logfile);
    return 0;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?