All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sean Anderson <seanga2@gmail.com>
To: u-boot@lists.denx.de
Subject: Re: [PATCH v2 1/3] lib: Add common semihosting library
Date: Sat, 17 Sep 2022 13:39:51 -0400	[thread overview]
Message-ID: <3c431605-4108-7b10-1dbf-d9e955514915@gmail.com> (raw)
In-Reply-To: <20220916081233.1970135-2-kconsul@ventanamicro.com>

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 <kconsul@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.anderson@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

  reply	other threads:[~2022-09-17 17:40 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-16  8:12 [PATCH v2 0/3] Add riscv semihosting support in u-boot Kautuk Consul
2022-09-16  8:12 ` [PATCH v2 1/3] lib: Add common semihosting library Kautuk Consul
2022-09-17 17:39   ` Sean Anderson [this message]
2022-09-19 11:14     ` Kautuk Consul
2022-09-16  8:12 ` [PATCH v2 2/3] arch/riscv: add semihosting support for RISC-V Kautuk Consul
2022-09-16  8:12 ` [PATCH v2 3/3] board: qemu-riscv: enable semihosting Kautuk Consul
2022-09-16  9:08 ` [PATCH v2 0/3] Add riscv semihosting support in u-boot Pali Rohár
2022-09-16  9:10   ` Kautuk Consul
2022-09-16  9:12     ` Pali Rohár
2022-09-16 13:11       ` Sean Anderson
2022-09-16 14:32         ` Tom Rini
2022-09-17 17:24           ` Sean Anderson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3c431605-4108-7b10-1dbf-d9e955514915@gmail.com \
    --to=seanga2@gmail.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.