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
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
© 2016 - 2026 Red Hat, Inc.