* [PATCH 0/6] TriCore Semihosting
@ 2023-10-15 20:59 Bastian Koppelmann
2023-10-15 20:59 ` [PATCH 1/6] target/tricore: Add semihosting stub Bastian Koppelmann
` (5 more replies)
0 siblings, 6 replies; 8+ messages in thread
From: Bastian Koppelmann @ 2023-10-15 20:59 UTC (permalink / raw)
To: qemu-devel; +Cc: kbastian
Hi,
this patch series implements semihosting as done in the golden Infineon
simulator 'TSIM'. 'TSIM' supports different semihosting variants, specific to
various toolchain vendors. Only the GNU toolchain with Newlib [1] is freely
available, thus I only implemented semihosting for GNU. This port of Newlib is
also available in the 'debian-tricore-cross.docker' image.
To build and run a binary with semihosting, one only has to link against libos, i.e.
tricore-gcc test.c -los -o test.elf
qemu-system-tricore -M tricore_testboard -semihosting -nographic -kernel test.elf
Cheers,
Bastian
[1] https://github.com/bkoppelmann/package_940/tree/main/newlib/libgloss/tricore
Bastian Koppelmann (6):
target/tricore: Add semihosting stub
target/tricore: Add read and write semihosting calls
target/tricore: Add lseek semihosting call
target/tricore: Add close semihosting call
target/tricore: Add open and creat semihosting calls
target/tricore: Enable semihosting
configs/devices/tricore-softmmu/default.mak | 1 +
docs/about/emulation.rst | 3 +
qemu-options.hx | 3 +-
target/tricore/helper.h | 1 +
target/tricore/meson.build | 1 +
target/tricore/translate.c | 13 +-
target/tricore/tricore-semi.c | 380 ++++++++++++++++++++
7 files changed, 399 insertions(+), 3 deletions(-)
create mode 100644 target/tricore/tricore-semi.c
--
2.42.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/6] target/tricore: Add semihosting stub
2023-10-15 20:59 [PATCH 0/6] TriCore Semihosting Bastian Koppelmann
@ 2023-10-15 20:59 ` Bastian Koppelmann
2023-10-15 20:59 ` [PATCH 2/6] target/tricore: Add read and write semihosting calls Bastian Koppelmann
` (4 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Bastian Koppelmann @ 2023-10-15 20:59 UTC (permalink / raw)
To: qemu-devel; +Cc: kbastian
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
---
target/tricore/helper.h | 1 +
target/tricore/meson.build | 1 +
target/tricore/tricore-semi.c | 197 ++++++++++++++++++++++++++++++++++
3 files changed, 199 insertions(+)
create mode 100644 target/tricore/tricore-semi.c
diff --git a/target/tricore/helper.h b/target/tricore/helper.h
index 1d97d078b0..587de1e06f 100644
--- a/target/tricore/helper.h
+++ b/target/tricore/helper.h
@@ -160,3 +160,4 @@ DEF_HELPER_2(psw_write, void, env, i32)
DEF_HELPER_1(psw_read, i32, env)
/* Exceptions */
DEF_HELPER_3(raise_exception_sync, noreturn, env, i32, i32)
+DEF_HELPER_2(tricore_semihost, void, env, i32)
diff --git a/target/tricore/meson.build b/target/tricore/meson.build
index 45f49f0128..6cfc9355b7 100644
--- a/target/tricore/meson.build
+++ b/target/tricore/meson.build
@@ -6,6 +6,7 @@ tricore_ss.add(files(
'op_helper.c',
'translate.c',
'gdbstub.c',
+ 'tricore-semi.c',
))
tricore_ss.add(zlib)
diff --git a/target/tricore/tricore-semi.c b/target/tricore/tricore-semi.c
new file mode 100644
index 0000000000..27e1bdc59d
--- /dev/null
+++ b/target/tricore/tricore-semi.c
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2023 Bastian Koppelmann
+ *
+ * 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.1 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 "qemu/osdep.h"
+#include "cpu.h"
+#include "exec/cpu_ldst.h"
+#include "exec/helper-proto.h"
+#include "exec/helper-gen.h"
+#include "qemu/log.h"
+
+enum {
+ SYS__OPEN = 0x01,
+ SYS__CLOSE = 0x02,
+ SYS__LSEEK = 0x03,
+ SYS__READ = 0x04,
+ SYS__WRITE = 0x05,
+ SYS__CREAT = 0x06,
+ SYS__UNLINK = 0x07,
+ SYS__STAT = 0x08,
+ SYS__FSTAT = 0x09,
+ SYS__GETTIME = 0x0a,
+};
+
+enum {
+ TARGET_EPERM = 1,
+ TARGET_ENOENT = 2,
+ TARGET_ESRCH = 3,
+ TARGET_EINTR = 4,
+ TARGET_EIO = 5,
+ TARGET_ENXIO = 6,
+ TARGET_E2BIG = 7,
+ TARGET_ENOEXEC = 8,
+ TARGET_EBADF = 9,
+ TARGET_ECHILD = 10,
+ TARGET_EAGAIN = 11,
+ TARGET_ENOMEM = 12,
+ TARGET_EACCES = 13,
+ TARGET_EFAULT = 14,
+ TARGET_ENOTBLK = 15,
+ TARGET_EBUSY = 16,
+ TARGET_EEXIST = 17,
+ TARGET_EXDEV = 18,
+ TARGET_ENODEV = 19,
+ TARGET_ENOTDIR = 20,
+ TARGET_EISDIR = 21,
+ TARGET_EINVAL = 22,
+ TARGET_ENFILE = 23,
+ TARGET_EMFILE = 24,
+ TARGET_ENOTTY = 25,
+ TARGET_ETXTBSY = 26,
+ TARGET_EFBIG = 27,
+ TARGET_ENOSPC = 28,
+ TARGET_ESPIPE = 29,
+ TARGET_EROFS = 30,
+ TARGET_EMLINK = 31,
+ TARGET_EPIPE = 32,
+ TARGET_ENOSYS = 88,
+ TARGET_ENOTEMPTY = 90,
+ TARGET_ENAMETOOLONG = 9
+};
+
+static int
+tricore_vio_errno_h2g(int host_errno)
+{
+ switch (host_errno) {
+ case EPERM:
+ return TARGET_EPERM;
+ case ENOENT:
+ return TARGET_ENOENT;
+ case ESRCH:
+ return TARGET_ESRCH;
+ case EINTR:
+ return TARGET_EINTR;
+ case EIO:
+ return TARGET_EIO;
+ case ENXIO:
+ return TARGET_ENXIO;
+ case E2BIG:
+ return TARGET_E2BIG;
+ case ENOEXEC:
+ return TARGET_ENOEXEC;
+ case EBADF:
+ return TARGET_EBADF;
+ case ECHILD:
+ return TARGET_ECHILD;
+ case EAGAIN:
+ return TARGET_EAGAIN;
+ case ENOMEM:
+ return TARGET_ENOMEM;
+ case EACCES:
+ return TARGET_EACCES;
+ case EFAULT:
+ return TARGET_EFAULT;
+ case ENOTBLK:
+ return TARGET_ENOTBLK;
+ case EBUSY:
+ return TARGET_EBUSY;
+ case EEXIST:
+ return TARGET_EEXIST;
+ case EXDEV:
+ return TARGET_EXDEV;
+ case ENODEV:
+ return TARGET_ENODEV;
+ case ENOTDIR:
+ return TARGET_ENOTDIR;
+ case EISDIR:
+ return TARGET_EISDIR;
+ case EINVAL:
+ return TARGET_EINVAL;
+ case ENFILE:
+ return TARGET_ENFILE;
+ case EMFILE:
+ return TARGET_EMFILE;
+ case ENOTTY:
+ return TARGET_ENOTTY;
+ case ETXTBSY:
+ return TARGET_ETXTBSY;
+ case EFBIG:
+ return TARGET_EFBIG;
+ case ENOSPC:
+ return TARGET_ENOSPC;
+ case ESPIPE:
+ return TARGET_ESPIPE;
+ case EROFS:
+ return TARGET_EROFS;
+ case EMLINK:
+ return TARGET_EMLINK;
+ case EPIPE:
+ return TARGET_EPIPE;
+ case ENOSYS:
+ return TARGET_ENOSYS;
+ case ENOTEMPTY:
+ return TARGET_ENOTEMPTY;
+ case ENAMETOOLONG:
+ return TARGET_ENAMETOOLONG;
+ default:
+ return host_errno;
+ }
+}
+
+/*
+ * Set return and errno values; the ___virtio function takes care
+ * that the target's errno variable gets updated from %d12, and
+ * eventually moves %d11 to the return register (%d2).
+ */
+static void tricore_vio_set_result(CPUTriCoreState *env, int retval,
+ int host_errno)
+{
+ env->gpr_d[11] = retval;
+ env->gpr_d[12] = tricore_vio_errno_h2g(host_errno);
+}
+
+
+#define TRICORE_VIO_MARKER 0x6f69765f /* "_vio" */
+#define TRICORE_VIO_EXIT_MARKER 0xE60
+#define TRICORE_VIO_SIMTEST_SUCC 0x900d
+void helper_tricore_semihost(CPUTriCoreState *env, uint32_t pc)
+{
+ int syscall;
+ uint32_t marker = cpu_ldl_code(env, pc - 4);
+
+ /* check for exit marker */
+ if (extract32(marker, 0, 12) == TRICORE_VIO_EXIT_MARKER) {
+ if (env->gpr_a[14] == TRICORE_VIO_SIMTEST_SUCC) {
+ exit(0);
+ } else {
+ exit(env->gpr_a[14]);
+ }
+ }
+
+ if (marker != TRICORE_VIO_MARKER) {
+ return;
+ }
+
+ syscall = (int)env->gpr_d[12];
+ switch (syscall) {
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR, "%s(%d): not implemented\n", __func__,
+ syscall);
+ tricore_vio_set_result(env, -1, ENOSYS);
+ break;
+ }
+}
--
2.42.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/6] target/tricore: Add read and write semihosting calls
2023-10-15 20:59 [PATCH 0/6] TriCore Semihosting Bastian Koppelmann
2023-10-15 20:59 ` [PATCH 1/6] target/tricore: Add semihosting stub Bastian Koppelmann
@ 2023-10-15 20:59 ` Bastian Koppelmann
2023-10-15 23:48 ` Richard Henderson
2023-10-15 20:59 ` [PATCH 3/6] target/tricore: Add lseek semihosting call Bastian Koppelmann
` (3 subsequent siblings)
5 siblings, 1 reply; 8+ messages in thread
From: Bastian Koppelmann @ 2023-10-15 20:59 UTC (permalink / raw)
To: qemu-devel; +Cc: kbastian
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
---
target/tricore/tricore-semi.c | 52 +++++++++++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
diff --git a/target/tricore/tricore-semi.c b/target/tricore/tricore-semi.c
index 27e1bdc59d..ccbeae4bc0 100644
--- a/target/tricore/tricore-semi.c
+++ b/target/tricore/tricore-semi.c
@@ -164,6 +164,52 @@ static void tricore_vio_set_result(CPUTriCoreState *env, int retval,
env->gpr_d[12] = tricore_vio_errno_h2g(host_errno);
}
+static void tricore_vio_readwrite(CPUTriCoreState *env, bool is_write)
+{
+ CPUState *cs = env_cpu(env);
+ hwaddr paddr, sz;
+ uint32_t page_left, io_sz, vaddr;
+ size_t count;
+ ssize_t ret = 0;
+
+ int fd = env->gpr_d[4];
+ vaddr = env->gpr_a[4];
+ count = env->gpr_d[5];
+
+ while (count > 0) {
+ paddr = cpu_get_phys_page_debug(cs, vaddr);
+ page_left = TARGET_PAGE_SIZE - (vaddr & (TARGET_PAGE_SIZE - 1));
+ io_sz = page_left < count ? page_left : count;
+ sz = io_sz;
+ void *buf = cpu_physical_memory_map(paddr, &sz, true);
+
+ if (buf) {
+ vaddr += io_sz;
+ count -= io_sz;
+ ret = is_write ?
+ write(fd, buf, io_sz) :
+ read(fd, buf, io_sz);
+ if (ret == -1) {
+ ret = 0;
+ tricore_vio_set_result(env, ret, EINVAL);
+ } else {
+ tricore_vio_set_result(env, ret, errno);
+ }
+ }
+ cpu_physical_memory_unmap(buf, sz, !is_write, ret);
+ }
+}
+
+static void tricore_vio_read(CPUTriCoreState *env)
+{
+ tricore_vio_readwrite(env, false);
+}
+
+static void tricore_vio_write(CPUTriCoreState *env)
+{
+ tricore_vio_readwrite(env, true);
+}
+
#define TRICORE_VIO_MARKER 0x6f69765f /* "_vio" */
#define TRICORE_VIO_EXIT_MARKER 0xE60
@@ -188,6 +234,12 @@ void helper_tricore_semihost(CPUTriCoreState *env, uint32_t pc)
syscall = (int)env->gpr_d[12];
switch (syscall) {
+ case SYS__READ:
+ tricore_vio_read(env);
+ break;
+ case SYS__WRITE:
+ tricore_vio_write(env);
+ break;
default:
qemu_log_mask(LOG_GUEST_ERROR, "%s(%d): not implemented\n", __func__,
syscall);
--
2.42.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 3/6] target/tricore: Add lseek semihosting call
2023-10-15 20:59 [PATCH 0/6] TriCore Semihosting Bastian Koppelmann
2023-10-15 20:59 ` [PATCH 1/6] target/tricore: Add semihosting stub Bastian Koppelmann
2023-10-15 20:59 ` [PATCH 2/6] target/tricore: Add read and write semihosting calls Bastian Koppelmann
@ 2023-10-15 20:59 ` Bastian Koppelmann
2023-10-15 20:59 ` [PATCH 4/6] target/tricore: Add close " Bastian Koppelmann
` (2 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Bastian Koppelmann @ 2023-10-15 20:59 UTC (permalink / raw)
To: qemu-devel; +Cc: kbastian
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
---
target/tricore/tricore-semi.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/target/tricore/tricore-semi.c b/target/tricore/tricore-semi.c
index ccbeae4bc0..6f321391ef 100644
--- a/target/tricore/tricore-semi.c
+++ b/target/tricore/tricore-semi.c
@@ -164,6 +164,17 @@ static void tricore_vio_set_result(CPUTriCoreState *env, int retval,
env->gpr_d[12] = tricore_vio_errno_h2g(host_errno);
}
+
+static void tricore_vio_lseek(CPUTriCoreState *env)
+{
+ int fd = env->gpr_d[4];
+ off_t offset = env->gpr_d[5];
+ int whence = env->gpr_d[6];
+
+ off_t res = lseek(fd, offset, whence);
+ tricore_vio_set_result(env, res, errno);
+}
+
static void tricore_vio_readwrite(CPUTriCoreState *env, bool is_write)
{
CPUState *cs = env_cpu(env);
@@ -234,6 +245,9 @@ void helper_tricore_semihost(CPUTriCoreState *env, uint32_t pc)
syscall = (int)env->gpr_d[12];
switch (syscall) {
+ case SYS__LSEEK:
+ tricore_vio_lseek(env);
+ break;
case SYS__READ:
tricore_vio_read(env);
break;
--
2.42.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 4/6] target/tricore: Add close semihosting call
2023-10-15 20:59 [PATCH 0/6] TriCore Semihosting Bastian Koppelmann
` (2 preceding siblings ...)
2023-10-15 20:59 ` [PATCH 3/6] target/tricore: Add lseek semihosting call Bastian Koppelmann
@ 2023-10-15 20:59 ` Bastian Koppelmann
2023-10-15 20:59 ` [PATCH 5/6] target/tricore: Add open and creat semihosting calls Bastian Koppelmann
2023-10-15 20:59 ` [PATCH 6/6] target/tricore: Enable semihosting Bastian Koppelmann
5 siblings, 0 replies; 8+ messages in thread
From: Bastian Koppelmann @ 2023-10-15 20:59 UTC (permalink / raw)
To: qemu-devel; +Cc: kbastian
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
---
target/tricore/tricore-semi.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/target/tricore/tricore-semi.c b/target/tricore/tricore-semi.c
index 6f321391ef..2188ceeed0 100644
--- a/target/tricore/tricore-semi.c
+++ b/target/tricore/tricore-semi.c
@@ -164,6 +164,19 @@ static void tricore_vio_set_result(CPUTriCoreState *env, int retval,
env->gpr_d[12] = tricore_vio_errno_h2g(host_errno);
}
+static void tricore_vio_close(CPUTriCoreState *env)
+{
+ int fd = env->gpr_d[4];
+ int res = 0;
+ int err = 0;
+
+ if (fd > 2) {
+ res = close(fd);
+ err = errno;
+ }
+
+ tricore_vio_set_result(env, res, err);
+}
static void tricore_vio_lseek(CPUTriCoreState *env)
{
@@ -245,6 +258,9 @@ void helper_tricore_semihost(CPUTriCoreState *env, uint32_t pc)
syscall = (int)env->gpr_d[12];
switch (syscall) {
+ case SYS__CLOSE:
+ tricore_vio_close(env);
+ break;
case SYS__LSEEK:
tricore_vio_lseek(env);
break;
--
2.42.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 5/6] target/tricore: Add open and creat semihosting calls
2023-10-15 20:59 [PATCH 0/6] TriCore Semihosting Bastian Koppelmann
` (3 preceding siblings ...)
2023-10-15 20:59 ` [PATCH 4/6] target/tricore: Add close " Bastian Koppelmann
@ 2023-10-15 20:59 ` Bastian Koppelmann
2023-10-15 20:59 ` [PATCH 6/6] target/tricore: Enable semihosting Bastian Koppelmann
5 siblings, 0 replies; 8+ messages in thread
From: Bastian Koppelmann @ 2023-10-15 20:59 UTC (permalink / raw)
To: qemu-devel; +Cc: kbastian
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
---
target/tricore/tricore-semi.c | 101 ++++++++++++++++++++++++++++++++++
1 file changed, 101 insertions(+)
diff --git a/target/tricore/tricore-semi.c b/target/tricore/tricore-semi.c
index 2188ceeed0..34e546c3bf 100644
--- a/target/tricore/tricore-semi.c
+++ b/target/tricore/tricore-semi.c
@@ -73,6 +73,21 @@ enum {
TARGET_ENAMETOOLONG = 9
};
+enum {
+ TARGET_O_RDONLY = 0x00001,
+ TARGET_O_WRONLY = 0x00002,
+ TARGET_O_RDWR = 0x00003,
+ TARGET_O_APPEND = 0x00008,
+ TARGET_O_CREAT = 0x00200,
+ TARGET_O_TRUNC = 0x00400,
+ TARGET_O_EXCL = 0x00800,
+ TARGET_O_NDELAY = 0x01000,
+ TARGET_O_SYNC = 0x02000,
+ TARGET_O_NONBLOCK = 0x04000,
+ TARGET_O_NOCTTY = 0x08000,
+ TARGET_O_BINARY = 0x10000,
+};
+
static int
tricore_vio_errno_h2g(int host_errno)
{
@@ -152,6 +167,49 @@ tricore_vio_errno_h2g(int host_errno)
}
}
+static int tricore_vio_open_flags_g2h(int guest_flags)
+{
+ int host_flags = guest_flags & 0x3;
+ if (guest_flags & TARGET_O_APPEND) {
+ host_flags |= O_APPEND;
+ }
+
+ if (guest_flags & TARGET_O_CREAT) {
+ host_flags |= O_CREAT;
+ }
+
+ if (guest_flags & TARGET_O_TRUNC) {
+ host_flags |= O_TRUNC;
+ }
+
+ if (guest_flags & TARGET_O_EXCL) {
+ host_flags |= O_EXCL;
+ }
+
+ if (guest_flags & TARGET_O_NDELAY) {
+ host_flags |= O_NDELAY;
+ }
+
+ if (guest_flags & TARGET_O_SYNC) {
+ host_flags |= O_SYNC;
+ }
+
+ if (guest_flags & TARGET_O_NONBLOCK) {
+ host_flags |= O_NONBLOCK;
+ }
+
+ if (guest_flags & TARGET_O_NOCTTY) {
+ host_flags |= O_NOCTTY;
+ }
+#ifdef O_BINARY
+ if (guest_flags & TARGET_O_BINARY) {
+ host_flags |= O_BINARY;
+ }
+#endif
+
+ return host_flags;
+}
+
/*
* Set return and errno values; the ___virtio function takes care
* that the target's errno variable gets updated from %d12, and
@@ -164,6 +222,43 @@ static void tricore_vio_set_result(CPUTriCoreState *env, int retval,
env->gpr_d[12] = tricore_vio_errno_h2g(host_errno);
}
+static void tricore_vio_opencreat(CPUTriCoreState *env, bool do_creat)
+{
+ CPUState *cs = env_cpu(env);
+ char name[1024];
+ int rc, i, res;
+ uint32_t nameptr = env->gpr_a[4];
+ for (i = 0; i < ARRAY_SIZE(name); ++i) {
+ rc = cpu_memory_rw_debug(cs, nameptr + i, (uint8_t *)name + i, 1, 0);
+ if (rc != 0 || name[i] == 0) {
+ break;
+ }
+ }
+
+ if (rc == 0 && i < ARRAY_SIZE(name)) {
+ if (do_creat) {
+ /* Infineon's TSIM hardcodes 'mode' */
+ res = creat(name, S_IROTH | S_IRUSR | S_IWUSR | S_IRGRP);
+ } else {
+ int flags = tricore_vio_open_flags_g2h(env->gpr_d[4]);
+ res = open(name, flags);
+ }
+ tricore_vio_set_result(env, res, errno);
+ } else {
+ tricore_vio_set_result(env, -1, EIO);
+ }
+}
+
+static void tricore_vio_open(CPUTriCoreState *env)
+{
+ tricore_vio_opencreat(env, false);
+}
+
+static void tricore_vio_creat(CPUTriCoreState *env)
+{
+ tricore_vio_opencreat(env, true);
+}
+
static void tricore_vio_close(CPUTriCoreState *env)
{
int fd = env->gpr_d[4];
@@ -258,6 +353,9 @@ void helper_tricore_semihost(CPUTriCoreState *env, uint32_t pc)
syscall = (int)env->gpr_d[12];
switch (syscall) {
+ case SYS__OPEN:
+ tricore_vio_open(env);
+ break;
case SYS__CLOSE:
tricore_vio_close(env);
break;
@@ -270,6 +368,9 @@ void helper_tricore_semihost(CPUTriCoreState *env, uint32_t pc)
case SYS__WRITE:
tricore_vio_write(env);
break;
+ case SYS__CREAT:
+ tricore_vio_creat(env);
+ break;
default:
qemu_log_mask(LOG_GUEST_ERROR, "%s(%d): not implemented\n", __func__,
syscall);
--
2.42.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 6/6] target/tricore: Enable semihosting
2023-10-15 20:59 [PATCH 0/6] TriCore Semihosting Bastian Koppelmann
` (4 preceding siblings ...)
2023-10-15 20:59 ` [PATCH 5/6] target/tricore: Add open and creat semihosting calls Bastian Koppelmann
@ 2023-10-15 20:59 ` Bastian Koppelmann
5 siblings, 0 replies; 8+ messages in thread
From: Bastian Koppelmann @ 2023-10-15 20:59 UTC (permalink / raw)
To: qemu-devel; +Cc: kbastian
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
---
configs/devices/tricore-softmmu/default.mak | 1 +
docs/about/emulation.rst | 3 +++
qemu-options.hx | 3 ++-
target/tricore/translate.c | 13 +++++++++++--
4 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/configs/devices/tricore-softmmu/default.mak b/configs/devices/tricore-softmmu/default.mak
index cb8fc286eb..883903073c 100644
--- a/configs/devices/tricore-softmmu/default.mak
+++ b/configs/devices/tricore-softmmu/default.mak
@@ -1,2 +1,3 @@
CONFIG_TRICORE_TESTBOARD=y
CONFIG_TRIBOARD=y
+CONFIG_SEMIHOSTING=y
diff --git a/docs/about/emulation.rst b/docs/about/emulation.rst
index 0ad0b86f0d..3ee90bd2aa 100644
--- a/docs/about/emulation.rst
+++ b/docs/about/emulation.rst
@@ -185,6 +185,9 @@ for that architecture.
* - RISC-V
- System and User-mode
- https://github.com/riscv/riscv-semihosting-spec/blob/main/riscv-semihosting-spec.adoc
+ * - TriCore
+ - System
+ - Infineon ISS syscall handling (for GNU tools)
* - Xtensa
- System
- Tensilica ISS SIMCALL
diff --git a/qemu-options.hx b/qemu-options.hx
index 54a7e94970..d7a6cb94c9 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -4816,7 +4816,8 @@ ERST
DEF("semihosting", 0, QEMU_OPTION_semihosting,
"-semihosting semihosting mode\n",
QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA |
- QEMU_ARCH_MIPS | QEMU_ARCH_NIOS2 | QEMU_ARCH_RISCV)
+ QEMU_ARCH_MIPS | QEMU_ARCH_NIOS2 | QEMU_ARCH_RISCV |
+ QEMU_ARCH_TRICORE)
SRST
``-semihosting``
Enable :ref:`Semihosting` mode (ARM, M68K, Xtensa, MIPS, Nios II, RISC-V only).
diff --git a/target/tricore/translate.c b/target/tricore/translate.c
index dd812ec0f0..1eb44c78c2 100644
--- a/target/tricore/translate.c
+++ b/target/tricore/translate.c
@@ -25,6 +25,7 @@
#include "tcg/tcg-op.h"
#include "exec/cpu_ldst.h"
#include "qemu/qemu-print.h"
+#include "semihosting/semihost.h"
#include "exec/helper-proto.h"
#include "exec/helper-gen.h"
@@ -3151,6 +3152,14 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1,
}
}
+static void gen_debug(DisasContext *ctx)
+{
+ if (semihosting_enabled(false)) {
+ gen_helper_1arg(tricore_semihost, ctx->base.pc_next);
+ } else {
+ /* raise EXCP_DEBUG */
+ }
+}
/*
* Functions for decoding instructions
@@ -3497,7 +3506,7 @@ static void decode_sr_system(DisasContext *ctx)
ctx->base.is_jmp = DISAS_EXIT;
break;
case OPC2_16_SR_DEBUG:
- /* raise EXCP_DEBUG */
+ gen_debug(ctx);
break;
case OPC2_16_SR_FRET:
gen_fret(ctx);
@@ -7926,7 +7935,7 @@ static void decode_sys_interrupts(DisasContext *ctx)
switch (op2) {
case OPC2_32_SYS_DEBUG:
- /* raise EXCP_DEBUG */
+ gen_debug(ctx);
break;
case OPC2_32_SYS_DISABLE:
if (ctx->priv == TRICORE_PRIV_SM || ctx->priv == TRICORE_PRIV_UM1) {
--
2.42.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 2/6] target/tricore: Add read and write semihosting calls
2023-10-15 20:59 ` [PATCH 2/6] target/tricore: Add read and write semihosting calls Bastian Koppelmann
@ 2023-10-15 23:48 ` Richard Henderson
0 siblings, 0 replies; 8+ messages in thread
From: Richard Henderson @ 2023-10-15 23:48 UTC (permalink / raw)
To: Bastian Koppelmann, qemu-devel
On 10/15/23 13:59, Bastian Koppelmann wrote:
> Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
> ---
> target/tricore/tricore-semi.c | 52 +++++++++++++++++++++++++++++++++++
> 1 file changed, 52 insertions(+)
>
> diff --git a/target/tricore/tricore-semi.c b/target/tricore/tricore-semi.c
> index 27e1bdc59d..ccbeae4bc0 100644
> --- a/target/tricore/tricore-semi.c
> +++ b/target/tricore/tricore-semi.c
> @@ -164,6 +164,52 @@ static void tricore_vio_set_result(CPUTriCoreState *env, int retval,
> env->gpr_d[12] = tricore_vio_errno_h2g(host_errno);
> }
>
> +static void tricore_vio_readwrite(CPUTriCoreState *env, bool is_write)
> +{
> + CPUState *cs = env_cpu(env);
> + hwaddr paddr, sz;
> + uint32_t page_left, io_sz, vaddr;
> + size_t count;
> + ssize_t ret = 0;
> +
> + int fd = env->gpr_d[4];
> + vaddr = env->gpr_a[4];
> + count = env->gpr_d[5];
> +
> + while (count > 0) {
> + paddr = cpu_get_phys_page_debug(cs, vaddr);
> + page_left = TARGET_PAGE_SIZE - (vaddr & (TARGET_PAGE_SIZE - 1));
> + io_sz = page_left < count ? page_left : count;
> + sz = io_sz;
> + void *buf = cpu_physical_memory_map(paddr, &sz, true);
> +
> + if (buf) {
> + vaddr += io_sz;
> + count -= io_sz;
> + ret = is_write ?
> + write(fd, buf, io_sz) :
> + read(fd, buf, io_sz);
You should be able to use "semihosting/syscalls.h".
Compare m68k-semi.c.
r~
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2023-10-15 23:49 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-10-15 20:59 [PATCH 0/6] TriCore Semihosting Bastian Koppelmann
2023-10-15 20:59 ` [PATCH 1/6] target/tricore: Add semihosting stub Bastian Koppelmann
2023-10-15 20:59 ` [PATCH 2/6] target/tricore: Add read and write semihosting calls Bastian Koppelmann
2023-10-15 23:48 ` Richard Henderson
2023-10-15 20:59 ` [PATCH 3/6] target/tricore: Add lseek semihosting call Bastian Koppelmann
2023-10-15 20:59 ` [PATCH 4/6] target/tricore: Add close " Bastian Koppelmann
2023-10-15 20:59 ` [PATCH 5/6] target/tricore: Add open and creat semihosting calls Bastian Koppelmann
2023-10-15 20:59 ` [PATCH 6/6] target/tricore: Enable semihosting Bastian Koppelmann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).