Annotation of qemu/roms/seabios/src/pciinit.c, revision 1.1.1.7

1.1       root        1: // Initialize PCI devices (on emulators)
                      2: //
                      3: // Copyright (C) 2008  Kevin O'Connor <[email protected]>
                      4: // Copyright (C) 2006 Fabrice Bellard
                      5: //
                      6: // This file may be distributed under the terms of the GNU LGPLv3 license.
                      7: 
                      8: #include "util.h" // dprintf
                      9: #include "pci.h" // pci_config_readl
                     10: #include "biosvar.h" // GET_EBDA
                     11: #include "pci_ids.h" // PCI_VENDOR_ID_INTEL
                     12: #include "pci_regs.h" // PCI_COMMAND
1.1.1.7 ! root       13: #include "xen.h" // usingXen
1.1       root       14: 
1.1.1.7 ! root       15: #define PCI_IO_INDEX_SHIFT 2
        !            16: #define PCI_MEM_INDEX_SHIFT 12
        !            17: 
        !            18: #define PCI_BRIDGE_IO_MIN      0x1000
        !            19: #define PCI_BRIDGE_MEM_MIN   0x100000
        !            20: 
        !            21: enum pci_region_type {
        !            22:     PCI_REGION_TYPE_IO,
        !            23:     PCI_REGION_TYPE_MEM,
        !            24:     PCI_REGION_TYPE_PREFMEM,
        !            25:     PCI_REGION_TYPE_COUNT,
        !            26: };
        !            27: 
        !            28: static const char *region_type_name[] = {
        !            29:     [ PCI_REGION_TYPE_IO ]      = "io",
        !            30:     [ PCI_REGION_TYPE_MEM ]     = "mem",
        !            31:     [ PCI_REGION_TYPE_PREFMEM ] = "prefmem",
        !            32: };
        !            33: 
        !            34: static struct pci_bus {
        !            35:     struct {
        !            36:         /* pci region stats */
        !            37:         u32 count[32 - PCI_MEM_INDEX_SHIFT];
        !            38:         u32 sum, max;
        !            39:         /* seconday bus region sizes */
        !            40:         u32 size;
        !            41:         /* pci region assignments */
        !            42:         u32 bases[32 - PCI_MEM_INDEX_SHIFT];
        !            43:         u32 base;
        !            44:     } r[PCI_REGION_TYPE_COUNT];
        !            45: } *busses;
        !            46: static int busses_count;
1.1       root       47: 
1.1.1.4   root       48: static void pci_bios_init_device_in_bus(int bus);
1.1.1.7 ! root       49: static void pci_bios_check_device_in_bus(int bus);
        !            50: static void pci_bios_init_bus_bases(struct pci_bus *bus);
        !            51: static void pci_bios_map_device_in_bus(int bus);
1.1.1.4   root       52: 
1.1.1.7 ! root       53: static int pci_size_to_index(u32 size, enum pci_region_type type)
        !            54: {
        !            55:     int index = __fls(size);
        !            56:     int shift = (type == PCI_REGION_TYPE_IO) ?
        !            57:         PCI_IO_INDEX_SHIFT : PCI_MEM_INDEX_SHIFT;
        !            58: 
        !            59:     if (index < shift)
        !            60:         index = shift;
        !            61:     index -= shift;
        !            62:     return index;
        !            63: }
        !            64: 
        !            65: static u32 pci_index_to_size(int index, enum pci_region_type type)
        !            66: {
        !            67:     int shift = (type == PCI_REGION_TYPE_IO) ?
        !            68:         PCI_IO_INDEX_SHIFT : PCI_MEM_INDEX_SHIFT;
        !            69: 
        !            70:     return 0x1 << (index + shift);
        !            71: }
        !            72: 
        !            73: static enum pci_region_type pci_addr_to_type(u32 addr)
        !            74: {
        !            75:     if (addr & PCI_BASE_ADDRESS_SPACE_IO)
        !            76:         return PCI_REGION_TYPE_IO;
        !            77:     if (addr & PCI_BASE_ADDRESS_MEM_PREFETCH)
        !            78:         return PCI_REGION_TYPE_PREFMEM;
        !            79:     return PCI_REGION_TYPE_MEM;
        !            80: }
        !            81: 
        !            82: static u32 pci_size_roundup(u32 size)
        !            83: {
        !            84:     int index = __fls(size-1)+1;
        !            85:     return 0x1 << index;
        !            86: }
