[PATCH v2 00/14] hexagon: add semihosting support

Matheus Tavares Bernardino posted 14 patches 1 week, 2 days ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/cover.1784225209.git.matheus.bernardino@oss.qualcomm.com
Maintainers: Brian Cain <brian.cain@oss.qualcomm.com>, Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>, Paolo Bonzini <pbonzini@redhat.com>, "Alex Bennée" <alex.bennee@linaro.org>, John Snow <jsnow@redhat.com>, Cleber Rosa <crosa@redhat.com>, Peter Maydell <peter.maydell@linaro.org>, Palmer Dabbelt <palmer@dabbelt.com>, Alistair Francis <alistair.francis@wdc.com>, Weiwei Li <liwei1518@gmail.com>, Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>, Liu Zhiwei <zhiwei_liu@linux.alibaba.com>, Chao Liu <chao.liu@processmission.com>, Thomas Huth <th.huth+qemu@posteo.eu>, "Philippe Mathieu-Daudé" <philmd@mailo.com>, "Daniel P. Berrangé" <berrange@redhat.com>
There is a newer version of this series
docs/system/target-hexagon.rst            |   8 +-
configs/targets/hexagon-softmmu.mak       |   2 +
include/semihosting/common-semi.h         |   2 +
include/semihosting/console.h             |   9 +
include/semihosting/guestfd.h             |   9 +
include/semihosting/syscalls.h            |   2 +
target/hexagon/cpu_helper.h               |  24 +
target/hexagon/internal.h                 |   1 +
hw/hexagon/hexagon_dsp.c                  |   2 +
semihosting/arm-compat-semi.c             |   3 +-
semihosting/console.c                     |   5 +
semihosting/guestfd.c                     |   8 +
semihosting/syscalls.c                    |  29 +
target/arm/common-semi-target.c           |   4 +
target/hexagon/common-semi-target.c       |  51 ++
target/hexagon/cpu.c                      |   7 +-
target/hexagon/cpu_helper.c               | 173 ++++++
target/hexagon/hexswi.c                   | 657 +++++++++++++++++++++-
target/hexagon/op_helper.c                |  18 +-
target/hexagon/translate.c                |  17 +-
target/riscv/common-semi-target.c         |   4 +
hw/hexagon/Kconfig                        |   1 +
python/qemu/machine/machine.py            |  10 +-
qemu-options.hx                           |   8 +-
target/hexagon/meson.build                |   3 +
tests/functional/hexagon/meson.build      |   9 +
tests/functional/hexagon/test_systests.py | 110 ++++
tests/functional/meson.build              |   1 +
28 files changed, 1142 insertions(+), 35 deletions(-)
create mode 100644 target/hexagon/common-semi-target.c
create mode 100644 tests/functional/hexagon/meson.build
create mode 100755 tests/functional/hexagon/test_systests.py
[PATCH v2 00/14] hexagon: add semihosting support
Posted by Matheus Tavares Bernardino 1 week, 2 days ago
This series adds semihosting support to hexagon system emulation,
together with functional tests for the added operations.

The Hexagon semihosting spec can be found at:
https://docs.qualcomm.com/doc/80-N2040-101_102648/topic/semihosting-specification.html

v1: https://lore.kernel.org/qemu-devel/cover.1783973054.git.matheus.bernardino@oss.qualcomm.com/

Changes in v2:
- Added patch 1, a fix for an existing bug that appeared with the new
  test semantics from the last patch.
- Patch 3: s/hexagon_touch_memory/hexagon_peek_memory_range/
- Patch 7:
  * Add semihosting spec link to docs
  * Fixed HEX_SYS_EXCEPTION
- Patch 10:
  * Moved tables to static definition
  * Fixed compilation for Windows
- Dropped patch 11 (OPEN/READ/CLOSE_DIR support): for now we don't have
  dirent semantics for Windows, so leave these ops to a followup series.
- Patch 14:
  * Update test version
  * Don't change directory
  * Don't use os.path, use scratch_file

Brian Cain (4):
  semihosting: add APIs for chardev-aware guest fd routing
  target/hexagon: Add an errno mapping
  python/machine: support routing semihosting output to the test console
  tests/functional: Add hexagon semihosting systests

