[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 37/68] target/arm/arm-semi: Implement support for semihosting feat
From: |
Peter Maydell |
Subject: |
[PULL 37/68] target/arm/arm-semi: Implement support for semihosting feature detection |
Date: |
Mon, 14 Oct 2019 17:03:33 +0100 |
Version 2.0 of the semihosting specification added support for
allowing a guest to detect whether the implementation supported
particular features. This works by the guest opening a magic
file ":semihosting-features", which contains a fixed set of
data with some magic numbers followed by a sequence of bytes
with feature flags. The file is expected to behave sensibly
for the various semihosting calls which operate on files
(SYS_FLEN, SYS_SEEK, etc).
Implement this as another kind of guest FD using our function
table dispatch mechanism. Initially we report no extended
features, so we have just one feature flag byte which is zero.
Signed-off-by: Peter Maydell <address@hidden>
Reviewed-by: Alex Bennée <address@hidden>
Message-id: address@hidden
---
target/arm/arm-semi.c | 109 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 108 insertions(+), 1 deletion(-)
diff --git a/target/arm/arm-semi.c b/target/arm/arm-semi.c
index 87c911f0187..57491740d73 100644
--- a/target/arm/arm-semi.c
+++ b/target/arm/arm-semi.c
@@ -110,6 +110,7 @@ typedef enum GuestFDType {
GuestFDUnused = 0,
GuestFDHost = 1,
GuestFDGDB = 2,
+ GuestFDFeatureFile = 3,
} GuestFDType;
/*
@@ -118,7 +119,10 @@ typedef enum GuestFDType {
*/
typedef struct GuestFD {
GuestFDType type;
- int hostfd;
+ union {
+ int hostfd;
+ target_ulong featurefile_offset;
+ };
} GuestFD;
static GArray *guestfd_array;
@@ -504,6 +508,89 @@ static uint32_t gdb_flenfn(ARMCPU *cpu, GuestFD *gf)
gf->hostfd, arm_flen_buf(cpu));
}
+#define SHFB_MAGIC_0 0x53
+#define SHFB_MAGIC_1 0x48
+#define SHFB_MAGIC_2 0x46
+#define SHFB_MAGIC_3 0x42
+
+static const uint8_t featurefile_data[] = {
+ SHFB_MAGIC_0,
+ SHFB_MAGIC_1,
+ SHFB_MAGIC_2,
+ SHFB_MAGIC_3,
+ 0, /* Feature byte 0 */
+};
+
+static void init_featurefile_guestfd(int guestfd)
+{
+ GuestFD *gf = do_get_guestfd(guestfd);
+
+ assert(gf);
+ gf->type = GuestFDFeatureFile;
+ gf->featurefile_offset = 0;
+}
+
+static uint32_t featurefile_closefn(ARMCPU *cpu, GuestFD *gf)
+{
+ /* Nothing to do */
+ return 0;
+}
+
+static uint32_t featurefile_writefn(ARMCPU *cpu, GuestFD *gf,
+ target_ulong buf, uint32_t len)
+{
+ /* This fd can never be open for writing */
+ CPUARMState *env = &cpu->env;
+
+ errno = EBADF;
+ return set_swi_errno(env, -1);
+}
+
+static uint32_t featurefile_readfn(ARMCPU *cpu, GuestFD *gf,
+ target_ulong buf, uint32_t len)
+{
+ uint32_t i;
+#ifndef CONFIG_USER_ONLY
+ CPUARMState *env = &cpu->env;
+#endif
+ char *s;
+
+ s = lock_user(VERIFY_WRITE, buf, len, 0);
+ if (!s) {
+ return len;
+ }
+
+ for (i = 0; i < len; i++) {
+ if (gf->featurefile_offset >= sizeof(featurefile_data)) {
+ break;
+ }
+ s[i] = featurefile_data[gf->featurefile_offset];
+ gf->featurefile_offset++;
+ }
+
+ unlock_user(s, buf, len);
+
+ /* Return number of bytes not read */
+ return len - i;
+}
+
+static uint32_t featurefile_isattyfn(ARMCPU *cpu, GuestFD *gf)
+{
+ return 0;
+}
+
+static uint32_t featurefile_seekfn(ARMCPU *cpu, GuestFD *gf,
+ target_ulong offset)
+{
+ gf->featurefile_offset = offset;
+ return 0;
+}
+
+static uint32_t featurefile_flenfn(ARMCPU *cpu, GuestFD *gf)
+{
+ return sizeof(featurefile_data);
+}
+
typedef struct GuestFDFunctions {
sys_closefn *closefn;
sys_writefn *writefn;
@@ -530,6 +617,14 @@ static const GuestFDFunctions guestfd_fns[] = {
.seekfn = gdb_seekfn,
.flenfn = gdb_flenfn,
},
+ [GuestFDFeatureFile] = {
+ .closefn = featurefile_closefn,
+ .writefn = featurefile_writefn,
+ .readfn = featurefile_readfn,
+ .isattyfn = featurefile_isattyfn,
+ .seekfn = featurefile_seekfn,
+ .flenfn = featurefile_flenfn,
+ },
};
/* Read the input value from the argument block; fail the semihosting
@@ -616,6 +711,18 @@ target_ulong do_arm_semihosting(CPUARMState *env)
unlock_user(s, arg0, 0);
return guestfd;
}
+ if (strcmp(s, ":semihosting-features") == 0) {
+ unlock_user(s, arg0, 0);
+ /* We must fail opens for modes other than 0 ('r') or 1 ('rb') */
+ if (arg1 != 0 && arg1 != 1) {
+ dealloc_guestfd(guestfd);
+ errno = EACCES;
+ return set_swi_errno(env, -1);
+ }
+ init_featurefile_guestfd(guestfd);
+ return guestfd;
+ }
+
if (use_gdb_syscalls()) {
arm_semi_open_guestfd = guestfd;
ret = arm_gdb_syscall(cpu, arm_semi_open_cb, "open,%s,%x,1a4",
arg0,
--
2.20.1
- [PULL 27/68] target/arm/arm-semi: Correct comment about gdb syscall races, (continued)
- [PULL 27/68] target/arm/arm-semi: Correct comment about gdb syscall races, Peter Maydell, 2019/10/14
- [PULL 30/68] target/arm/arm-semi: Use set_swi_errno() in gdbstub callback functions, Peter Maydell, 2019/10/14
- [PULL 28/68] target/arm/arm-semi: Make semihosting code hand out its own file descriptors, Peter Maydell, 2019/10/14
- [PULL 29/68] target/arm/arm-semi: Restrict use of TaskState*, Peter Maydell, 2019/10/14
- [PULL 31/68] target/arm/arm-semi: Factor out implementation of SYS_CLOSE, Peter Maydell, 2019/10/14
- [PULL 32/68] target/arm/arm-semi: Factor out implementation of SYS_WRITE, Peter Maydell, 2019/10/14
- [PULL 33/68] target/arm/arm-semi: Factor out implementation of SYS_READ, Peter Maydell, 2019/10/14
- [PULL 34/68] target/arm/arm-semi: Factor out implementation of SYS_ISTTY, Peter Maydell, 2019/10/14
- [PULL 35/68] target/arm/arm-semi: Factor out implementation of SYS_SEEK, Peter Maydell, 2019/10/14
- [PULL 36/68] target/arm/arm-semi: Factor out implementation of SYS_FLEN, Peter Maydell, 2019/10/14
- [PULL 37/68] target/arm/arm-semi: Implement support for semihosting feature detection,
Peter Maydell <=
- [PULL 38/68] target/arm/arm-semi: Implement SH_EXT_EXIT_EXTENDED extension, Peter Maydell, 2019/10/14
- [PULL 39/68] target/arm/arm-semi: Implement SH_EXT_STDOUT_STDERR extension, Peter Maydell, 2019/10/14
- [PULL 40/68] aspeed/wdt: Check correct register for clock source, Peter Maydell, 2019/10/14
- [PULL 41/68] hw/sd/aspeed_sdhci: New device, Peter Maydell, 2019/10/14
- [PULL 44/68] aspeed/timer: Add support for control register 3, Peter Maydell, 2019/10/14
- [PULL 42/68] hw: aspeed_scu: Add AST2600 support, Peter Maydell, 2019/10/14
- [PULL 43/68] aspeed/timer: Introduce an object class per SoC, Peter Maydell, 2019/10/14
- [PULL 45/68] aspeed/timer: Add AST2600 support, Peter Maydell, 2019/10/14
- [PULL 46/68] aspeed/timer: Add support for IRQ status register on the AST2600, Peter Maydell, 2019/10/14
- [PULL 47/68] aspeed/sdmc: Introduce an object class per SoC, Peter Maydell, 2019/10/14