|
|
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 ! 13: ! 14: #define PCI_ROM_SLOT 6 ! 15: #define PCI_NUM_REGIONS 7 ! 16: ! 17: static u32 pci_bios_io_addr; ! 18: static u32 pci_bios_mem_addr; ! 19: static u32 pci_bios_bigmem_addr; ! 20: /* host irqs corresponding to PCI irqs A-D */ ! 21: static u8 pci_irqs[4] = { ! 22: 10, 10, 11, 11 ! 23: }; ! 24: ! 25: static void pci_set_io_region_addr(u16 bdf, int region_num, u32 addr) ! 26: { ! 27: u32 ofs, old_addr; ! 28: ! 29: if (region_num == PCI_ROM_SLOT) { ! 30: ofs = PCI_ROM_ADDRESS; ! 31: } else { ! 32: ofs = PCI_BASE_ADDRESS_0 + region_num * 4; ! 33: } ! 34: ! 35: old_addr = pci_config_readl(bdf, ofs); ! 36: ! 37: pci_config_writel(bdf, ofs, addr); ! 38: dprintf(1, "region %d: 0x%08x\n", region_num, addr); ! 39: } ! 40: ! 41: /* return the global irq number corresponding to a given device irq ! 42: pin. We could also use the bus number to have a more precise ! 43: mapping. */ ! 44: static int pci_slot_get_pirq(u16 bdf, int irq_num) ! 45: { ! 46: int slot_addend = pci_bdf_to_dev(bdf) - 1; ! 47: return (irq_num + slot_addend) & 3; ! 48: } ! 49: ! 50: static void pci_bios_init_bridges(u16 bdf) ! 51: { ! 52: u16 vendor_id = pci_config_readw(bdf, PCI_VENDOR_ID); ! 53: u16 device_id = pci_config_readw(bdf, PCI_DEVICE_ID); ! 54: ! 55: if (vendor_id == PCI_VENDOR_ID_INTEL ! 56: && (device_id == PCI_DEVICE_ID_INTEL_82371SB_0 ! 57: || device_id == PCI_DEVICE_ID_INTEL_82371AB_0)) { ! 58: int i, irq; ! 59: u8 elcr[2]; ! 60: ! 61: /* PIIX3/PIIX4 PCI to ISA bridge */ ! 62: ! 63: elcr[0] = 0x00; ! 64: elcr[1] = 0x00; ! 65: for (i = 0; i < 4; i++) { ! 66: irq = pci_irqs[i]; ! 67: /* set to trigger level */ ! 68: elcr[irq >> 3] |= (1 << (irq & 7)); ! 69: /* activate irq remapping in PIIX */ ! 70: pci_config_writeb(bdf, 0x60 + i, irq); ! 71: } ! 72: outb(elcr[0], 0x4d0); ! 73: outb(elcr[1], 0x4d1); ! 74: dprintf(1, "PIIX3/PIIX4 init: elcr=%02x %02x\n", ! 75: elcr[0], elcr[1]); ! 76: } ! 77: } ! 78: ! 79: static void pci_bios_init_device(u16 bdf) ! 80: { ! 81: int class; ! 82: u32 *paddr; ! 83: int i, pin, pic_irq, vendor_id, device_id; ! 84: ! 85: class = pci_config_readw(bdf, PCI_CLASS_DEVICE); ! 86: vendor_id = pci_config_readw(bdf, PCI_VENDOR_ID); ! 87: device_id = pci_config_readw(bdf, PCI_DEVICE_ID); ! 88: dprintf(1, "PCI: bus=%d devfn=0x%02x: vendor_id=0x%04x device_id=0x%04x\n" ! 89: , pci_bdf_to_bus(bdf), pci_bdf_to_devfn(bdf), vendor_id, device_id); ! 90: switch (class) { ! 91: case PCI_CLASS_STORAGE_IDE: ! 92: if (vendor_id == PCI_VENDOR_ID_INTEL ! 93: && (device_id == PCI_DEVICE_ID_INTEL_82371SB_1 ! 94: || device_id == PCI_DEVICE_ID_INTEL_82371AB)) { ! 95: /* PIIX3/PIIX4 IDE */ ! 96: pci_config_writew(bdf, 0x40, 0x8000); // enable IDE0 ! 97: pci_config_writew(bdf, 0x42, 0x8000); // enable IDE1 ! 98: goto default_map; ! 99: } else { ! 100: /* IDE: we map it as in ISA mode */ ! 101: pci_set_io_region_addr(bdf, 0, PORT_ATA1_CMD_BASE); ! 102: pci_set_io_region_addr(bdf, 1, PORT_ATA1_CTRL_BASE); ! 103: pci_set_io_region_addr(bdf, 2, PORT_ATA2_CMD_BASE); ! 104: pci_set_io_region_addr(bdf, 3, PORT_ATA2_CTRL_BASE); ! 105: } ! 106: break; ! 107: case PCI_CLASS_SYSTEM_PIC: ! 108: /* PIC */ ! 109: if (vendor_id == PCI_VENDOR_ID_IBM) { ! 110: /* IBM */ ! 111: if (device_id == 0x0046 || device_id == 0xFFFF) { ! 112: /* MPIC & MPIC2 */ ! 113: pci_set_io_region_addr(bdf, 0, 0x80800000 + 0x00040000); ! 114: } ! 115: } ! 116: break; ! 117: case 0xff00: ! 118: if (vendor_id == PCI_VENDOR_ID_APPLE && ! 119: (device_id == 0x0017 || device_id == 0x0022)) { ! 120: /* macio bridge */ ! 121: pci_set_io_region_addr(bdf, 0, 0x80800000); ! 122: } ! 123: break; ! 124: default: ! 125: default_map: ! 126: /* default memory mappings */ ! 127: for (i = 0; i < PCI_NUM_REGIONS; i++) { ! 128: int ofs; ! 129: if (i == PCI_ROM_SLOT) ! 130: ofs = PCI_ROM_ADDRESS; ! 131: else ! 132: ofs = PCI_BASE_ADDRESS_0 + i * 4; ! 133: ! 134: u32 old = pci_config_readl(bdf, ofs); ! 135: u32 mask; ! 136: if (i == PCI_ROM_SLOT) { ! 137: mask = PCI_ROM_ADDRESS_MASK; ! 138: pci_config_writel(bdf, ofs, mask); ! 139: } else { ! 140: if (old & PCI_BASE_ADDRESS_SPACE_IO) ! 141: mask = PCI_BASE_ADDRESS_IO_MASK; ! 142: else ! 143: mask = PCI_BASE_ADDRESS_MEM_MASK; ! 144: pci_config_writel(bdf, ofs, ~0); ! 145: } ! 146: u32 val = pci_config_readl(bdf, ofs); ! 147: pci_config_writel(bdf, ofs, old); ! 148: ! 149: if (val != 0) { ! 150: u32 size = (~(val & mask)) + 1; ! 151: if (val & PCI_BASE_ADDRESS_SPACE_IO) ! 152: paddr = &pci_bios_io_addr; ! 153: else if (size >= 0x04000000) ! 154: paddr = &pci_bios_bigmem_addr; ! 155: else ! 156: paddr = &pci_bios_mem_addr; ! 157: *paddr = ALIGN(*paddr, size); ! 158: pci_set_io_region_addr(bdf, i, *paddr); ! 159: *paddr += size; ! 160: } ! 161: } ! 162: break; ! 163: } ! 164: ! 165: /* enable memory mappings */ ! 166: pci_config_maskw(bdf, PCI_COMMAND, 0, PCI_COMMAND_IO | PCI_COMMAND_MEMORY); ! 167: ! 168: /* map the interrupt */ ! 169: pin = pci_config_readb(bdf, PCI_INTERRUPT_PIN); ! 170: if (pin != 0) { ! 171: pin = pci_slot_get_pirq(bdf, pin - 1); ! 172: pic_irq = pci_irqs[pin]; ! 173: pci_config_writeb(bdf, PCI_INTERRUPT_LINE, pic_irq); ! 174: } ! 175: ! 176: if (vendor_id == PCI_VENDOR_ID_INTEL ! 177: && device_id == PCI_DEVICE_ID_INTEL_82371AB_3) { ! 178: /* PIIX4 Power Management device (for ACPI) */ ! 179: ! 180: // acpi sci is hardwired to 9 ! 181: pci_config_writeb(bdf, PCI_INTERRUPT_LINE, 9); ! 182: ! 183: pci_config_writel(bdf, 0x40, PORT_ACPI_PM_BASE | 1); ! 184: pci_config_writeb(bdf, 0x80, 0x01); /* enable PM io space */ ! 185: pci_config_writel(bdf, 0x90, PORT_SMB_BASE | 1); ! 186: pci_config_writeb(bdf, 0xd2, 0x09); /* enable SMBus io space */ ! 187: } ! 188: } ! 189: ! 190: void ! 191: pci_setup(void) ! 192: { ! 193: if (CONFIG_COREBOOT) ! 194: // Already done by coreboot. ! 195: return; ! 196: ! 197: dprintf(3, "pci setup\n"); ! 198: ! 199: pci_bios_io_addr = 0xc000; ! 200: pci_bios_mem_addr = 0xf0000000; ! 201: pci_bios_bigmem_addr = RamSize; ! 202: if (pci_bios_bigmem_addr < 0x90000000) ! 203: pci_bios_bigmem_addr = 0x90000000; ! 204: ! 205: int bdf, max; ! 206: foreachpci(bdf, max) { ! 207: pci_bios_init_bridges(bdf); ! 208: } ! 209: foreachpci(bdf, max) { ! 210: pci_bios_init_device(bdf); ! 211: } ! 212: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.