aboutsummaryrefslogtreecommitdiff
path: root/target-mips/translate.c
diff options
context:
space:
mode:
authorLeon Alrae <leon.alrae@imgtec.com>2015-06-19 11:08:43 +0100
committerLeon Alrae <leon.alrae@imgtec.com>2015-06-26 09:08:50 +0100
commit3b3c1694cfd394b73de426edebdbf90c28f664fd (patch)
treedcd93bdb3b5bc6a41bf4d9c518cca24925d10b94 /target-mips/translate.c
parentff334767728011218c62f7476232d260cb5b28e6 (diff)
downloadqemu-arm-3b3c1694cfd394b73de426edebdbf90c28f664fd.tar.gz
target-mips: add Unified Hosting Interface (UHI) support
Add UHI semihosting support for MIPS. QEMU run with "-semihosting" option will alter the behaviour of SDBBP 1 instruction -- UHI operation will be called instead of generating a debug exception. Also tweak Malta's pseudo-bootloader. On CPU reset the $4 register is set to -1 if semihosting arguments are passed to indicate that the UHI operations should be used to obtain input arguments. Signed-off-by: Leon Alrae <leon.alrae@imgtec.com> Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Diffstat (limited to 'target-mips/translate.c')
-rw-r--r--target-mips/translate.c75
1 files changed, 55 insertions, 20 deletions
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 7d9f2dac6b..8547e2d04d 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -29,6 +29,7 @@
#include "exec/helper-proto.h"
#include "exec/helper-gen.h"
#include "sysemu/kvm.h"
+#include "exec/semihost.h"
#include "trace-tcg.h"
@@ -11549,6 +11550,15 @@ static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
return 4;
}
+static inline bool is_uhi(int sdbbp_code)
+{
+#ifdef CONFIG_USER_ONLY
+ return false;
+#else
+ return semihosting_enabled() && sdbbp_code == 1;
+#endif
+}
+
static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
{
int rx, ry;
@@ -11848,11 +11858,15 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
}
break;
case RR_SDBBP:
- /* XXX: not clear which exception should be raised
- * when in debug mode...
- */
- check_insn(ctx, ISA_MIPS32);
- generate_exception(ctx, EXCP_DBp);
+ if (is_uhi(extract32(ctx->opcode, 5, 6))) {
+ gen_helper_do_semihosting(cpu_env);
+ } else {
+ /* XXX: not clear which exception should be raised
+ * when in debug mode...
+ */
+ check_insn(ctx, ISA_MIPS32);
+ generate_exception(ctx, EXCP_DBp);
+ }
break;
case RR_SLT:
gen_slt(ctx, OPC_SLT, 24, rx, ry);
@@ -12699,11 +12713,15 @@ static void gen_pool16c_insn(DisasContext *ctx)
generate_exception(ctx, EXCP_BREAK);
break;
case SDBBP16:
- /* XXX: not clear which exception should be raised
- * when in debug mode...
- */
- check_insn(ctx, ISA_MIPS32);
- generate_exception(ctx, EXCP_DBp);
+ if (is_uhi(extract32(ctx->opcode, 0, 4))) {
+ gen_helper_do_semihosting(cpu_env);
+ } else {
+ /* XXX: not clear which exception should be raised
+ * when in debug mode...
+ */
+ check_insn(ctx, ISA_MIPS32);
+ generate_exception(ctx, EXCP_DBp);
+ }
break;
case JRADDIUSP + 0:
case JRADDIUSP + 1:
@@ -13067,8 +13085,12 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
ctx->bstate = BS_STOP;
break;
case SDBBP:
- check_insn(ctx, ISA_MIPS32);
- generate_exception(ctx, EXCP_DBp);
+ if (is_uhi(extract32(ctx->opcode, 16, 10))) {
+ gen_helper_do_semihosting(cpu_env);
+ } else {
+ check_insn(ctx, ISA_MIPS32);
+ generate_exception(ctx, EXCP_DBp);
+ }
break;
default:
goto pool32axf_invalid;
@@ -16460,10 +16482,14 @@ static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
}
break;
case R6_OPC_SDBBP:
- if (ctx->hflags & MIPS_HFLAG_SBRI) {
- generate_exception(ctx, EXCP_RI);
+ if (is_uhi(extract32(ctx->opcode, 6, 20))) {
+ gen_helper_do_semihosting(cpu_env);
} else {
- generate_exception(ctx, EXCP_DBp);
+ if (ctx->hflags & MIPS_HFLAG_SBRI) {
+ generate_exception(ctx, EXCP_RI);
+ } else {
+ generate_exception(ctx, EXCP_DBp);
+ }
}
break;
#if defined(TARGET_MIPS64)
@@ -16833,11 +16859,15 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
gen_cl(ctx, op1, rd, rs);
break;
case OPC_SDBBP:
- /* XXX: not clear which exception should be raised
- * when in debug mode...
- */
- check_insn(ctx, ISA_MIPS32);
- generate_exception(ctx, EXCP_DBp);
+ if (is_uhi(extract32(ctx->opcode, 6, 20))) {
+ gen_helper_do_semihosting(cpu_env);
+ } else {
+ /* XXX: not clear which exception should be raised
+ * when in debug mode...
+ */
+ check_insn(ctx, ISA_MIPS32);
+ generate_exception(ctx, EXCP_DBp);
+ }
break;
#if defined(TARGET_MIPS64)
case OPC_DCLO:
@@ -19910,6 +19940,11 @@ void cpu_state_reset(CPUMIPSState *env)
restore_flush_mode(env);
restore_pamask(env);
cs->exception_index = EXCP_NONE;
+
+ if (semihosting_get_argc()) {
+ /* UHI interface can be used to obtain argc and argv */
+ env->active_tc.gpr[4] = -1;
+ }
}
void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)