All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v3 0/5] target-mips: add UHI semihosting support
@ 2015-06-19 10:08 Leon Alrae
  2015-06-19 10:08 ` [Qemu-devel] [PATCH v3 1/5] include/softmmu-semi.h: Make semihosting support 64-bit clean Leon Alrae
                   ` (4 more replies)
  0 siblings, 5 replies; 13+ messages in thread
From: Leon Alrae @ 2015-06-19 10:08 UTC (permalink / raw)
  To: qemu-devel; +Cc: matthew.fortune, aurelien

This series introduces the Unified Hosting Interface support to QEMU.
Version 3 of this patchset contains just minor cleanup and corrections
in mips-semi.c comparing to previous version.

It has been on the mailing list for a while and given that command line
option responsible for passing semihosting arguments is clarified I'm
planning to apply this patch series to mips-next soon.

Patches apply on top of:
https://lists.gnu.org/archive/html/qemu-devel/2015-06/msg05013.html

Simple example for those who would like to give it a try:

Bare Metal Toolchain containing UHI support can be obtained from:
http://codescape-mips-sdk.imgtec.com/components/toolchain/2015.01-7/

* Source file:
  #include <stdio.h>

  int main(int argc, char *argv[])
  {
      int i;
      for (i = 0; i < argc; i++) {
          printf("argv[%d] = %s\n", i, argv[i]);
      }
      return 0;
  }

* Build:
  $ mips-img-elf-gcc -mips64r6 -mabi=64 -EL -Tuhi64_64.ld main.c

* Run
  $ qemu-system-mips64el -cpu mips64r6-generic -M malta -nographic -kernel a.out -semihosting-config arg=a.out,arg=foo,arg="bar baz"
  argv[0] = a.out
  argv[1] = foo
  argv[2] = bar baz

Regards,
Leon

v3:
* remove useless #ifndef CONFIG_USER_ONLY
* correct errno in copy_stat_to_target(), write_to_file() and read_from_file()

v2:
* use new -semihosting arg option
* if semihosting args are not present, then fall back to old-style
  -kernel/-append
* clean up SDBBP and remove identical code in different branch
* fix overlooked microMIPS SDBBP
* translate errno values which don't map 1:1
* update dates in the licence header
* return -1 and fake errno when lock_user() fails in write_to_file() and
  read_from_file()

Leon Alrae (3):
  target-mips: remove identical code in different branch
  target-mips: add Unified Hosting Interface (UHI) support
  target-mips: convert host to MIPS errno values when required

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        |  11 +-
 include/exec/softmmu-semi.h |  13 +-
 qemu-options.hx             |  10 +-
 target-mips/Makefile.objs   |   2 +-
 target-mips/helper.h        |   2 +
 target-mips/mips-semi.c     | 358 ++++++++++++++++++++++++++++++++++++++++++++
 target-mips/translate.c     |  68 +++++----
 7 files changed, 426 insertions(+), 38 deletions(-)
 create mode 100644 target-mips/mips-semi.c

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH v3 1/5] include/softmmu-semi.h: Make semihosting support 64-bit clean
  2015-06-19 10:08 [Qemu-devel] [PATCH v3 0/5] target-mips: add UHI semihosting support Leon Alrae
@ 2015-06-19 10:08 ` Leon Alrae
  2015-06-24 14:24   ` Aurelien Jarno
  2015-06-19 10:08 ` [Qemu-devel] [PATCH v3 2/5] hw/mips: Do not clear BEV for MIPS malta kernel load Leon Alrae
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Leon Alrae @ 2015-06-19 10:08 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>
---
 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;

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH v3 2/5] hw/mips: Do not clear BEV for MIPS malta kernel load
  2015-06-19 10:08 [Qemu-devel] [PATCH v3 0/5] target-mips: add UHI semihosting support Leon Alrae
  2015-06-19 10:08 ` [Qemu-devel] [PATCH v3 1/5] include/softmmu-semi.h: Make semihosting support 64-bit clean Leon Alrae