1.1.1.6   root       87: 
1.1       root       88: /* host irqs corresponding to PCI irqs A-D */
1.1.1.4   root       89: const u8 pci_irqs[4] = {
1.1       root       90:     10, 10, 11, 11
                     91: };
                     92: 
1.1.1.4   root       93: static u32 pci_bar(u16 bdf, int region_num)
                     94: {
                     95:     if (region_num != PCI_ROM_SLOT) {
                     96:         return PCI_BASE_ADDRESS_0 + region_num * 4;
                     97:     }
                     98: 
                     99: #define PCI_HEADER_TYPE_MULTI_FUNCTION 0x80
                    100:     u8 type = pci_config_readb(bdf, PCI_HEADER_TYPE);
                    101:     type &= ~PCI_HEADER_TYPE_MULTI_FUNCTION;
                    102:     return type == PCI_HEADER_TYPE_BRIDGE ? PCI_ROM_ADDRESS1 : PCI_ROM_ADDRESS;
                    103: }
                    104: 
1.1       root      105: static void pci_set_io_region_addr(u16 bdf, int region_num, u32 addr)
                    106: {
1.1.1.5   root      107:     u32 ofs;
1.1       root      108: 
1.1.1.4   root      109:     ofs = pci_bar(bdf, region_num);
1.1       root      110: 
                    111:     pci_config_writel(bdf, ofs, addr);
1.1.1.4   root      112: }
                    113: 
1.1       root      114: /* return the global irq number corresponding to a given device irq
                    115:    pin. We could also use the bus number to have a more precise
                    116:    mapping. */
                    117: static int pci_slot_get_pirq(u16 bdf, int irq_num)
                    118: {
                    119:     int slot_addend = pci_bdf_to_dev(bdf) - 1;
                    120:     return (irq_num + slot_addend) & 3;
                    121: }
                    122: 
1.1.1.7 ! root      123: /* PIIX3/PIIX4 PCI to ISA bridge */
        !           124: static void piix_isa_bridge_init(struct pci_device *pci, void *arg)
        !           125: {
        !           126:     int i, irq;
        !           127:     u8 elcr[2];
        !           128: 
        !           129:     elcr[0] = 0x00;
        !           130:     elcr[1] = 0x00;
        !           131:     for (i = 0; i < 4; i++) {
        !           132:         irq = pci_irqs[i];
        !           133:         /* set to trigger level */
        !           134:         elcr[irq >> 3] |= (1 << (irq & 7));
        !           135:         /* activate irq remapping in PIIX */
        !           136:         pci_config_writeb(pci->bdf, 0x60 + i, irq);
        !           137:     }
        !           138:     outb(elcr[0], 0x4d0);
        !           139:     outb(elcr[1], 0x4d1);
        !           140:     dprintf(1, "PIIX3/PIIX4 init: elcr=%02x %02x\n", elcr[0], elcr[1]);
        !           141: }
        !           142: 
1.1.1.4   root      143: static const struct pci_device_id pci_isa_bridge_tbl[] = {
                    144:     /* PIIX3/PIIX4 PCI to ISA bridge */
                    145:     PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0,
                    146:                piix_isa_bridge_init),
                    147:     PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0,
                    148:                piix_isa_bridge_init),
                    149: 
                    150:     PCI_DEVICE_END
                    151: };
                    152: 
                    153: #define PCI_IO_ALIGN            4096
                    154: #define PCI_IO_SHIFT            8
                    155: #define PCI_MEMORY_ALIGN        (1UL << 20)
                    156: #define PCI_MEMORY_SHIFT        16
                    157: #define PCI_PREF_MEMORY_ALIGN   (1UL << 20)
                    158: #define PCI_PREF_MEMORY_SHIFT   16
                    159: 
