summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Jiaxun Yang <jiaxun.yang@flygoat.com>2023-04-29 21:28:08 +0100
committer GitHub <noreply@github.com>2023-04-30 06:28:08 +1000
commit6678c80e3e7dec477dcddc83a57904445e69ac6a (patch)
tree8150efe07f9348f0d9170c48768889e94f4fb57a
parentbb0a957d333fcdd4c118cd8fcb32143c1dcfe424 (diff)
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.
-rw-r--r--src/devices/cpu/mips/mips3.cpp6
-rw-r--r--src/devices/cpu/mips/mips3.h1
-rw-r--r--src/devices/cpu/mips/mips3com.cpp10
-rw-r--r--src/mame/sgi/indigo.cpp2
-rw-r--r--src/mame/sgi/indy_indigo2.cpp39
-rw-r--r--src/mame/sgi/sgi.cpp45
-rw-r--r--src/mame/sgi/sgi.h13
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 <typename T, typename U>
- 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<T>(cpu_tag));
m_eeprom.set_tag(std::forward<U>(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<cpu_device> m_maincpu;
required_device<eeprom_serial_93cxx_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)