@ 2015-06-19 10:08 ` Leon Alrae
  2015-06-24 14:29   ` Aurelien Jarno
  2015-06-19 10:08 ` [Qemu-devel] [PATCH v3 3/5] target-mips: remove identical code in different branch Leon Alrae
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Leon Alrae @ 2015-06-19 10:08 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 786a8f0..a5d64d5 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -887,7 +887,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);

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH v3 3/5] target-mips: remove identical code in different branch
  2015-06-19 10:08 [Qemu-devel] [PATCH v3 0/5] target-mips: add UHI semihosting support Leon Alrae
  2015-06-19 10:08 ` [Qemu-devel] [PATCH v3 1/5] include/softmmu-semi.h: Make semihosting support 64-bit clean Leon Alrae
  2015-06-19 10:08 ` [Qemu-devel] [PATCH v3 2/5] hw/mips: Do not clear BEV for MIPS malta kernel load Leon Alrae
@ 2015-06-19 10:08 ` Leon Alrae
  2015-06-24 14:37   ` Aurelien Jarno
  2015-06-19 10:08 ` [Qemu-devel] [PATCH v3 4/5] target-mips: add Unified Hosting Interface (UHI) support Leon Alrae
  2015-06-19 10:08 ` [Qemu-devel] [PATCH v3 5/5] target-mips: convert host to MIPS errno values when required Leon Alrae
  4 siblings, 1 reply; 13+ messages in thread
From: Leon Alrae @ 2015-06-19 10:08 UTC (permalink / raw)
  To: qemu-devel; +Cc: matthew.fortune, aurelien

Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
---
 target-mips/translate.c | 25 ++++---------------------
 1 file changed, 4 insertions(+), 21 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index 1d128ee..6fd6dd9 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -11852,11 +11852,7 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
              *      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);
-            }
+            generate_exception(ctx, EXCP_DBp);
             break;
         case RR_SLT:
             gen_slt(ctx, OPC_SLT, 24, rx, ry);
@@ -12707,11 +12703,7 @@ static void gen_pool16c_insn(DisasContext *ctx)
          *      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);
-        }
+        generate_exception(ctx, EXCP_DBp);
         break;
     case JRADDIUSP + 0:
     case JRADDIUSP + 1:
@@ -13076,11 +13068,7 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
             break;
         case SDBBP:
             check_insn(ctx, ISA_MIPS32);
-            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
-                generate_exception(ctx, EXCP_DBp);
-            } else {
-                generate_exception(ctx, EXCP_DBp);
-            }
+            generate_exception(ctx, EXCP_DBp);
             break;
         default:
             goto pool32axf_invalid;
@@ -16849,12 +16837,7 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
          *      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. */
+        generate_exception(ctx, EXCP_DBp);
         break;
 #if defined(TARGET_MIPS64)
     case OPC_DCLO:

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH v3 4/5] target-mips: add Unified Hosting Interface (UHI) support
  2015-06-19 10:08 [Qemu-devel] [PATCH v3 0/5] target-mips: add UHI semihosting support Leon Alrae
                   ` (2 preceding siblings ...)
  2015-06-19 10:08 ` [Qemu-devel] [PATCH v3 3/5] target-mips: remove identical code in different branch Leon Alrae
@ 2015-06-19 10:08 ` Leon Alrae
  2015-06-24 14:40   ` Aurelien Jarno
  2015-06-19 10:08 ` [Qemu-devel] [PATCH v3 5/5] target-mips: convert host to MIPS errno values when required Leon Alrae
  4 siblings, 1 reply; 13+ messages in thread
From: Leon Alrae @ 2015-06-19 10:08 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.

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>
---
 hw/mips/mips_malta.c      |   9 +-
 qemu-options.hx           |  10 +-
 target-mips/Makefile.objs |   2 +-
 target-mips/helper.h      |   2 +
 target-mips/mips-semi.c   | 336 ++++++++++++++++++++++++++++++++++++++++++++++
 target-mips/translate.c   |  75 ++++++++---
 6 files changed, 408 insertions(+), 26 deletions(-)
 create mode 100644 target-mips/mips-semi.c

diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index a5d64d5..3082e75 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) */
diff --git a/qemu-options.hx b/qemu-options.hx
index 7959dd0..5243aee 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -3344,20 +3344,22 @@ 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][,arg=str[,...]]\n" \
     "                semihosting configuration\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-config [enable=on|off][,target=native|gdb|auto][,arg=str[,...]]
 @findex -semihosting-config
-Enable and configure semihosting (ARM, M68K, Xtensa only).
+Enable and configure semihosting (ARM, M68K, Xtensa, MIPS only).
 @table @option
 @item target=@code{native|gdb|auto}
 Defines where the semihosting calls will be addressed, to QEMU (@code{native})
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 8df98c7..2b28e87 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..6944e98
--- /dev/null
+++ b/target-mips/mips-semi.c
@@ -0,0 +1,336 @@
+/*
+ * Unified Hosting Interface syscalls.
+ *
+ * Copyright (c) 2015 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"
+#include "exec/semihost.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) {
+        errno = EFAULT;
+        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) {
+        errno = EFAULT;
+        return -1;
+    }
+
+    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) {
+        errno = EFAULT;
+        return -1;
+    }
+
+    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;
+}
+
+static int copy_argn_to_target(CPUMIPSState *env, int arg_num,
+                               target_ulong vaddr)
+{
+    int strsize = strlen(semihosting_get_arg(arg_num)) + 1;
+    char *dst = lock_user(VERIFY_WRITE, vaddr, strsize, 0);
+    if (!dst) {
+        return -1;
+    }
+
+    strcpy(dst, semihosting_get_arg(arg_num));
+
+    unlock_user(dst, vaddr, strsize);
+    return 0;
+}
+
+#define GET_TARGET_STRING(p, addr)              \
+    do {                                        \
+        p = lock_user_string(addr);             \
+        if (!p) {                               \
+            gpr[2] = -1;                        \
+            gpr[3] = EFAULT;                    \
+            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]);
+            gpr[3] = errno;
+        }
+        break;
+    case UHI_argc:
+        gpr[2] = semihosting_get_argc();
+        break;
+    case UHI_argnlen:
+        if (gpr[4] >= semihosting_get_argc()) {
+            gpr[2] = -1;
+            goto uhi_done;
+        }
+        gpr[2] = strlen(semihosting_get_arg(gpr[4]));
+        break;
+    case UHI_argn:
+        if (gpr[4] >= semihosting_get_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]);
+        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 6fd6dd9..9a0d601 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)

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH v3 5/5] target-mips: convert host to MIPS errno values when required
  2015-06-19 10:08 [Qemu-devel] [PATCH v3 0/5] target-mips: add UHI semihosting support Leon Alrae
                   ` (3 preceding siblings ...)
  2015-06-19 10:08 ` [Qemu-devel] [PATCH v3 4/5] target-mips: add Unified Hosting Interface (UHI) support Leon Alrae
@ 2015-06-19 10:08 ` Leon Alrae
  2015-06-24 14:40   ` Aurelien Jarno
  4 siblings, 1 reply; 13+ messages in thread
From: Leon Alrae @ 2015-06-19 10:08 UTC (permalink / raw)
  To: qemu-devel; +Cc: matthew.fortune, aurelien

Convert only errno values which can be returned by system calls in
mips-semi.c and are not generic to all archs.

Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
---
 target-mips/mips-semi.c | 44 +++++++++++++++++++++++++++++++++-----------
 1 file changed, 33 insertions(+), 11 deletions(-)

diff --git a/target-mips/mips-semi.c b/target-mips/mips-semi.c
index 6944e98..1162c76 100644
--- a/target-mips/mips-semi.c
+++ b/target-mips/mips-semi.c
@@ -72,6 +72,28 @@ enum UHIOpenFlags {
     UHIOpen_EXCL   = 0x800
 };
 
+/* Errno values taken from asm-mips/errno.h */
+static uint16_t host_to_mips_errno[] = {
+    [ENAMETOOLONG] = 78,
+#ifdef EOVERFLOW
+    [EOVERFLOW]    = 79,
+#endif
+#ifdef ELOOP
+    [ELOOP]        = 90,
+#endif
+};
+
+static int errno_mips(int err)
+{
+    if (err < 0 || err >= ARRAY_SIZE(host_to_mips_errno)) {
+        return EINVAL;
+    } else if (host_to_mips_errno[err]) {
+        return host_to_mips_errno[err];
+    } else {
+        return err;
+    }
+}
+
 static int copy_stat_to_target(CPUMIPSState *env, const struct stat *src,
                                target_ulong vaddr)
 {
@@ -223,7 +245,7 @@ void helper_do_semihosting(CPUMIPSState *env)
             gpr[2] = 2;
         } else {
             gpr[2] = open(p, get_open_flags(gpr[5]), gpr[6]);
-            gpr[3] = errno;
+            gpr[3] = errno_mips(errno);
         }
         FREE_TARGET_STRING(p, gpr[4]);
         break;
