From a6ce93036eb4ebfbcb89f395225767c0e23b14a0 Mon Sep 17 00:00:00 2001 From: Olivier Galibert Date: Fri, 7 Nov 2014 14:27:39 +0100 Subject: pci: A little more, reaches an unemulated pslldq at fd228 [O. Galibert] --- src/emu/machine/i6300esb.c | 171 ++++++++++++++++++++++++++++++++++++++++++++- src/emu/machine/i6300esb.h | 40 +++++++++-- src/emu/machine/pci.c | 95 ++++++++++++++++++++----- src/emu/machine/pci.h | 29 +++++--- 4 files changed, 298 insertions(+), 37 deletions(-) diff --git a/src/emu/machine/i6300esb.c b/src/emu/machine/i6300esb.c index 59fc013a226..1057774c739 100644 --- a/src/emu/machine/i6300esb.c +++ b/src/emu/machine/i6300esb.c @@ -29,10 +29,21 @@ DEVICE_ADDRESS_MAP_START(config_map, 32, i6300esb_lpc_device) AM_RANGE(0xe4, 0xe7) AM_READWRITE16(gen1_dec_r, gen1_dec_w, 0x0000ffff) AM_RANGE(0xe4, 0xe7) AM_READWRITE16(lpc_en_r, lpc_en_w, 0xffff0000) AM_RANGE(0xe8, 0xeb) AM_READWRITE (fwh_sel1_r, fwh_sel1_w) + AM_RANGE(0xfc, 0xff) AM_READWRITE (unk_fc_r, unk_fc_w) AM_INHERIT_FROM(pci_device::config_map) ADDRESS_MAP_END +DEVICE_ADDRESS_MAP_START(internal_io_map, 32, i6300esb_lpc_device) + if(lpc_en & 0x2000) { + AM_RANGE(0x004c, 0x004f) AM_READWRITE8(siu_config_port_r, siu_config_port_w, 0x00ff0000) + AM_RANGE(0x004c, 0x004f) AM_READWRITE8(siu_data_port_r, siu_data_port_w, 0xff000000) + } + + AM_RANGE(0x80, 0x83) AM_WRITE8( nop_w, 0x000000ff) // POST/non-existing, used for delays by the bios/os + AM_RANGE(0xec, 0xef) AM_WRITE8( nop_w, 0x0000ff00) // Non-existing, used for delays by the bios/os +ADDRESS_MAP_END + i6300esb_lpc_device::i6300esb_lpc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : pci_device(mconfig, I6300ESB_LPC, "i6300ESB southbridge ISA/LPC bridge", tag, owner, clock, "i6300esb_lpc", __FILE__) @@ -47,10 +58,20 @@ void i6300esb_lpc_device::device_start() void i6300esb_lpc_device::device_reset() { pci_device::device_reset(); + siu_config_port = 0; + siu_config_state = 0; +} + +void i6300esb_lpc_device::reset_all_mappings() +{ gpio_base = 0; gpio_cntl = 0x00; + lpc_if_com_range = 0x00; + lpc_if_fdd_lpt_range = 0x00; + lpc_if_sound_range = 0x00; + fwh_dec_en1 = 0xff; gen1_dec = 0x0000; - lpc_en = 0x0000; + lpc_en = 0x2000; fwh_sel1 = 0x00112233; } @@ -77,6 +98,50 @@ WRITE8_MEMBER (i6300esb_lpc_device::gpio_cntl_w) logerror("%s: gpio_cntl = %02x\n", tag(), gpio_cntl); } +READ8_MEMBER (i6300esb_lpc_device::lpc_if_com_range_r) +{ + return lpc_if_com_range; +} + +WRITE8_MEMBER (i6300esb_lpc_device::lpc_if_com_range_w) +{ + COMBINE_DATA(&lpc_if_com_range); + logerror("%s: lpc_if_com_range = %02x\n", tag(), lpc_if_com_range); +} + +READ8_MEMBER (i6300esb_lpc_device::lpc_if_fdd_lpt_range_r) +{ + return lpc_if_fdd_lpt_range; +} + +WRITE8_MEMBER (i6300esb_lpc_device::lpc_if_fdd_lpt_range_w) +{ + COMBINE_DATA(&lpc_if_fdd_lpt_range); + logerror("%s: lpc_if_fdd_lpt_range = %02x\n", tag(), lpc_if_fdd_lpt_range); +} + +READ8_MEMBER (i6300esb_lpc_device::lpc_if_sound_range_r) +{ + return lpc_if_sound_range; +} + +WRITE8_MEMBER (i6300esb_lpc_device::lpc_if_sound_range_w) +{ + COMBINE_DATA(&lpc_if_sound_range); + logerror("%s: lpc_if_sound_range = %02x\n", tag(), lpc_if_sound_range); +} + +READ8_MEMBER (i6300esb_lpc_device::fwh_dec_en1_r) +{ + return fwh_dec_en1; +} + +WRITE8_MEMBER (i6300esb_lpc_device::fwh_dec_en1_w) +{ + fwh_dec_en1 = data | 0x80; + logerror("%s: fwh_dec_en1 = %02x\n", tag(), fwh_dec_en1); +} + READ16_MEMBER (i6300esb_lpc_device::gen1_dec_r) { return gen1_dec; @@ -110,10 +175,110 @@ WRITE32_MEMBER(i6300esb_lpc_device::fwh_sel1_w) logerror("%s: fwh_sel1 = %08x\n", tag(), fwh_sel1); } +READ32_MEMBER (i6300esb_lpc_device::unk_fc_r) +{ + logerror("%s: read undocumented config reg fc\n", tag()); + return 0; +} + +WRITE32_MEMBER(i6300esb_lpc_device::unk_fc_w) +{ + logerror("%s: write undocumented config reg fc (%08x)\n", tag(), data); +} + + + +READ8_MEMBER (i6300esb_lpc_device::siu_config_port_r) +{ + return siu_config_port; +} + +WRITE8_MEMBER (i6300esb_lpc_device::siu_config_port_w) +{ + siu_config_port = data; + switch(siu_config_state) { + case 0: + siu_config_state = data == 0x80 ? 1 : 0; + break; + case 1: + siu_config_state = data == 0x86 ? 2 : data == 0x80 ? 1 : 0; + if(siu_config_state == 2) + logerror("%s: siu configuration active\n", tag()); + break; + case 2: + siu_config_state = data == 0x68 ? 3 : 2; + break; + case 3: + siu_config_state = data == 0x08 ? 0 : data == 0x68 ? 3 : 2; + if(!siu_config_state) + logerror("%s: siu configuration disabled\n", tag()); + break; + } +} + +READ8_MEMBER (i6300esb_lpc_device::siu_data_port_r) +{ + logerror("%s: siu config read port %02x\n", tag(), siu_config_port); + return 0xff; +} + +WRITE8_MEMBER (i6300esb_lpc_device::siu_data_port_w) +{ + if(siu_config_state < 2) { + logerror("%s: siu config write port with config disabled (port=%02x, data=%02x)\n", tag(), siu_config_port, data); + return; + } + logerror("%s: siu config write port %02x, %02x\n", tag(), siu_config_port, data); +} + +WRITE8_MEMBER (i6300esb_lpc_device::nop_w) +{ +} + +void i6300esb_lpc_device::map_bios(address_space *memory_space, UINT32 start, UINT32 end, int idsel) +{ + // Ignore idsel, a16 inversion for now + UINT32 mask = m_region->bytes() - 1; + memory_space->install_rom(start, end, m_region->base() + (start & mask)); +} + void i6300esb_lpc_device::map_extra(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) { - memory_space->install_rom(0xfff00000, 0xffffffff, m_region->base()); - memory_space->install_rom(0x000f0000, 0x000fffff, m_region->base()+0xf0000); + if(fwh_dec_en1 & 0x80) { + map_bios(memory_space, 0xfff80000, 0xffffffff, 7); + map_bios(memory_space, 0xffb80000, 0xffbfffff, 7); + map_bios(memory_space, 0x000e0000, 0x000fffff, 7); + } + if(fwh_dec_en1 & 0x40) { + map_bios(memory_space, 0xfff00000, 0xfff7ffff, 6); + map_bios(memory_space, 0xffb00000, 0xffb7ffff, 6); + } + if(fwh_dec_en1 & 0x20) { + map_bios(memory_space, 0xffe80000, 0xffefffff, 5); + map_bios(memory_space, 0xffa80000, 0xffafffff, 5); + } + if(fwh_dec_en1 & 0x10) { + map_bios(memory_space, 0xffe00000, 0xffe7ffff, 4); + map_bios(memory_space, 0xffa00000, 0xffa7ffff, 4); + } + if(fwh_dec_en1 & 0x08) { + map_bios(memory_space, 0xffd80000, 0xffdfffff, 3); + map_bios(memory_space, 0xff980000, 0xff9fffff, 3); + } + if(fwh_dec_en1 & 0x04) { + map_bios(memory_space, 0xffd00000, 0xffd7ffff, 2); + map_bios(memory_space, 0xff900000, 0xff97ffff, 2); + } + if(fwh_dec_en1 & 0x02) { + map_bios(memory_space, 0xffc80000, 0xffcfffff, 1); + map_bios(memory_space, 0xff880000, 0xff8fffff, 1); + } + if(fwh_dec_en1 & 0x01) { + map_bios(memory_space, 0xffc00000, 0xffc7ffff, 0); + map_bios(memory_space, 0xff800000, 0xff87ffff, 0); + } + + io_space->install_device(0, 0xffff, *this, &i6300esb_lpc_device::internal_io_map); } diff --git a/src/emu/machine/i6300esb.h b/src/emu/machine/i6300esb.h index 1749b6dcefb..ec6dfbb5995 100644 --- a/src/emu/machine/i6300esb.h +++ b/src/emu/machine/i6300esb.h @@ -15,31 +15,59 @@ class i6300esb_lpc_device : public pci_device { public: i6300esb_lpc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + virtual void reset_all_mappings(); virtual void map_extra(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); virtual DECLARE_ADDRESS_MAP(config_map, 32); + protected: virtual void device_start(); virtual void device_reset(); private: + DECLARE_ADDRESS_MAP(internal_io_map, 32); + UINT32 gpio_base, fwh_sel1; UINT16 gen1_dec, lpc_en; - UINT8 gpio_cntl; + UINT8 gpio_cntl, lpc_if_com_range, lpc_if_fdd_lpt_range, lpc_if_sound_range, fwh_dec_en1, siu_config_port; + int siu_config_state; - DECLARE_READ32_MEMBER (gpio_base_r); // 58 + DECLARE_WRITE8_MEMBER (nop_w); + + // configuration space registers + DECLARE_READ32_MEMBER (gpio_base_r); // 58 DECLARE_WRITE32_MEMBER(gpio_base_w); - DECLARE_READ8_MEMBER (gpio_cntl_r); // 5c + DECLARE_READ8_MEMBER (gpio_cntl_r); // 5c DECLARE_WRITE8_MEMBER (gpio_cntl_w); - DECLARE_READ16_MEMBER (gen1_dec_r); // e4 + DECLARE_READ8_MEMBER (lpc_if_com_range_r); // e0 + DECLARE_WRITE8_MEMBER (lpc_if_com_range_w); + DECLARE_READ8_MEMBER (lpc_if_fdd_lpt_range_r); // e1 + DECLARE_WRITE8_MEMBER (lpc_if_fdd_lpt_range_w); + DECLARE_READ8_MEMBER (lpc_if_sound_range_r); // e2 + DECLARE_WRITE8_MEMBER (lpc_if_sound_range_w); + DECLARE_READ8_MEMBER (fwh_dec_en1_r); // e3 + DECLARE_WRITE8_MEMBER (fwh_dec_en1_w); + DECLARE_READ16_MEMBER (gen1_dec_r); // e4 DECLARE_WRITE16_MEMBER(gen1_dec_w); - DECLARE_READ16_MEMBER (lpc_en_r); // e6 + DECLARE_READ16_MEMBER (lpc_en_r); // e6 DECLARE_WRITE16_MEMBER(lpc_en_w); - DECLARE_READ32_MEMBER (fwh_sel1_r); // e8 + DECLARE_READ32_MEMBER (fwh_sel1_r); // e8 DECLARE_WRITE32_MEMBER(fwh_sel1_w); + + DECLARE_READ32_MEMBER (unk_fc_r); // fc + DECLARE_WRITE32_MEMBER(unk_fc_w); + + + // i/o space registers + DECLARE_READ8_MEMBER (siu_config_port_r); // 4e + DECLARE_WRITE8_MEMBER (siu_config_port_w); + DECLARE_READ8_MEMBER (siu_data_port_r); // 4f + DECLARE_WRITE8_MEMBER (siu_data_port_w); + + void map_bios(address_space *memory_space, UINT32 start, UINT32 end, int idsel); }; class i6300esb_watchdog_device : public pci_device { diff --git a/src/emu/machine/pci.c b/src/emu/machine/pci.c index 33baec75ad8..9f12520cbd7 100644 --- a/src/emu/machine/pci.c +++ b/src/emu/machine/pci.c @@ -4,6 +4,17 @@ const device_type PCI_ROOT = &device_creator; const device_type PCI_BRIDGE = &device_creator; 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(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(0x2c, 0x2f) AM_READ16(subvendor_r, 0x0000ffff) + AM_RANGE(0x2c, 0x2f) AM_READ16(subsystem_r, 0xffff0000) 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) @@ -12,15 +23,15 @@ pci_device::pci_device(const machine_config &mconfig, device_type type, const ch main_id = 0xffffffff; revision = 0x00; pclass = 0xffffff; - subdevice_id = 0xffffffff; + subsystem_id = 0xffffffff; } -void pci_device::set_ids(UINT32 _main_id, UINT8 _revision, UINT32 _pclass, UINT32 _subdevice_id) +void pci_device::set_ids(UINT32 _main_id, UINT8 _revision, UINT32 _pclass, UINT32 _subsystem_id) { main_id = _main_id; revision = _revision; pclass = _pclass; - subdevice_id = _subdevice_id; + subsystem_id = _subsystem_id; } void pci_device::device_start() @@ -31,6 +42,51 @@ void pci_device::device_reset() { } +READ16_MEMBER(pci_device::vendor_r) +{ + return main_id >> 16; +} + +READ16_MEMBER(pci_device::device_r) +{ + return main_id; +} + +READ32_MEMBER(pci_device::class_rev_r) +{ + return (pclass << 8) | revision; +} + +READ8_MEMBER(pci_device::cache_line_size_r) +{ + return 0x00; +} + +READ8_MEMBER(pci_device::latency_timer_r) +{ + return 0x00; +} + +READ8_MEMBER(pci_device::header_type_r) +{ + return 0x00; +} + +READ8_MEMBER(pci_device::bist_r) +{ + return 0x00; +} + +READ16_MEMBER(pci_device::subvendor_r) +{ + return subsystem_id >> 16; +} + +READ16_MEMBER(pci_device::subsystem_r) +{ + return subsystem_id; +} + void pci_device::scan_sub_devices(pci_device **devices, dynamic_array &all, dynamic_array &bridges, device_t *root) { } @@ -92,6 +148,11 @@ pci_bridge_device::pci_bridge_device(const machine_config &mconfig, device_type { } +READ8_MEMBER(pci_bridge_device::header_type_r) +{ + return 0x01; +} + const address_space_config *pci_bridge_device::memory_space_config(address_spacenum spacenum) const { return spacenum == AS_PROGRAM ? &configure_space_config : NULL; @@ -110,8 +171,6 @@ void pci_bridge_device::device_start() sub_devices[i] = NULL; for(device_t *d = bus_root()->first_subdevice(); d != NULL; d = d->next()) { - if(d == this) - continue; const char *t = d->tag(); int l = strlen(t); if(l <= 4 || t[l-5] != ':' || t[l-2] != '.') @@ -123,9 +182,11 @@ void pci_bridge_device::device_start() for(int i=0; i<32*8; i++) if(sub_devices[i]) { all_devices.append(sub_devices[i]); - pci_bridge_device *bridge = dynamic_cast(sub_devices[i]); - if(bridge) - all_bridges.append(bridge); + if(sub_devices[i] != this) { + pci_bridge_device *bridge = dynamic_cast(sub_devices[i]); + if(bridge) + all_bridges.append(bridge); + } } } @@ -138,7 +199,8 @@ void pci_bridge_device::device_reset() void pci_bridge_device::reset_all_mappings() { for(int i=0; i != all_devices.count(); i++) - all_devices[i]->reset_all_mappings(); + if(all_devices[i] != this) + all_devices[i]->reset_all_mappings(); } @@ -146,8 +208,9 @@ void pci_bridge_device::map_device(UINT64 memory_window_start, UINT64 memory_win UINT64 io_window_start, UINT64 io_window_end, UINT64 io_offset, address_space *io_space) { for(int i = all_devices.count()-1; i>=0; i--) - all_devices[i]->map_device(memory_window_start, memory_window_end, memory_offset, memory_space, - io_window_start, io_window_end, io_offset, io_space); + if(all_devices[i] != this) + all_devices[i]->map_device(memory_window_start, memory_window_end, memory_offset, memory_space, + io_window_start, io_window_end, io_offset, io_space); map_extra(memory_window_start, memory_window_end, memory_offset, memory_space, io_window_start, io_window_end, io_offset, io_space); @@ -208,8 +271,7 @@ void pci_host_device::device_start() void pci_host_device::device_reset() { pci_bridge_device::device_reset(); - for(int i=0; i != all_devices.count(); i++) - all_devices[i]->reset_all_mappings(); + reset_all_mappings(); regenerate_mapping(); config_address = 0; @@ -217,6 +279,7 @@ void pci_host_device::device_reset() void pci_host_device::regenerate_mapping() { + logerror("Regenerating mapping\n"); memory_space->unmap_readwrite(memory_window_start, memory_window_end); io_space->unmap_readwrite(io_window_start, io_window_end); @@ -224,12 +287,6 @@ void pci_host_device::regenerate_mapping() io_window_start, io_window_end, io_offset, io_space); } -void pci_host_device::regenerate_config_mapping() -{ - pci_bridge_device::regenerate_config_mapping(); - map_config(0, &space(AS_PROGRAM)); -} - READ32_MEMBER(pci_host_device::config_address_r) { return config_address; diff --git a/src/emu/machine/pci.h b/src/emu/machine/pci.h index a2e48ddc7e8..3f5b6d93e58 100644 --- a/src/emu/machine/pci.h +++ b/src/emu/machine/pci.h @@ -6,15 +6,15 @@ #define MCFG_PCI_ROOT_ADD(_tag) \ MCFG_DEVICE_ADD(_tag, PCI_ROOT, 0) -#define MCFG_PCI_DEVICE_ADD(_tag, _type, _main_id, _revision, _pclass, _subdevice_id) \ +#define MCFG_PCI_DEVICE_ADD(_tag, _type, _main_id, _revision, _pclass, _subsystem_id) \ MCFG_DEVICE_ADD(_tag, _type, 0) \ - downcast(device)->set_ids(_main_id, _revision, _pclass, _subdevice_id); + downcast(device)->set_ids(_main_id, _revision, _pclass, _subsystem_id); -#define MCFG_AGP_DEVICE_ADD(_tag, _type, _main_id, _revision, _subdevice_id) \ - MCFG_PCI_DEVICE_ADD(_tag, _type, _main_id, _revision, 0x030000, _subdevice_id) +#define MCFG_AGP_DEVICE_ADD(_tag, _type, _main_id, _revision, _subsystem_id) \ + MCFG_PCI_DEVICE_ADD(_tag, _type, _main_id, _revision, 0x030000, _subsystem_id) -#define MCFG_PCI_HOST_ADD(_tag, _type, _main_id, _revision, _subdevice_id) \ - MCFG_PCI_DEVICE_ADD(_tag, _type, _main_id, _revision, 0x060000, _subdevice_id) +#define MCFG_PCI_HOST_ADD(_tag, _type, _main_id, _revision, _subsystem_id) \ + MCFG_PCI_DEVICE_ADD(_tag, _type, _main_id, _revision, 0x060000, _subsystem_id) #define MCFG_PCI_BRIDGE_ADD(_tag, _main_id, _revision) \ MCFG_PCI_DEVICE_ADD(_tag, PCI_BRIDGE, _main_id, _revision, 0x060400, 0x00000000) @@ -26,7 +26,7 @@ class pci_device : public device_t { public: 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); - void set_ids(UINT32 main_id, UINT8 revision, UINT32 pclass, UINT32 subdevice_id); + void set_ids(UINT32 main_id, UINT8 revision, UINT32 pclass, UINT32 subsystem_id); virtual void reset_all_mappings(); virtual void map_device(UINT64 memory_window_start, UINT64 memory_window_end, UINT64 memory_offset, address_space *memory_space, @@ -38,6 +38,16 @@ public: virtual DECLARE_ADDRESS_MAP(config_map, 32); + DECLARE_READ16_MEMBER(vendor_r); + DECLARE_READ16_MEMBER(device_r); + DECLARE_READ32_MEMBER(class_rev_r); + virtual DECLARE_READ8_MEMBER(cache_line_size_r); + virtual DECLARE_READ8_MEMBER(latency_timer_r); + virtual DECLARE_READ8_MEMBER(header_type_r); + virtual DECLARE_READ8_MEMBER(bist_r); + DECLARE_READ16_MEMBER(subvendor_r); + DECLARE_READ16_MEMBER(subsystem_r); + protected: enum { M_MEM = 0, @@ -47,7 +57,7 @@ protected: M_PREF = 8 }; - UINT32 main_id, subdevice_id; + UINT32 main_id, subsystem_id; UINT32 pclass; UINT8 revision; @@ -81,6 +91,8 @@ public: UINT64 io_window_start, UINT64 io_window_end, UINT64 io_offset, address_space *io_space); virtual void reset_all_mappings(); + virtual DECLARE_READ8_MEMBER(header_type_r); + protected: pci_device *sub_devices[32*8]; dynamic_array all_devices; @@ -134,7 +146,6 @@ protected: void config_write(UINT8 bus, UINT8 device, UINT16 reg, UINT32 data, UINT32 mem_mask); void regenerate_mapping(); - virtual void regenerate_config_mapping(); }; class pci_root_device : public device_t { -- cgit v1.2.3