1.1.1.7 ! root      160: static void storage_ide_init(struct pci_device *pci, void *arg)
1.1.1.4   root      161: {
1.1.1.7 ! root      162:     u16 bdf = pci->bdf;
1.1.1.4   root      163:     /* IDE: we map it as in ISA mode */
                    164:     pci_set_io_region_addr(bdf, 0, PORT_ATA1_CMD_BASE);
                    165:     pci_set_io_region_addr(bdf, 1, PORT_ATA1_CTRL_BASE);
                    166:     pci_set_io_region_addr(bdf, 2, PORT_ATA2_CMD_BASE);
                    167:     pci_set_io_region_addr(bdf, 3, PORT_ATA2_CTRL_BASE);
                    168: }
                    169: 
1.1.1.7 ! root      170: /* PIIX3/PIIX4 IDE */
        !           171: static void piix_ide_init(struct pci_device *pci, void *arg)
        !           172: {
        !           173:     u16 bdf = pci->bdf;
        !           174:     pci_config_writew(bdf, 0x40, 0x8000); // enable IDE0
        !           175:     pci_config_writew(bdf, 0x42, 0x8000); // enable IDE1
        !           176: }
        !           177: 
        !           178: static void pic_ibm_init(struct pci_device *pci, void *arg)
1.1.1.4   root      179: {
                    180:     /* PIC, IBM, MPIC & MPIC2 */
1.1.1.7 ! root      181:     pci_set_io_region_addr(pci->bdf, 0, 0x80800000 + 0x00040000);
1.1       root      182: }
                    183: 
1.1.1.7 ! root      184: static void apple_macio_init(struct pci_device *pci, void *arg)
1.1.1.4   root      185: {
                    186:     /* macio bridge */
1.1.1.7 ! root      187:     pci_set_io_region_addr(pci->bdf, 0, 0x80800000);
1.1.1.4   root      188: }
                    189: 
                    190: static const struct pci_device_id pci_class_tbl[] = {
                    191:     /* STORAGE IDE */
                    192:     PCI_DEVICE_CLASS(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_1,
                    193:                      PCI_CLASS_STORAGE_IDE, piix_ide_init),
                    194:     PCI_DEVICE_CLASS(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB,
                    195:                      PCI_CLASS_STORAGE_IDE, piix_ide_init),
                    196:     PCI_DEVICE_CLASS(PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE,
                    197:                      storage_ide_init),
                    198: 
                    199:     /* PIC, IBM, MIPC & MPIC2 */
                    200:     PCI_DEVICE_CLASS(PCI_VENDOR_ID_IBM, 0x0046, PCI_CLASS_SYSTEM_PIC,
                    201:                      pic_ibm_init),
                    202:     PCI_DEVICE_CLASS(PCI_VENDOR_ID_IBM, 0xFFFF, PCI_CLASS_SYSTEM_PIC,
                    203:                      pic_ibm_init),
                    204: 
                    205:     /* 0xff00 */
                    206:     PCI_DEVICE_CLASS(PCI_VENDOR_ID_APPLE, 0x0017, 0xff00, apple_macio_init),
                    207:     PCI_DEVICE_CLASS(PCI_VENDOR_ID_APPLE, 0x0022, 0xff00, apple_macio_init),
                    208: 
                    209:     PCI_DEVICE_END,
                    210: };
                    211: 
1.1.1.7 ! root      212: /* PIIX4 Power Management device (for ACPI) */
        !           213: static void piix4_pm_init(struct pci_device *pci, void *arg)
        !           214: {
        !           215:     u16 bdf = pci->bdf;
        !           216:     // acpi sci is hardwired to 9
        !           217:     pci_config_writeb(bdf, PCI_INTERRUPT_LINE, 9);
        !           218: 
        !           219:     pci_config_writel(bdf, 0x40, PORT_ACPI_PM_BASE | 1);
        !           220:     pci_config_writeb(bdf, 0x80, 0x01); /* enable PM io space */
        !           221:     pci_config_writel(bdf, 0x90, PORT_SMB_BASE | 1);
        !           222:     pci_config_writeb(bdf, 0xd2, 0x09); /* enable SMBus io space */
        !           223: }
        !           224: 
1.1.1.4   root      225: static const struct pci_device_id pci_device_tbl[] = {
                    226:     /* PIIX4 Power Management device (for ACPI) */
                    227:     PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3,
                    228:                piix4_pm_init),
                    229: 
                    230:     PCI_DEVICE_END,
                    231: };
                    232: 
