* [Qemu-devel] [PATCH 0/4] target-mips: add UHI semihosting support
@ 2015-02-27 17:00 Leon Alrae
2015-02-27 17:00 ` [Qemu-devel] [PATCH 1/4] include/softmmu-semi.h: Make semihosting support 64-bit clean Leon Alrae
` (3 more replies)
0 siblings, 4 replies; 9+ messages in thread
From: Leon Alrae @ 2015-02-27 17:00 UTC (permalink / raw)
To: qemu-devel; +Cc: matthew.fortune, aurelien
Hi,
This patch series introduces the Unified Hosting Interface [1] support to QEMU.
UHI is a common bare metal semi-hosting interface for the MIPS architecture
and in QEMU it comes down to reserving SDBBP 1 instruction which triggers
semi-hosting syscalls.
Since we are already in soft-freeze these patches are not intended for 2.3. I'm
submitting it now as I would like to get your feedback. I'm particularly
interested in your opinion about the new command line option for semihosting
input arguments.
When QEMU is executed with -semihosting option the SDBBP instruction with
code = 1 will not cause a debug exception, but instead it will call one of
the UHI operations which are handled in target-mips/mips-semi.c file. Input
arguments as well as return values are passed via GPRs as specified in the
manual.
UHI provides 3 operations allowing to construct argv and argc:
* Argc: returns number of arguments.
* Argnlen: returns the length of the n'th argument.
* Argn: copies the n'th argument to the provided buffer.
In order to keep it simple it would be ideal to be able to pass multiple input
arguments which can contain any character to the guest program without having
to care about separators and escape characters (they might be quite unintuitive
if we also consider Windows environment). Therefore rather than using existing
"-append" I would like to introduce "-semihosting-arg" option which can occur
multiple times in the command line.
For those who want to test the implementation -- here are the steps for
building simple hello world bare metal program and running it on Malta board.
Bare Metal Toolchain containing UHI support can be obtained from:
http://codescape-mips-sdk.imgtec.com/components/toolchain/2014.07-1/
* Source file:
$ cat main.c
#include <stdio.h>
int main()
{
printf("Hello world!\n");
return 0;
}
* Build:
$ mips-mti-elf-gcc -T mti32-uhi.ld -mips32r2 -EL main.c
* Run:
$ qemu-system-mipsel -cpu 24Kf -M malta -semihosting -nographic -kernel a.out
Hello world!
References:
[1] "MIPS Toolchain, MD01069 UHI Reference Manual", Version: 1.0.14
The manual is available here:
http://prplfoundation.org/wiki/MIPS_documentation
Regards,
Leon
Leon Alrae (2):
target-mips: add Unified Hosting Interface (UHI) support
target-mips: add "-semihosting-arg" option and implement UHI Arg* ops
Maciej W. Rozycki (1):
include/softmmu-semi.h: Make semihosting support 64-bit clean
Matthew Fortune (1):
hw/mips: Do not clear BEV for MIPS malta kernel load
hw/mips/mips_malta.c | 10 +-
include/exec/softmmu-semi.h | 13 +-
include/sysemu/sysemu.h | 2 +
qemu-options.hx | 13 +-
target-mips/Makefile.objs | 2 +-
target-mips/helper.h | 2 +
target-mips/mips-semi.c | 340 ++++++++++++++++++++++++++++++++++++++++++++
target-mips/translate.c | 82 +++++++----
vl.c | 28 ++++
9 files changed, 456 insertions(+), 36 deletions(-)
create mode 100644 target-mips/mips-semi.c
--
2.1.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH 1/4] include/softmmu-semi.h: Make semihosting support 64-bit clean
2015-02-27 17:00 [Qemu-devel] [PATCH 0/4] target-mips: add UHI semihosting support Leon Alrae
@ 2015-02-27 17:00 ` Leon Alrae
2015-02-27 17:00 ` [Qemu-devel] [PATCH 2/4] target-mips: add Unified Hosting Interface (UHI) support Leon Alrae
` (2 subsequent siblings)
3 siblings, 0 replies; 9+ messages in thread
From: Leon Alrae @ 2015-02-27 17:00 UTC (permalink / raw)
To: qemu-devel; +Cc: Maciej W. Rozycki, matthew.fortune, aurelien
From: "Maciej W. Rozycki" <macro@codesourcery.com>
Correct addresses passed around in semihosting to use a data type suitable
for both 32-bit and 64-bit targets.
Signed-off-by: Maciej W. Rozycki <macro@codesourcery.com>
Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
---
Maciej,
I kept the same fix locally. I'm replacing it in this patchset with your
patch since you submitted it first :)
Leon
---
include/exec/softmmu-semi.h | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/include/exec/softmmu-semi.h b/include/exec/softmmu-semi.h
index 8401f7d..1819cc2 100644
--- a/include/exec/softmmu-semi.h
+++ b/include/exec/softmmu-semi.h
@@ -9,14 +9,14 @@
#ifndef SOFTMMU_SEMI_H
#define SOFTMMU_SEMI_H 1
-static inline uint32_t softmmu_tget32(CPUArchState *env, uint32_t addr)
+static inline uint32_t softmmu_tget32(CPUArchState *env, target_ulong addr)
{
uint32_t val;
cpu_memory_rw_debug(ENV_GET_CPU(env), addr, (uint8_t *)&val, 4, 0);
return tswap32(val);
}
-static inline uint32_t softmmu_tget8(CPUArchState *env, uint32_t addr)
+static inline uint32_t softmmu_tget8(CPUArchState *env, target_ulong addr)
{
uint8_t val;
@@ -28,7 +28,8 @@ static inline uint32_t softmmu_tget8(CPUArchState *env, uint32_t addr)
#define get_user_u8(arg, p) ({ arg = softmmu_tget8(env, p) ; 0; })
#define get_user_ual(arg, p) get_user_u32(arg, p)
-static inline void softmmu_tput32(CPUArchState *env, uint32_t addr, uint32_t val)
+static inline void softmmu_tput32(CPUArchState *env,
+ target_ulong addr, uint32_t val)
{
val = tswap32(val);
cpu_memory_rw_debug(ENV_GET_CPU(env), addr, (uint8_t *)&val, 4, 1);
@@ -36,8 +37,8 @@ static inline void softmmu_tput32(CPUArchState *env, uint32_t addr, uint32_t val
#define put_user_u32(arg, p) ({ softmmu_tput32(env, p, arg) ; 0; })
#define put_user_ual(arg, p) put_user_u32(arg, p)
-static void *softmmu_lock_user(CPUArchState *env, uint32_t addr, uint32_t len,
- int copy)
+static void *softmmu_lock_user(CPUArchState *env,
+ target_ulong addr, target_ulong len, int copy)
{
uint8_t *p;
/* TODO: Make this something that isn't fixed size. */
@@ -48,7 +49,7 @@ static void *softmmu_lock_user(CPUArchState *env, uint32_t addr, uint32_t len,
return p;
}
#define lock_user(type, p, len, copy) softmmu_lock_user(env, p, len, copy)
-static char *softmmu_lock_user_string(CPUArchState *env, uint32_t addr)
+static char *softmmu_lock_user_string(CPUArchState *env, target_ulong addr)
{
char *p;
char *s;
--
2.1.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH 2/4] target-mips: add Unified Hosting Interface (UHI) support
2015-02-27 17:00 [Qemu-devel] [PATCH 0/4] target-mips: add UHI semihosting support Leon Alrae
2015-02-27 17:00 ` [Qemu-devel] [PATCH 1/4] include/softmmu-semi.h: Make semihosting support 64-bit clean Leon Alrae
@ 2015-02-27 17:00 ` Leon Alrae
2015-03-01 22:17 ` Matthew Fortune
2015-02-27 17:00 ` [Qemu-devel] [PATCH 3/4] target-mips: add "-semihosting-arg" option and implement UHI Arg* ops Leon Alrae
2015-02-27 17:00 ` [Qemu-devel] [PATCH 4/4] hw/mips: Do not clear BEV for MIPS malta kernel load Leon Alrae
3 siblings, 1 reply; 9+ messages in thread
From: Leon Alrae @ 2015-02-27 17:00 UTC (permalink / raw)
To: qemu-devel; +Cc: matthew.fortune, aurelien
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.
This commit implements all UHI operations apart from Argc, Argnlen and Argn.
Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
---
qemu-options.hx | 5 +-
target-mips/Makefile.objs | 2 +-
target-mips/helper.h | 2 +
target-mips/mips-semi.c | 304 ++++++++++++++++++++++++++++++++++++++++++++++
target-mips/translate.c | 75 ++++++++----
5 files changed, 360 insertions(+), 28 deletions(-)
create mode 100644 target-mips/mips-semi.c
diff --git a/qemu-options.hx b/qemu-options.hx
index 85ca3ad..99ad1ae 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -3223,11 +3223,12 @@ Set OpenBIOS nvram @var{variable} to given @var{value} (PPC, SPARC only).
ETEXI
DEF("semihosting", 0, QEMU_OPTION_semihosting,
"-semihosting semihosting mode\n",
- QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA | QEMU_ARCH_LM32)
+ QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA | QEMU_ARCH_LM32 |
+ QEMU_ARCH_MIPS)
STEXI
@item -semihosting
@findex -semihosting
-Enable semihosting mode (ARM, M68K, Xtensa only).
+Enable semihosting mode (ARM, M68K, Xtensa, MIPS only).
ETEXI
DEF("semihosting-config", HAS_ARG, QEMU_OPTION_semihosting_config,
"-semihosting-config [enable=on|off,]target=native|gdb|auto semihosting configuration\n",
diff --git a/target-mips/Makefile.objs b/target-mips/Makefile.objs
index 108fd9b..bc5ed85 100644
--- a/target-mips/Makefile.objs
+++ b/target-mips/Makefile.objs
@@ -1,4 +1,4 @@
obj-y += translate.o dsp_helper.o op_helper.o lmi_helper.o helper.o cpu.o
-obj-y += gdbstub.o msa_helper.o
+obj-y += gdbstub.o msa_helper.o mips-semi.o
obj-$(CONFIG_SOFTMMU) += machine.o
obj-$(CONFIG_KVM) += kvm.o
diff --git a/target-mips/helper.h b/target-mips/helper.h
index 3bd0b02..7c7582f 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -1,6 +1,8 @@
DEF_HELPER_3(raise_exception_err, noreturn, env, i32, int)
DEF_HELPER_2(raise_exception, noreturn, env, i32)
+DEF_HELPER_1(do_semihosting, void, env)
+
#ifdef TARGET_MIPS64
DEF_HELPER_4(sdl, void, env, tl, tl, int)
DEF_HELPER_4(sdr, void, env, tl, tl, int)
diff --git a/target-mips/mips-semi.c b/target-mips/mips-semi.c
new file mode 100644
index 0000000..3bf7b2a
--- /dev/null
+++ b/target-mips/mips-semi.c
@@ -0,0 +1,304 @@
+/*
+ * Unified Hosting Interface syscalls.
+ *
+ * Copyright (c) 2014 Imagination Technologies
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/stat.h>
+#include "cpu.h"
+#include "exec/helper-proto.h"
+#include "exec/softmmu-semi.h"
+
+typedef enum UHIOp {
+ UHI_exit = 1,
+ UHI_open = 2,
+ UHI_close = 3,
+ UHI_read = 4,
+ UHI_write = 5,
+ UHI_lseek = 6,
+ UHI_unlink = 7,
+ UHI_fstat = 8,
+ UHI_argc = 9,
+ UHI_argnlen = 10,
+ UHI_argn = 11,
+ UHI_plog = 13,
+ UHI_assert = 14,
+ UHI_pread = 19,
+ UHI_pwrite = 20,
+ UHI_link = 22
+} UHIOp;
+
+typedef struct UHIStat {
+ int16_t uhi_st_dev;
+ uint16_t uhi_st_ino;
+ uint32_t uhi_st_mode;
+ uint16_t uhi_st_nlink;
+ uint16_t uhi_st_uid;
+ uint16_t uhi_st_gid;
+ int16_t uhi_st_rdev;
+ uint64_t uhi_st_size;
+ uint64_t uhi_st_atime;
+ uint64_t uhi_st_spare1;
+ uint64_t uhi_st_mtime;
+ uint64_t uhi_st_spare2;
+ uint64_t uhi_st_ctime;
+ uint64_t uhi_st_spare3;
+ uint64_t uhi_st_blksize;
+ uint64_t uhi_st_blocks;
+ uint64_t uhi_st_spare4[2];
+} UHIStat;
+
+enum UHIOpenFlags {
+ UHIOpen_RDONLY = 0x0,
+ UHIOpen_WRONLY = 0x1,
+ UHIOpen_RDWR = 0x2,
+ UHIOpen_APPEND = 0x8,
+ UHIOpen_CREAT = 0x200,
+ UHIOpen_TRUNC = 0x400,
+ UHIOpen_EXCL = 0x800
+};
+
+static int copy_stat_to_target(CPUMIPSState *env, const struct stat *src,
+ target_ulong vaddr)
+{
+ hwaddr len = sizeof(struct UHIStat);
+ UHIStat *dst = lock_user(VERIFY_WRITE, vaddr, len, 0);
+ if (!dst) {
+ return -1;
+ }
+
+ dst->uhi_st_dev = tswap16(src->st_dev);
+ dst->uhi_st_ino = tswap16(src->st_ino);
+ dst->uhi_st_mode = tswap32(src->st_mode);
+ dst->uhi_st_nlink = tswap16(src->st_nlink);
+ dst->uhi_st_uid = tswap16(src->st_uid);
+ dst->uhi_st_gid = tswap16(src->st_gid);
+ dst->uhi_st_rdev = tswap16(src->st_rdev);
+ dst->uhi_st_size = tswap64(src->st_size);
+ dst->uhi_st_atime = tswap64(src->st_atime);
+ dst->uhi_st_mtime = tswap64(src->st_mtime);
+ dst->uhi_st_ctime = tswap64(src->st_ctime);
+#ifdef _WIN32
+ dst->uhi_st_blksize = 0;
+ dst->uhi_st_blocks = 0;
+#else
+ dst->uhi_st_blksize = tswap64(src->st_blksize);
+ dst->uhi_st_blocks = tswap64(src->st_blocks);
+#endif
+ unlock_user(dst, vaddr, len);
+ return 0;
+}
+
+static int get_open_flags(target_ulong target_flags)
+{
+ int open_flags = 0;
+
+ if (target_flags & UHIOpen_RDWR) {
+ open_flags |= O_RDWR;
+ } else if (target_flags & UHIOpen_WRONLY) {
+ open_flags |= O_WRONLY;
+ } else {
+ open_flags |= O_RDONLY;
+ }
+
+ open_flags |= (target_flags & UHIOpen_APPEND) ? O_APPEND : 0;
+ open_flags |= (target_flags & UHIOpen_CREAT) ? O_CREAT : 0;
+ open_flags |= (target_flags & UHIOpen_TRUNC) ? O_TRUNC : 0;
+ open_flags |= (target_flags & UHIOpen_EXCL) ? O_EXCL : 0;
+
+ return open_flags;
+}
+
+static int write_to_file(CPUMIPSState *env, target_ulong fd, target_ulong vaddr,
+ target_ulong len, target_ulong offset)
+{
+ int num_of_bytes;
+ void *dst = lock_user(VERIFY_READ, vaddr, len, 1);
+ if (!dst) {
+ return 0;
+ }
+
+ if (offset) {
+#ifdef _WIN32
+ num_of_bytes = 0;
+#else
+ num_of_bytes = pwrite(fd, dst, len, offset);
+#endif
+ } else {
+ num_of_bytes = write(fd, dst, len);
+ }
+
+ unlock_user(dst, vaddr, 0);
+ return num_of_bytes;
+}
+
+static int read_from_file(CPUMIPSState *env, target_ulong fd,
+ target_ulong vaddr, target_ulong len,
+ target_ulong offset)
+{
+ int num_of_bytes;
+ void *dst = lock_user(VERIFY_WRITE, vaddr, len, 0);
+ if (!dst) {
+ return 0;
+ }
+
+ if (offset) {
+#ifdef _WIN32
+ num_of_bytes = 0;
+#else
+ num_of_bytes = pread(fd, dst, len, offset);
+#endif
+ } else {
+ num_of_bytes = read(fd, dst, len);
+ }
+
+ unlock_user(dst, vaddr, len);
+ return num_of_bytes;
+}
+
+#define GET_TARGET_STRING(p, addr) \
+ do { \
+ p = lock_user_string(addr); \
+ if (!p) { \
+ gpr[2] = -1; \
+ gpr[3] = ENAMETOOLONG; \
+ goto uhi_done; \
+ } \
+ } while (0)
+
+#define FREE_TARGET_STRING(p, gpr) \
+ do { \
+ unlock_user(p, gpr, 0); \
+ } while (0)
+
+void helper_do_semihosting(CPUMIPSState *env)
+{
+ target_ulong *gpr = env->active_tc.gpr;
+ const UHIOp op = gpr[25];
+ char *p, *p2;
+
+ switch (op) {
+ case UHI_exit:
+ qemu_log("UHI(%d): exit(%d)\n", op, (int)gpr[4]);
+ exit(gpr[4]);
+ case UHI_open:
+ GET_TARGET_STRING(p, gpr[4]);
+ if (!strcmp("/dev/stdin", p)) {
+ gpr[2] = 0;
+ } else if (!strcmp("/dev/stdout", p)) {
+ gpr[2] = 1;
+ } else if (!strcmp("/dev/stderr", p)) {
+ gpr[2] = 2;
+ } else {
+ gpr[2] = open(p, get_open_flags(gpr[5]), gpr[6]);
+ gpr[3] = errno;
+ }
+ FREE_TARGET_STRING(p, gpr[4]);
+ break;
+ case UHI_close:
+ if (gpr[4] < 3) {
+ /* ignore closing stdin/stdout/stderr */
+ gpr[2] = 0;
+ goto uhi_done;
+ }
+ gpr[2] = close(gpr[4]);
+ gpr[3] = errno;
+ break;
+ case UHI_read:
+ gpr[2] = read_from_file(env, gpr[4], gpr[5], gpr[6], 0);
+ gpr[3] = errno;
+ break;
+ case UHI_write:
+ gpr[2] = write_to_file(env, gpr[4], gpr[5], gpr[6], 0);
+ gpr[3] = errno;
+ break;
+ case UHI_lseek:
+ gpr[2] = lseek(gpr[4], gpr[5], gpr[6]);
+ gpr[3] = errno;
+ break;
+ case UHI_unlink:
+ GET_TARGET_STRING(p, gpr[4]);
+ gpr[2] = remove(p);
+ gpr[3] = errno;
+ FREE_TARGET_STRING(p, gpr[4]);
+ break;
+ case UHI_fstat:
+ {
+ struct stat sbuf;
+ memset(&sbuf, 0, sizeof(sbuf));
+ gpr[2] = fstat(gpr[4], &sbuf);
+ gpr[3] = errno;
+ if (gpr[2]) {
+ goto uhi_done;
+ }
+ gpr[2] = copy_stat_to_target(env, &sbuf, gpr[5]);
+ }
+ break;
+ case UHI_argc:
+ case UHI_argnlen:
+ case UHI_argn:
+ /* TODO */
+ break;
+ case UHI_plog:
+ GET_TARGET_STRING(p, gpr[4]);
+ p2 = strstr(p, "%d");
+ if (p2) {
+ int char_num = p2 - p;
+ char *buf = g_malloc(char_num + 1);
+ strncpy(buf, p, char_num);
+ buf[char_num] = '\0';
+ gpr[2] = printf("%s%d%s", buf, (int)gpr[5], p2 + 2);
+ g_free(buf);
+ } else {
+ gpr[2] = printf("%s", p);
+ }
+ FREE_TARGET_STRING(p, gpr[4]);
+ break;
+ case UHI_assert:
+ GET_TARGET_STRING(p, gpr[4]);
+ GET_TARGET_STRING(p2, gpr[5]);
+ printf("assertion '");
+ printf("\"%s\"", p);
+ printf("': file \"%s\", line %d\n", p2, (int)gpr[6]);
+ FREE_TARGET_STRING(p2, gpr[5]);
+ FREE_TARGET_STRING(p, gpr[4]);
+ abort();
+ break;
+ case UHI_pread:
+ gpr[2] = read_from_file(env, gpr[4], gpr[5], gpr[6], gpr[7]);
+ gpr[3] = errno;
+ break;
+ case UHI_pwrite:
+ gpr[2] = write_to_file(env, gpr[4], gpr[5], gpr[6], gpr[7]);
+ gpr[3] = errno;
+ break;
+#ifndef _WIN32
+ case UHI_link:
+ GET_TARGET_STRING(p, gpr[4]);
+ GET_TARGET_STRING(p2, gpr[5]);
+ gpr[2] = link(p, p2);
+ gpr[3] = errno;
+ FREE_TARGET_STRING(p2, gpr[5]);
+ FREE_TARGET_STRING(p, gpr[4]);
+ break;
+#endif
+ default:
+ fprintf(stderr, "Unknown UHI operation %d\n", op);
+ abort();
+ }
+uhi_done:
+ return;
+}
diff --git a/target-mips/translate.c b/target-mips/translate.c
index ca51149..82fa5a4 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -25,6 +25,7 @@
#include "disas/disas.h"
#include "tcg-op.h"
#include "exec/cpu_ldst.h"
+#include "sysemu/sysemu.h"
#include "exec/helper-proto.h"
#include "exec/helper-gen.h"
@@ -11267,6 +11268,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;
@@ -11566,14 +11576,18 @@ 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);
- if (!(ctx->hflags & MIPS_HFLAG_DM)) {
- generate_exception(ctx, EXCP_DBp);
+ if (is_uhi(extract32(ctx->opcode, 5, 6))) {
+ gen_helper_do_semihosting(cpu_env);
} else {
- generate_exception(ctx, EXCP_DBp);
+ /* XXX: not clear which exception should be raised
+ * when in debug mode...
+ */
+ check_insn(ctx, ISA_MIPS32);
+ if (!(ctx->hflags & MIPS_HFLAG_DM)) {
+ generate_exception(ctx, EXCP_DBp);
+ } else {
+ generate_exception(ctx, EXCP_DBp);
+ }
}
break;
case RR_SLT:
@@ -12421,14 +12435,18 @@ 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);
- if (!(ctx->hflags & MIPS_HFLAG_DM)) {
- generate_exception(ctx, EXCP_DBp);
+ if (is_uhi(extract32(ctx->opcode, 0, 4))) {
+ gen_helper_do_semihosting(cpu_env);
} else {
- generate_exception(ctx, EXCP_DBp);
+ /* XXX: not clear which exception should be raised
+ * when in debug mode...
+ */
+ check_insn(ctx, ISA_MIPS32);
+ if (!(ctx->hflags & MIPS_HFLAG_DM)) {
+ generate_exception(ctx, EXCP_DBp);
+ } else {
+ generate_exception(ctx, EXCP_DBp);
+ }
}
break;
case JRADDIUSP + 0:
@@ -16190,10 +16208,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)
@@ -16563,16 +16585,19 @@ 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);
- if (!(ctx->hflags & MIPS_HFLAG_DM)) {
- generate_exception(ctx, EXCP_DBp);
+ if (is_uhi(extract32(ctx->opcode, 6, 20))) {
+ gen_helper_do_semihosting(cpu_env);
} else {
- generate_exception(ctx, EXCP_DBp);
+ /* XXX: not clear which exception should be raised
+ * when in debug mode...
+ */
+ check_insn(ctx, ISA_MIPS32);
+ if (!(ctx->hflags & MIPS_HFLAG_DM)) {
+ generate_exception(ctx, EXCP_DBp);
+ } else {
+ generate_exception(ctx, EXCP_DBp);
+ }
}
- /* Treat as NOP. */
break;
#if defined(TARGET_MIPS64)
case OPC_DCLO:
--
2.1.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH 3/4] target-mips: add "-semihosting-arg" option and implement UHI Arg* ops
2015-02-27 17:00 [Qemu-devel] [PATCH 0/4] target-mips: add UHI semihosting support Leon Alrae
2015-02-27 17:00 ` [Qemu-devel] [PATCH 1/4] include/softmmu-semi.h: Make semihosting support 64-bit clean Leon Alrae
2015-02-27 17:00 ` [Qemu-devel] [PATCH 2/4] target-mips: add Unified Hosting Interface (UHI) support Leon Alrae
@ 2015-02-27 17:00 ` Leon Alrae
2015-03-01 22:39 ` Matthew Fortune
2015-02-27 17:00 ` [Qemu-devel] [PATCH 4/4] hw/mips: Do not clear BEV for MIPS malta kernel load Leon Alrae
3 siblings, 1 reply; 9+ messages in thread
From: Leon Alrae @ 2015-02-27 17:00 UTC (permalink / raw)
To: qemu-devel; +Cc: matthew.fortune, aurelien
Add new command line option "-semihosting-arg". It is used for passing input
arguments to the guest in semihosting mode. The option can be used multiple
times. If n arguments are passed, then argument count (semihosting_argc) will
be equal to n+1 as semihosting_argv[0] points at the program name. However, if
no arguments are passed then argument count will be 0.
Also tweak Malta's pseudo-bootloader. On CPU reset the $4 register is set to -1
when semihosting is enabled in order to indicate that the UHI operations should
be used to obtain input arguments.
Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
---
hw/mips/mips_malta.c | 8 +++++++-
include/sysemu/sysemu.h | 2 ++
qemu-options.hx | 8 ++++++++
target-mips/mips-semi.c | 38 +++++++++++++++++++++++++++++++++++++-
target-mips/translate.c | 7 +++++++
vl.c | 28 ++++++++++++++++++++++++++++
6 files changed, 89 insertions(+), 2 deletions(-)
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 5845158..2dfe964 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -634,7 +634,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_enabled) {
+ /* Preserve a0 content when semihosting is enabled. */
+ 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) */
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 1ab7063..7d63da2 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -125,6 +125,8 @@ extern int graphic_rotate;
extern int no_quit;
extern int no_shutdown;
extern int semihosting_enabled;
+extern const char **semihosting_argv;
+extern int semihosting_argc;
extern int old_param;
extern int boot_menu;
extern bool boot_strict;
diff --git a/qemu-options.hx b/qemu-options.hx
index 99ad1ae..bd058d0 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -3240,6 +3240,14 @@ Enable semihosting and define where the semihosting calls will be addressed,
to QEMU (@code{native}) or to GDB (@code{gdb}). The default is @code{auto}, which means
@code{gdb} during debug sessions and @code{native} otherwise (ARM, M68K, Xtensa only).
ETEXI
+DEF("semihosting-arg", HAS_ARG, QEMU_OPTION_semihosting_arg,
+ "-semihosting-arg arguments passed to the guest program\n",
+ QEMU_ARCH_MIPS)
+STEXI
+@item -semihosting-arg
+@findex -semihosting-arg
+Arguments passed to the guest program (MIPS only).
+ETEXI
DEF("old-param", 0, QEMU_OPTION_old_param,
"-old-param old param mode\n", QEMU_ARCH_ARM)
STEXI
diff --git a/target-mips/mips-semi.c b/target-mips/mips-semi.c
index 3bf7b2a..63f2700 100644
--- a/target-mips/mips-semi.c
+++ b/target-mips/mips-semi.c
@@ -21,6 +21,9 @@
#include "cpu.h"
#include "exec/helper-proto.h"
#include "exec/softmmu-semi.h"
+#ifndef CONFIG_USER_ONLY
+#include "sysemu/sysemu.h"
+#endif
typedef enum UHIOp {
UHI_exit = 1,
@@ -71,6 +74,12 @@ enum UHIOpenFlags {
UHIOpen_EXCL = 0x800
};
+#ifdef CONFIG_USER_ONLY
+/* Suppress compiler errors in linux-user. */
+static const char **semihosting_argv;
+static int semihosting_argc;
+#endif
+
static int copy_stat_to_target(CPUMIPSState *env, const struct stat *src,
target_ulong vaddr)
{
@@ -169,6 +178,21 @@ static int read_from_file(CPUMIPSState *env, target_ulong fd,
return num_of_bytes;
}
+static int copy_argn_to_target(CPUMIPSState *env, int arg_num,
+ target_ulong vaddr)
+{
+ int strsize = strlen(semihosting_argv[arg_num]) + 1;
+ char *dst = lock_user(VERIFY_WRITE, vaddr, strsize, 0);
+ if (!dst) {
+ return -1;
+ }
+
+ strcpy(dst, semihosting_argv[arg_num]);
+
+ unlock_user(dst, vaddr, strsize);
+ return 0;
+}
+
#define GET_TARGET_STRING(p, addr) \
do { \
p = lock_user_string(addr); \
@@ -248,9 +272,21 @@ void helper_do_semihosting(CPUMIPSState *env)
}
break;
case UHI_argc:
+ gpr[2] = semihosting_argc;
+ break;
case UHI_argnlen:
+ if (gpr[4] >= semihosting_argc) {
+ gpr[2] = -1;
+ goto uhi_done;
+ }
+ gpr[2] = strlen(semihosting_argv[gpr[4]]);
+ break;
case UHI_argn:
- /* TODO */
+ if (gpr[4] >= semihosting_argc) {
+ gpr[2] = -1;
+ goto uhi_done;
+ }
+ gpr[2] = copy_argn_to_target(env, gpr[4], gpr[5]);
break;
case UHI_plog:
GET_TARGET_STRING(p, gpr[4]);
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 82fa5a4..678c3d5 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -19652,6 +19652,13 @@ void cpu_state_reset(CPUMIPSState *env)
restore_rounding_mode(env);
restore_flush_mode(env);
cs->exception_index = EXCP_NONE;
+
+#ifndef CONFIG_USER_ONLY
+ if (semihosting_enabled) {
+ /* When $4 is -1 the UHI interface will be used for argc and argv */
+ env->active_tc.gpr[4] = -1;
+ }
+#endif
}
void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
diff --git a/vl.c b/vl.c
index e1ffd0a..b2d3422 100644
--- a/vl.c
+++ b/vl.c
@@ -169,6 +169,8 @@ const char *watchdog;
QEMUOptionRom option_rom[MAX_OPTION_ROMS];
int nb_option_roms;
int semihosting_enabled = 0;
+const char **semihosting_argv;
+int semihosting_argc;
int old_param = 0;
const char *qemu_name;
int alt_grab = 0;
@@ -3560,6 +3562,22 @@ int main(int argc, char **argv, char **envp)
exit(1);
}
break;
+ case QEMU_OPTION_semihosting_arg:
+ if (semihosting_argc == 0) {
+ /* If arguments are present then the first argument goes to
+ argv[1] as argv[0] is reserved for the program name */
+ semihosting_argc = 2;
+ semihosting_argv =
+ g_malloc(semihosting_argc * sizeof(void *));
+ semihosting_argv[1] = optarg;
+ } else {
+ semihosting_argc++;
+ semihosting_argv =
+ g_realloc(semihosting_argv,
+ semihosting_argc * sizeof(void *));
+ semihosting_argv[semihosting_argc - 1] = optarg;
+ }
+ break;
case QEMU_OPTION_tdf:
fprintf(stderr, "Warning: user space PIT time drift fix "
"is no longer supported.\n");
@@ -4078,6 +4096,16 @@ int main(int argc, char **argv, char **envp)
current_machine->kernel_cmdline = (char *)kernel_cmdline;
}
+ if (semihosting_argc) {
+ if (kernel_filename) {
+ semihosting_argv[0] = kernel_filename;
+ } else if (bios_name) {
+ semihosting_argv[0] = bios_name;
+ } else {
+ semihosting_argv[0] = "";
+ }
+ }
+
linux_boot = (kernel_filename != NULL);
if (!linux_boot && *kernel_cmdline != '\0') {
--
2.1.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH 4/4] hw/mips: Do not clear BEV for MIPS malta kernel load
2015-02-27 17:00 [Qemu-devel] [PATCH 0/4] target-mips: add UHI semihosting support Leon Alrae
` (2 preceding siblings ...)
2015-02-27 17:00 ` [Qemu-devel] [PATCH 3/4] target-mips: add "-semihosting-arg" option and implement UHI Arg* ops Leon Alrae
@ 2015-02-27 17:00 ` Leon Alrae
3 siblings, 0 replies; 9+ messages in thread
From: Leon Alrae @ 2015-02-27 17:00 UTC (permalink / raw)
To: qemu-devel; +Cc: matthew.fortune, aurelien
From: Matthew Fortune <matthew.fortune@imgtec.com>
The BEV flag controls whether the boot exception vector is still
in place when starting a kernel. When cleared the exception vector
at EBASE (or hard coded address of 0x80000000) is used instead.
The early stages of the linux kernel would benefit from BEV still
being set to ensure any faults get handled by the boot rom exception
handlers. This is a moot point for system qemu as there aren't really
any BEV handlers, but there are other good reasons to change this...
The UHI (semi-hosting interface) defines special behaviours depending
on whether an application starts in an environment with BEV set or
cleared. When BEV is set then UHI assumes that a bootloader is
relatively dumb and has no advanced exception handling logic.
However, when BEV is cleared then UHI assumes that the bootloader
has the ability to handle UHI exceptions with its exception handlers
and will unwind and forward UHI SYSCALL exceptions to the exception
vector that was installed prior to running the application.
Signed-off-by: Matthew Fortune <matthew.fortune@imgtec.com>
Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
---
hw/mips/mips_malta.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 2dfe964..79fd671 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -890,7 +890,7 @@ static void main_cpu_reset(void *opaque)
read only location. The kernel location and the arguments table
location does not change. */
if (loaderparams.kernel_filename) {
- env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL));
+ env->CP0_Status &= ~(1 << CP0St_ERL);
}
malta_mips_config(cpu);
--
2.1.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH 2/4] target-mips: add Unified Hosting Interface (UHI) support
2015-02-27 17:00 ` [Qemu-devel] [PATCH 2/4] target-mips: add Unified Hosting Interface (UHI) support Leon Alrae
@ 2015-03-01 22:17 ` Matthew Fortune
2015-03-02 17:31 ` Leon Alrae
0 siblings, 1 reply; 9+ messages in thread
From: Matthew Fortune @ 2015-03-01 22:17 UTC (permalink / raw)
To: Leon Alrae, qemu-devel@nongnu.org; +Cc: aurelien@aurel32.net
Hi Leon,
Many thanks for implementing this interface in QEMU. I haven't reviewed
in great detail as I am not familiar enough with QEMU internals to do
so. Overall it seems to match the UHI spec. The one potential issue is
translation of errno values, I suspect some do not map 1:1.
A couple of minor review comments below:
> + * Copyright (c) 2014 Imagination Technologies
Dates need updating.
> +static int write_to_file(CPUMIPSState *env, target_ulong fd,
> target_ulong vaddr,
> + target_ulong len, target_ulong offset) {
> + int num_of_bytes;
> + void *dst = lock_user(VERIFY_READ, vaddr, len, 1);
> + if (!dst) {
> + return 0;
> + }
Ideally I think this this should return -1 and fake an errno but I
may not understand what case this code is dealing with.
> +static int read_from_file(CPUMIPSState *env, target_ulong fd,
> + target_ulong vaddr, target_ulong len,
> + target_ulong offset) {
> + int num_of_bytes;
> + void *dst = lock_user(VERIFY_WRITE, vaddr, len, 0);
> + if (!dst) {
> + return 0;
> + }
Likewise.
> + case UHI_plog:
> + GET_TARGET_STRING(p, gpr[4]);
> + p2 = strstr(p, "%d");
> + if (p2) {
> + int char_num = p2 - p;
> + char *buf = g_malloc(char_num + 1);
> + strncpy(buf, p, char_num);
> + buf[char_num] = '\0';
> + gpr[2] = printf("%s%d%s", buf, (int)gpr[5], p2 + 2);
> + g_free(buf);
> + } else {
> + gpr[2] = printf("%s", p);
> + }
Is all this necessary vs just: printf(p, (int)gpr[5])? I guess you
may want to do the scan for %d and choose between that and just
printf(p).
Thanks,
Matthew
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH 3/4] target-mips: add "-semihosting-arg" option and implement UHI Arg* ops
2015-02-27 17:00 ` [Qemu-devel] [PATCH 3/4] target-mips: add "-semihosting-arg" option and implement UHI Arg* ops Leon Alrae
@ 2015-03-01 22:39 ` Matthew Fortune
0 siblings, 0 replies; 9+ messages in thread
From: Matthew Fortune @ 2015-03-01 22:39 UTC (permalink / raw)
To: Leon Alrae, qemu-devel@nongnu.org; +Cc: aurelien@aurel32.net
> Add new command line option "-semihosting-arg". It is used for passing
> input arguments to the guest in semihosting mode. The option can be used
> multiple times. If n arguments are passed, then argument count
> (semihosting_argc) will be equal to n+1 as semihosting_argv[0] points at
> the program name. However, if no arguments are passed then argument
> count will be 0.
Is there any specific reason for not passing the name of the executable
even if no -semihosting-arg is present?
I think there are the following cases:
1) one or more -semihosting-arg options are given. So n+1 arguments are
passed with the first one being kernel/boot name if available. The
arguments are passed using UHI argc/argn operations (a0 == -1).
2) No -semihosting-arg options are given but the kernel/boot name is known.
This could be passed either via the normal argument passing conventions
that are already in place or via argc/argn operations.
3) No -semihosting arg options and unknown application name. For this you
could again either do what is already done and pass kernel/append
options or set a0=0 and indicate that there is no information at all.
I wonder if there should be some detection of using both -semihosting-arg
and -append? I think they are in direct conflict. It would probably be
good to have cases 2/3 above do the same as what happened before and
pass kernel name + append options. (By that I also mean setting up the
argv array directly and setting a0 to a positive value (2) rather than
using the new interface).
While it may not be used, this would theoretically allow a kernel to be
booted with -semihosting enabled, pass arguments in the same way they
always have and allow very early boot to emit messages using UHI. I.e.
the kernel will almost certainly never use the argc/argn/argnlen
interface.
I don't have any comments on the code except to say it looks to match
the spec for argc/argn/argnlen.
Thanks,
Matthew
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH 2/4] target-mips: add Unified Hosting Interface (UHI) support
2015-03-01 22:17 ` Matthew Fortune
@ 2015-03-02 17:31 ` Leon Alrae
2015-03-02 20:44 ` Matthew Fortune
0 siblings, 1 reply; 9+ messages in thread
From: Leon Alrae @ 2015-03-02 17:31 UTC (permalink / raw)
To: Matthew Fortune, qemu-devel@nongnu.org; +Cc: aurelien@aurel32.net
Hi Matthew,
On 01/03/2015 22:17, Matthew Fortune wrote:
> Hi Leon,
>
> Many thanks for implementing this interface in QEMU. I haven't reviewed
> in great detail as I am not familiar enough with QEMU internals to do
> so. Overall it seems to match the UHI spec. The one potential issue is
> translation of errno values, I suspect some do not map 1:1.
>
> A couple of minor review comments below:
>
>> + * Copyright (c) 2014 Imagination Technologies
>
> Dates need updating.
>
>> +static int write_to_file(CPUMIPSState *env, target_ulong fd,
>> target_ulong vaddr,
>> + target_ulong len, target_ulong offset) {
>> + int num_of_bytes;
>> + void *dst = lock_user(VERIFY_READ, vaddr, len, 1);
>> + if (!dst) {
>> + return 0;
>> + }
>
> Ideally I think this this should return -1 and fake an errno but I
> may not understand what case this code is dealing with.
Indeed, indicating an error by returning -1 would be better. Thanks for
spotting that.
>> +static int read_from_file(CPUMIPSState *env, target_ulong fd,
>> + target_ulong vaddr, target_ulong len,
>> + target_ulong offset) {
>> + int num_of_bytes;
>> + void *dst = lock_user(VERIFY_WRITE, vaddr, len, 0);
>> + if (!dst) {
>> + return 0;
>> + }
>
> Likewise.
>
>> + case UHI_plog:
>> + GET_TARGET_STRING(p, gpr[4]);
>> + p2 = strstr(p, "%d");
>> + if (p2) {
>> + int char_num = p2 - p;
>> + char *buf = g_malloc(char_num + 1);
>> + strncpy(buf, p, char_num);
>> + buf[char_num] = '\0';
>> + gpr[2] = printf("%s%d%s", buf, (int)gpr[5], p2 + 2);
>> + g_free(buf);
>> + } else {
>> + gpr[2] = printf("%s", p);
>> + }
>
> Is all this necessary vs just: printf(p, (int)gpr[5])? I guess you
> may want to do the scan for %d and choose between that and just
> printf(p).
I don't think we should use p as a format string directly as it might
contain more/different format specifiers. Presumably we would need
additional logic for checking this and returning an error for such cases
-- and this new implementation wouldn't be much simpler than current I
believe.
Current implementation allows any string given by the guest to be
printed out. If there are multiple format specifiers then only the first
occurrence of %d will be replaced with the integer.
Leon
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH 2/4] target-mips: add Unified Hosting Interface (UHI) support
2015-03-02 17:31 ` Leon Alrae
@ 2015-03-02 20:44 ` Matthew Fortune
0 siblings, 0 replies; 9+ messages in thread
From: Matthew Fortune @ 2015-03-02 20:44 UTC (permalink / raw)
To: Leon Alrae, qemu-devel@nongnu.org; +Cc: aurelien@aurel32.net
Leon Alrae <Leon.Alrae@imgtec.com> writes:
> On 01/03/2015 22:17, Matthew Fortune wrote:
> >> + case UHI_plog:
> >> + GET_TARGET_STRING(p, gpr[4]);
> >> + p2 = strstr(p, "%d");
> >> + if (p2) {
> >> + int char_num = p2 - p;
> >> + char *buf = g_malloc(char_num + 1);
> >> + strncpy(buf, p, char_num);
> >> + buf[char_num] = '\0';
> >> + gpr[2] = printf("%s%d%s", buf, (int)gpr[5], p2 + 2);
> >> + g_free(buf);
> >> + } else {
> >> + gpr[2] = printf("%s", p);
> >> + }
> >
> > Is all this necessary vs just: printf(p, (int)gpr[5])? I guess you may
> > want to do the scan for %d and choose between that and just printf(p).
>
> I don't think we should use p as a format string directly as it might
> contain more/different format specifiers. Presumably we would need
> additional logic for checking this and returning an error for such cases
> -- and this new implementation wouldn't be much simpler than current I
> believe.
>
> Current implementation allows any string given by the guest to be
> printed out. If there are multiple format specifiers then only the first
> occurrence of %d will be replaced with the integer.
Good point. That makes sense.
Matthew
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2015-03-02 20:44 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-02-27 17:00 [Qemu-devel] [PATCH 0/4] target-mips: add UHI semihosting support Leon Alrae
2015-02-27 17:00 ` [Qemu-devel] [PATCH 1/4] include/softmmu-semi.h: Make semihosting support 64-bit clean Leon Alrae
2015-02-27 17:00 ` [Qemu-devel] [PATCH 2/4] target-mips: add Unified Hosting Interface (UHI) support Leon Alrae
2015-03-01 22:17 ` Matthew Fortune
2015-03-02 17:31 ` Leon Alrae
2015-03-02 20:44 ` Matthew Fortune
2015-02-27 17:00 ` [Qemu-devel] [PATCH 3/4] target-mips: add "-semihosting-arg" option and implement UHI Arg* ops Leon Alrae
2015-03-01 22:39 ` Matthew Fortune
2015-02-27 17:00 ` [Qemu-devel] [PATCH 4/4] hw/mips: Do not clear BEV for MIPS malta kernel load Leon Alrae
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).