pcireg_t pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg) { pcireg_t data; int bus; KASSERT((reg & 0x3) == 0); if (pci_mcfg_addr && reg >= PCI_CONFIG_SPACE_SIZE) { pci_decompose_tag(pc, tag, &bus, NULL, NULL); if (bus >= pci_mcfg_min_bus && bus <= pci_mcfg_max_bus) { pci_mcfg_map_bus(bus); data = bus_space_read_4(pci_mcfgt, pci_mcfgh[bus], (tag & 0x000ff00) << 4 | reg); return data; } } PCI_CONF_LOCK(); outl(PCI_MODE1_ADDRESS_REG, tag | reg); data = inl(PCI_MODE1_DATA_REG); outl(PCI_MODE1_ADDRESS_REG, 0); PCI_CONF_UNLOCK(); return data; }
void pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data) { int bus; if (pci_mcfg_addr && reg >= PCI_CONFIG_SPACE_SIZE) { pci_decompose_tag(pc, tag, &bus, NULL, NULL); if (bus >= pci_mcfg_min_bus && bus <= pci_mcfg_max_bus) { pci_mcfg_map_bus(bus); bus_space_write_4(pci_mcfgt, pci_mcfgh[bus], (tag.mode1 & 0x000ff00) << 4 | reg, data); return; } } PCI_CONF_LOCK(); switch (pci_mode) { case 1: outl(PCI_MODE1_ADDRESS_REG, tag.mode1 | reg); outl(PCI_MODE1_DATA_REG, data); outl(PCI_MODE1_ADDRESS_REG, 0); break; case 2: outb(PCI_MODE2_ENABLE_REG, tag.mode2.enable); outb(PCI_MODE2_FORWARD_REG, tag.mode2.forward); outl(tag.mode2.port | reg, data); outb(PCI_MODE2_ENABLE_REG, 0); break; default: panic("pci_conf_write: mode not configured"); } PCI_CONF_UNLOCK(); }