@@ -234,24 +256,24 @@ void helper_do_semihosting(CPUMIPSState *env)
             goto uhi_done;
         }
         gpr[2] = close(gpr[4]);
-        gpr[3] = errno;
+        gpr[3] = errno_mips(errno);
         break;
     case UHI_read:
         gpr[2] = read_from_file(env, gpr[4], gpr[5], gpr[6], 0);
-        gpr[3] = errno;
+        gpr[3] = errno_mips(errno);
         break;
     case UHI_write:
         gpr[2] = write_to_file(env, gpr[4], gpr[5], gpr[6], 0);
-        gpr[3] = errno;
+        gpr[3] = errno_mips(errno);
         break;
     case UHI_lseek:
         gpr[2] = lseek(gpr[4], gpr[5], gpr[6]);
-        gpr[3] = errno;
+        gpr[3] = errno_mips(errno);
         break;
     case UHI_unlink:
         GET_TARGET_STRING(p, gpr[4]);
         gpr[2] = remove(p);
-        gpr[3] = errno;
+        gpr[3] = errno_mips(errno);
         FREE_TARGET_STRING(p, gpr[4]);
         break;
     case UHI_fstat:
@@ -259,12 +281,12 @@ void helper_do_semihosting(CPUMIPSState *env)
             struct stat sbuf;
             memset(&sbuf, 0, sizeof(sbuf));
             gpr[2] = fstat(gpr[4], &sbuf);
-            gpr[3] = errno;
+            gpr[3] = errno_mips(errno);
             if (gpr[2]) {
                 goto uhi_done;
             }
             gpr[2] = copy_stat_to_target(env, &sbuf, gpr[5]);
-            gpr[3] = errno;
+            gpr[3] = errno_mips(errno);
         }
         break;
     case UHI_argc:
@@ -311,18 +333,18 @@ void helper_do_semihosting(CPUMIPSState *env)
         break;
     case UHI_pread:
         gpr[2] = read_from_file(env, gpr[4], gpr[5], gpr[6], gpr[7]);
-        gpr[3] = errno;
+        gpr[3] = errno_mips(errno);
         break;
     case UHI_pwrite:
         gpr[2] = write_to_file(env, gpr[4], gpr[5], gpr[6], gpr[7]);
-        gpr[3] = errno;
+        gpr[3] = errno_mips(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;
+        gpr[3] = errno_mips(errno);
         FREE_TARGET_STRING(p2, gpr[5]);
         FREE_TARGET_STRING(p, gpr[4]);
         break;

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] [PATCH v3 1/5] include/softmmu-semi.h: Make semihosting support 64-bit clean
  2015-06-19 10:08 ` [Qemu-devel] [PATCH v3 1/5] include/softmmu-semi.h: Make semihosting support 64-bit clean Leon Alrae
@ 2015-06-24 14:24   ` Aurelien Jarno
  0 siblings, 0 replies; 13+ messages in thread
