aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--qtmips_gui/coreview.cpp11
-rw-r--r--qtmips_machine/cop0state.cpp30
-rw-r--r--qtmips_machine/cop0state.h4
-rw-r--r--qtmips_machine/core.cpp2
-rw-r--r--qtmips_machine/machinedefs.h8
-rw-r--r--qtmips_machine/serialport.cpp4
6 files changed, 38 insertions, 21 deletions
diff --git a/qtmips_gui/coreview.cpp b/qtmips_gui/coreview.cpp
index d21f7f2..a6bd8fc 100644
--- a/qtmips_gui/coreview.cpp
+++ b/qtmips_gui/coreview.cpp
@@ -110,11 +110,16 @@ CoreViewScene::CoreViewScene(machine::QtMipsMachine *machine) : QGraphicsScene()
static QMap<std::uint32_t, QString> excause_map =
{{machine::EXCAUSE_NONE, "NONE"},
{machine::EXCAUSE_INT, "INT"},
- {machine::EXCAUSE_BREAK, "BERAK"},
+ {machine::EXCAUSE_ADDRL, "ADDRL"},
+ {machine::EXCAUSE_ADDRS, "ADDRS"},
+ {machine::EXCAUSE_IBUS, "IBUS"},
+ {machine::EXCAUSE_DBUS, "DBUS"},
{machine::EXCAUSE_SYSCALL, "SYSCALL"},
- {machine::EXCAUSE_HWBREAK, "HWBREAK"},
+ {machine::EXCAUSE_BREAK, "BREAK"},
+ {machine::EXCAUSE_OVERFLOW, "OVERFLOW"},
{machine::EXCAUSE_TRAP, "TRAP"},
- {machine::EXCAUSE_OVERFLOW, "OVERFLOW"}};
+ {machine::EXCAUSE_HWBREAK, "HWBREAK"}
+ };
NEW_MULTI(mm.multi_excause, 602, 447, memory_excause_value, excause_map, true);
new_label("Exception", 595, 437);
// WriteBack stage
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;
}