Annotation of qemu/roms/seabios/src/pci.c, revision 1.1.1.1

1.1       root        1: // PCI config space access functions.
                      2: //
                      3: // Copyright (C) 2008  Kevin O'Connor <[email protected]>
                      4: // Copyright (C) 2002  MandrakeSoft S.A.
                      5: //
                      6: // This file may be distributed under the terms of the GNU LGPLv3 license.
                      7: 
                      8: #include "pci.h" // pci_config_writel
                      9: #include "ioport.h" // outl
                     10: #include "util.h" // dprintf
                     11: #include "config.h" // CONFIG_*
                     12: #include "pci_regs.h" // PCI_VENDOR_ID
                     13: #include "pci_ids.h" // PCI_CLASS_DISPLAY_VGA
                     14: 
                     15: void pci_config_writel(u16 bdf, u32 addr, u32 val)
                     16: {
                     17:     outl(0x80000000 | (bdf << 8) | (addr & 0xfc), PORT_PCI_CMD);
                     18:     outl(val, PORT_PCI_DATA);
                     19: }
                     20: 
                     21: void pci_config_writew(u16 bdf, u32 addr, u16 val)
                     22: {
                     23:     outl(0x80000000 | (bdf << 8) | (addr & 0xfc), PORT_PCI_CMD);
                     24:     outw(val, PORT_PCI_DATA + (addr & 2));
                     25: }
                     26: 
                     27: void pci_config_writeb(u16 bdf, u32 addr, u8 val)
                     28: {
                     29:     outl(0x80000000 | (bdf << 8) | (addr & 0xfc), PORT_PCI_CMD);
                     30:     outb(val, PORT_PCI_DATA + (addr & 3));
                     31: }
                     32: 
                     33: u32 pci_config_readl(u16 bdf, u32 addr)
                     34: {
                     35:     outl(0x80000000 | (bdf << 8) | (addr & 0xfc), PORT_PCI_CMD);
                     36:     return inl(PORT_PCI_DATA);
                     37: }
                     38: 
                     39: u16 pci_config_readw(u16 bdf, u32 addr)
                     40: {
                     41:     outl(0x80000000 | (bdf << 8) | (addr & 0xfc), PORT_PCI_CMD);
                     42:     return inw(PORT_PCI_DATA + (addr & 2));
                     43: }
                     44: 
                     45: u8 pci_config_readb(u16 bdf, u32 addr)
                     46: {
                     47:     outl(0x80000000 | (bdf << 8) | (addr & 0xfc), PORT_PCI_CMD);
                     48:     return inb(PORT_PCI_DATA + (addr & 3));
                     49: }
                     50: 
                     51: void
                     52: pci_config_maskw(u16 bdf, u32 addr, u16 off, u16 on)
                     53: {
                     54:     u16 val = pci_config_readw(bdf, addr);
                     55:     val = (val & ~off) | on;
                     56:     pci_config_writew(bdf, addr, val);
                     57: }
                     58: 
                     59: // Helper function for foreachpci() macro - return next device
                     60: int
                     61: pci_next(int bdf, int *pmax)
                     62: {
                     63:     if (pci_bdf_to_fn(bdf) == 1
                     64:         && (pci_config_readb(bdf-1, PCI_HEADER_TYPE) & 0x80) == 0)
                     65:         // Last found device wasn't a multi-function device - skip to
                     66:         // the next device.
                     67:         bdf += 7;
                     68: 
                     69:     int max = *pmax;
                     70:     for (;;) {
                     71:         if (bdf >= max) {
                     72:             if (CONFIG_PCI_ROOT1 && bdf <= (CONFIG_PCI_ROOT1 << 8))
                     73:                 bdf = CONFIG_PCI_ROOT1 << 8;
                     74:             else if (CONFIG_PCI_ROOT2 && bdf <= (CONFIG_PCI_ROOT2 << 8))
                     75:                 bdf = CONFIG_PCI_ROOT2 << 8;
                     76:             else
                     77:                return -1;
                     78:             *pmax = max = bdf + 0x0100;
                     79:         }
                     80: 
                     81:         u16 v = pci_config_readw(bdf, PCI_VENDOR_ID);
                     82:         if (v != 0x0000 && v != 0xffff)
                     83:             // Device is present.
                     84:             break;
                     85: 
                     86:         if (pci_bdf_to_fn(bdf) == 0)
                     87:             bdf += 8;
                     88:         else
                     89:             bdf += 1;
                     90:     }
                     91: 
                     92:     // Check if found device is a bridge.
                     93:     u32 v = pci_config_readb(bdf, PCI_HEADER_TYPE);
                     94:     v &= 0x7f;
                     95:     if (v == PCI_HEADER_TYPE_BRIDGE || v == PCI_HEADER_TYPE_CARDBUS) {
                     96:         v = pci_config_readl(bdf, PCI_PRIMARY_BUS);
                     97:         int newmax = (v & 0xff00) + 0x0100;
                     98:         if (newmax > max)
                     99:             *pmax = newmax;
                    100:     }
                    101: 
                    102:     return bdf;
                    103: }
                    104: 
                    105: // Find a vga device with legacy address decoding enabled.
                    106: int
                    107: pci_find_vga()
                    108: {
                    109:     int bdf = 0x0000, max = 0x0100;
                    110:     for (;;) {
                    111:         if (bdf >= max) {
                    112:             if (CONFIG_PCI_ROOT1 && bdf <= (CONFIG_PCI_ROOT1 << 8))
                    113:                 bdf = CONFIG_PCI_ROOT1 << 8;
                    114:             else if (CONFIG_PCI_ROOT2 && bdf <= (CONFIG_PCI_ROOT2 << 8))
                    115:                 bdf = CONFIG_PCI_ROOT2 << 8;
                    116:             else
                    117:                return -1;
                    118:             max = bdf + 0x0100;
                    119:         }
                    120: 
                    121:         u16 cls = pci_config_readw(bdf, PCI_CLASS_DEVICE);
                    122:         if (cls == 0x0000 || cls == 0xffff) {
                    123:             // Device not present.
                    124:             if (pci_bdf_to_fn(bdf) == 0)
                    125:                 bdf += 8;
                    126:             else
                    127:                 bdf += 1;
                    128:             continue;
                    129:         }
                    130:         if (cls == PCI_CLASS_DISPLAY_VGA) {
                    131:             u16 cmd = pci_config_readw(bdf, PCI_COMMAND);
                    132:             if (cmd & PCI_COMMAND_IO && cmd & PCI_COMMAND_MEMORY)
                    133:                 // Found active vga card
                    134:                 return bdf;
                    135:         }
                    136: 
                    137:         // Check if device is a bridge.
                    138:         u8 hdr = pci_config_readb(bdf, PCI_HEADER_TYPE);
                    139:         u8 ht = hdr & 0x7f;
                    140:         if (ht == PCI_HEADER_TYPE_BRIDGE || ht == PCI_HEADER_TYPE_CARDBUS) {
                    141:             u32 ctrl = pci_config_readb(bdf, PCI_BRIDGE_CONTROL);
                    142:             if (ctrl & PCI_BRIDGE_CTL_VGA) {
                    143:                 // Found a VGA enabled bridge.
                    144:                 u32 pbus = pci_config_readl(bdf, PCI_PRIMARY_BUS);
                    145:                 bdf = (pbus & 0xff00);
                    146:                 max = bdf + 0x100;
                    147:                 continue;
                    148:             }
                    149:         }
                    150: 
                    151:         if (pci_bdf_to_fn(bdf) == 0 && (hdr & 0x80) == 0)
                    152:             // Last found device wasn't a multi-function device - skip to
                    153:             // the next device.
                    154:             bdf += 8;
                    155:         else
                    156:             bdf += 1;
                    157:     }
                    158: }
                    159: 
                    160: // Search for a device with the specified vendor and device ids.
                    161: int
                    162: pci_find_device(u16 vendid, u16 devid)
                    163: {
                    164:     u32 id = (devid << 16) | vendid;
                    165:     int bdf, max;
                    166:     foreachpci(bdf, max) {
                    167:         u32 v = pci_config_readl(bdf, PCI_VENDOR_ID);
                    168:         if (v == id)
                    169:             return bdf;
                    170:     }
                    171:     return -1;
                    172: }
                    173: 
                    174: // Search for a device with the specified class id.
                    175: int
                    176: pci_find_class(u16 classid)
                    177: {
                    178:     int bdf, max;
                    179:     foreachpci(bdf, max) {
                    180:         u16 v = pci_config_readw(bdf, PCI_CLASS_DEVICE);
                    181:         if (v == classid)
                    182:             return bdf;
                    183:     }
                    184:     return -1;
                    185: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.