diff options
Diffstat (limited to 'src/devices/machine/pci.cpp')
-rw-r--r-- | src/devices/machine/pci.cpp | 305 |
1 files changed, 202 insertions, 103 deletions
diff --git a/src/devices/machine/pci.cpp b/src/devices/machine/pci.cpp index 7148c37ee81..e4c582e29a8 100644 --- a/src/devices/machine/pci.cpp +++ b/src/devices/machine/pci.cpp @@ -1,7 +1,13 @@ // license:BSD-3-Clause // copyright-holders:Olivier Galibert +/* + * References: + * - PCI local bus (rev 2.x) + * - https://wiki.osdev.org/PCI + */ #include "emu.h" #include "pci.h" +#include "bus/pci/pci_slot.h" DEFINE_DEVICE_TYPE(PCI_ROOT, pci_root_device, "pci_root", "PCI virtual root") DEFINE_DEVICE_TYPE(PCI_BRIDGE, pci_bridge_device, "pci_bridge", "PCI-PCI Bridge") @@ -72,11 +78,27 @@ pci_device::pci_device(const machine_config &mconfig, device_type type, const ch revision = 0x00; pclass = 0xffffff; subsystem_id = 0xffffffff; + expansion_rom = nullptr; + expansion_rom_size = 0; + expansion_rom_base = 0; is_multifunction_device = false; intr_pin = 0x0; intr_line = 0xff; + for(int i=0; i<6; i++) { + bank_infos[i].adr = -1; + bank_infos[i].size = 0; + bank_infos[i].flags = 0; + bank_reg_infos[i].bank = -1; + bank_reg_infos[i].hi = 0; + } } +// main_id << 16 = vendor ID ($00-$01) +// main_id & 0xffff = device ID ($02-$03) +// revision = board versioning ($08) +// pclass = programming interface/sub class code/base class code ($09-$0b) +// subsystem_id << 16 = sub vendor ID ($2c-$2d) - NB: not all cards have these +// subsystem_id & 0xffff = sub device ID ($2e-$2f) / void pci_device::set_ids(uint32_t _main_id, uint8_t _revision, uint32_t _pclass, uint32_t _subsystem_id) { main_id = _main_id; @@ -87,33 +109,27 @@ void pci_device::set_ids(uint32_t _main_id, uint8_t _revision, uint32_t _pclass, void pci_device::device_start() { - command = 0x0080; + command = 0x0000; command_mask = 0x01bf; status = 0x0000; - for(int i=0; i<6; i++) { - bank_infos[i].adr = -1; - bank_infos[i].size = 0; - bank_infos[i].flags = 0; - bank_reg_infos[i].bank = -1; - bank_reg_infos[i].hi = 0; - } - bank_count = 0; bank_reg_count = 0; - expansion_rom = nullptr; - expansion_rom_size = 0; - expansion_rom_base = 0; - - for (int i = 0; i < ARRAY_LENGTH(bank_infos); i++) { - save_item(NAME(bank_infos[i].adr), i); - } + save_item(STRUCT_MEMBER(bank_infos, adr)); save_item(NAME(command)); save_item(NAME(command_mask)); save_item(NAME(status)); save_item(NAME(intr_line)); save_item(NAME(intr_pin)); + + device_t *root = owner(); + while(root && root->type() != PCI_ROOT) + root = root->owner(); + if(!root) + fatalerror("PCI device %s is without a PCI root\n", tag()); + + m_pci_root = downcast<pci_root_device *>(root); } void pci_device::device_reset() @@ -131,21 +147,21 @@ void pci_device::unmapped_w(offs_t offset, uint32_t data, uint32_t mem_mask, int logerror("%s: unmapped write to %08x = %08x & %08x (%s)\n", machine().describe_context(), offset*4, data, mem_mask, bank_infos[bank].map.name()); } -READ32_MEMBER(pci_device::unmapped0_r) { return unmapped_r(offset, mem_mask, 0); } -WRITE32_MEMBER(pci_device::unmapped0_w) { return unmapped_w(offset, data, mem_mask, 0); } -READ32_MEMBER(pci_device::unmapped1_r) { return unmapped_r(offset, mem_mask, 1); } -WRITE32_MEMBER(pci_device::unmapped1_w) { return unmapped_w(offset, data, mem_mask, 1); } -READ32_MEMBER(pci_device::unmapped2_r) { return unmapped_r(offset, mem_mask, 2); } -WRITE32_MEMBER(pci_device::unmapped2_w) { return unmapped_w(offset, data, mem_mask, 2); } -READ32_MEMBER(pci_device::unmapped3_r) { return unmapped_r(offset, mem_mask, 3); } -WRITE32_MEMBER(pci_device::unmapped3_w) { return unmapped_w(offset, data, mem_mask, 3); } -READ32_MEMBER(pci_device::unmapped4_r) { return unmapped_r(offset, mem_mask, 4); } -WRITE32_MEMBER(pci_device::unmapped4_w) { return unmapped_w(offset, data, mem_mask, 4); } -READ32_MEMBER(pci_device::unmapped5_r) { return unmapped_r(offset, mem_mask, 5); } -WRITE32_MEMBER(pci_device::unmapped5_w) { return unmapped_w(offset, data, mem_mask, 5); } +uint32_t pci_device::unmapped0_r(offs_t offset, uint32_t mem_mask) { return unmapped_r(offset, mem_mask, 0); } +void pci_device::unmapped0_w(offs_t offset, uint32_t data, uint32_t mem_mask) { return unmapped_w(offset, data, mem_mask, 0); } +uint32_t pci_device::unmapped1_r(offs_t offset, uint32_t mem_mask) { return unmapped_r(offset, mem_mask, 1); } +void pci_device::unmapped1_w(offs_t offset, uint32_t data, uint32_t mem_mask) { return unmapped_w(offset, data, mem_mask, 1); } +uint32_t pci_device::unmapped2_r(offs_t offset, uint32_t mem_mask) { return unmapped_r(offset, mem_mask, 2); } +void pci_device::unmapped2_w(offs_t offset, uint32_t data, uint32_t mem_mask) { return unmapped_w(offset, data, mem_mask, 2); } +uint32_t pci_device::unmapped3_r(offs_t offset, uint32_t mem_mask) { return unmapped_r(offset, mem_mask, 3); } +void pci_device::unmapped3_w(offs_t offset, uint32_t data, uint32_t mem_mask) { return unmapped_w(offset, data, mem_mask, 3); } +uint32_t pci_device::unmapped4_r(offs_t offset, uint32_t mem_mask) { return unmapped_r(offset, mem_mask, 4); } +void pci_device::unmapped4_w(offs_t offset, uint32_t data, uint32_t mem_mask) { return unmapped_w(offset, data, mem_mask, 4); } +uint32_t pci_device::unmapped5_r(offs_t offset, uint32_t mem_mask) { return unmapped_r(offset, mem_mask, 5); } +void pci_device::unmapped5_w(offs_t offset, uint32_t data, uint32_t mem_mask) { return unmapped_w(offset, data, mem_mask, 5); } -READ32_MEMBER(pci_device::address_base_r) +uint32_t pci_device::address_base_r(offs_t offset) { if(bank_reg_infos[offset].bank == -1) return 0; @@ -156,7 +172,7 @@ READ32_MEMBER(pci_device::address_base_r) return (bank_infos[bid].adr & ~(bank_infos[bid].size - 1)) | (flags & M_IO ? 1 : 0) | (flags & M_64A ? 4 : 0) | (flags & M_PREF ? 8 : 0); } -WRITE32_MEMBER(pci_device::address_base_w) +void pci_device::address_base_w(offs_t offset, uint32_t data) { if(bank_reg_infos[offset].bank == -1) { logerror("write to address base (%d, %08x) not linked to any bank\n", offset, data); @@ -172,22 +188,22 @@ WRITE32_MEMBER(pci_device::address_base_w) remap_cb(); } -READ16_MEMBER(pci_device::vendor_r) +uint16_t pci_device::vendor_r() { return main_id >> 16; } -READ16_MEMBER(pci_device::device_r) +uint16_t pci_device::device_r() { return main_id; } -READ16_MEMBER(pci_device::command_r) +uint16_t pci_device::command_r() { return command; } -WRITE16_MEMBER(pci_device::command_w) +void pci_device::command_w(offs_t offset, uint16_t data, uint16_t mem_mask) { uint16_t old = command; @@ -198,22 +214,22 @@ WRITE16_MEMBER(pci_device::command_w) remap_cb(); } -READ16_MEMBER(pci_device::status_r) +uint16_t pci_device::status_r() { return status; } -READ32_MEMBER(pci_device::class_rev_r) +uint32_t pci_device::class_rev_r() { return (pclass << 8) | revision; } -READ8_MEMBER(pci_device::cache_line_size_r) +uint8_t pci_device::cache_line_size_r() { return 0x00; } -READ8_MEMBER(pci_device::latency_timer_r) +uint8_t pci_device::latency_timer_r() { return 0x00; } @@ -223,33 +239,33 @@ void pci_device::set_multifunction_device(bool enable) is_multifunction_device = enable; } -READ8_MEMBER(pci_device::header_type_r) +uint8_t pci_device::header_type_r() { return is_multifunction_device ? 0x80 : 0x00; } -READ8_MEMBER(pci_device::bist_r) +uint8_t pci_device::bist_r() { return 0x00; } -READ16_MEMBER(pci_device::subvendor_r) +uint16_t pci_device::subvendor_r() { return subsystem_id >> 16; } -READ16_MEMBER(pci_device::subsystem_r) +uint16_t pci_device::subsystem_r() { return subsystem_id; } -READ32_MEMBER(pci_device::expansion_base_r) +uint32_t pci_device::expansion_base_r() { return expansion_rom_base; } -WRITE32_MEMBER(pci_device::expansion_base_w) +void pci_device::expansion_base_w(offs_t offset, uint32_t data, uint32_t mem_mask) { COMBINE_DATA(&expansion_rom_base); if(!expansion_rom_size) @@ -261,30 +277,41 @@ WRITE32_MEMBER(pci_device::expansion_base_w) remap_cb(); } -READ8_MEMBER(pci_device::capptr_r) +// if non-zero a CAPability PoinTeR marks an offset in PCI config space where a standard extension is located +// For example if capptr_r is 0xc0 then [offset+0xc0] has a capability identifier that is set with: +// bits 31-16 <capability dependant, usually revision and supported sub-features> +// bits 15-8 next capptr offset, 0x00 to determine the given item as last +// bits 7-0 capability ID: +// - 0x01 PMI Power Management Interface +// - 0x02 AGP Accelerated Graphics Port +// - 0x03 VPD Vital Product Data +// - 0x04 Slot Identification +// - 0x05 MSI Message Signaled Interrupts +// - 0x06 CompactPCI Hot Swap +uint8_t pci_device::capptr_r() { return 0x00; } -READ8_MEMBER(pci_device::interrupt_line_r) +uint8_t pci_device::interrupt_line_r() { logerror("interrupt_line_r = %02x\n", intr_line); return intr_line; } -WRITE8_MEMBER(pci_device::interrupt_line_w) +void pci_device::interrupt_line_w(offs_t offset, uint8_t data, uint8_t mem_mask) { COMBINE_DATA(&intr_line); logerror("interrupt_line_w %02x\n", data); } -READ8_MEMBER(pci_device::interrupt_pin_r) +uint8_t pci_device::interrupt_pin_r() { logerror("interrupt_pin_r = %02x\n", intr_pin); return intr_pin; } -WRITE8_MEMBER(pci_device::interrupt_pin_w) +void pci_device::interrupt_pin_w(offs_t offset, uint8_t data, uint8_t mem_mask) { COMBINE_DATA(&intr_pin); logerror("interrupt_pin_w = %02x\n", data); @@ -328,12 +355,12 @@ void pci_device::map_device(uint64_t memory_window_start, uint64_t memory_window } uint64_t end = start + bi.size-1; switch(i) { - case 0: space->install_readwrite_handler(start, end, read32_delegate(FUNC(pci_device::unmapped0_r), this), write32_delegate(FUNC(pci_device::unmapped0_w), this)); break; - case 1: space->install_readwrite_handler(start, end, read32_delegate(FUNC(pci_device::unmapped1_r), this), write32_delegate(FUNC(pci_device::unmapped1_w), this)); break; - case 2: space->install_readwrite_handler(start, end, read32_delegate(FUNC(pci_device::unmapped2_r), this), write32_delegate(FUNC(pci_device::unmapped2_w), this)); break; - case 3: space->install_readwrite_handler(start, end, read32_delegate(FUNC(pci_device::unmapped3_r), this), write32_delegate(FUNC(pci_device::unmapped3_w), this)); break; - case 4: space->install_readwrite_handler(start, end, read32_delegate(FUNC(pci_device::unmapped4_r), this), write32_delegate(FUNC(pci_device::unmapped4_w), this)); break; - case 5: space->install_readwrite_handler(start, end, read32_delegate(FUNC(pci_device::unmapped5_r), this), write32_delegate(FUNC(pci_device::unmapped5_w), this)); break; + case 0: space->install_readwrite_handler(start, end, read32s_delegate(*this, FUNC(pci_device::unmapped0_r)), write32s_delegate(*this, FUNC(pci_device::unmapped0_w))); break; + case 1: space->install_readwrite_handler(start, end, read32s_delegate(*this, FUNC(pci_device::unmapped1_r)), write32s_delegate(*this, FUNC(pci_device::unmapped1_w))); break; + case 2: space->install_readwrite_handler(start, end, read32s_delegate(*this, FUNC(pci_device::unmapped2_r)), write32s_delegate(*this, FUNC(pci_device::unmapped2_w))); break; + case 3: space->install_readwrite_handler(start, end, read32s_delegate(*this, FUNC(pci_device::unmapped3_r)), write32s_delegate(*this, FUNC(pci_device::unmapped3_w))); break; + case 4: space->install_readwrite_handler(start, end, read32s_delegate(*this, FUNC(pci_device::unmapped4_r)), write32s_delegate(*this, FUNC(pci_device::unmapped4_w))); break; + case 5: space->install_readwrite_handler(start, end, read32s_delegate(*this, FUNC(pci_device::unmapped5_r)), write32s_delegate(*this, FUNC(pci_device::unmapped5_w))); break; } space->install_device_delegate(start, end, *bi.device, bi.map); @@ -457,7 +484,7 @@ pci_bridge_device::pci_bridge_device(const machine_config &mconfig, device_type { } -READ8_MEMBER(pci_bridge_device::header_type_r) +uint8_t pci_bridge_device::header_type_r() { return 0x01; } @@ -491,13 +518,25 @@ void pci_bridge_device::device_start() for (device_t &d : bus_root()->subdevices()) { - const char *t = d.tag(); - int l = strlen(t); - if(l <= 4 || t[l-5] != ':' || t[l-2] != '.') - continue; - int id = strtol(t+l-4, nullptr, 16); - int fct = t[l-1] - '0'; - sub_devices[(id << 3) | fct] = downcast<pci_device *>(&d); + if(d.type() == PCI_SLOT) { + pci_slot_device &slot = downcast<pci_slot_device &>(d); + pci_device *card = slot.get_card(); + if(card) { + int id = slot.get_slot(); + sub_devices[id << 3] = card; + } + + } else { + const char *t = d.tag(); + int l = strlen(t); + if(l <= 4 || t[l-5] != ':' || t[l-2] != '.') { + logerror("Device %s unhandled\n", t); + continue; + } + int id = strtol(t+l-4, nullptr, 16); + int fct = t[l-1] - '0'; + sub_devices[(id << 3) | fct] = downcast<pci_device *>(&d); + } } mapper_cb cf_cb(&pci_bridge_device::regenerate_config_mapping, this); @@ -526,6 +565,10 @@ void pci_bridge_device::device_reset() primary_bus = 0x00; secondary_bus = 0x00; subordinate_bus = 0x00; +} + +void pci_bridge_device::interface_post_reset() +{ regenerate_config_mapping(); } @@ -631,191 +674,191 @@ void pci_bridge_device::config_write(uint8_t bus, uint8_t device, uint16_t reg, propagate_config_write(bus, device, reg, data, mem_mask); } -READ32_MEMBER (pci_bridge_device::b_address_base_r) +uint32_t pci_bridge_device::b_address_base_r(offs_t offset) { logerror("b_address_base_r %d\n", offset); return 0xffffffff; } -WRITE32_MEMBER(pci_bridge_device::b_address_base_w) +void pci_bridge_device::b_address_base_w(offs_t offset, uint32_t data) { logerror("b_address_base_w %d, %08x\n", offset, data); } -READ8_MEMBER (pci_bridge_device::primary_bus_r) +uint8_t pci_bridge_device::primary_bus_r() { logerror("primary_bus_r\n"); return primary_bus; } -WRITE8_MEMBER (pci_bridge_device::primary_bus_w) +void pci_bridge_device::primary_bus_w(uint8_t data) { primary_bus = data; logerror("primary_bus_w %02x\n", data); } -READ8_MEMBER (pci_bridge_device::secondary_bus_r) +uint8_t pci_bridge_device::secondary_bus_r() { logerror("secondary_bus_r\n"); return secondary_bus; } -WRITE8_MEMBER (pci_bridge_device::secondary_bus_w) +void pci_bridge_device::secondary_bus_w(uint8_t data) { secondary_bus = data; logerror("secondary_bus_w %02x\n", data); } -READ8_MEMBER (pci_bridge_device::subordinate_bus_r) +uint8_t pci_bridge_device::subordinate_bus_r() { logerror("subordinate_bus_r\n"); return subordinate_bus; } -WRITE8_MEMBER (pci_bridge_device::subordinate_bus_w) +void pci_bridge_device::subordinate_bus_w(uint8_t data) { subordinate_bus = data; logerror("subordinate_bus_w %02x\n", data); } -READ8_MEMBER (pci_bridge_device::secondary_latency_r) +uint8_t pci_bridge_device::secondary_latency_r() { logerror("secondary_latency_r\n"); return 0xff; } -WRITE8_MEMBER (pci_bridge_device::secondary_latency_w) +void pci_bridge_device::secondary_latency_w(uint8_t data) { logerror("secondary_latency_w %02x\n", data); } -READ8_MEMBER (pci_bridge_device::iobase_r) +uint8_t pci_bridge_device::iobase_r() { return iobase; } -WRITE8_MEMBER (pci_bridge_device::iobase_w) +void pci_bridge_device::iobase_w(uint8_t data) { iobase = data; logerror("iobase_w %02x\n", data); } -READ8_MEMBER (pci_bridge_device::iolimit_r) +uint8_t pci_bridge_device::iolimit_r() { return iolimit; } -WRITE8_MEMBER (pci_bridge_device::iolimit_w) +void pci_bridge_device::iolimit_w(uint8_t data) { iolimit = data; logerror("iolimit_w %02x\n", data); } -READ16_MEMBER (pci_bridge_device::secondary_status_r) +uint16_t pci_bridge_device::secondary_status_r() { logerror("secondary_status_r\n"); return 0xffff; } -WRITE16_MEMBER(pci_bridge_device::secondary_status_w) +void pci_bridge_device::secondary_status_w(uint16_t data) { logerror("secondary_status_w %04x\n", data); } -READ16_MEMBER (pci_bridge_device::memory_base_r) +uint16_t pci_bridge_device::memory_base_r() { return memory_base; } -WRITE16_MEMBER(pci_bridge_device::memory_base_w) +void pci_bridge_device::memory_base_w(offs_t offset, uint16_t data, uint16_t mem_mask) { COMBINE_DATA(&memory_base); logerror("memory_base_w %04x\n", memory_base); } -READ16_MEMBER (pci_bridge_device::memory_limit_r) +uint16_t pci_bridge_device::memory_limit_r() { return memory_limit; } -WRITE16_MEMBER(pci_bridge_device::memory_limit_w) +void pci_bridge_device::memory_limit_w(offs_t offset, uint16_t data, uint16_t mem_mask) { COMBINE_DATA(&memory_limit); logerror("memory_limit_w %04x\n", memory_limit); } -READ16_MEMBER (pci_bridge_device::prefetch_base_r) +uint16_t pci_bridge_device::prefetch_base_r() { return prefetch_base; } -WRITE16_MEMBER(pci_bridge_device::prefetch_base_w) +void pci_bridge_device::prefetch_base_w(offs_t offset, uint16_t data, uint16_t mem_mask) { COMBINE_DATA(&prefetch_base); logerror("prefetch_base_w %04x\n", prefetch_base); } -READ16_MEMBER (pci_bridge_device::prefetch_limit_r) +uint16_t pci_bridge_device::prefetch_limit_r() { return prefetch_limit; } -WRITE16_MEMBER(pci_bridge_device::prefetch_limit_w) +void pci_bridge_device::prefetch_limit_w(offs_t offset, uint16_t data, uint16_t mem_mask) { COMBINE_DATA(&prefetch_limit); logerror("prefetch_limit_w %04x\n", prefetch_limit); } -READ32_MEMBER (pci_bridge_device::prefetch_baseu_r) +uint32_t pci_bridge_device::prefetch_baseu_r() { return prefetch_baseu; } -WRITE32_MEMBER(pci_bridge_device::prefetch_baseu_w) +void pci_bridge_device::prefetch_baseu_w(offs_t offset, uint32_t data, uint32_t mem_mask) { COMBINE_DATA(&prefetch_baseu); logerror("prefetch_baseu_w %08x\n", prefetch_baseu); } -READ32_MEMBER (pci_bridge_device::prefetch_limitu_r) +uint32_t pci_bridge_device::prefetch_limitu_r() { return prefetch_limitu; } -WRITE32_MEMBER(pci_bridge_device::prefetch_limitu_w) +void pci_bridge_device::prefetch_limitu_w(offs_t offset, uint32_t data, uint32_t mem_mask) { COMBINE_DATA(&prefetch_limitu); logerror("prefetch_limitu_w %08x\n", prefetch_limitu); } -READ16_MEMBER (pci_bridge_device::iobaseu_r) +uint16_t pci_bridge_device::iobaseu_r() { return iobaseu; } -WRITE16_MEMBER(pci_bridge_device::iobaseu_w) +void pci_bridge_device::iobaseu_w(offs_t offset, uint16_t data, uint16_t mem_mask) { COMBINE_DATA(&iobaseu); logerror("iobaseu_w %04x\n", iobaseu); } -READ16_MEMBER (pci_bridge_device::iolimitu_r) +uint16_t pci_bridge_device::iolimitu_r() { return iolimitu; } -WRITE16_MEMBER(pci_bridge_device::iolimitu_w) +void pci_bridge_device::iolimitu_w(offs_t offset, uint16_t data, uint16_t mem_mask) { COMBINE_DATA(&iolimitu); logerror("iolimitu_w %04x\n", iolimitu); } -READ16_MEMBER (pci_bridge_device::bridge_control_r) +uint16_t pci_bridge_device::bridge_control_r() { return bridge_control; } -WRITE16_MEMBER(pci_bridge_device::bridge_control_w) +void pci_bridge_device::bridge_control_w(offs_t offset, uint16_t data, uint16_t mem_mask) { COMBINE_DATA(&bridge_control); logerror("bridge_control_w %04x\n", bridge_control); @@ -845,6 +888,12 @@ void pci_host_device::io_configuration_access_map(address_map &map) map(0xcfc, 0xcff).rw(FUNC(pci_host_device::config_data_r), FUNC(pci_host_device::config_data_w)); } +void pci_host_device::set_spaces(address_space *memory, address_space *io, address_space *busmaster) +{ + memory_space = memory; + io_space = io ? io : memory; + m_pci_root->set_pci_busmaster_space(busmaster ? busmaster : memory); +} pci_host_device::pci_host_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : pci_bridge_device(mconfig, type, tag, owner, clock) @@ -875,11 +924,16 @@ void pci_host_device::device_reset() { pci_bridge_device::device_reset(); reset_all_mappings(); - regenerate_mapping(); config_address = 0; } +void pci_host_device::interface_post_reset() +{ + pci_bridge_device::interface_post_reset(); + regenerate_mapping(); +} + void pci_host_device::regenerate_mapping() { logerror("Regenerating mapping\n"); @@ -890,27 +944,59 @@ void pci_host_device::regenerate_mapping() io_window_start, io_window_end, io_offset, io_space); } -READ32_MEMBER(pci_host_device::config_address_r) +uint32_t pci_host_device::config_address_r() { return config_address; } -WRITE32_MEMBER(pci_host_device::config_address_w) +void pci_host_device::config_address_w(offs_t offset, uint32_t data, uint32_t mem_mask) { COMBINE_DATA(&config_address); } -READ32_MEMBER(pci_host_device::config_data_r) +uint32_t pci_host_device::config_data_r(offs_t offset, uint32_t mem_mask) { return config_address & 0x80000000 ? root_config_read((config_address >> 16) & 0xff, (config_address >> 8) & 0xff, config_address & 0xfc, mem_mask) : 0xffffffff; } -WRITE32_MEMBER(pci_host_device::config_data_w) +void pci_host_device::config_data_w(offs_t offset, uint32_t data, uint32_t mem_mask) { if(config_address & 0x80000000) root_config_write((config_address >> 16) & 0xff, (config_address >> 8) & 0xff, config_address & 0xfc, data, mem_mask); } +uint32_t pci_host_device::config_data_ex_r(offs_t offset, uint32_t mem_mask) +{ + // is this a Type 0 or Type 1 configuration address? (page 31, PCI 2.2 Specification) + if ((config_address & 3) == 0) + { + const int devnum = 31 - count_leading_zeros_32(config_address & 0xfffff800); + return root_config_read(0, devnum << 3, config_address & 0xfc, mem_mask); + } + else if ((config_address & 3) == 1) + return config_address & 0x80000000 ? root_config_read((config_address >> 16) & 0xff, (config_address >> 8) & 0xff, config_address & 0xfc, mem_mask) : 0xffffffff; + + logerror("pci: configuration address format %d unsupported", config_address & 3); + return 0xffffffff; +} + +void pci_host_device::config_data_ex_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + // is this a Type 0 or Type 1 configuration address? (page 31, PCI 2.2 Specification) + if ((config_address & 3) == 0) + { + const int devnum = 31 - count_leading_zeros_32(config_address & 0xfffff800); + root_config_write(0, devnum << 3, config_address & 0xfc, data, mem_mask); + } + else if ((config_address & 3) == 1) + { + if (config_address & 0x80000000) + root_config_write((config_address >> 16) & 0xff, (config_address >> 8) & 0xff, config_address & 0xfc, data, mem_mask); + } + else + logerror("pci: configuration address format %d unsupported", config_address & 3); +} + uint32_t pci_host_device::root_config_read(uint8_t bus, uint8_t device, uint16_t reg, uint32_t mem_mask) { if(bus == 0x00) @@ -930,7 +1016,10 @@ void pci_host_device::root_config_write(uint8_t bus, uint8_t device, uint16_t re pci_root_device::pci_root_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, PCI_ROOT, tag, owner, clock) + : device_t(mconfig, PCI_ROOT, tag, owner, clock), + m_pin_mapper(*this), + m_irq_handler(*this), + m_pci_busmaster_space(nullptr) { } @@ -941,3 +1030,13 @@ void pci_root_device::device_start() void pci_root_device::device_reset() { } + +void pci_root_device::irq_pin_w(int pin, int state) +{ + m_irq_handler(m_pin_mapper(pin), state); +} + +void pci_root_device::irq_w(int line, int state) +{ + m_irq_handler(line, state); +} |