Matheus Tavares Bernardino (10):
  target/hexagon: fix improper assign of cause code to exception index
  target/hexagon: fix get_phys_addr_debug with in-page offset
  target/hexagon: fix PC advancement for non-COF TB terminators
  target/hexagon: add aux functions for guest mem load/store
  hexagon: cpu_helper: add reg reading/writing helpers
  semihosting: add callback to set error
  target/hexagon: add semihosting support
  semihosting: add ftruncate helper (to be used for hexagon)
  target/hexagon: add main arch-specific semihosting operations
  target/hexagon: add COREDUMP semihosting operation

 docs/system/target-hexagon.rst            |   8 +-
 configs/targets/hexagon-softmmu.mak       |   2 +
 include/semihosting/common-semi.h         |   2 +
 include/semihosting/console.h             |   9 +
 include/semihosting/guestfd.h             |   9 +
 include/semihosting/syscalls.h            |   2 +
 target/hexagon/cpu_helper.h               |  24 +
 target/hexagon/internal.h                 |   1 +
 hw/hexagon/hexagon_dsp.c                  |   2 +
 semihosting/arm-compat-semi.c             |   3 +-
 semihosting/console.c                     |   5 +
 semihosting/guestfd.c                     |   8 +
 semihosting/syscalls.c                    |  29 +
 target/arm/common-semi-target.c           |   4 +
 target/hexagon/common-semi-target.c       |  51 ++
 target/hexagon/cpu.c                      |   7 +-
 target/hexagon/cpu_helper.c               | 173 ++++++
 target/hexagon/hexswi.c                   | 657 +++++++++++++++++++++-
 target/hexagon/op_helper.c                |  18 +-
 target/hexagon/translate.c                |  17 +-
 target/riscv/common-semi-target.c         |   4 +
 hw/hexagon/Kconfig                        |   1 +
 python/qemu/machine/machine.py            |  10 +-
 qemu-options.hx                           |   8 +-
 target/hexagon/meson.build                |   3 +
 tests/functional/hexagon/meson.build      |   9 +
 tests/functional/hexagon/test_systests.py | 110 ++++
 tests/functional/meson.build              |   1 +
 28 files changed, 1142 insertions(+), 35 deletions(-)
 create mode 100644 target/hexagon/common-semi-target.c
 create mode 100644 tests/functional/hexagon/meson.build
 create mode 100755 tests/functional/hexagon/test_systests.py

