From 73886d9d1733368fe3c876c8e613ba5821e12944 Mon Sep 17 00:00:00 2001 From: Pavel Pisa Date: Mon, 4 Mar 2019 22:38:34 +0100 Subject: Use irq 3 (HW1) for Rx and irq 2 (HW0) for Tx to be compatible with SPIM. Jump to address 0x8000180 by default and to EBase + 0x180 when EBase is set to be compatible with real MIPS CPU. Signed-off-by: Pavel Pisa --- qtmips_machine/cop0state.cpp | 30 +++++++++++++++++------------- qtmips_machine/cop0state.h | 4 ++++ qtmips_machine/core.cpp | 2 +- qtmips_machine/machinedefs.h | 8 ++++++-- qtmips_machine/serialport.cpp | 4 ++-- 5 files changed, 30 insertions(+), 18 deletions(-) (limited to 'qtmips_machine') diff --git a/qtmips_machine/cop0state.cpp b/qtmips_machine/cop0state.cpp index 9c5fa1c..9957560 100644 --- a/qtmips_machine/cop0state.cpp +++ b/qtmips_machine/cop0state.cpp @@ -40,7 +40,6 @@ using namespace machine; - // sorry, unimplemented: non-trivial designated initializers not supported static enum Cop0State::Cop0Regsisters cop0reg_map[32][8] = { @@ -81,25 +80,25 @@ static enum Cop0State::Cop0Regsisters cop0reg_map[32][8] = { // sorry, unimplemented: non-trivial designated initializers not supported const Cop0State::cop0reg_desc_t Cop0State::cop0reg_desc[Cop0State::COP0REGS_CNT] = { - [Cop0State::Unsupported] = {"Unsupported", 0x00000000, + [Cop0State::Unsupported] = {"Unsupported", 0x00000000, 0x00000000, &Cop0State::read_cop0reg_default, &Cop0State::write_cop0reg_default}, - [Cop0State::UserLocal] = {"UserLocal", 0xffffffff, + [Cop0State::UserLocal] = {"UserLocal", 0xffffffff, 0x00000000, &Cop0State::read_cop0reg_default, &Cop0State::write_cop0reg_default}, - [Cop0State::BadVAddr] = {"BadVAddr", 0x00000000, + [Cop0State::BadVAddr] = {"BadVAddr", 0x00000000, 0x00000000, &Cop0State::read_cop0reg_default, &Cop0State::write_cop0reg_default}, - [Cop0State::Count] = {"Count", 0x00000000, + [Cop0State::Count] = {"Count", 0x00000000, 0x00000000, &Cop0State::read_cop0reg_default, &Cop0State::write_cop0reg_default}, - [Cop0State::Compare] = {"Compare", 0x00000000, + [Cop0State::Compare] = {"Compare", 0x00000000, 0x00000000, &Cop0State::read_cop0reg_default, &Cop0State::write_cop0reg_default}, - [Cop0State::Status] = {"Status", Status_IE | Status_IntMask, + [Cop0State::Status] = {"Status", Status_IE | Status_IntMask, 0x00000000, &Cop0State::read_cop0reg_default, &Cop0State::write_cop0reg_default}, - [Cop0State::Cause] = {"Cause", 0x00000000, + [Cop0State::Cause] = {"Cause", 0x00000000, 0x00000000, &Cop0State::read_cop0reg_default, &Cop0State::write_cop0reg_default}, - [Cop0State::EPC] = {"EPC", 0xffffffff, + [Cop0State::EPC] = {"EPC", 0xffffffff, 0x00000000, &Cop0State::read_cop0reg_default, &Cop0State::write_cop0reg_default}, - [Cop0State::EBase] = {"EBase", 0xfffffffc, + [Cop0State::EBase] = {"EBase", 0xfffffffc, 0x80000000, &Cop0State::read_cop0reg_default, &Cop0State::write_cop0reg_default}, - [Cop0State::Config] = {"Config", 0x00000000, + [Cop0State::Config] = {"Config", 0x00000000, 0x00000000, &Cop0State::read_cop0reg_default, &Cop0State::write_cop0reg_default}, }; @@ -166,7 +165,7 @@ bool Cop0State::operator!=(const Cop0State &c) const { void Cop0State::reset() { for (int i = 0; i < COP0REGS_CNT; i++) - this->cop0reg[i] = 0; + this->cop0reg[i] = cop0reg_desc[i].init_value; } void Cop0State::update_execption_cause(enum ExceptionCause excause, bool in_delay_slot) { @@ -197,7 +196,8 @@ bool Cop0State::core_interrupt_request() { irqs &= Status_IntMask; return !!(irqs && cop0reg[(int)Status] & Status_IntMask && - !(cop0reg[(int)Status] & Status_EXL)); + !(cop0reg[(int)Status] & Status_EXL) && + !(cop0reg[(int)Status] & Status_ERL)); } void Cop0State::set_status_exl(bool value) { @@ -206,3 +206,7 @@ void Cop0State::set_status_exl(bool value) { else cop0reg[(int)Status] &= ~Status_EXL; } + +std::uint32_t Cop0State::exception_pc_address() { + return cop0reg[(int)EBase] + 0x180; +} diff --git a/qtmips_machine/cop0state.h b/qtmips_machine/cop0state.h index 649348e..06be9a7 100644 --- a/qtmips_machine/cop0state.h +++ b/qtmips_machine/cop0state.h @@ -64,6 +64,7 @@ public: enum StatusReg { Status_IE = 0x00000001, Status_EXL = 0x00000002, + Status_ERL = 0x00000004, Status_IntMask = 0x0000ff00, Status_Int0 = 0x00000100, }; @@ -82,6 +83,7 @@ public: void reset(); // Reset all values to zero bool core_interrupt_request(); + std::uint32_t exception_pc_address(); public slots: void set_interrupt_signal(uint irq_num, bool active); @@ -102,8 +104,10 @@ private: struct cop0reg_desc_t { const char *name; std::uint32_t write_mask; + std::uint32_t init_value; reg_read_t reg_read; reg_write_t reg_write; + }; static const cop0reg_desc_t cop0reg_desc[COP0REGS_CNT]; diff --git a/qtmips_machine/core.cpp b/qtmips_machine/core.cpp index 22dfdc8..351ffb0 100644 --- a/qtmips_machine/core.cpp +++ b/qtmips_machine/core.cpp @@ -141,7 +141,7 @@ bool Core::handle_exception(Core *core, Registers *regs, ExceptionCause excause, if (cop0state->read_cop0reg(Cop0State::EBase) != 0) { if (excause == EXCAUSE_INT) { cop0state->set_status_exl(true); - regs->pc_abs_jmp(cop0state->read_cop0reg(Cop0State::EBase)); + regs->pc_abs_jmp(cop0state->exception_pc_address()); } } } diff --git a/qtmips_machine/machinedefs.h b/qtmips_machine/machinedefs.h index eb7f6d4..8ccc81c 100644 --- a/qtmips_machine/machinedefs.h +++ b/qtmips_machine/machinedefs.h @@ -58,8 +58,12 @@ enum AccessControl { }; enum ExceptionCause { - EXCAUSE_NONE = 0, - EXCAUSE_INT = 1, + EXCAUSE_NONE = 0, // Use zero as default value when no exception is pending + EXCAUSE_INT = 1, // Int is 0 on real CPU and in Cause regsiter + EXCAUSE_ADDRL = 4, + EXCAUSE_ADDRS = 5, + EXCAUSE_IBUS = 6, + EXCAUSE_DBUS = 7, EXCAUSE_SYSCALL = 8, EXCAUSE_BREAK = 9, EXCAUSE_OVERFLOW = 12, diff --git a/qtmips_machine/serialport.cpp b/qtmips_machine/serialport.cpp index 7eb9c53..8db5725 100644 --- a/qtmips_machine/serialport.cpp +++ b/qtmips_machine/serialport.cpp @@ -53,8 +53,8 @@ SerialPort::SerialPort() { rx_st_reg = 0; rx_data_reg = 0; tx_st_reg = 0; - tx_irq_level = 0; - rx_irq_level = 1; + tx_irq_level = 2; // HW Interrupt 0 + rx_irq_level = 3; // HW Interrupt 1 tx_irq_active = false; rx_irq_active = false; } -- cgit v1.2.3