trunk/src/emu/machine/pci.c
| r241858 | r241859 | |
| 4 | 4 | const device_type PCI_BRIDGE = &device_creator<pci_bridge_device>; |
| 5 | 5 | |
| 6 | 6 | DEVICE_ADDRESS_MAP_START(config_map, 32, pci_device) |
| 7 | | AM_RANGE(0x00, 0x03) AM_READ16 (vendor_r, 0x0000ffff) |
| 8 | | AM_RANGE(0x00, 0x03) AM_READ16 (device_r, 0xffff0000) |
| 9 | | AM_RANGE(0x04, 0x07) AM_READWRITE16(command_r, command_w, 0x0000ffff) |
| 10 | | AM_RANGE(0x04, 0x07) AM_READ16 (status_r, 0xffff0000) |
| 11 | | |
| 7 | AM_RANGE(0x00, 0x03) AM_READ16 (vendor_r, 0x0000ffff) |
| 8 | AM_RANGE(0x00, 0x03) AM_READ16 (device_r, 0xffff0000) |
| 9 | AM_RANGE(0x04, 0x07) AM_READWRITE16(command_r, command_w, 0x0000ffff) |
| 10 | AM_RANGE(0x04, 0x07) AM_READ16 (status_r, 0xffff0000) |
| 12 | 11 | AM_RANGE(0x08, 0x0b) AM_READ (class_rev_r) |
| 13 | | AM_RANGE(0x0c, 0x0f) AM_READ8 (cache_line_size_r, 0x000000ff) |
| 14 | | AM_RANGE(0x0c, 0x0f) AM_READ8 (latency_timer_r, 0x0000ff00) |
| 15 | | AM_RANGE(0x0c, 0x0f) AM_READ8 (header_type_r, 0x00ff0000) |
| 16 | | AM_RANGE(0x0c, 0x0f) AM_READ8 (bist_r, 0xff000000) |
| 12 | AM_RANGE(0x0c, 0x0f) AM_READ8 (cache_line_size_r, 0x000000ff) |
| 13 | AM_RANGE(0x0c, 0x0f) AM_READ8 (latency_timer_r, 0x0000ff00) |
| 14 | AM_RANGE(0x0c, 0x0f) AM_READ8 (header_type_r, 0x00ff0000) |
| 15 | AM_RANGE(0x0c, 0x0f) AM_READ8 (bist_r, 0xff000000) |
| 16 | AM_RANGE(0x10, 0x27) AM_READWRITE (address_base_r, address_base_w) |
| 17 | 17 | |
| 18 | | AM_RANGE(0x2c, 0x2f) AM_READ16 (subvendor_r, 0x0000ffff) |
| 19 | | AM_RANGE(0x2c, 0x2f) AM_READ16 (subsystem_r, 0xffff0000) |
| 18 | AM_RANGE(0x2c, 0x2f) AM_READ16 (subvendor_r, 0x0000ffff) |
| 19 | AM_RANGE(0x2c, 0x2f) AM_READ16 (subsystem_r, 0xffff0000) |
| 20 | 20 | |
| 21 | | AM_RANGE(0x34, 0x37) AM_READ8 (capptr_r, 0x000000ff) |
| 21 | AM_RANGE(0x34, 0x37) AM_READ8 (capptr_r, 0x000000ff) |
| 22 | 22 | ADDRESS_MAP_END |
| 23 | 23 | |
| 24 | 24 | 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) |
| r241858 | r241859 | |
| 43 | 43 | command = 0x0080; |
| 44 | 44 | command_mask = 0x01bf; |
| 45 | 45 | status = 0x0000; |
| 46 | |
| 47 | for(int i=0; i<6; i++) { |
| 48 | bank_infos[i].adr = 0; |
| 49 | bank_infos[i].size = 0; |
| 50 | bank_infos[i].flags = 0; |
| 51 | bank_reg_infos[i].bank = -1; |
| 52 | bank_reg_infos[i].hi = 0; |
| 53 | } |
| 54 | |
| 55 | bank_count = 0; |
| 56 | bank_reg_count = 0; |
| 46 | 57 | } |
| 47 | 58 | |
| 48 | 59 | void pci_device::device_reset() |
| 49 | 60 | { |
| 50 | 61 | } |
| 51 | 62 | |
| 63 | UINT32 pci_device::unmapped_r(offs_t offset, UINT32 mem_mask, int bank) |
| 64 | { |
| 65 | logerror("%s: unmapped read from %08x & %08x (%s)\n", machine().describe_context(), offset*4, mem_mask, bank_infos[bank].map.name()); |
| 66 | return 0; |
| 67 | } |
| 68 | |
| 69 | void pci_device::unmapped_w(offs_t offset, UINT32 data, UINT32 mem_mask, int bank) |
| 70 | { |
| 71 | logerror("%s: unmapped write to %08x = %08x & %08x (%s)\n", machine().describe_context(), offset*4, data, mem_mask, bank_infos[bank].map.name()); |
| 72 | } |
| 73 | |
| 74 | READ32_MEMBER(pci_device::unmapped0_r) { return unmapped_r(offset, mem_mask, 0); } |
| 75 | WRITE32_MEMBER(pci_device::unmapped0_w) { return unmapped_w(offset, data, mem_mask, 0); } |
| 76 | READ32_MEMBER(pci_device::unmapped1_r) { return unmapped_r(offset, mem_mask, 1); } |
| 77 | WRITE32_MEMBER(pci_device::unmapped1_w) { return unmapped_w(offset, data, mem_mask, 1); } |
| 78 | READ32_MEMBER(pci_device::unmapped2_r) { return unmapped_r(offset, mem_mask, 2); } |
| 79 | WRITE32_MEMBER(pci_device::unmapped2_w) { return unmapped_w(offset, data, mem_mask, 2); } |
| 80 | READ32_MEMBER(pci_device::unmapped3_r) { return unmapped_r(offset, mem_mask, 3); } |
| 81 | WRITE32_MEMBER(pci_device::unmapped3_w) { return unmapped_w(offset, data, mem_mask, 3); } |
| 82 | READ32_MEMBER(pci_device::unmapped4_r) { return unmapped_r(offset, mem_mask, 4); } |
| 83 | WRITE32_MEMBER(pci_device::unmapped4_w) { return unmapped_w(offset, data, mem_mask, 4); } |
| 84 | READ32_MEMBER(pci_device::unmapped5_r) { return unmapped_r(offset, mem_mask, 5); } |
| 85 | WRITE32_MEMBER(pci_device::unmapped5_w) { return unmapped_w(offset, data, mem_mask, 5); } |
| 86 | |
| 87 | |
| 88 | READ32_MEMBER(pci_device::address_base_r) |
| 89 | { |
| 90 | if(bank_reg_infos[offset].bank == -1) |
| 91 | return 0; |
| 92 | int bid = bank_reg_infos[offset].bank; |
| 93 | if(bank_reg_infos[offset].hi) |
| 94 | return bank_infos[bid].adr >> 32; |
| 95 | int flags = bank_infos[bid].flags; |
| 96 | return bank_infos[bid].adr | (flags & M_IO ? 1 : 0) | (flags & M_64A ? 4 : 0) | (flags & M_PREF ? 8 : 0); |
| 97 | } |
| 98 | |
| 99 | WRITE32_MEMBER(pci_device::address_base_w) |
| 100 | { |
| 101 | if(bank_reg_infos[offset].bank == -1) { |
| 102 | logerror("%s: write to address base (%d, %08x) not linked to any bank\n", tag(), offset, data); |
| 103 | return; |
| 104 | } |
| 105 | |
| 106 | int bid = bank_reg_infos[offset].bank; |
| 107 | if(bank_reg_infos[offset].hi) |
| 108 | bank_infos[bid].adr = (bank_infos[bid].adr & 0xffffffff) | (UINT64(data) << 32); |
| 109 | else { |
| 110 | data &= ~(bank_infos[bid].size - 1); |
| 111 | bank_infos[bid].adr = (bank_infos[bid].adr & U64(0xffffffff00000000)) | data; |
| 112 | } |
| 113 | remap_cb(); |
| 114 | } |
| 115 | |
| 52 | 116 | READ16_MEMBER(pci_device::vendor_r) |
| 53 | 117 | { |
| 54 | 118 | return main_id >> 16; |
| r241858 | r241859 | |
| 132 | 196 | void pci_device::map_device(UINT64 memory_window_start, UINT64 memory_window_end, UINT64 memory_offset, address_space *memory_space, |
| 133 | 197 | UINT64 io_window_start, UINT64 io_window_end, UINT64 io_offset, address_space *io_space) |
| 134 | 198 | { |
| 199 | for(int i=0; i<bank_count; i++) { |
| 200 | bank_info &bi = bank_infos[i]; |
| 201 | if(!bi.adr) |
| 202 | continue; |
| 203 | if(UINT32(bi.adr) == UINT32(~(bi.size - 1))) |
| 204 | continue; |
| 205 | |
| 206 | UINT64 start; |
| 207 | address_space *space; |
| 208 | if(bi.flags & M_IO) { |
| 209 | space = io_space; |
| 210 | start = bi.adr + io_offset; |
| 211 | } else { |
| 212 | space = memory_space; |
| 213 | start = bi.adr + memory_offset; |
| 214 | } |
| 215 | UINT64 end = start + bi.size-1; |
| 216 | switch(i) { |
| 217 | 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; |
| 218 | 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; |
| 219 | 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; |
| 220 | 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; |
| 221 | 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; |
| 222 | 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; |
| 223 | } |
| 224 | space->install_device_delegate(start, end, *this, bi.map); |
| 225 | } |
| 226 | |
| 135 | 227 | map_extra(memory_window_start, memory_window_end, memory_offset, memory_space, |
| 136 | 228 | io_window_start, io_window_end, io_offset, io_space); |
| 137 | 229 | } |
| r241858 | r241859 | |
| 146 | 238 | config_space->install_device(device << 12, (device << 12) | 0xfff, *this, &pci_device::config_map); |
| 147 | 239 | } |
| 148 | 240 | |
| 241 | void pci_device::skip_map_regs(int count) |
| 242 | { |
| 243 | bank_reg_count += count; |
| 244 | assert(bank_reg_count <= 6); |
| 245 | } |
| 246 | |
| 149 | 247 | void pci_device::add_map(UINT64 size, int flags, address_map_delegate &map) |
| 150 | 248 | { |
| 249 | assert(bank_count < 6); |
| 250 | int bid = bank_count++; |
| 251 | bank_infos[bid].map = map; |
| 252 | bank_infos[bid].adr = 0; |
| 253 | bank_infos[bid].size = size; |
| 254 | bank_infos[bid].flags = flags; |
| 255 | |
| 256 | if(flags & M_64A) { |
| 257 | assert(bank_reg_count < 5); |
| 258 | int breg = bank_reg_count; |
| 259 | bank_reg_infos[breg].bank = bid; |
| 260 | bank_reg_infos[breg].hi = 0; |
| 261 | bank_reg_infos[breg+1].bank = bid; |
| 262 | bank_reg_infos[breg+1].hi = 1; |
| 263 | bank_reg_count += 2; |
| 264 | } else { |
| 265 | assert(bank_reg_count < 6); |
| 266 | int breg = bank_reg_count++; |
| 267 | bank_reg_infos[breg].bank = bid; |
| 268 | bank_reg_infos[breg].hi = 0; |
| 269 | } |
| 270 | |
| 151 | 271 | logerror("Device %s (%s) has 0x%" I64FMT "x bytes of %s named %s\n", tag(), name(), size, flags & M_IO ? "io" : "memory", map.name()); |
| 152 | 272 | } |
| 153 | 273 | |
trunk/src/emu/machine/pci.h
| r241858 | r241859 | |
| 43 | 43 | |
| 44 | 44 | virtual DECLARE_ADDRESS_MAP(config_map, 32); |
| 45 | 45 | |
| 46 | UINT32 unmapped_r(offs_t offset, UINT32 mem_mask, int bank); |
| 47 | void unmapped_w(offs_t offset, UINT32 data, UINT32 mem_mask, int bank); |
| 48 | |
| 49 | READ32_MEMBER (unmapped0_r); |
| 50 | WRITE32_MEMBER(unmapped0_w); |
| 51 | READ32_MEMBER (unmapped1_r); |
| 52 | WRITE32_MEMBER(unmapped1_w); |
| 53 | READ32_MEMBER (unmapped2_r); |
| 54 | WRITE32_MEMBER(unmapped2_w); |
| 55 | READ32_MEMBER (unmapped3_r); |
| 56 | WRITE32_MEMBER(unmapped3_w); |
| 57 | READ32_MEMBER (unmapped4_r); |
| 58 | WRITE32_MEMBER(unmapped4_w); |
| 59 | READ32_MEMBER (unmapped5_r); |
| 60 | WRITE32_MEMBER(unmapped5_w); |
| 61 | |
| 62 | |
| 46 | 63 | DECLARE_READ16_MEMBER(vendor_r); |
| 47 | 64 | DECLARE_READ16_MEMBER(device_r); |
| 48 | 65 | DECLARE_READ16_MEMBER(command_r); |
| r241858 | r241859 | |
| 53 | 70 | virtual DECLARE_READ8_MEMBER(latency_timer_r); |
| 54 | 71 | virtual DECLARE_READ8_MEMBER(header_type_r); |
| 55 | 72 | virtual DECLARE_READ8_MEMBER(bist_r); |
| 73 | DECLARE_READ32_MEMBER(address_base_r); |
| 74 | DECLARE_WRITE32_MEMBER(address_base_w); |
| 56 | 75 | DECLARE_READ16_MEMBER(subvendor_r); |
| 57 | 76 | DECLARE_READ16_MEMBER(subsystem_r); |
| 58 | 77 | virtual DECLARE_READ8_MEMBER(capptr_r); |
| r241858 | r241859 | |
| 66 | 85 | M_PREF = 8 |
| 67 | 86 | }; |
| 68 | 87 | |
| 88 | struct bank_info { |
| 89 | address_map_delegate map; |
| 90 | UINT64 adr; |
| 91 | UINT32 size; |
| 92 | int flags; |
| 93 | }; |
| 94 | |
| 95 | struct bank_reg_info { |
| 96 | int bank, hi; |
| 97 | }; |
| 98 | |
| 99 | bank_info bank_infos[6]; |
| 100 | int bank_count, bank_reg_count; |
| 101 | bank_reg_info bank_reg_infos[6]; |
| 102 | |
| 69 | 103 | UINT32 main_id, subsystem_id; |
| 70 | 104 | UINT32 pclass; |
| 71 | 105 | UINT8 revision; |
| r241858 | r241859 | |
| 76 | 110 | |
| 77 | 111 | static void scan_sub_devices(pci_device **devices, dynamic_array<pci_device *> &all, dynamic_array<pci_device *> &bridges, device_t *root); |
| 78 | 112 | |
| 113 | void skip_map_regs(int count); |
| 79 | 114 | void add_map(UINT64 size, int flags, address_map_delegate &map); |
| 80 | 115 | template <typename T> void add_map(UINT64 size, int flags, void (T::*map)(address_map &map, device_t &device), const char *name) { |
| 81 | 116 | address_map_delegate delegate(map, name, static_cast<T *>(this)); |