⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcilib.c

📁 source code of armboot for s3c4510
💻 C
📖 第 1 页 / 共 3 页
字号:
    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 + -