From 2d043d387dc44ea71eaa6b5b6efeeff2c9e5d9b4 Mon Sep 17 00:00:00 2001 From: mio Date: Sun, 3 Oct 2021 23:10:39 +0200 Subject: [PATCH] Change mips model to add DSP --- include/unicorn/mips.h | 1 + qemu/target/mips/cpu.c | 3 ++- qemu/target/mips/unicorn.c | 11 +++++++++++ tests/unit/test_mips.c | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 1 deletion(-) diff --git a/include/unicorn/mips.h b/include/unicorn/mips.h index 77fde3c1..df54893f 100644 --- a/include/unicorn/mips.h +++ b/include/unicorn/mips.h @@ -177,6 +177,7 @@ typedef enum UC_MIPS_REG { UC_MIPS_REG_CP0_CONFIG3, UC_MIPS_REG_CP0_USERLOCAL, + UC_MIPS_REG_CP0_STATUS, UC_MIPS_REG_ENDING, // <-- mark the end of the list or registers diff --git a/qemu/target/mips/cpu.c b/qemu/target/mips/cpu.c index 3f041afc..43f55687 100644 --- a/qemu/target/mips/cpu.c +++ b/qemu/target/mips/cpu.c @@ -162,7 +162,8 @@ MIPSCPU *cpu_mips_init(struct uc_struct *uc, const char *cpu_model) #ifdef TARGET_MIPS64 cpu_model = "R4000"; #else - cpu_model = "24Kf"; + // Add UC_MODE_ flag to select model? + cpu_model = "74Kf"; #endif } diff --git a/qemu/target/mips/unicorn.c b/qemu/target/mips/unicorn.c index 044f384b..2c9dae5f 100644 --- a/qemu/target/mips/unicorn.c +++ b/qemu/target/mips/unicorn.c @@ -7,6 +7,7 @@ #include "unicorn_common.h" #include "uc_priv.h" #include "unicorn.h" +#include "internal.h" #ifdef TARGET_MIPS64 typedef uint64_t mipsreg_t; @@ -82,6 +83,9 @@ static void reg_read(CPUMIPSState *env, unsigned int regid, void *value) case UC_MIPS_REG_CP0_CONFIG3: *(mipsreg_t *)value = env->CP0_Config3; break; + case UC_MIPS_REG_CP0_STATUS: + *(mipsreg_t *)value = env->CP0_Status; + break; case UC_MIPS_REG_CP0_USERLOCAL: *(mipsreg_t *)value = env->active_tc.CP0_UserLocal; break; @@ -104,6 +108,13 @@ static void reg_write(CPUMIPSState *env, unsigned int regid, const void *value) case UC_MIPS_REG_CP0_CONFIG3: env->CP0_Config3 = *(mipsreg_t *)value; break; + case UC_MIPS_REG_CP0_STATUS: + // TODO: ALL CP0 REGS + // https://s3-eu-west-1.amazonaws.com/downloads-mips/documents/MD00090-2B-MIPS32PRA-AFP-06.02.pdf + // https://s3-eu-west-1.amazonaws.com/downloads-mips/documents/MD00582-2B-microMIPS32-AFP-05.04.pdf + env->CP0_Status = *(mipsreg_t *)value; + compute_hflags(env); + break; case UC_MIPS_REG_CP0_USERLOCAL: env->active_tc.CP0_UserLocal = *(mipsreg_t *)value; break; diff --git a/tests/unit/test_mips.c b/tests/unit/test_mips.c index a3b93cff..bfff4cad 100644 --- a/tests/unit/test_mips.c +++ b/tests/unit/test_mips.c @@ -81,10 +81,42 @@ static void test_mips_stop_at_delay_slot() { OK(uc_close(uc)); } +static void test_mips_lwx_exception_issue_1314() { + uc_engine* uc; + char code[] = "\x0a\xc8\x79\x7e"; // lwx $t9, $t9($s3) + int reg; + + uc_common_setup(&uc, UC_ARCH_MIPS, UC_MODE_32 | UC_MODE_LITTLE_ENDIAN, code, sizeof(code) - 1); + OK(uc_mem_map(uc, 0x10000, 0x4000, UC_PROT_ALL)); + + // Enable DSP + // https://s3-eu-west-1.amazonaws.com/downloads-mips/documents/MD00090-2B-MIPS32PRA-AFP-06.02.pdf + OK(uc_reg_read(uc, UC_MIPS_REG_CP0_STATUS, ®)); + reg |= (1 << 24); + OK(uc_reg_write(uc, UC_MIPS_REG_CP0_STATUS, ®)); + + reg = 0; + OK(uc_reg_write(uc, UC_MIPS_REG_1, ®)); + OK(uc_reg_write(uc, UC_MIPS_REG_T9, ®)); + reg = 0xdeadbeef; + OK(uc_mem_write(uc, 0x10000, ®, 4)); + reg = 0x10000; + OK(uc_reg_write(uc, UC_MIPS_REG_S3, ®)); + + OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0)); + + OK(uc_reg_read(uc, UC_MIPS_REG_T9, ®)); + + TEST_CHECK(reg == 0xdeadbeef); + + OK(uc_close(uc)); +} + TEST_LIST = { { "test_mips_stop_at_branch", test_mips_stop_at_branch }, { "test_mips_stop_at_delay_slot", test_mips_stop_at_delay_slot}, { "test_mips_el_ori", test_mips_el_ori}, { "test_mips_eb_ori", test_mips_eb_ori}, + { "test_mips_lwx_exception_issue_1314", test_mips_lwx_exception_issue_1314}, { NULL, NULL } }; \ No newline at end of file