summaryrefslogtreecommitdiffstats
path: root/hw/mips/mips_malta.c
diff options
context:
space:
mode:
authorLeon Alrae2015-06-19 12:08:43 +0200
committerLeon Alrae2015-06-26 10:08:50 +0200
commit3b3c1694cfd394b73de426edebdbf90c28f664fd (patch)
treedcd93bdb3b5bc6a41bf4d9c518cca24925d10b94 /hw/mips/mips_malta.c
parenttarget-mips: remove identical code in different branch (diff)
downloadqemu-3b3c1694cfd394b73de426edebdbf90c28f664fd.tar.gz
qemu-3b3c1694cfd394b73de426edebdbf90c28f664fd.tar.xz
qemu-3b3c1694cfd394b73de426edebdbf90c28f664fd.zip
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 'hw/mips/mips_malta.c')
-rw-r--r--hw/mips/mips_malta.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index a5d64d5030..3082e75340 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -53,6 +53,7 @@
#include "qemu/error-report.h"
#include "hw/empty_slot.h"
#include "sysemu/kvm.h"
+#include "exec/semihost.h"
//#define DEBUG_BOARD_INIT
@@ -634,7 +635,13 @@ static void write_bootloader (CPUMIPSState *env, uint8_t *base,
/* Second part of the bootloader */
p = (uint32_t *) (base + 0x580);
- stl_p(p++, 0x24040002); /* addiu a0, zero, 2 */
+
+ if (semihosting_get_argc()) {
+ /* Preserve a0 content as arguments have been passed */
+ stl_p(p++, 0x00000000); /* nop */
+ } else {
+ stl_p(p++, 0x24040002); /* addiu a0, zero, 2 */
+ }
stl_p(p++, 0x3c1d0000 | (((ENVP_ADDR - 64) >> 16) & 0xffff)); /* lui sp, high(ENVP_ADDR) */
stl_p(p++, 0x37bd0000 | ((ENVP_ADDR - 64) & 0xffff)); /* ori sp, sp, low(ENVP_ADDR) */
stl_p(p++, 0x3c050000 | ((ENVP_ADDR >> 16) & 0xffff)); /* lui a1, high(ENVP_ADDR) */