From: Aurelien Jarno @ 2015-06-24 14:24 UTC (permalink / raw)
  To: Leon Alrae; +Cc: Maciej W. Rozycki, qemu-devel, matthew.fortune

On 2015-06-19 11:08, Leon Alrae wrote:
> 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>
> ---
>  include/exec/softmmu-semi.h | 13 +++++++------
>  1 file changed, 7 insertions(+), 6 deletions(-)
> 

Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>

-- 
Aurelien Jarno                          GPG: 4096R/1DDD8C9B
aurelien@aurel32.net                 http://www.aurel32.net

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] [PATCH v3 2/5] hw/mips: Do not clear BEV for MIPS malta kernel load
  2015-06-19 10:08 ` [Qemu-devel] [PATCH v3 2/5] hw/mips: Do not clear BEV for MIPS malta kernel load Leon Alrae
@ 2015-06-24 14:29   ` Aurelien Jarno
  2015-06-24 16:21     ` Matthew Fortune
  0 siblings, 1 reply; 13+ messages in thread
From: Aurelien Jarno @ 2015-06-24 14:29 UTC (permalink / raw)
  To: Leon Alrae; +Cc: qemu-devel, matthew.fortune

On 2015-06-19 11:08, Leon Alrae wrote:
> 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 fake boot loader doesn't provide any exception handler at address
0xbcf00200. On the other hand the kernel might provide an exception
handler at address 0x80000000 through the ELF file (this doesn't seem to
be the case currently).

Is there a clear interface which defines the value of this bit when
booting a kernel. If not, it would be a good idea to look what YAMON or
U-Boot do and mimic that.

> 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.

In UHI mode that indeed makes sense.

> 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 786a8f0..a5d64d5 100644
> --- a/hw/mips/mips_malta.c
> +++ b/hw/mips/mips_malta.c
> @@ -887,7 +887,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);
> 

-- 
Aurelien Jarno                          GPG: 4096R/1DDD8C9B
aurelien@aurel32.net                 http://www.aurel32.net

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] [PATCH v3 3/5] target-mips: remove identical code in different branch
  2015-06-19 10:08 ` [Qemu-devel] [PATCH v3 3/5] target-mips: remove identical code in different branch Leon Alrae
@ 2015-06-24 14:37   ` Aurelien Jarno
  2015-06-24 14:59     ` Leon Alrae
  0 siblings, 1 reply; 13+ messages in thread
From: Aurelien Jarno @ 2015-06-24 14:37 UTC (permalink / raw)
  To: Leon Alrae; +Cc: qemu-devel, matthew.fortune

On 2015-06-19 11:08, Leon Alrae wrote:
> Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
> ---
>  target-mips/translate.c | 25 ++++---------------------
>  1 file changed, 4 insertions(+), 21 deletions(-)
> 
> diff --git a/target-mips/translate.c b/target-mips/translate.c
> index 1d128ee..6fd6dd9 100644
> --- a/target-mips/translate.c
> +++ b/target-mips/translate.c
> @@ -11852,11 +11852,7 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
>               *      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);
> -            }
> +            generate_exception(ctx, EXCP_DBp);

The reason for this duplicated code, is from the comment above, that is
we are not sure which exception should be generated in debug mode. If
someone knows the answer (or my experiment that on real hardware) that 
might be a good opportu to fix that the correct way.

>              break;
>          case RR_SLT:
>              gen_slt(ctx, OPC_SLT, 24, rx, ry);
> @@ -12707,11 +12703,7 @@ static void gen_pool16c_insn(DisasContext *ctx)
>           *      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);
> -        }
> +        generate_exception(ctx, EXCP_DBp);
>          break;
>      case JRADDIUSP + 0:
>      case JRADDIUSP + 1:
> @@ -13076,11 +13068,7 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
>              break;
>          case SDBBP:
>              check_insn(ctx, ISA_MIPS32);
> -            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
> -                generate_exception(ctx, EXCP_DBp);
> -            } else {
> -                generate_exception(ctx, EXCP_DBp);
> -            }
> +            generate_exception(ctx, EXCP_DBp);
>              break;
>          default:
>              goto pool32axf_invalid;
> @@ -16849,12 +16837,7 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
>           *      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. */
> +        generate_exception(ctx, EXCP_DBp);
>          break;
>  #if defined(TARGET_MIPS64)
>      case OPC_DCLO:
> 

Besides the nitpick above:

Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>

-- 
Aurelien Jarno                          GPG: 4096R/1DDD8C9B
aurelien@aurel32.net                 http://www.aurel32.net

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] [PATCH v3 4/5] target-mips: add Unified Hosting Interface (UHI) support
  2015-06-19 10:08 ` [Qemu-devel] [PATCH v3 4/5] target-mips: add Unified Hosting Interface (UHI) support Leon Alrae
@ 2015-06-24 14:40   ` Aurelien Jarno
  0 siblings, 0 replies; 13+ messages in thread
From: Aurelien Jarno @ 2015-06-24 14:40 UTC (permalink / raw)
  To: Leon Alrae; +Cc: qemu-devel, matthew.fortune

On 2015-06-19 11:08, Leon Alrae wrote:
> 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>
> ---
>  hw/mips/mips_malta.c      |   9 +-
>  qemu-options.hx           |  10 +-
>  target-mips/Makefile.objs |   2 +-
>  target-mips/helper.h      |   2 +
>  target-mips/mips-semi.c   | 336 ++++++++++++++++++++++++++++++++++++++++++++++
>  target-mips/translate.c   |  75 ++++++++---
>  6 files changed, 408 insertions(+), 26 deletions(-)
>  create mode 100644 target-mips/mips-semi.c

Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>

-- 
Aurelien Jarno                          GPG: 4096R/1DDD8C9B
aurelien@aurel32.net                 http://www.aurel32.net

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] [PATCH v3 5/5] target-mips: convert host to MIPS errno values when required
  2015-06-19 10:08 ` [Qemu-devel] [PATCH v3 5/5] target-mips: convert host to MIPS errno values when required Leon Alrae
@ 2015-06-24 14:40   ` Aurelien Jarno
  0 siblings, 0 replies; 13+ messages in thread
From: Aurelien Jarno @ 2015-06-24 14:40 UTC (permalink / raw)
  To: Leon Alrae; +Cc: qemu-devel, matthew.fortune

On 2015-06-19 11:08, Leon Alrae wrote:
> Convert only errno values which can be returned by system calls in
> mips-semi.c and are not generic to all archs.
> 
> Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
> ---
>  target-mips/mips-semi.c | 44 +++++++++++++++++++++++++++++++++-----------
>  1 file changed, 33 insertions(+), 11 deletions(-)

Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>

-- 
Aurelien Jarno                          GPG: 4096R/1DDD8C9B
aurelien@aurel32.net                 http://www.aurel32.net

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] [PATCH v3 3/5] target-mips: remove identical code in different branch
  2015-06-24 14:37   ` Aurelien Jarno
@ 2015-06-24 14:59     ` Leon Alrae
  0 siblings, 0 replies; 13+ messages in thread
From: Leon Alrae @ 2015-06-24 14:59 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: qemu-devel, matthew.fortune

On 24/06/2015 15:37, Aurelien Jarno wrote:
> On 2015-06-19 11:08, Leon Alrae wrote:
>> Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
>> ---
>>  target-mips/translate.c | 25 ++++---------------------
>>  1 file changed, 4 insertions(+), 21 deletions(-)
>>
>> diff --git a/target-mips/translate.c b/target-mips/translate.c
>> index 1d128ee..6fd6dd9 100644
>> --- a/target-mips/translate.c
>> +++ b/target-mips/translate.c
>> @@ -11852,11 +11852,7 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
>>               *      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);
>> -            }
>> +            generate_exception(ctx, EXCP_DBp);
> 
> The reason for this duplicated code, is from the comment above, that is
> we are not sure which exception should be generated in debug mode. If
> someone knows the answer (or my experiment that on real hardware) that 
> might be a good opportu to fix that the correct way.