Range-diff against v1:
 -:  ----------- >  1:  aaac9492e5a target/hexagon: fix improper assign of cause code to exception index
 1:  dd52bfe14af !  2:  2f5247200ec target/hexagon: fix get_phys_addr_debug with in-page offset
    @@ Commit message
     
         This would break semihosting argument reads when it is added for Hexagon.
     
    +    Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
         Signed-off-by: Matheus Tavares Bernardino <matheus.bernardino@oss.qualcomm.com>
     
      ## target/hexagon/cpu.c ##
 2:  c0cc9ab4c7d !  3:  2cac81d1782 target/hexagon: fix PC advancement for non-COF TB terminators
    @@ Commit message
         hex_gpr[HEX_REG_PC]).  Drop the special case so these packets advance to
         the following packet like any other non-COF TB terminator.
     
    +    Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
         Signed-off-by: Matheus Tavares Bernardino <matheus.bernardino@oss.qualcomm.com>
     
      ## target/hexagon/translate.c ##
 3:  9cdc7c7f27a !  4:  b0f794c467a target/hexagon: add aux functions for guest mem load/store
    @@
      ## Metadata ##
    -Author: Matheus Tavares Bernardino <quic_mathbern@quicinc.com>
    +Author: Matheus Tavares Bernardino <matheus.bernardino@oss.qualcomm.com>
     
      ## Commit message ##
         target/hexagon: add aux functions for guest mem load/store
     
         Will be used for semihosting.
     
    -    Signed-off-by: Matheus Tavares Bernardino <quic_mathbern@quicinc.com>
    +    Signed-off-by: Matheus Tavares Bernardino <matheus.bernardino@oss.qualcomm.com>
         Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
    +    Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
     
      ## target/hexagon/cpu_helper.h ##
     @@
    @@ target/hexagon/cpu_helper.h
     +                         void *retptr, uintptr_t retaddr);
     +void hexagon_write_memory(CPUHexagonState *env, target_ulong vaddr,
     +                          int size, uint64_t data, uintptr_t retaddr);
    -+void hexagon_touch_memory(CPUHexagonState *env, uint32_t start_addr,
    -+                          uint32_t length, uintptr_t retaddr);
    ++void hexagon_peek_memory_range(CPUHexagonState *env, uint32_t start_addr,
    ++                               uint32_t length, uintptr_t retaddr);
      uint32_t hexagon_get_pmu_counter(CPUHexagonState *cur_env, int index);
      void hexagon_modify_ssr(CPUHexagonState *env, uint32_t new, uint32_t old);
      int get_cpu_mode(CPUHexagonState *env);
    @@ target/hexagon/cpu_helper.c
     +    return addr & page_align;
     +}
     +
    -+void hexagon_touch_memory(CPUHexagonState *env, uint32_t start_addr,
    -+                          uint32_t length, uintptr_t retaddr)
    ++void hexagon_peek_memory_range(CPUHexagonState *env, uint32_t start_addr,
    ++                               uint32_t length, uintptr_t retaddr)
     +{
     +    unsigned int warm;
     +    uint32_t first = page_start(start_addr);
 4:  636d47e381c !  5:  5b16ff40a6e hexagon: cpu_helper: add reg reading/writing helpers
    @@ Commit message
         And adjust op_helper to use those. They will also be used on upcoming
         semihosting commits.
     
    +    Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
         Signed-off-by: Matheus Tavares Bernardino <matheus.bernardino@oss.qualcomm.com>
     
      ## target/hexagon/cpu_helper.h ##
 6:  726a2186349 !  6:  90074658cf5 semihosting: add APIs for chardev-aware guest fd routing
    @@ Commit message
         rather than directly to host stdio.
     
         Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
    +    Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
     
      ## include/semihosting/console.h ##
     @@ include/semihosting/console.h: void qemu_semihosting_console_block_until_ready(CPUState *cs);
 5:  df1607f5ee3 !  7:  a08d1e274e7 semihosting: add callback to set error
    @@ Commit message
         semihosting: add callback to set error
     
         This is currently unused by existing semihosting targets, but it will be
    -    used by hexagon.
    +    used by hexagon in the following commit.
     
    -    Signed-off-by: Matheus Tavares Bernardino <matheus.bernardino@oss.qualcomm.com>
         Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
    +    Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
    +    Signed-off-by: Matheus Tavares Bernardino <matheus.bernardino@oss.qualcomm.com>
     
      ## include/semihosting/common-semi.h ##
     @@
 7:  e01b8e57d6b !  8:  5c5c06f35f7 target/hexagon: add semihosting support
    @@
      ## Metadata ##
    -Author: Matheus Tavares Bernardino <quic_mathbern@quicinc.com>
    +Author: Matheus Tavares Bernardino <matheus.bernardino@oss.qualcomm.com>
     
      ## Commit message ##
         target/hexagon: add semihosting support
    @@ Commit message
         CONFIG_ARM_COMPATIBLE_SEMIHOSTING and routing trap0 to the
         semihosting handler.
     
    -    Signed-off-by: Matheus Tavares Bernardino <quic_mathbern@quicinc.com>
    +    Signed-off-by: Matheus Tavares Bernardino <matheus.bernardino@oss.qualcomm.com>
         Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
    +    Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
    +
    + ## docs/system/target-hexagon.rst ##
    +@@ docs/system/target-hexagon.rst: Semihosting
    + -----------
    + Hexagon supports a semihosting interface similar to other architectures'.
    + The ``trap0`` instruction can activate these semihosting calls so that the
    +-guest software can access the host console and filesystem.  Semihosting
    +-is not yet implemented in QEMU hexagon.
    +-
    ++guest software can access the host console and filesystem. Read the
    ++`Hexagon Semihosting Specification
    ++<https://docs.qualcomm.com/doc/80-N2040-101_102648/topic/semihosting-specification.html>`__
    ++for details. Semihosting is enabled on qemu-system-hexagon machines by default,
    ++and it can be configured through ``-semihosting-config``.
    + 
    + Hexagon Features
    + ================
     
      ## configs/targets/hexagon-softmmu.mak ##
     @@ configs/targets/hexagon-softmmu.mak: TARGET_LONG_BITS=32
    @@ target/hexagon/hexswi.c
     +
     +    hexagon_read_memory(env, swi_info + 4, 4, &addr, retaddr);
     +    hexagon_read_memory(env, swi_info + 8, 4, &count, retaddr);
    -+    hexagon_touch_memory(env, addr, count, retaddr);
    ++    hexagon_peek_memory_range(env, addr, count, retaddr);
     +}
     +
     +static void sim_handle_trap0(CPUHexagonState *env)
     +{
     +    target_ulong what_swi, swi_info;
    -+    G_GNUC_UNUSED uintptr_t retaddr = 0;
     +    CPUState *cs = env_cpu(env);
     +
     +    g_assert(bql_locked());
    @@ target/hexagon/hexswi.c
     +    switch (what_swi) {
     +
     +    case HEX_SYS_EXCEPTION:
    ++    {
    ++        uint32_t ret = arch_get_thread_reg(env, HEX_REG_R02);
     +        arch_set_system_reg(env, HEX_SREG_MODECTL, 0);
    -+        qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
    -+        break;
    ++        gdb_exit(ret);
    ++        exit(ret);
    ++    }
    ++    break;
     +
     +    /* TODO: implement other hexagon-specific semihosting calls */
     +
 8:  8f1099dc944 !  9:  7399327e99b semihosting: add ftruncate helper (to be used for hexagon)
    @@ Commit message
         operation.  Add semihost_sys_ftruncate() so that Hexagon
         can delegate to it rather than calling ftruncate directly.
     
    -    Signed-off-by: Matheus Tavares Bernardino <matheus.bernardino@oss.qualcomm.com>
         Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
    +    Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
    +    Signed-off-by: Matheus Tavares Bernardino <matheus.bernardino@oss.qualcomm.com>
     
      ## include/semihosting/syscalls.h ##
     @@ include/semihosting/syscalls.h: void semihost_sys_gettimeofday(CPUState *cs, gdb_syscall_complete_cb complete,
 9:  45fc870a747 ! 10:  b66476c599c target/hexagon: add main arch-specific semihosting operations
    @@ Commit message
         that baremetal programs using the standard Hexagon simulator ABI can
         perform file I/O when running on qemu-system-hexagon.
     
    -    Signed-off-by: Matheus Tavares Bernardino <matheus.bernardino@oss.qualcomm.com>
         Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
    +    Signed-off-by: Matheus Tavares Bernardino <matheus.bernardino@oss.qualcomm.com>
     
      ## include/semihosting/common-semi.h ##
     @@
    @@ semihosting/arm-compat-semi.c: static inline uint32_t get_swi_errno(CPUState *cs
      #ifdef CONFIG_USER_ONLY
     
      ## target/hexagon/hexswi.c ##
    +@@ target/hexagon/hexswi.c: static inline bool is_hexagon_specific_swi_flag(enum hex_swi_flag what_swi)
    + }
    + #undef DEF_SWI_FLAG
    + 
    ++static const unsigned int angel_to_host_filemode_table[] = {
    ++    O_RDONLY,
    ++    O_RDONLY | O_BINARY,
    ++    O_RDWR,
    ++    O_RDWR | O_BINARY,
    ++    O_WRONLY | O_CREAT | O_TRUNC,
    ++    O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
    ++    O_RDWR | O_CREAT | O_TRUNC,
    ++    O_RDWR | O_CREAT | O_TRUNC | O_BINARY,
    ++    O_WRONLY | O_APPEND | O_CREAT,
    ++    O_WRONLY | O_APPEND | O_CREAT | O_BINARY,
    ++    O_RDWR | O_APPEND | O_CREAT,
    ++    O_RDWR | O_APPEND | O_CREAT | O_BINARY,
    ++    O_RDWR | O_CREAT,
    ++    O_RDWR | O_CREAT | O_EXCL
    ++};
    ++
    ++/*
    ++ * This must match the caller's definition, it would be in the
    ++ * caller's angel.h or equivalent header.
    ++ */
    ++struct __SYS_STAT {
    ++    uint64_t dev;
    ++    uint64_t ino;
    ++    uint32_t mode;
    ++    uint32_t nlink;
    ++    uint64_t rdev;
    ++    uint32_t size;
    ++    uint32_t __pad1;
    ++    uint32_t atime;
    ++    uint32_t mtime;
    ++    uint32_t ctime;
    ++    uint32_t __pad2;
    ++} sys_stat;
    ++
    + static void init_semihosting_guestfds(void)
    + {
    +     static gsize initialized;
     @@ target/hexagon/hexswi.c: static void do_preload(CPUHexagonState *env, target_ulong swi_info, bool load)
    -     hexagon_touch_memory(env, addr, count, retaddr);
    +     hexagon_peek_memory_range(env, addr, count, retaddr);
      }
      
     +static void common_semi_ftell_cb(CPUState *cs, uint64_t ret, int err)
    @@ target/hexagon/hexswi.c: static void do_preload(CPUHexagonState *env, target_ulo
      static void sim_handle_trap0(CPUHexagonState *env)
      {
          target_ulong what_swi, swi_info;
    +     CPUState *cs = env_cpu(env);
    ++    uintptr_t retaddr = 0;
    + 
    +     g_assert(bql_locked());
    +     init_semihosting_guestfds();
     @@ target/hexagon/hexswi.c: static void sim_handle_trap0(CPUHexagonState *env)
    -         qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
    -         break;
    +     }
    +     break;
      
     -    /* TODO: implement other hexagon-specific semihosting calls */
    -+#ifndef _WIN32
     +    case HEX_SYS_OPEN:
     +    {
     +        char filename[BUFSIZ];
    -+        target_ulong physicalFilenameAddr;
    ++        target_ulong physical_filename_addr;
     +        unsigned int filemode;
     +        int length;
     +        int real_openmode;
     +        int ret, err = 0;
     +        int i = 0;
    -+        static const unsigned int mode_table[] = {
    -+            O_RDONLY,
    -+            O_RDONLY | O_BINARY,
    -+            O_RDWR,
    -+            O_RDWR | O_BINARY,
    -+            O_WRONLY | O_CREAT | O_TRUNC,
    -+            O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
    -+            O_RDWR | O_CREAT | O_TRUNC,
    -+            O_RDWR | O_CREAT | O_TRUNC | O_BINARY,
    -+            O_WRONLY | O_APPEND | O_CREAT,
    -+            O_WRONLY | O_APPEND | O_CREAT | O_BINARY,
    -+            O_RDWR | O_APPEND | O_CREAT,
    -+            O_RDWR | O_APPEND | O_CREAT | O_BINARY,
    -+            O_RDWR | O_CREAT,
    -+            O_RDWR | O_CREAT | O_EXCL
    -+        };
     +
    -+
    -+        hexagon_read_memory(env, swi_info, 4, &physicalFilenameAddr, retaddr);
    ++        hexagon_read_memory(env, swi_info, 4, &physical_filename_addr, retaddr);
     +        hexagon_read_memory(env, swi_info + 4, 4, &filemode, retaddr);
     +        hexagon_read_memory(env, swi_info + 8, 4, &length, retaddr);
     +
    @@ target/hexagon/hexswi.c: static void sim_handle_trap0(CPUHexagonState *env)
     +        }
     +
     +        do {
    -+            hexagon_read_memory(env, physicalFilenameAddr + i, 1, &filename[i],
    ++            hexagon_read_memory(env, physical_filename_addr + i, 1, &filename[i],
     +                                retaddr);
     +            i++;
     +        } while (filename[i - 1]);
     +
     +        /* convert ARM ANGEL filemode into host filemode */
    -+        if (filemode < 14) {
    -+            real_openmode = mode_table[filemode];
    ++        if (filemode < ARRAY_SIZE(angel_to_host_filemode_table)) {
    ++            real_openmode = angel_to_host_filemode_table[filemode];
     +        } else {
     +            qemu_log_mask(LOG_GUEST_ERROR,
     +                          "%s: invalid OPEN mode: %u\n",
    @@ target/hexagon/hexswi.c: static void sim_handle_trap0(CPUHexagonState *env)
     +
     +    /*
     +     * Hexagon's SYS_ISTTY is a bit different than arm's: we do not return -1
    -+     * on error, neither errno. So we override with out own implementation.
    ++     * on error, neither errno. So we override with our own implementation.
     +     */
     +    case HEX_SYS_ISTTY:
     +    {
    @@ target/hexagon/hexswi.c: static void sim_handle_trap0(CPUHexagonState *env)
     +    case HEX_SYS_STAT:
     +    case HEX_SYS_FSTAT:
     +    {
    -+        /*
    -+         * This must match the caller's definition, it would be in the
    -+         * caller's angel.h or equivalent header.
    -+         */
    -+        struct __SYS_STAT {
    -+            uint64_t dev;
    -+            uint64_t ino;
    -+            uint32_t mode;
    -+            uint32_t nlink;
    -+            uint64_t rdev;
    -+            uint32_t size;
    -+            uint32_t __pad1;
    -+            uint32_t atime;
    -+            uint32_t mtime;
    -+            uint32_t ctime;
    -+            uint32_t __pad2;
    -+        } sys_stat;
     +        struct stat st_buf;
     +        uint8_t *st_bufptr = (uint8_t *)&sys_stat;
     +        int rc, err = 0;
     +        char filename[BUFSIZ];
    -+        target_ulong physicalFilenameAddr;
    ++        target_ulong physical_filename_addr;
     +        target_ulong statBufferAddr;
    -+        hexagon_read_memory(env, swi_info, 4, &physicalFilenameAddr, retaddr);
    ++        hexagon_read_memory(env, swi_info, 4, &physical_filename_addr, retaddr);
     +
     +        if (what_swi == HEX_SYS_STAT) {
     +            int i = 0;
     +            do {
    -+                hexagon_read_memory(env, physicalFilenameAddr + i, 1,
    ++                hexagon_read_memory(env, physical_filename_addr + i, 1,
     +                                    &filename[i], retaddr);
     +                i++;
     +            } while ((i < BUFSIZ) && filename[i - 1]);
     +            rc = stat(filename, &st_buf);
     +            err = errno;
     +        } else {
    -+            int fd = physicalFilenameAddr;
    ++            int fd = physical_filename_addr;
     +            GuestFD *gf = get_guestfd(fd);
     +            if (!gf || gf->type != GuestFDHost) {
     +                qemu_log_mask(LOG_UNIMP,
    @@ target/hexagon/hexswi.c: static void sim_handle_trap0(CPUHexagonState *env)
     +            sys_stat.nlink = (uint32_t) st_buf.st_nlink;
     +            sys_stat.rdev  = st_buf.st_rdev;
     +            sys_stat.size  = (uint32_t) st_buf.st_size;
    ++#if defined(__linux__)
     +            sys_stat.atime = (uint32_t) st_buf.st_atim.tv_sec;
     +            sys_stat.mtime = (uint32_t) st_buf.st_mtim.tv_sec;
     +            sys_stat.ctime = (uint32_t) st_buf.st_ctim.tv_sec;
    ++#elif defined(_WIN32)
    ++            sys_stat.atime = st_buf.st_atime;
    ++            sys_stat.mtime = st_buf.st_mtime;
    ++            sys_stat.ctime = st_buf.st_ctime;
    ++#endif
     +        }
     +        hexagon_read_memory(env, swi_info + 4, 4, &statBufferAddr, retaddr);
     +
    @@ target/hexagon/hexswi.c: static void sim_handle_trap0(CPUHexagonState *env)
     +                      " is unimplemented in QEMU\n",
     +                      (uint32_t)what_swi);
     +        break;
    -+
    -+#endif /* ! _WIN32 */
      
          default:
              qemu_log_mask(LOG_GUEST_ERROR,
10:  a2e686ac0ba ! 11:  7fd1831acb4 target/hexagon: add COREDUMP semihosting operation
    @@
      ## Metadata ##
    -Author: Matheus Tavares Bernardino <quic_mathbern@quicinc.com>
    +Author: Matheus Tavares Bernardino <matheus.bernardino@oss.qualcomm.com>
     
      ## Commit message ##
         target/hexagon: add COREDUMP semihosting operation
    @@ Commit message
         Implement the handler to decode the SSR cause field and
         print the full register file, matching hexagon-sim behavior.
     
    -    Signed-off-by: Matheus Tavares Bernardino <quic_mathbern@quicinc.com>
    +    Signed-off-by: Matheus Tavares Bernardino <matheus.bernardino@oss.qualcomm.com>
         Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
    +    Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
     
      ## target/hexagon/internal.h ##
     @@ target/hexagon/internal.h: int hexagon_hvx_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n);
11:  db95d3b7af7 <  -:  ----------- target/hexagon: add OPEN/READ/CLOSE_DIR semihosting operations
12:  60a8f2decf0 ! 12:  24731ad7a27 target/hexagon: Add an errno mapping
    @@ Commit message
         guest so that baremetal programs see the expected error codes.
     
         Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
    +    Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
         Signed-off-by: Matheus Tavares Bernardino <matheus.bernardino@oss.qualcomm.com>
     
      ## target/hexagon/hexswi.c ##
     @@ target/hexagon/hexswi.c: static void do_preload(CPUHexagonState *env, target_ulong swi_info, bool load)
    -     hexagon_touch_memory(env, addr, count, retaddr);
    +     hexagon_peek_memory_range(env, addr, count, retaddr);
      }
      
     +/* Hexagon semihosting errno values */
    @@ target/hexagon/hexswi.c: static void sim_handle_trap0(CPUHexagonState *env)
          }
          break;
      
    -@@ target/hexagon/hexswi.c: static void sim_handle_trap0(CPUHexagonState *env)
    -         } else {
    -             err = errno;
    -         }
    --        common_semi_cb(cs, rc, rc != 0 ? 0 : err);
    -+        semi_cb(cs, rc, rc != 0 ? 0 : err);
    -         break;
    -     }
    - 
    -@@ target/hexagon/hexswi.c: static void sim_handle_trap0(CPUHexagonState *env)
    -             }
    -             rc = guest_dir_entry;
    -         }
    --        common_semi_cb(cs, rc, err);
    -+        semi_cb(cs, rc, err);
    -         break;
    -     }
    - 
    -@@ target/hexagon/hexswi.c: static void sim_handle_trap0(CPUHexagonState *env)
    -         } else {
    -             err = EBADF;
    -         }
    --        common_semi_cb(cs, ret, ret == 0 ? 0 : err);
    -+        semi_cb(cs, ret, ret == 0 ? 0 : err);
    -         break;
    -     }
    - 
     @@ target/hexagon/hexswi.c: static void sim_handle_trap0(CPUHexagonState *env)
          case HEX_SYS_PROF_STATSRESET:
          case HEX_SYS_DUMP_PMU_STATS:
13:  c366abf8749 ! 13:  c16ea7a7e6c python/machine: support routing semihosting output to the test console
    @@ Commit message
         console.
     
         Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
    +    Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
         Signed-off-by: Matheus Tavares Bernardino <matheus.bernardino@oss.qualcomm.com>
     
      ## python/qemu/machine/machine.py ##
14:  da280da8fec ! 14:  87a6d2559c3 tests/functional: Add hexagon semihosting systests
    @@ Commit message
         tests/functional: Add hexagon semihosting systests
     
         Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
    +    Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
         Signed-off-by: Matheus Tavares Bernardino <matheus.bernardino@oss.qualcomm.com>
     
      ## tests/functional/hexagon/meson.build (new) ##
    @@ tests/functional/hexagon/test_systests.py (new)
     +#!/usr/bin/env python3
     +#
     +# Copyright(c) Qualcomm Innovation Center, Inc. All Rights Reserved.
    -+#
     +# SPDX-License-Identifier: GPL-2.0-or-later
     +
     +import os
    @@ tests/functional/hexagon/test_systests.py (new)
     +from qemu_test import QemuSystemTest, Asset, wait_for_console_pattern
     +
     +
    -+_TARBALL_BIN_PATH = os.path.join(
    ++_TARBALL_BIN_PATH = (
     +    "systests_standalone_package",
     +    "StandaloneSysTests_6.4.0.2_v68",
     +    "bin",
     +)
     +
    -+
     +class SysTestsStandaloneTests(QemuSystemTest):
     +    SYSTEST_TIMEOUT_SEC = 30
     +
     +    ASSET_TARBALL = Asset(
    -+        "https://github.com/qualcomm/qemu-hexagon-testing/releases/download/v0.2.9/systests_standalone.tar.gz",
    -+        "db961ea3fcc389b478b3d5c2f3bac60bec87e7f3d7efef5e58a9ae8ee78d0e40",
    ++        "https://github.com/qualcomm/qemu-hexagon-testing/releases/download/v0.2.11/systests_standalone.tar.gz",
    ++        "b5777aa65245de7710a7a08d717953c1362be7c8b60d9014c9fee8b17610ad1c",
     +    )
     +
     +    def setUp(self):
     +        super().setUp()
     +        self.archive_extract(self.ASSET_TARBALL)
    -+        self.bin_dir = os.path.join(self.workdir, _TARBALL_BIN_PATH)
    -+        self._orig_cwd = os.getcwd()
    -+        os.chdir(self.workdir)
    -+        self.addCleanup(os.chdir, self._orig_cwd)
    -+
    -+    def tearDown(self):
    -+        if hasattr(self, "_orig_cwd"):
    -+            os.chdir(self._orig_cwd)
    -+        super().tearDown()
     +
     +    def binary(self, name):
    -+        """Return the full path to binary *name* inside bin_dir."""
    -+        return os.path.join(self.bin_dir, name)
    ++        """Return the full path to binary *name* inside bin dir."""
    ++        path = self.scratch_file(*_TARBALL_BIN_PATH, name)
    ++        self.assertTrue(os.path.exists(path))
    ++        return path
     +
     +    def run_exit_zero(self, binary_name, *extra_args, machine="V66G_1024"):
     +        """Launch *binary_name* and assert it exits with code 0.
     +
    -+        :param binary_name: name of the binary inside bin_dir.
    ++        :param binary_name: name of the binary inside bin dir.
     +        :param extra_args: optional pairs of (flag, value) strings passed
     +            to set_vm_arg(), e.g. ('-append', 'myarg').
     +        :param machine: QEMU machine type (default "V66G_1024").
    @@ tests/functional/hexagon/test_systests.py (new)
     +                            machine="V66G_1024"):
     +        """Launch *binary_name* and wait for *pattern* on the semihosting console.
     +
    -+        :param binary_name: name of the binary inside bin_dir.
    ++        :param binary_name: name of the binary inside bin dir.
     +        :param pattern: string pattern to wait for via wait_for_console_pattern.
     +        :param extra_args: optional pairs of (flag, value) strings passed
     +            to set_vm_arg(), e.g. ('-append', 'myarg').
    @@ tests/functional/hexagon/test_systests.py (new)
     +
     +    def test_fopen(self):
     +        """fopen reads a file passed via --append and verifies its contents."""
    -+        with open(os.path.join(self.workdir, "dummy.so"), "w") as f:
    ++        import tempfile
    ++        # The fopen binary has a short cmdline buffer; use a short path.
    ++        dummy = os.path.join(tempfile.gettempdir(), "qemu_fopen_test.so")
    ++        with open(dummy, "w") as f:
     +            f.write("valid\n")
    -+        self.run_exit_zero("fopen", "-append", "dummy.so")
    ++        self.run_exit_zero("fopen", "-append", dummy)
     +
     +    def test_ftrunc(self):
     +        """ftrunc truncates _testfile_ftrunc from 6 bytes to 1 byte."""
    -+        ftrunc_path = os.path.join(self.workdir, "_testfile_ftrunc")
    ++        ftrunc_path = self.scratch_file("_testfile_ftrunc")
     +        with open(ftrunc_path, "w") as f:
     +            f.write("valid\n")
     +        # Sleep 1 s so mtime change is observable
     +        time.sleep(1)
    -+        self.run_exit_zero("ftrunc")
    -+        self.assertEqual(
    -+            os.path.getsize(ftrunc_path),
    -+            1,
    -+            "_testfile_ftrunc should be 1 byte after ftrunc",
    -+        )
    -+
    -+    def test_dirent(self):
    -+        """dirent lists a directory passed via --append; output must be
    -+        '. .. fileA fileB'."""
    -+        dirent_dir = os.path.join(self.workdir, "_dirent_testdir")
    -+        os.makedirs(dirent_dir, exist_ok=True)
    -+        open(os.path.join(dirent_dir, "fileA"), "w").close()
    -+        open(os.path.join(dirent_dir, "fileB"), "w").close()
    -+        self.run_console_pattern(
    -+            "dirent", ". .. fileA fileB", "-append", "_dirent_testdir"
    -+        )
    ++        self.run_exit_zero("ftrunc", "-append", ftrunc_path)
    ++        self.assertEqual(os.path.getsize(ftrunc_path), 1,
    ++                         "_testfile_ftrunc should be 1 byte after ftrunc")
     +
     +    def test_access(self):
     +        """access checks R_OK|W_OK on _testfile_access."""
    -+        with open(os.path.join(self.workdir, "_testfile_access"), "w") as f:
    ++        testfile = self.scratch_file("_testfile_access")
    ++        with open(testfile, "w") as f:
     +            f.write("valid\n")
    -+        self.run_exit_zero("access")
    ++        self.run_exit_zero("access", "-append", testfile)
     +
     +    def test_semihost(self):
    -+        semihost_dir = os.path.join(self.workdir, "_semihost_dir")
    -+        os.makedirs(semihost_dir, exist_ok=True)
    -+        open(os.path.join(semihost_dir, "fileA"), "w").close()
    -+        open(os.path.join(semihost_dir, "fileB"), "w").close()
     +        self.run_console_pattern("semihost", "PASS", "-append", "arg1", "arg2")
     +
     +if __name__ == "__main__":
-- 
2.37.2