Thanks for spotting that. There was a config option selection that I was trying to avoid.
Will send out a v3 patch with your suggestions. On Sat, Sep 17, 2022 at 11:10 PM Sean Anderson <sean...@gmail.com> wrote: > > On 9/16/22 04:12, Kautuk Consul wrote: > > We factor out the arch-independent parts of the ARM semihosting > > implementation as a common library so that it can be shared > > with RISC-V. > > > > Signed-off-by: Kautuk Consul <kcon...@ventanamicro.com> > > --- > > arch/arm/Kconfig | 2 + > > arch/arm/lib/semihosting.c | 179 +---------------------------------- > > include/semihosting.h | 11 +++ > > lib/Kconfig | 3 + > > lib/Makefile | 2 + > > lib/semihosting.c | 186 +++++++++++++++++++++++++++++++++++++ > > 6 files changed, 205 insertions(+), 178 deletions(-) > > create mode 100644 lib/semihosting.c > > > > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig > > index 82cd456f51..81440ff7ea 100644 > > --- a/arch/arm/Kconfig > > +++ b/arch/arm/Kconfig > > @@ -415,6 +415,7 @@ config ARM_SMCCC > > > > config SEMIHOSTING > > bool "Support ARM semihosting" > > + select LIB_SEMIHOSTING > > help > > Semihosting is a method for a target to communicate with a host > > debugger. It uses special instructions which the debugger will trap > > @@ -437,6 +438,7 @@ config SEMIHOSTING_FALLBACK > > > > config SPL_SEMIHOSTING > > bool "Support ARM semihosting in SPL" > > + select LIB_SEMIHOSTING > > depends on SPL > > help > > Semihosting is a method for a target to communicate with a host > > Sorry if I wasn't clear enough last time. Both the code and these Kconfigs > should be moved to a common location. > > > diff --git a/arch/arm/lib/semihosting.c b/arch/arm/lib/semihosting.c > > index 01d652a6b8..41bc5cd62b 100644 > > --- a/arch/arm/lib/semihosting.c > > +++ b/arch/arm/lib/semihosting.c > > @@ -13,22 +13,10 @@ > > #include <log.h> > > #include <semihosting.h> > > > > -#define SYSOPEN 0x01 > > -#define SYSCLOSE 0x02 > > -#define SYSWRITEC 0x03 > > -#define SYSWRITE0 0x04 > > -#define SYSWRITE 0x05 > > -#define SYSREAD 0x06 > > -#define SYSREADC 0x07 > > -#define SYSISERROR 0x08 > > -#define SYSSEEK 0x0A > > -#define SYSFLEN 0x0C > > -#define SYSERRNO 0x13 > > - > > /* > > * Call the handler > > */ > > -static noinline long smh_trap(unsigned int sysnum, void *addr) > > +long smh_trap(unsigned int sysnum, void *addr) > > { > > register long result asm("r0"); > > #if defined(CONFIG_ARM64) > > @@ -41,168 +29,3 @@ static noinline long smh_trap(unsigned int sysnum, void > > *addr) > > #endif > > return result; > > } > > - > > -#if CONFIG_IS_ENABLED(SEMIHOSTING_FALLBACK) > > -static bool _semihosting_enabled = true; > > -static bool try_semihosting = true; > > - > > -bool semihosting_enabled(void) > > -{ > > - if (try_semihosting) { > > - smh_trap(SYSERRNO, NULL); > > - try_semihosting = false; > > - } > > - > > - return _semihosting_enabled; > > -} > > - > > -void disable_semihosting(void) > > -{ > > - _semihosting_enabled = false; > > -} > > -#endif > > - > > -/** > > - * smh_errno() - Read the host's errno > > - * > > - * This gets the value of the host's errno and negates it. The host's > > errno may > > - * or may not be set, so only call this function if a previous semihosting > > call > > - * has failed. > > - * > > - * Return: a negative error value > > - */ > > -static int smh_errno(void) > > -{ > > - long ret = smh_trap(SYSERRNO, NULL); > > - > > - if (ret > 0 && ret < INT_MAX) > > - return -ret; > > - return -EIO; > > -} > > - > > -long smh_open(const char *fname, enum smh_open_mode mode) > > -{ > > - long fd; > > - struct smh_open_s { > > - const char *fname; > > - unsigned long mode; > > - size_t len; > > - } open; > > - > > - debug("%s: file \'%s\', mode \'%u\'\n", __func__, fname, mode); > > - > > - open.fname = fname; > > - open.len = strlen(fname); > > - open.mode = mode; > > - > > - /* Open the file on the host */ > > - fd = smh_trap(SYSOPEN, &open); > > - if (fd == -1) > > - return smh_errno(); > > - return fd; > > -} > > - > > -/** > > - * struct smg_rdwr_s - Arguments for read and write > > - * @fd: A file descriptor returned from smh_open() > > - * @memp: Pointer to a buffer of memory of at least @len bytes > > - * @len: The number of bytes to read or write > > - */ > > -struct smh_rdwr_s { > > - long fd; > > - void *memp; > > - size_t len; > > -}; > > - > > -long smh_read(long fd, void *memp, size_t len) > > -{ > > - long ret; > > - struct smh_rdwr_s read; > > - > > - debug("%s: fd %ld, memp %p, len %zu\n", __func__, fd, memp, len); > > - > > - read.fd = fd; > > - read.memp = memp; > > - read.len = len; > > - > > - ret = smh_trap(SYSREAD, &read); > > - if (ret < 0) > > - return smh_errno(); > > - return len - ret; > > -} > > - > > -long smh_write(long fd, const void *memp, size_t len, ulong *written) > > -{ > > - long ret; > > - struct smh_rdwr_s write; > > - > > - debug("%s: fd %ld, memp %p, len %zu\n", __func__, fd, memp, len); > > - > > - write.fd = fd; > > - write.memp = (void *)memp; > > - write.len = len; > > - > > - ret = smh_trap(SYSWRITE, &write); > > - *written = len - ret; > > - if (ret) > > - return smh_errno(); > > - return 0; > > -} > > - > > -long smh_close(long fd) > > -{ > > - long ret; > > - > > - debug("%s: fd %ld\n", __func__, fd); > > - > > - ret = smh_trap(SYSCLOSE, &fd); > > - if (ret == -1) > > - return smh_errno(); > > - return 0; > > -} > > - > > -long smh_flen(long fd) > > -{ > > - long ret; > > - > > - debug("%s: fd %ld\n", __func__, fd); > > - > > - ret = smh_trap(SYSFLEN, &fd); > > - if (ret == -1) > > - return smh_errno(); > > - return ret; > > -} > > - > > -long smh_seek(long fd, long pos) > > -{ > > - long ret; > > - struct smh_seek_s { > > - long fd; > > - long pos; > > - } seek; > > - > > - debug("%s: fd %ld pos %ld\n", __func__, fd, pos); > > - > > - seek.fd = fd; > > - seek.pos = pos; > > - > > - ret = smh_trap(SYSSEEK, &seek); > > - if (ret) > > - return smh_errno(); > > - return 0; > > -} > > - > > -int smh_getc(void) > > -{ > > - return smh_trap(SYSREADC, NULL); > > -} > > - > > -void smh_putc(char ch) > > -{ > > - smh_trap(SYSWRITEC, &ch); > > -} > > - > > -void smh_puts(const char *s) > > -{ > > - smh_trap(SYSWRITE0, (char *)s); > > -} > > diff --git a/include/semihosting.h b/include/semihosting.h > > index f1f73464e4..f883676b91 100644 > > --- a/include/semihosting.h > > +++ b/include/semihosting.h > > @@ -17,6 +17,17 @@ > > #define SMH_T32_SVC 0xDFAB > > #define SMH_T32_HLT 0xBABC > > > > +/** > > + * semh_trap() - ARCH-specific semihosting call. > > + * > > + * Semihosting library/driver can use this function to do the > > + * actual semihosting calls. > > + * > > + * Return: Error code defined by semihosting spec. > > + */ > > + > > +long smh_trap(unsigned int sysnum, void *addr); > > + > > #if CONFIG_IS_ENABLED(SEMIHOSTING_FALLBACK) > > /** > > * semihosting_enabled() - Determine whether semihosting is supported > > diff --git a/lib/Kconfig b/lib/Kconfig > > index 6121c80dc8..286d316110 100644 > > --- a/lib/Kconfig > > +++ b/lib/Kconfig > > @@ -71,6 +71,9 @@ config HAVE_PRIVATE_LIBGCC > > config LIB_UUID > > bool > > > > +config LIB_SEMIHOSTING > > + bool > > + > > config PRINTF > > bool > > default y > > diff --git a/lib/Makefile b/lib/Makefile > > index e3deb15287..96be8fe7e9 100644 > > --- a/lib/Makefile > > +++ b/lib/Makefile > > @@ -145,6 +145,8 @@ obj-y += date.o > > obj-y += rtc-lib.o > > obj-$(CONFIG_LIB_ELF) += elf.o > > > > +obj-$(CONFIG_LIB_SEMIHOSTING) += semihosting.o > > + > > # > > # Build a fast OID lookup registry from include/linux/oid_registry.h > > # > > diff --git a/lib/semihosting.c b/lib/semihosting.c > > new file mode 100644 > > index 0000000000..831774e356 > > --- /dev/null > > +++ b/lib/semihosting.c > > @@ -0,0 +1,186 @@ > > +// SPDX-License-Identifier: GPL-2.0+ > > +/* > > + * Copyright (C) 2022 Sean Anderson <sean.ander...@seco.com> > > + * Copyright 2014 Broadcom Corporation > > + */ > > + > > +#include <common.h> > > +#include <log.h> > > +#include <semihosting.h> > > + > > +#define SYSOPEN 0x01 > > +#define SYSCLOSE 0x02 > > +#define SYSWRITEC 0x03 > > +#define SYSWRITE0 0x04 > > +#define SYSWRITE 0x05 > > +#define SYSREAD 0x06 > > +#define SYSREADC 0x07 > > +#define SYSISERROR 0x08 > > +#define SYSSEEK 0x0A > > +#define SYSFLEN 0x0C > > +#define SYSERRNO 0x13 > > + > > +#if CONFIG_IS_ENABLED(SEMIHOSTING_FALLBACK) > > +static bool _semihosting_enabled = true; > > +static bool try_semihosting = true; > > + > > +bool semihosting_enabled(void) > > +{ > > + if (try_semihosting) { > > + smh_trap(SYSERRNO, NULL); > > + try_semihosting = false; > > + } > > + > > + return _semihosting_enabled; > > +} > > + > > +void disable_semihosting(void) > > +{ > > + _semihosting_enabled = false; > > +} > > +#endif > > + > > +/** > > + * smh_errno() - Read the host's errno > > + * > > + * This gets the value of the host's errno and negates it. The host's > > errno may > > + * or may not be set, so only call this function if a previous semihosting > > call > > + * has failed. > > + * > > + * Return: a negative error value > > + */ > > +static int smh_errno(void) > > +{ > > + long ret = smh_trap(SYSERRNO, NULL); > > + > > + if (ret > 0 && ret < INT_MAX) > > + return -ret; > > + return -EIO; > > +} > > + > > +long smh_open(const char *fname, enum smh_open_mode mode) > > +{ > > + long fd; > > + struct smh_open_s { > > + const char *fname; > > + unsigned long mode; > > + size_t len; > > + } open; > > + > > + debug("%s: file \'%s\', mode \'%u\'\n", __func__, fname, mode); > > + > > + open.fname = fname; > > + open.len = strlen(fname); > > + open.mode = mode; > > + > > + /* Open the file on the host */ > > + fd = smh_trap(SYSOPEN, &open); > > + if (fd == -1) > > + return smh_errno(); > > + return fd; > > +} > > + > > +/** > > + * struct smg_rdwr_s - Arguments for read and write > > + * @fd: A file descriptor returned from smh_open() > > + * @memp: Pointer to a buffer of memory of at least @len bytes > > + * @len: The number of bytes to read or write > > + */ > > +struct smh_rdwr_s { > > + long fd; > > + void *memp; > > + size_t len; > > +}; > > + > > +long smh_read(long fd, void *memp, size_t len) > > +{ > > + long ret; > > + struct smh_rdwr_s read; > > + > > + debug("%s: fd %ld, memp %p, len %zu\n", __func__, fd, memp, len); > > + > > + read.fd = fd; > > + read.memp = memp; > > + read.len = len; > > + > > + ret = smh_trap(SYSREAD, &read); > > + if (ret < 0) > > + return smh_errno(); > > + return len - ret; > > +} > > + > > +long smh_write(long fd, const void *memp, size_t len, ulong *written) > > +{ > > + long ret; > > + struct smh_rdwr_s write; > > + > > + debug("%s: fd %ld, memp %p, len %zu\n", __func__, fd, memp, len); > > + > > + write.fd = fd; > > + write.memp = (void *)memp; > > + write.len = len; > > + > > + ret = smh_trap(SYSWRITE, &write); > > + *written = len - ret; > > + if (ret) > > + return smh_errno(); > > + return 0; > > +} > > + > > +long smh_close(long fd) > > +{ > > + long ret; > > + > > + debug("%s: fd %ld\n", __func__, fd); > > + > > + ret = smh_trap(SYSCLOSE, &fd); > > + if (ret == -1) > > + return smh_errno(); > > + return 0; > > +} > > + > > +long smh_flen(long fd) > > +{ > > + long ret; > > + > > + debug("%s: fd %ld\n", __func__, fd); > > + > > + ret = smh_trap(SYSFLEN, &fd); > > + if (ret == -1) > > + return smh_errno(); > > + return ret; > > +} > > + > > +long smh_seek(long fd, long pos) > > +{ > > + long ret; > > + struct smh_seek_s { > > + long fd; > > + long pos; > > + } seek; > > + > > + debug("%s: fd %ld pos %ld\n", __func__, fd, pos); > > + > > + seek.fd = fd; > > + seek.pos = pos; > > + > > + ret = smh_trap(SYSSEEK, &seek); > > + if (ret) > > + return smh_errno(); > > + return 0; > > +} > > + > > +int smh_getc(void) > > +{ > > + return smh_trap(SYSREADC, NULL); > > +} > > + > > +void smh_putc(char ch) > > +{ > > + smh_trap(SYSWRITEC, &ch); > > +} > > + > > +void smh_puts(const char *s) > > +{ > > + smh_trap(SYSWRITE0, (char *)s); > > +} > > The rest looks fine. > > --Sean