Yes, that's why I left the comment so we are still aware of this problem and
we know where to fix it once we know the answer. But at the time I was
touching this code I felt it should be removed (it generates 4 medium issues
in Coverity).

Leon

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] [PATCH v3 2/5] hw/mips: Do not clear BEV for MIPS malta kernel load
  2015-06-24 14:29   ` Aurelien Jarno
@ 2015-06-24 16:21     ` Matthew Fortune
  0 siblings, 0 replies; 13+ messages in thread
From: Matthew Fortune @ 2015-06-24 16:21 UTC (permalink / raw)
  To: Aurelien Jarno, Leon Alrae; +Cc: qemu-devel

Aurelien Jarno <aurelien@aurel32.net> writes:
> On 2015-06-19 11:08, Leon Alrae wrote:
> > 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 fake boot loader doesn't provide any exception handler at address
> 0xbcf00200. On the other hand the kernel might provide an exception
> handler at address 0x80000000 through the ELF file (this doesn't seem to
> be the case currently).

I don't think this would be a reasonable thing to support. If something
clears BEV then IMO it is responsible for putting an exception handler
in 0x80000000 (/EBASE). The fact that the fake bootloader has nothing at
0xbfc00200 doesn't really make anything any worse, it doesn't have one
at 0x80000000 either. An application that is aware of the need for
providing an exception vector is also going to have to account for BEV
and EBASE to operate safely so I'd call it an app bug if it did anything
other.
 
> Is there a clear interface which defines the value of this bit when
> booting a kernel. If not, it would be a good idea to look what YAMON or
> U-Boot do and mimic that.

My investigation at the time (as a non-kernel developer) showed that
the status register is taken over entirely with the only exception being
that the ERL bit is mostly expected to be clear by the time the kernel
is entered.

u-boot and yamon clear BEV but, importantly, provide an exception vector
at EBASE.

Thanks,
Matthew

> > 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.
> 
> In UHI mode that indeed makes sense.
> 
> > 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
> > 786a8f0..a5d64d5 100644
> > --- a/hw/mips/mips_malta.c
> > +++ b/hw/mips/mips_malta.c
> > @@ -887,7 +887,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);
> >
> 
> --
> Aurelien Jarno                          GPG: 4096R/1DDD8C9B
> aurelien@aurel32.net                 http://www.aurel32.net

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2015-06-24 16:21 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-19 10:08 [Qemu-devel] [PATCH v3 0/5] target-mips: add UHI semihosting support Leon Alrae
2015-06-19 10:08 ` [Qemu-devel] [PATCH v3 1/5] include/softmmu-semi.h: Make semihosting support 64-bit clean Leon Alrae
2015-06-24 14:24   ` Aurelien Jarno
2015-06-19 10:08 ` [Qemu-devel] [PATCH v3 2/5] hw/mips: Do not clear BEV for MIPS malta kernel load Leon Alrae
2015-06-24 14:29   ` Aurelien Jarno
2015-06-24 16:21     ` Matthew Fortune
2015-06-19 10:08 ` [Qemu-devel] [PATCH v3 3/5] target-mips: remove identical code in different branch Leon Alrae
2015-06-24 14:37   ` Aurelien Jarno
2015-06-24 14:59     ` Leon Alrae
2015-06-19 10:08 ` [Qemu-devel] [PATCH v3 4/5] target-mips: add Unified Hosting Interface (UHI) support Leon Alrae
2015-06-24 14:40   ` Aurelien Jarno
2015-06-19 10:08 ` [Qemu-devel] [PATCH v3 5/5] target-mips: convert host to MIPS errno values when required Leon Alrae
2015-06-24 14:40   ` Aurelien Jarno

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.