diff options
Diffstat (limited to 'src/emu/machine/pci.c')
-rw-r--r-- | src/emu/machine/pci.c | 144 |
1 files changed, 132 insertions, 12 deletions
diff --git a/src/emu/machine/pci.c b/src/emu/machine/pci.c index 13ae0cd26a2..4faf56b79ff 100644 --- a/src/emu/machine/pci.c +++ b/src/emu/machine/pci.c @@ -4,21 +4,21 @@ const device_type PCI_ROOT = &device_creator<pci_root_device>; const device_type PCI_BRIDGE = &device_creator<pci_bridge_device>; DEVICE_ADDRESS_MAP_START(config_map, 32, pci_device) - AM_RANGE(0x00, 0x03) AM_READ16 (vendor_r, 0x0000ffff) - AM_RANGE(0x00, 0x03) AM_READ16 (device_r, 0xffff0000) - AM_RANGE(0x04, 0x07) AM_READWRITE16(command_r, command_w, 0x0000ffff) - AM_RANGE(0x04, 0x07) AM_READ16 (status_r, 0xffff0000) - + AM_RANGE(0x00, 0x03) AM_READ16 (vendor_r, 0x0000ffff) + AM_RANGE(0x00, 0x03) AM_READ16 (device_r, 0xffff0000) + AM_RANGE(0x04, 0x07) AM_READWRITE16(command_r, command_w, 0x0000ffff) + AM_RANGE(0x04, 0x07) AM_READ16 (status_r, 0xffff0000) AM_RANGE(0x08, 0x0b) AM_READ (class_rev_r) - AM_RANGE(0x0c, 0x0f) AM_READ8 (cache_line_size_r, 0x000000ff) - AM_RANGE(0x0c, 0x0f) AM_READ8 (latency_timer_r, 0x0000ff00) - AM_RANGE(0x0c, 0x0f) AM_READ8 (header_type_r, 0x00ff0000) - AM_RANGE(0x0c, 0x0f) AM_READ8 (bist_r, 0xff000000) + AM_RANGE(0x0c, 0x0f) AM_READ8 (cache_line_size_r, 0x000000ff) + AM_RANGE(0x0c, 0x0f) AM_READ8 (latency_timer_r, 0x0000ff00) + AM_RANGE(0x0c, 0x0f) AM_READ8 (header_type_r, 0x00ff0000) + AM_RANGE(0x0c, 0x0f) AM_READ8 (bist_r, 0xff000000) + AM_RANGE(0x10, 0x27) AM_READWRITE (address_base_r, address_base_w) - AM_RANGE(0x2c, 0x2f) AM_READ16 (subvendor_r, 0x0000ffff) - AM_RANGE(0x2c, 0x2f) AM_READ16 (subsystem_r, 0xffff0000) + AM_RANGE(0x2c, 0x2f) AM_READ16 (subvendor_r, 0x0000ffff) + AM_RANGE(0x2c, 0x2f) AM_READ16 (subsystem_r, 0xffff0000) - AM_RANGE(0x34, 0x37) AM_READ8 (capptr_r, 0x000000ff) + AM_RANGE(0x34, 0x37) AM_READ8 (capptr_r, 0x000000ff) ADDRESS_MAP_END pci_device::pci_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) @@ -43,12 +43,76 @@ void pci_device::device_start() command = 0x0080; command_mask = 0x01bf; status = 0x0000; + + for(int i=0; i<6; i++) { + bank_infos[i].adr = 0; + 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; } void pci_device::device_reset() { } +UINT32 pci_device::unmapped_r(offs_t offset, UINT32 mem_mask, int bank) +{ + logerror("%s: unmapped read from %08x & %08x (%s)\n", machine().describe_context(), offset*4, mem_mask, bank_infos[bank].map.name()); + return 0; +} + +void pci_device::unmapped_w(offs_t offset, UINT32 data, UINT32 mem_mask, int bank) +{ + 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); } + + +READ32_MEMBER(pci_device::address_base_r) +{ + if(bank_reg_infos[offset].bank == -1) + return 0; + int bid = bank_reg_infos[offset].bank; + if(bank_reg_infos[offset].hi) + return bank_infos[bid].adr >> 32; + int flags = bank_infos[bid].flags; + return bank_infos[bid].adr | (flags & M_IO ? 1 : 0) | (flags & M_64A ? 4 : 0) | (flags & M_PREF ? 8 : 0); +} + +WRITE32_MEMBER(pci_device::address_base_w) +{ + if(bank_reg_infos[offset].bank == -1) { + logerror("%s: write to address base (%d, %08x) not linked to any bank\n", tag(), offset, data); + return; + } + + int bid = bank_reg_infos[offset].bank; + if(bank_reg_infos[offset].hi) + bank_infos[bid].adr = (bank_infos[bid].adr & 0xffffffff) | (UINT64(data) << 32); + else { + data &= ~(bank_infos[bid].size - 1); + bank_infos[bid].adr = (bank_infos[bid].adr & U64(0xffffffff00000000)) | data; + } + remap_cb(); +} + READ16_MEMBER(pci_device::vendor_r) { return main_id >> 16; @@ -132,6 +196,34 @@ void pci_device::reset_all_mappings() void pci_device::map_device(UINT64 memory_window_start, UINT64 memory_window_end, UINT64 memory_offset, address_space *memory_space, UINT64 io_window_start, UINT64 io_window_end, UINT64 io_offset, address_space *io_space) { + for(int i=0; i<bank_count; i++) { + bank_info &bi = bank_infos[i]; + if(!bi.adr) + continue; + if(UINT32(bi.adr) == UINT32(~(bi.size - 1))) + continue; + + UINT64 start; + address_space *space; + if(bi.flags & M_IO) { + space = io_space; + start = bi.adr + io_offset; + } else { + space = memory_space; + start = bi.adr + memory_offset; + } + UINT64 end = start + bi.size-1; + switch(i) { + case 0: space->install_readwrite_handler(start, end, 0, 0, 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, 0, 0, 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, 0, 0, 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, 0, 0, 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, 0, 0, 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, 0, 0, read32_delegate(FUNC(pci_device::unmapped5_r), this), write32_delegate(FUNC(pci_device::unmapped5_w), this)); break; + } + space->install_device_delegate(start, end, *this, bi.map); + } + map_extra(memory_window_start, memory_window_end, memory_offset, memory_space, io_window_start, io_window_end, io_offset, io_space); } @@ -146,8 +238,36 @@ void pci_device::map_config(UINT8 device, address_space *config_space) config_space->install_device(device << 12, (device << 12) | 0xfff, *this, &pci_device::config_map); } +void pci_device::skip_map_regs(int count) +{ + bank_reg_count += count; + assert(bank_reg_count <= 6); +} + void pci_device::add_map(UINT64 size, int flags, address_map_delegate &map) { + assert(bank_count < 6); + int bid = bank_count++; + bank_infos[bid].map = map; + bank_infos[bid].adr = 0; + bank_infos[bid].size = size; + bank_infos[bid].flags = flags; + + if(flags & M_64A) { + assert(bank_reg_count < 5); + int breg = bank_reg_count; + bank_reg_infos[breg].bank = bid; + bank_reg_infos[breg].hi = 0; + bank_reg_infos[breg+1].bank = bid; + bank_reg_infos[breg+1].hi = 1; + bank_reg_count += 2; + } else { + assert(bank_reg_count < 6); + int breg = bank_reg_count++; + bank_reg_infos[breg].bank = bid; + bank_reg_infos[breg].hi = 0; + } + logerror("Device %s (%s) has 0x%" I64FMT "x bytes of %s named %s\n", tag(), name(), size, flags & M_IO ? "io" : "memory", map.name()); } |