📄 pcilib.c
字号:
int i;
UINT32 addr;
UINT32 vendor, device, rev, devClass, cmd;
//dump the details of this device Print("\n");
Print ("\n");
Print ("Bus Slot Func Vendor Device Rev Class Cmd\n");
Print ("=== ==== ==== ====== ====== ==== ================ ====\n");
Print (" %02d %02d %02d ", bus, slot, func);
//grab more details from the device's PCI configuration area
vendor = PCICFG_Read16 (bus, slot, func, PCIHVID_OFF);
device = PCICFG_Read16 (bus, slot, func, PCIHDID_OFF);
rev = PCICFG_Read8 (bus, slot, func, PCIHREV_OFF);
devClass = (0x00ffffff & PCICFG_Read32 (bus, slot, func, PCIHCLASS_OFF));
cmd = PCICFG_Read16 (bus, slot, func, PCIHCMD_OFF);
Print ("0x%04x 0x%04x 0x%02x ", vendor, device, rev);
Print ("%s 0x%02x\n\n", getDeviceClass (vendor, device, devClass), cmd);
Print (" Reg Address Type\n");
Print (" ==== ========== ======\n");
// Scan each of the BARS for this device
for (i = 0; i < PCI_MAX_BAR; i++)
{
Print (" 0x%02x ", offset);
/* Read back address assigned for this BAR */
data = PCICFG_Read32 (bus, slot, func, offset);
/* Mask off BAR bits */
addr = data & (~0x0F);
if (data & PCI_IO_ENABLE){
/* IO space BAR */
Print ("0x%08x IO\n", data);
//Print ("0x%08x IO\n", addr);
}
else{
/* memory space BAR */
Print ("0x%08x Memory\n", data);
//Print ("0x%08x Memory\n", addr);
}
/* increment the BAR offset value */
offset += 4;
}
// Do the ROM bar separately
Print (" 0x%02x ", PCIHEXPR_OFF);
data = PCICFG_Read32 (bus, slot, func, PCIHEXPR_OFF);
Print ("0x%08x ROM\n", data);
// Interrupt pin & slot
Print (" 0x%02x ", PCIHINTPIN_OFF);
data = PCICFG_Read8 (bus, slot, func, PCIHINTPIN_OFF);
Print ("0x%08x Interrupt Pin\n", data);
Print (" 0x%02x ", PCIHINTLINE_OFF);
data = PCICFG_Read8 (bus, slot, func, PCIHINTLINE_OFF);
Print ("0x%08x Interrupt Line\n", data);
}
/*============================================================================
*
* description: Call the action routine specified once for every PCI device
* in the system.
*
* returns: void.
*
*/
void PCIr_ForEveryDevice (void (action) (UINT32, UINT32, UINT32))
{
PCIDevice_t *device;
// look through the PCI device list for each PCI device
for (device = g_sPCIDeviceList; device != NULL; device = device->next)
{
// call the action routine
(PCI_Action) (device->bus, device->slot, device->func);
}
}
char * getDeviceClass (UINT id, UINT device, UINT devClass)
{
UINT baseClass = devClass >> 16;
UINT subClass = ((devClass & 0xff00) >> 8);
switch (baseClass)
{
case PCI_HISTORY_CLASS:
/* Early revisions of these devices have no class value. Future
* versions hopefully will. */
if ((id == 0x8086) && (device == 0x484))
return (char *) "ISA Bridge";
if ((id == 0x8086) && (device == 0x483))
return (char *) "Host Bridge";
if ((id == 0x8086) && (device == 0x482))
return (char *) "EISA Bridge";
if ((id == 0x8086) && (device == 0x453))
return (char *) "PCI Test Card";
if ((id == 0x1011) && (device == 0x004))
return (char *) "TGA video card";
if ((id == 0x1011) && (device == 0x002))
return (char *) "21040";
if ((id == 0x1000) && (device == 0x1))
return (char *) "SCSI Bus";
switch (subClass)
{
case 0:
return (char *) "PCI Device";
case 1:
return (char *) "VGA Device";
}
case PCI_STORAGE_CLASS:
switch (subClass)
{
case 0:
return (char *) "SCSI Bus";
case 1:
return (char *) "IDE";
case 2:
return (char *) "Floppy Disk";
case 3:
return (char *) "IPI Disk";
case 4:
return (char *) "RAID Controller";
default:
return (char *) "Mass Storage";
}
case PCI_NETWORK_CLASS:
switch (subClass)
{
case 0:
return (char *) "Ethernet";
case 1:
return (char *) "Token Ring";
case 2:
return (char *) "FDDI";
case 3:
return (char *) "ATM";
default:
return (char *) "Network";
}
case PCI_DISPLAY_CLASS:
switch (subClass)
{
case 0:
return (char *) "VGA";
case 1:
return (char *) "XGA";
case 0x80:
return (char *) "Other";
default:
return (char *) "Display";
}
case PCI_MMEDIA_CLASS:
switch (subClass)
{
case 0:
return (char *) "Multimedia Video";
case 1:
return (char *) "Multimedia Audio";
default:
return (char *) "Multimedia";
}
case PCI_MEMORY_CLASS:
switch (subClass)
{
case 0:
return (char *) "RAM";
case 1:
return (char *) "FLASH";
default:
return (char *) "Memory";
}
case PCI_BRIDGE_CLASS:
switch (subClass)
{
case 0:
return (char *) "Host Bridge";
case 1:
return (char *) "ISA Bridge";
case 2:
return (char *) "EISA Bridge";
case 3:
return (char *) "MC Bridge";
case 4:
return (char *) "PCI->PCI Bridge";
case 5:
return (char *) "PCMCIA Bridge";
case 6:
return (char *) "NuBus Bridge";
case 7:
return (char *) "CardBus Bridge";
default:
return (char *) "Bridge Device";
}
case PCI_COMMS_CLASS:
switch (subClass)
{
case 0:
return (char *) "Serial port";
case 1:
return (char *) "Parallel port";
default:
return (char *) "Comm Device";
}
case PCI_PERIPH_CLASS:
switch (subClass)
{
case 0:
return (char *) "PIC";
case 1:
return (char *) "DMA Controller";
case 2:
return (char *) "System Timer";
case 3:
return (char *) "RTC";
default:
return (char *) "Peripheral";
}
case PCI_INPUT_CLASS:
switch (subClass)
{
case 0:
return (char *) "Keyboard";
case 1:
return (char *) "Digitizer (pen)";
case 2:
return (char *) "Mouse";
default:
return (char *) "Input Controller";
}
case PCI_DOCKING_CLASS:
switch (subClass)
{
case 0:
return (char *) "Docking Station";
default:
return (char *) "Docking Station";
}
case PCI_PROCESS_CLASS:
if ((id == 0x1011) && (device == 0x1065))
return (char *) "DIGITAL DC21285";
switch (subClass)
{
case 0:
return (char *) "386 Processor";
case 1:
return (char *) "486 Processor";
case 2:
return (char *) "Pentium";
case 0x10:
return (char *) "Alpha Processor";
case 0x20:
return (char *) "Power PC";
case 0x40:
return (char *) "Co-processor";
default:
return (char *) "Unknown Device";
}
case PCI_SERIAL_CLASS:
switch (subClass)
{
case 0:
return (char *) "FireWire";
case 1:
return (char *) "ACCESS.bus";
case 2:
return (char *) "SSA";
case 3:
return (char *) "USB";
case 4:
return (char *) "Fibre Channel";
default:
return (char *) "Unknown Device";
}
case PCI_MISC_CLASS:
if ((id == 0x103C) && (device == 0x2925))
return (char *) "HP PCI Exerciser";
return (char *) "PCI Device";
default:
if ((id == 0x8086) && (device == 0x4248))
return (char *) "PCI Dlock Card";
return (char *) "Unknown Device";
}
}
/*============================================================================
*
* description: Allocate PCI IO and Memory to all of the PCI devices
* attached to this PCI bus. If this is not the host bus (#0),
* then set up the PCI-PCI bridge's IO and Memory windows
*
* returns: void
*/
void PCIir_ConfigurePCIDevices (PCIDevice_t * bus)
{
UINT32 temp;
UINT32 bio, tio, bmem, tmem;
PCIDevice_t *current;
// align the current IO and Memory bases on appropriate boundaries
bio = g_u32PciIoBase = ALIGN (g_u32PciIoBase, SZ_4K);
bmem = g_u32PciMemBase = ALIGN (g_u32PciMemBase, SZ_1M);
// scan all of the devices on this bus, recurse through bridges
for (current = bus->bridge.children; current != NULL; current = current->sibling)
{
if (current->flags.bridge)
// configure all buses downstream (note that this is deliberately recursive)
PCIir_ConfigurePCIDevices (current);
else
// assign this device some resources
PCIir_AssignResources (current);
}
// If this is not the host bus (#0), set up the PCI-PCI bridge's IO and
// memory windows.
// align the current IO and Memory bases on appropriate boundaries
tio = g_u32PciIoBase = ALIGN (g_u32PciIoBase, SZ_4K);
tmem = g_u32PciMemBase = ALIGN (g_u32PciMemBase, SZ_1M);
if (bus->bridge.number != 0)
{
// ...and set up the bridge's PCI IO and PCI Memory windows
// ...IO
temp = PCICFG_Read32 (bus->bus, bus->slot, bus->func, 0x1C);
temp = (temp & 0xffff0000) | ((bio >> 8) & 0x00f0) | ((tio - 1) & 0xf000);
PCICFG_Write32 (bus->bus, bus->slot, bus->func, 0x1C, temp);
// ...Memory
temp = ((bmem & 0xfff00000) >> 16) | ((tmem - 1) & 0xfff00000);
PCICFG_Write32 (bus->bus, bus->slot, bus->func, 0x20, temp);
// allow the bus to do IO and Memory
temp = PCICFG_Read16 (bus->bus, bus->slot, bus->func, PCIHCMD_OFF);
temp |= (PCI_MASTER_ENABLE | PCI_MEM_ENABLE | PCI_IO_ENABLE);
PCICFG_Write16 (bus->bus, bus->slot, bus->func, PCIHCMD_OFF, temp);
}
}
UINT32 ALIGN (UINT32 val, UINT32 align)
{
// Some heuristics
// ...if the value is zero, it is aligned, no matter what the size
if (val == 0)
return val;
// ...if the value is less than the alignment, return the alignment
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -