From 6678c80e3e7dec477dcddc83a57904445e69ac6a Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Sat, 29 Apr 2023 21:28:08 +0100 Subject: cpu/mips, sgi/sgi.cpp: Fixed MIPS3 PRID and memory controller RPSS issues: (#11128) * cpu/mips3: Report proper fcr0 PRID (same as CPU PRID in most cases). * cpu/mips3: Bumped major rev of R4600 PRID to 2 (original R4600 was too problematic so almost all systems are shipped with R4600 rev 2.0). * sgi/indigo.cpp, sgi/indy_indigo2.cpp: Supply clock frequency for memory controller. * sgi/indigo.cpp, sgi/indy_indigo2.cpp: Corrected CPU clock frequencies. * sgi/sgi.cpp: Reimplemented memory controller RPSS taking clock frequency into account and without using a timer. --- src/devices/cpu/mips/mips3.cpp | 6 +++++- src/devices/cpu/mips/mips3.h | 1 + src/devices/cpu/mips/mips3com.cpp | 10 ++++++++- src/mame/sgi/indigo.cpp | 2 +- src/mame/sgi/indy_indigo2.cpp | 39 ++++++++++++++++++--------------- src/mame/sgi/sgi.cpp | 45 +++++++++++++++------------------------ src/mame/sgi/sgi.h | 13 ++++++----- 7 files changed, 61 insertions(+), 55 deletions(-) diff --git a/src/devices/cpu/mips/mips3.cpp b/src/devices/cpu/mips/mips3.cpp index 529f82b6d30..751e8666018 100644 --- a/src/devices/cpu/mips/mips3.cpp +++ b/src/devices/cpu/mips/mips3.cpp @@ -472,7 +472,8 @@ void mips3_device::device_start() m_drcuml->symbol_add(&m_core->cpr[0][COP0_TagLo], sizeof(m_core->cpr[0][COP0_TagLo]), "TagLo"); m_drcuml->symbol_add(&m_core->cpr[0][COP0_TagHi], sizeof(m_core->cpr[0][COP0_TagHi]), "TagHi"); m_drcuml->symbol_add(&m_core->cpr[0][COP0_ErrorPC], sizeof(m_core->cpr[0][COP0_ErrorPC]), "ErrorPC"); - m_drcuml->symbol_add(&m_core->ccr[1][31], sizeof(m_core->cpr[1][31]), "fcr31"); + m_drcuml->symbol_add(&m_core->ccr[1][0], sizeof(m_core->ccr[1][0]), "fcr0"); + m_drcuml->symbol_add(&m_core->ccr[1][31], sizeof(m_core->ccr[1][31]), "fcr31"); m_drcuml->symbol_add(&m_core->mode, sizeof(m_core->mode), "mode"); m_drcuml->symbol_add(&m_core->arg0, sizeof(m_core->arg0), "arg0"); m_drcuml->symbol_add(&m_core->arg1, sizeof(m_core->arg1), "arg1"); @@ -1109,6 +1110,9 @@ void mips3_device::device_reset() m_core->llbit = 0; m_core->count_zero_time = total_cycles(); + /* initialize the FPU state */ + m_core->ccr[1][0] = compute_fpu_prid_register(); + /* initialize the TLB state */ for (int tlbindex = 0; tlbindex < m_tlbentries; tlbindex++) { diff --git a/src/devices/cpu/mips/mips3.h b/src/devices/cpu/mips/mips3.h index 18c0d60bbc6..c2849f67787 100644 --- a/src/devices/cpu/mips/mips3.h +++ b/src/devices/cpu/mips/mips3.h @@ -542,6 +542,7 @@ public: private: uint32_t compute_config_register(); uint32_t compute_prid_register(); + uint32_t compute_fpu_prid_register(); uint32_t generate_tlb_index(); void tlb_map_entry(int tlbindex); diff --git a/src/devices/cpu/mips/mips3com.cpp b/src/devices/cpu/mips/mips3com.cpp index 8d965d792d9..cf8e65cd5af 100644 --- a/src/devices/cpu/mips/mips3com.cpp +++ b/src/devices/cpu/mips/mips3com.cpp @@ -336,8 +336,10 @@ uint32_t mips3_device::compute_prid_register() return 0x5500; case MIPS3_TYPE_R4600: + return 0x2020; + case MIPS3_TYPE_R4650: - return 0x2000; + return 0x2200; case MIPS3_TYPE_R4700: return 0x2100; @@ -364,6 +366,12 @@ uint32_t mips3_device::compute_prid_register() //return 0x2000; } +uint32_t mips3_device::compute_fpu_prid_register() +{ + /* For most CPUs they are same */ + return compute_prid_register(); +} + /*------------------------------------------------- tlb_map_entry - map a single TLB entry diff --git a/src/mame/sgi/indigo.cpp b/src/mame/sgi/indigo.cpp index bdd3785db2c..a369a430939 100644 --- a/src/mame/sgi/indigo.cpp +++ b/src/mame/sgi/indigo.cpp @@ -222,7 +222,7 @@ void indigo4k_state::indigo4k(machine_config &config) //m_maincpu->set_dcache_size(32768); m_maincpu->set_addrmap(AS_PROGRAM, &indigo4k_state::mem_map); - SGI_MC(config, m_mem_ctrl, m_maincpu, m_eeprom); + SGI_MC(config, m_mem_ctrl, m_maincpu, m_eeprom, 50000000); m_mem_ctrl->eisa_present().set_constant(0); SGI_HPC1(config, m_hpc, m_maincpu, m_eeprom); } diff --git a/src/mame/sgi/indy_indigo2.cpp b/src/mame/sgi/indy_indigo2.cpp index 913f7d3ea82..36be2ef8934 100644 --- a/src/mame/sgi/indy_indigo2.cpp +++ b/src/mame/sgi/indy_indigo2.cpp @@ -107,8 +107,8 @@ public: { } - void ip24_base(machine_config &config); - void ip24(machine_config &config); + void ip24_base(machine_config &config, uint32_t system_clock); + void ip24(machine_config &config, uint32_t system_clock); void indy_5015(machine_config &config); void indy_4613(machine_config &config); void indy_4610(machine_config &config); @@ -329,9 +329,9 @@ void ip24_state::scsi_devices(device_slot_interface &device) //device.set_option_machine_config("cdrom", cdrom_config); } -void ip24_state::ip24_base(machine_config &config) +void ip24_state::ip24_base(machine_config &config, uint32_t system_clock) { - SGI_MC(config, m_mem_ctrl, m_maincpu, m_eeprom); + SGI_MC(config, m_mem_ctrl, m_maincpu, m_eeprom, system_clock); m_mem_ctrl->int_dma_done_cb().set(m_ioc2, FUNC(ioc2_device::mc_dma_done_w)); m_mem_ctrl->eisa_present().set_constant(1); @@ -387,9 +387,9 @@ void ip24_state::ip24_base(machine_config &config) SOFTWARE_LIST(config, "sgi_mips_hdd").set_original("sgi_mips_hdd"); } -void ip24_state::ip24(machine_config &config) +void ip24_state::ip24(machine_config &config, uint32_t system_clock) { - ip24_base(config); + ip24_base(config, system_clock); m_hpc3->set_addrmap(hpc3_device::AS_PIO6, &ip24_state::pio6_map); @@ -408,9 +408,10 @@ void ip24_state::ip24(machine_config &config) void ip24_state::indy_5015(machine_config &config) { - ip24(config); - - R5000BE(config, m_maincpu, 75'000'000); + constexpr uint32_t system_clock = 50'000'000; + ip24(config, system_clock); + R5000BE(config, m_maincpu, 3 * system_clock); + m_maincpu->set_system_clock(system_clock); m_maincpu->set_icache_size(0x8000); m_maincpu->set_dcache_size(0x8000); m_maincpu->set_addrmap(AS_PROGRAM, &ip24_state::ip24_map); @@ -418,9 +419,10 @@ void ip24_state::indy_5015(machine_config &config) void ip24_state::indy_4613(machine_config &config) { - ip24(config); - - R4600BE(config, m_maincpu, 66'666'666); + constexpr uint32_t system_clock = 66'666'666; + ip24(config, system_clock); + R4600BE(config, m_maincpu, 2 * system_clock); + m_maincpu->set_system_clock(system_clock); m_maincpu->set_icache_size(0x4000); m_maincpu->set_dcache_size(0x4000); m_maincpu->set_addrmap(AS_PROGRAM, &ip24_state::ip24_map); @@ -428,9 +430,10 @@ void ip24_state::indy_4613(machine_config &config) void ip24_state::indy_4610(machine_config &config) { - ip24(config); - - R4600BE(config, m_maincpu, 50'000'000); + constexpr uint32_t system_clock = 50'000'000; + ip24(config, system_clock); + R4600BE(config, m_maincpu, 2 * system_clock); + m_maincpu->set_system_clock(system_clock); m_maincpu->set_icache_size(0x4000); m_maincpu->set_dcache_size(0x4000); m_maincpu->set_addrmap(AS_PROGRAM, &ip24_state::ip24_map); @@ -445,12 +448,14 @@ void ip22_state::wd33c93_2(device_t *device) void ip22_state::indigo2_4415(machine_config &config) { - R4400BE(config, m_maincpu, 75'000'000); + constexpr uint32_t system_clock = 50'000'000; + R4400BE(config, m_maincpu, 3 * system_clock); + m_maincpu->set_system_clock(system_clock); m_maincpu->set_icache_size(0x4000); m_maincpu->set_dcache_size(0x4000); m_maincpu->set_addrmap(AS_PROGRAM, &ip22_state::ip22_map); - ip24_base(config); + ip24_base(config, system_clock); NSCSI_BUS(config, "scsibus2", 0); NSCSI_CONNECTOR(config, "scsibus2:0").option_set("wd33c93", WD33C93B) diff --git a/src/mame/sgi/sgi.cpp b/src/mame/sgi/sgi.cpp index 0b943ae4d90..9203a705a23 100644 --- a/src/mame/sgi/sgi.cpp +++ b/src/mame/sgi/sgi.cpp @@ -33,8 +33,8 @@ sgi_mc_device::sgi_mc_device(const machine_config &mconfig, const char *tag, dev , m_eeprom(*this, finder_base::DUMMY_TAG) , m_int_dma_done_cb(*this) , m_eisa_present(*this) - , m_rpss_timer(nullptr) , m_dma_timer(nullptr) + , m_last_update_time(attotime::zero) , m_watchdog(0) , m_sys_id(0) , m_rpss_divider(0) @@ -65,9 +65,6 @@ sgi_mc_device::sgi_mc_device(const machine_config &mconfig, const char *tag, dev , m_dma_count(0) , m_dma_run(0) , m_eeprom_ctrl(0) - , m_rpss_divide_counter(0) - , m_rpss_divide_count(0) - , m_rpss_increment(0) { } @@ -86,12 +83,10 @@ void sgi_mc_device::device_start() m_sys_id = 0x03; // rev. C MC m_sys_id |= m_eisa_present() << 4; - m_rpss_timer = timer_alloc(FUNC(sgi_mc_device::rpss_tick), this); - m_rpss_timer->adjust(attotime::never); - m_dma_timer = timer_alloc(FUNC(sgi_mc_device::perform_dma), this); m_dma_timer->adjust(attotime::never); + save_item(NAME(m_last_update_time)); save_item(NAME(m_cpu_control)); save_item(NAME(m_watchdog)); save_item(NAME(m_sys_id)); @@ -127,9 +122,6 @@ void sgi_mc_device::device_start() save_item(NAME(m_dma_run)); save_item(NAME(m_eeprom_ctrl)); save_item(NAME(m_semaphore)); - save_item(NAME(m_rpss_divide_counter)); - save_item(NAME(m_rpss_divide_count)); - save_item(NAME(m_rpss_increment)); } void sgi_mc_device::device_reset() @@ -173,10 +165,6 @@ void sgi_mc_device::device_reset() m_dma_run = 0; m_eeprom_ctrl = 0; memset(m_semaphore, 0, sizeof(uint32_t) * 16); - m_rpss_timer->adjust(attotime::from_hz(10000000), 0, attotime::from_hz(10000000)); - m_rpss_divide_counter = 4; - m_rpss_divide_count = 4; - m_rpss_increment = 1; m_space = &m_maincpu->space(AS_PROGRAM); } @@ -311,6 +299,18 @@ TIMER_CALLBACK_MEMBER(sgi_mc_device::perform_dma) } } +void sgi_mc_device::update_count() +{ + const uint32_t divide = (m_rpss_divider & 0xff) + 1; + const uint32_t increment = (m_rpss_divider >> 8) & 0xff; + const uint32_t freq = clock() / divide; + const attotime elapsed = machine().scheduler().time() - m_last_update_time; + /* Quantise elapsed to the clock frequency */ + const auto ticks = elapsed.as_ticks(freq); + m_last_update_time += attotime::from_ticks(ticks, freq); + m_rpss_counter += uint32_t(ticks * increment); +} + uint32_t sgi_mc_device::read(offs_t offset, uint32_t mem_mask) { switch (offset & ~1) @@ -424,7 +424,8 @@ uint32_t sgi_mc_device::read(offs_t offset, uint32_t mem_mask) LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA TLB Entry 3 Low Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry_lo[3], mem_mask); return m_dma_tlb_entry_lo[3]; case 0x1000/4: - LOGMASKED(LOG_RPSS, "%s: RPSS 100ns Counter Read: %08x & %08x\n", machine().describe_context(), m_rpss_counter, mem_mask); + LOGMASKED(LOG_RPSS, "%s: RPSS Counter Read: %08x & %08x\n", machine().describe_context(), m_rpss_counter, mem_mask); + update_count(); return m_rpss_counter; case 0x2000/4: case 0x2008/4: @@ -505,10 +506,8 @@ void sgi_mc_device::write(offs_t offset, uint32_t data, uint32_t mem_mask) break; case 0x0028/4: LOGMASKED(LOG_RPSS, "%s: RPSS Divider Write: %08x & %08x\n", machine().describe_context(), data, mem_mask); + update_count(); m_rpss_divider = data; - m_rpss_divide_count = (int)(m_rpss_divider & 0xff); - m_rpss_divide_counter = m_rpss_divide_count; - m_rpss_increment = (m_rpss_divider >> 8) & 0xff; break; case 0x0030/4: LOGMASKED(LOG_WRITES, "%s: R4000 EEPROM Write: CS:%d, SCK:%d, SO:%d\n", machine().describe_context(), @@ -720,13 +719,3 @@ void sgi_mc_device::write(offs_t offset, uint32_t data, uint32_t mem_mask) break; } } - -TIMER_CALLBACK_MEMBER(sgi_mc_device::rpss_tick) -{ - m_rpss_divide_counter--; - if (m_rpss_divide_counter < 0) - { - m_rpss_divide_counter = m_rpss_divide_count; - m_rpss_counter += m_rpss_increment; - } -} diff --git a/src/mame/sgi/sgi.h b/src/mame/sgi/sgi.h index b9cac68dec5..118a63b1468 100644 --- a/src/mame/sgi/sgi.h +++ b/src/mame/sgi/sgi.h @@ -19,8 +19,8 @@ class sgi_mc_device : public device_t { public: template - sgi_mc_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&cpu_tag, U &&eeprom_tag) - : sgi_mc_device(mconfig, tag, owner, (uint32_t)0) + sgi_mc_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&cpu_tag, U &&eeprom_tag, uint32_t clock) + : sgi_mc_device(mconfig, tag, owner, clock) { m_maincpu.set_tag(std::forward(cpu_tag)); m_eeprom.set_tag(std::forward(eeprom_tag)); @@ -54,7 +54,6 @@ private: uint32_t dma_translate(uint32_t address); TIMER_CALLBACK_MEMBER(perform_dma); - TIMER_CALLBACK_MEMBER(rpss_tick); uint32_t get_line_count() { return m_dma_size >> 16; } uint32_t get_line_width() { return (uint16_t)m_dma_size; } @@ -63,6 +62,8 @@ private: uint32_t get_zoom_count() { return (m_dma_count >> 16) & 0x3ff; } uint32_t get_byte_count() { return (uint16_t)m_dma_count; } + void update_count(); + required_device m_maincpu; required_device m_eeprom; @@ -71,9 +72,10 @@ private: address_space *m_space; - emu_timer *m_rpss_timer; emu_timer *m_dma_timer; + attotime m_last_update_time; + uint32_t m_cpu_control[2]; uint32_t m_watchdog; uint32_t m_sys_id; @@ -109,9 +111,6 @@ private: uint32_t m_dma_run; uint32_t m_eeprom_ctrl; uint32_t m_semaphore[16]; - int m_rpss_divide_counter; - int m_rpss_divide_count; - uint8_t m_rpss_increment; }; DECLARE_DEVICE_TYPE(SGI_MC, sgi_mc_device) -- cgit v1.2.3