1.1.1.7 ! root      233: static void pci_bios_init_device(struct pci_device *pci)
1.1       root      234: {
1.1.1.7 ! root      235:     u16 bdf = pci->bdf;
        !           236:     int pin, pic_irq;
1.1       root      237: 
                    238:     dprintf(1, "PCI: bus=%d devfn=0x%02x: vendor_id=0x%04x device_id=0x%04x\n"
1.1.1.7 ! root      239:             , pci_bdf_to_bus(bdf), pci_bdf_to_devfn(bdf)
        !           240:             , pci->vendor, pci->device);
        !           241:     pci_init_device(pci_class_tbl, pci, NULL);
1.1       root      242: 
                    243:     /* enable memory mappings */
                    244:     pci_config_maskw(bdf, PCI_COMMAND, 0, PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
                    245: 
                    246:     /* map the interrupt */
                    247:     pin = pci_config_readb(bdf, PCI_INTERRUPT_PIN);
                    248:     if (pin != 0) {
                    249:         pin = pci_slot_get_pirq(bdf, pin - 1);
                    250:         pic_irq = pci_irqs[pin];
                    251:         pci_config_writeb(bdf, PCI_INTERRUPT_LINE, pic_irq);
                    252:     }
                    253: 
1.1.1.7 ! root      254:     pci_init_device(pci_device_tbl, pci, NULL);
1.1.1.4   root      255: }
                    256: 
                    257: static void pci_bios_init_device_in_bus(int bus)
                    258: {
1.1.1.7 ! root      259:     struct pci_device *pci;
        !           260:     foreachpci(pci) {
        !           261:         u8 pci_bus = pci_bdf_to_bus(pci->bdf);
        !           262:         if (pci_bus < bus)
        !           263:             continue;
        !           264:         if (pci_bus > bus)
        !           265:             break;
        !           266:         pci_bios_init_device(pci);
1.1       root      267:     }
                    268: }
                    269: 
1.1.1.4   root      270: static void
                    271: pci_bios_init_bus_rec(int bus, u8 *pci_bus)
                    272: {
1.1.1.7 ! root      273:     int bdf;
1.1.1.4   root      274:     u16 class;
                    275: 
                    276:     dprintf(1, "PCI: %s bus = 0x%x\n", __func__, bus);
                    277: 
                    278:     /* prevent accidental access to unintended devices */
1.1.1.7 ! root      279:     foreachbdf(bdf, bus) {
1.1.1.4   root      280:         class = pci_config_readw(bdf, PCI_CLASS_DEVICE);
                    281:         if (class == PCI_CLASS_BRIDGE_PCI) {
                    282:             pci_config_writeb(bdf, PCI_SECONDARY_BUS, 255);
                    283:             pci_config_writeb(bdf, PCI_SUBORDINATE_BUS, 0);
                    284:         }
                    285:     }
                    286: 
1.1.1.7 ! root      287:     foreachbdf(bdf, bus) {
1.1.1.4   root      288:         class = pci_config_readw(bdf, PCI_CLASS_DEVICE);
                    289:         if (class != PCI_CLASS_BRIDGE_PCI) {
                    290:             continue;
                    291:         }
                    292:         dprintf(1, "PCI: %s bdf = 0x%x\n", __func__, bdf);
                    293: 
                    294:         u8 pribus = pci_config_readb(bdf, PCI_PRIMARY_BUS);
                    295:         if (pribus != bus) {
                    296:             dprintf(1, "PCI: primary bus = 0x%x -> 0x%x\n", pribus, bus);
                    297:             pci_config_writeb(bdf, PCI_PRIMARY_BUS, bus);
                    298:         } else {
                    299:             dprintf(1, "PCI: primary bus = 0x%x\n", pribus);
                    300:         }
                    301: 
                    302:         u8 secbus = pci_config_readb(bdf, PCI_SECONDARY_BUS);
                    303:         (*pci_bus)++;
                    304:         if (*pci_bus != secbus) {
                    305:             dprintf(1, "PCI: secondary bus = 0x%x -> 0x%x\n",
                    306:                     secbus, *pci_bus);
                    307:             secbus = *pci_bus;
                    308:             pci_config_writeb(bdf, PCI_SECONDARY_BUS, secbus);
                    309:         } else {
                    310:             dprintf(1, "PCI: secondary bus = 0x%x\n", secbus);
                    311:         }
                    312: 
                    313:         /* set to max for access to all subordinate buses.
                    314:            later set it to accurate value */
                    315:         u8 subbus = pci_config_readb(bdf, PCI_SUBORDINATE_BUS);
                    316:         pci_config_writeb(bdf, PCI_SUBORDINATE_BUS, 255);
                    317: 
                    318:         pci_bios_init_bus_rec(secbus, pci_bus);
                    319: 
                    320:         if (subbus != *pci_bus) {
                    321:             dprintf(1, "PCI: subordinate bus = 0x%x -> 0x%x\n",
                    322:                     subbus, *pci_bus);
                    323:             subbus = *pci_bus;
                    324:         } else {
                    325:             dprintf(1, "PCI: subordinate bus = 0x%x\n", subbus);
                    326:         }
                    327:         pci_config_writeb(bdf, PCI_SUBORDINATE_BUS, subbus);
                    328:     }
                    329: }
                    330: 
                    331: static void
                    332: pci_bios_init_bus(void)
                    333: {
                    334:     u8 pci_bus = 0;
                    335:     pci_bios_init_bus_rec(0 /* host bus */, &pci_bus);
1.1.1.7 ! root      336:     busses_count = pci_bus + 1;
        !           337: }
        !           338: 
        !           339: static void pci_bios_bus_get_bar(struct pci_bus *bus, int bdf, int bar,
        !           340:                                  u32 *val, u32 *size)
        !           341: {
        !           342:     u32 ofs = pci_bar(bdf, bar);
        !           343:     u32 old = pci_config_readl(bdf, ofs);
        !           344:     u32 mask;
        !           345: 
        !           346:     if (bar == PCI_ROM_SLOT) {
        !           347:         mask = PCI_ROM_ADDRESS_MASK;
        !           348:         pci_config_writel(bdf, ofs, mask);
        !           349:     } else {
        !           350:         if (old & PCI_BASE_ADDRESS_SPACE_IO)
        !           351:             mask = PCI_BASE_ADDRESS_IO_MASK;
        !           352:         else
        !           353:             mask = PCI_BASE_ADDRESS_MEM_MASK;
        !           354:         pci_config_writel(bdf, ofs, ~0);
        !           355:     }
        !           356:     *val = pci_config_readl(bdf, ofs);
        !           357:     pci_config_writel(bdf, ofs, old);
        !           358:     *size = (~(*val & mask)) + 1;
        !           359: }
        !           360: 
        !           361: static void pci_bios_bus_reserve(struct pci_bus *bus, int type, u32 size)
        !           362: {
        !           363:     u32 index;
        !           364: 
        !           365:     index = pci_size_to_index(size, type);
        !           366:     size = pci_index_to_size(index, type);
        !           367:     bus->r[type].count[index]++;
        !           368:     bus->r[type].sum += size;
        !           369:     if (bus->r[type].max < size)
        !           370:         bus->r[type].max = size;
        !           371: }
        !           372: 
        !           373: static u32 pci_bios_bus_get_addr(struct pci_bus *bus, int type, u32 size)
        !           374: {
        !           375:     u32 index, addr;
        !           376: 
        !           377:     index = pci_size_to_index(size, type);
        !           378:     addr = bus->r[type].bases[index];
        !           379:     bus->r[type].bases[index] += pci_index_to_size(index, type);
        !           380:     return addr;
        !           381: }
        !           382: 
        !           383: static void pci_bios_check_device(struct pci_bus *bus, struct pci_device *dev)
        !           384: {
        !           385:     u16 bdf = dev->bdf;
        !           386:     u32 limit;
        !           387:     int i,type;
        !           388: 
        !           389:     if (dev->class == PCI_CLASS_BRIDGE_PCI) {
        !           390:         if (dev->secondary_bus >= busses_count) {
        !           391:             /* should never trigger */
        !           392:             dprintf(1, "PCI: bus count too small (%d), skipping bus #%d\n",
        !           393:                     busses_count, dev->secondary_bus);
        !           394:             return;
        !           395:         }
        !           396:         struct pci_bus *s = busses + dev->secondary_bus;
        !           397:         pci_bios_check_device_in_bus(dev->secondary_bus);
        !           398:         for (type = 0; type < PCI_REGION_TYPE_COUNT; type++) {
        !           399:             limit = (type == PCI_REGION_TYPE_IO) ?
        !           400:                 PCI_BRIDGE_IO_MIN : PCI_BRIDGE_MEM_MIN;
        !           401:             s->r[type].size = s->r[type].sum;
        !           402:             if (s->r[type].size < limit)
        !           403:                 s->r[type].size = limit;
        !           404:             s->r[type].size = pci_size_roundup(s->r[type].size);
        !           405:             pci_bios_bus_reserve(bus, type, s->r[type].size);
        !           406:         }
        !           407:         dprintf(1, "PCI: secondary bus %d sizes: io %x, mem %x, prefmem %x\n",
        !           408:                 dev->secondary_bus,
        !           409:                 s->r[PCI_REGION_TYPE_IO].size,
        !           410:                 s->r[PCI_REGION_TYPE_MEM].size,
        !           411:                 s->r[PCI_REGION_TYPE_PREFMEM].size);
        !           412:         return;
        !           413:     }
        !           414: 
        !           415:     for (i = 0; i < PCI_NUM_REGIONS; i++) {
        !           416:         u32 val, size;
        !           417:         pci_bios_bus_get_bar(bus, bdf, i, &val, &size);
        !           418:         if (val == 0) {
        !           419:             continue;
        !           420:         }
        !           421:         pci_bios_bus_reserve(bus, pci_addr_to_type(val), size);
        !           422:         dev->bars[i].addr = val;
        !           423:         dev->bars[i].size = size;
        !           424:         dev->bars[i].is64 = (!(val & PCI_BASE_ADDRESS_SPACE_IO) &&
        !           425:             (val & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64);
        !           426: 
        !           427:         if (dev->bars[i].is64) {
        !           428:             i++;
        !           429:         }
        !           430:     }
        !           431: }
        !           432: 
        !           433: static void pci_bios_map_device(struct pci_bus *bus, struct pci_device *dev)
        !           434: {
        !           435:     u16 bdf = dev->bdf;
        !           436:     int type, i;
        !           437: 
        !           438:     if (dev->class == PCI_CLASS_BRIDGE_PCI) {
        !           439:         if (dev->secondary_bus >= busses_count) {
        !           440:             return;
        !           441:         }
        !           442:         struct pci_bus *s = busses + dev->secondary_bus;
        !           443:         u32 base, limit;
        !           444: 
        !           445:         for (type = 0; type < PCI_REGION_TYPE_COUNT; type++) {
        !           446:             s->r[type].base = pci_bios_bus_get_addr(bus, type, s->r[type].size);
        !           447:         }
        !           448:         dprintf(1, "PCI: init bases bus %d (secondary)\n", dev->secondary_bus);
        !           449:         pci_bios_init_bus_bases(s);
        !           450: 
        !           451:         base = s->r[PCI_REGION_TYPE_IO].base;
        !           452:         limit = base + s->r[PCI_REGION_TYPE_IO].size - 1;
        !           453:         pci_config_writeb(bdf, PCI_IO_BASE, base >> PCI_IO_SHIFT);
        !           454:         pci_config_writew(bdf, PCI_IO_BASE_UPPER16, 0);
        !           455:         pci_config_writeb(bdf, PCI_IO_LIMIT, limit >> PCI_IO_SHIFT);
        !           456:         pci_config_writew(bdf, PCI_IO_LIMIT_UPPER16, 0);
        !           457: 
        !           458:         base = s->r[PCI_REGION_TYPE_MEM].base;
        !           459:         limit = base + s->r[PCI_REGION_TYPE_MEM].size - 1;
        !           460:         pci_config_writew(bdf, PCI_MEMORY_BASE, base >> PCI_MEMORY_SHIFT);
        !           461:         pci_config_writew(bdf, PCI_MEMORY_LIMIT, limit >> PCI_MEMORY_SHIFT);
        !           462: 
        !           463:         base = s->r[PCI_REGION_TYPE_PREFMEM].base;
        !           464:         limit = base + s->r[PCI_REGION_TYPE_PREFMEM].size - 1;
        !           465:         pci_config_writew(bdf, PCI_PREF_MEMORY_BASE, base >> PCI_PREF_MEMORY_SHIFT);
        !           466:         pci_config_writew(bdf, PCI_PREF_MEMORY_LIMIT, limit >> PCI_PREF_MEMORY_SHIFT);
        !           467:         pci_config_writel(bdf, PCI_PREF_BASE_UPPER32, 0);
        !           468:         pci_config_writel(bdf, PCI_PREF_LIMIT_UPPER32, 0);
        !           469: 
        !           470:         pci_bios_map_device_in_bus(dev->secondary_bus);
        !           471:         return;
        !           472:     }
        !           473: 
        !           474:     for (i = 0; i < PCI_NUM_REGIONS; i++) {
        !           475:         u32 addr;
        !           476:         if (dev->bars[i].addr == 0) {
        !           477:             continue;
        !           478:         }
        !           479: 
        !           480:         addr = pci_bios_bus_get_addr(bus, pci_addr_to_type(dev->bars[i].addr),
        !           481:                                      dev->bars[i].size);
        !           482:         dprintf(1, "  bar %d, addr %x, size %x [%s]\n",
        !           483:                 i, addr, dev->bars[i].size,
        !           484:                 dev->bars[i].addr & PCI_BASE_ADDRESS_SPACE_IO ? "io" : "mem");
        !           485:         pci_set_io_region_addr(bdf, i, addr);
        !           486: 
        !           487:         if (dev->bars[i].is64) {
        !           488:             i++;
        !           489:         }
        !           490:     }
        !           491: }
        !           492: 
        !           493: static void pci_bios_check_device_in_bus(int bus)
        !           494: {
        !           495:     struct pci_device *pci;
        !           496: 
        !           497:     dprintf(1, "PCI: check devices bus %d\n", bus);
        !           498:     foreachpci(pci) {
        !           499:         if (pci_bdf_to_bus(pci->bdf) != bus)
        !           500:             continue;
        !           501:         pci_bios_check_device(&busses[bus], pci);
        !           502:     }
        !           503: }
        !           504: 
        !           505: static void pci_bios_map_device_in_bus(int bus)
        !           506: {
        !           507:     struct pci_device *pci;
        !           508: 
        !           509:     foreachpci(pci) {
        !           510:         if (pci_bdf_to_bus(pci->bdf) != bus)
        !           511:             continue;
        !           512:         dprintf(1, "PCI: map device bus %d, bfd 0x%x\n", bus, pci->bdf);
        !           513:         pci_bios_map_device(&busses[bus], pci);
        !           514:     }
        !           515: }
        !           516: 
        !           517: static void pci_bios_init_bus_bases(struct pci_bus *bus)
        !           518: {
        !           519:     u32 base, newbase, size;
        !           520:     int type, i;
        !           521: 
        !           522:     for (type = 0; type < PCI_REGION_TYPE_COUNT; type++) {
        !           523:         dprintf(1, "  type %s max %x sum %x base %x\n", region_type_name[type],
        !           524:                 bus->r[type].max, bus->r[type].sum, bus->r[type].base);
        !           525:         base = bus->r[type].base;
        !           526:         for (i = ARRAY_SIZE(bus->r[type].count)-1; i >= 0; i--) {
        !           527:             size = pci_index_to_size(i, type);
        !           528:             if (!bus->r[type].count[i])
        !           529:                 continue;
        !           530:             newbase = base + size * bus->r[type].count[i];
        !           531:             dprintf(1, "    size %8x: %d bar(s), %8x -> %8x\n",
        !           532:                     size, bus->r[type].count[i], base, newbase - 1);
        !           533:             bus->r[type].bases[i] = base;
        !           534:             base = newbase;
        !           535:         }
        !           536:     }
        !           537: }
        !           538: 
        !           539: #define ROOT_BASE(top, sum, align) ALIGN_DOWN((top)-(sum),(align))
        !           540: 
        !           541: static int pci_bios_init_root_regions(u32 start, u32 end)
        !           542: {
        !           543:     struct pci_bus *bus = &busses[0];
        !           544: 
        !           545:     bus->r[PCI_REGION_TYPE_IO].base = 0xc000;
        !           546: 
        !           547:     if (bus->r[PCI_REGION_TYPE_MEM].sum < bus->r[PCI_REGION_TYPE_PREFMEM].sum) {
        !           548:         bus->r[PCI_REGION_TYPE_MEM].base =
        !           549:             ROOT_BASE(end,
        !           550:                       bus->r[PCI_REGION_TYPE_MEM].sum,
        !           551:                       bus->r[PCI_REGION_TYPE_MEM].max);
        !           552:         bus->r[PCI_REGION_TYPE_PREFMEM].base =
        !           553:             ROOT_BASE(bus->r[PCI_REGION_TYPE_MEM].base,
        !           554:                       bus->r[PCI_REGION_TYPE_PREFMEM].sum,
        !           555:                       bus->r[PCI_REGION_TYPE_PREFMEM].max);
        !           556:         if (bus->r[PCI_REGION_TYPE_PREFMEM].base >= start) {
        !           557:             return 0;
        !           558:         }
        !           559:     } else {
        !           560:         bus->r[PCI_REGION_TYPE_PREFMEM].base =
        !           561:             ROOT_BASE(end,
        !           562:                       bus->r[PCI_REGION_TYPE_PREFMEM].sum,
        !           563:                       bus->r[PCI_REGION_TYPE_PREFMEM].max);
        !           564:         bus->r[PCI_REGION_TYPE_MEM].base =
        !           565:             ROOT_BASE(bus->r[PCI_REGION_TYPE_PREFMEM].base,
        !           566:                       bus->r[PCI_REGION_TYPE_MEM].sum,
        !           567:                       bus->r[PCI_REGION_TYPE_MEM].max);
        !           568:         if (bus->r[PCI_REGION_TYPE_MEM].base >= start) {
        !           569:             return 0;
        !           570:         }
        !           571:     }
        !           572:     return -1;
1.1.1.4   root      573: }
                    574: 
1.1       root      575: void
                    576: pci_setup(void)
                    577: {
1.1.1.7 ! root      578:     if (CONFIG_COREBOOT || usingXen()) {
        !           579:         // PCI setup already done by coreboot or Xen - just do probe.
        !           580:         pci_probe();
1.1       root      581:         return;
1.1.1.7 ! root      582:     }
1.1       root      583: 
                    584:     dprintf(3, "pci setup\n");
                    585: 
1.1.1.7 ! root      586:     u32 start = BUILD_PCIMEM_START;
        !           587:     u32 end   = BUILD_PCIMEM_END;
1.1.1.4   root      588: 
1.1.1.7 ! root      589:     dprintf(1, "=== PCI bus & bridge init ===\n");
1.1.1.4   root      590:     pci_bios_init_bus();
1.1       root      591: 
1.1.1.7 ! root      592:     dprintf(1, "=== PCI device probing ===\n");
        !           593:     pci_probe();
        !           594: 
        !           595:     dprintf(1, "=== PCI new allocation pass #1 ===\n");
        !           596:     busses = malloc_tmp(sizeof(*busses) * busses_count);
        !           597:     memset(busses, 0, sizeof(*busses) * busses_count);
        !           598:     pci_bios_check_device_in_bus(0 /* host bus */);
        !           599:     if (pci_bios_init_root_regions(start, end) != 0) {
        !           600:         panic("PCI: out of address space\n");
1.1       root      601:     }
1.1.1.7 ! root      602: 
        !           603:     dprintf(1, "=== PCI new allocation pass #2 ===\n");
        !           604:     dprintf(1, "PCI: init bases bus 0 (primary)\n");
        !           605:     pci_bios_init_bus_bases(&busses[0]);
        !           606:     pci_bios_map_device_in_bus(0 /* host bus */);
        !           607: 
1.1.1.4   root      608:     pci_bios_init_device_in_bus(0 /* host bus */);
1.1.1.7 ! root      609: 
        !           610:     struct pci_device *pci;
        !           611:     foreachpci(pci) {
        !           612:         pci_init_device(pci_isa_bridge_tbl, pci, NULL);
        !           613:     }
        !           614: 
        !           615:     free(busses);
        !           616:     busses_count = 0;
1.1       root      617: }

unix.superglobalmegacorp.com

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