All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kautuk Consul <kconsul@ventanamicro.com>
To: Rayagonda Kokatanur <rayagonda.kokatanur@broadcom.com>,
	Sean Anderson <sean.anderson@seco.com>,
	Rick Chen <rick@andestech.com>, Leo <ycliang@andestech.com>,
	Bin Meng <bmeng.cn@gmail.com>, Simon Glass <sjg@chromium.org>,
	Ilias Apalodimas <ilias.apalodimas@linaro.org>,
	Alexandru Gagniuc <mr.nuke.me@gmail.com>,
	Philippe Reynes <philippe.reynes@softathome.com>,
	Heinrich Schuchardt <xypron.glpk@gmx.de>,
	Rasmus Villemoes <rasmus.villemoes@prevas.dk>,
	Eugen Hristev <eugen.hristev@microchip.com>,
	Stefan Roese <sr@denx.de>, Loic Poulain <loic.poulain@linaro.org>,
	Peng Fan <peng.fan@nxp.com>, Michal Simek <michal.simek@amd.com>
Cc: u-boot@lists.denx.de, Kautuk Consul <kconsul@ventanamicro.com>
Subject: [PATCH v5 1/3] lib: Add common semihosting library
Date: Fri, 23 Sep 2022 12:33:18 +0530	[thread overview]
Message-ID: <20220923070320.617623-2-kconsul@ventanamicro.com> (raw)
In-Reply-To: <20220923070320.617623-1-kconsul@ventanamicro.com>

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           |  46 ---------
 arch/arm/lib/semihosting.c | 181 +-----------------------------------
 include/semihosting.h      |  11 +++
 lib/Kconfig                |  47 ++++++++++
 lib/Makefile               |   2 +
 lib/semihosting.c          | 186 +++++++++++++++++++++++++++++++++++++
 6 files changed, 247 insertions(+), 226 deletions(-)
 create mode 100644 lib/semihosting.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 82cd456f51..ee6a9fadd9 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -413,52 +413,6 @@ config ARM_SMCCC
 	  This should be enabled if U-Boot needs to communicate with system
 	  firmware (for example, PSCI) according to SMCCC.
 
-config SEMIHOSTING
-	bool "Support ARM semihosting"
-	help
-	  Semihosting is a method for a target to communicate with a host
-	  debugger. It uses special instructions which the debugger will trap
-	  on and interpret. This allows U-Boot to read/write files, print to
-	  the console, and execute arbitrary commands on the host system.
-
-	  Enabling this option will add support for reading and writing files
-	  on the host system. If you don't have a debugger attached then trying
-	  to do this will likely cause U-Boot to hang. Say 'n' if you are unsure.
-
-config SEMIHOSTING_FALLBACK
-	bool "Recover gracefully when semihosting fails"
-	depends on SEMIHOSTING && ARM64
-	default y
-	help
-	  Normally, if U-Boot makes a semihosting call and no debugger is
-	  attached, then it will panic due to a synchronous abort
-	  exception. This config adds an exception handler which will allow
-	  U-Boot to recover. Say 'y' if unsure.
-
-config SPL_SEMIHOSTING
-	bool "Support ARM semihosting in SPL"
-	depends on SPL
-	help
-	  Semihosting is a method for a target to communicate with a host
-	  debugger. It uses special instructions which the debugger will trap
-	  on and interpret. This allows U-Boot to read/write files, print to
-	  the console, and execute arbitrary commands on the host system.
-
-	  Enabling this option will add support for reading and writing files
-	  on the host system. If you don't have a debugger attached then trying
-	  to do this will likely cause U-Boot to hang. Say 'n' if you are unsure.
-
-config SPL_SEMIHOSTING_FALLBACK
-	bool "Recover gracefully when semihosting fails in SPL"
-	depends on SPL_SEMIHOSTING && ARM64
-	select ARMV8_SPL_EXCEPTION_VECTORS
-	default y
-	help
-	  Normally, if U-Boot makes a semihosting call and no debugger is
-	  attached, then it will panic due to a synchronous abort
-	  exception. This config adds an exception handler which will allow
-	  U-Boot to recover. Say 'y' if unsure.
-
 config SYS_THUMB_BUILD
 	bool "Build U-Boot using the Thumb instruction set"
 	depends on !ARM64
diff --git a/arch/arm/lib/semihosting.c b/arch/arm/lib/semihosting.c
index 01d652a6b8..11e7b85ee6 100644
--- a/arch/arm/lib/semihosting.c
+++ b/arch/arm/lib/semihosting.c
@@ -10,25 +10,11 @@
  * available in silicon now, fastmodel usage makes less sense for them.
  */
 #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
 
 /*
  * 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 +27,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..4e844cbad8 100644
--- a/include/semihosting.h
+++ b/include/semihosting.h
@@ -17,6 +17,17 @@
 #define SMH_T32_SVC 0xDFAB
 #define SMH_T32_HLT 0xBABC
 
+/**
+ * smh_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..de7e797f11 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -71,6 +71,53 @@ config HAVE_PRIVATE_LIBGCC
 config LIB_UUID
 	bool
 
+config SEMIHOSTING
+	bool "Support semihosting"
+	depends on ARM
+	help
+	  Semihosting is a method for a target to communicate with a host
+	  debugger. It uses special instructions which the debugger will trap
+	  on and interpret. This allows U-Boot to read/write files, print to
+	  the console, and execute arbitrary commands on the host system.
+
+	  Enabling this option will add support for reading and writing files
+	  on the host system. If you don't have a debugger attached then trying
+	  to do this will likely cause U-Boot to hang. Say 'n' if you are unsure.
+
+config SEMIHOSTING_FALLBACK
+	bool "Recover gracefully when semihosting fails"
+	depends on SEMIHOSTING && ARM64
+	default y
+	help
+	  Normally, if U-Boot makes a semihosting call and no debugger is
+	  attached, then it will panic due to a synchronous abort
+	  exception. This config adds an exception handler which will allow
+	  U-Boot to recover. Say 'y' if unsure.
+
+config SPL_SEMIHOSTING
+	bool "Support semihosting in SPL"
+	depends on SPL && ARM
+	help
+	  Semihosting is a method for a target to communicate with a host
+	  debugger. It uses special instructions which the debugger will trap
+	  on and interpret. This allows U-Boot to read/write files, print to
+	  the console, and execute arbitrary commands on the host system.
+
+	  Enabling this option will add support for reading and writing files
+	  on the host system. If you don't have a debugger attached then trying
+	  to do this will likely cause U-Boot to hang. Say 'n' if you are unsure.
+
+config SPL_SEMIHOSTING_FALLBACK
+	bool "Recover gracefully when semihosting fails in SPL"
+	depends on SPL_SEMIHOSTING && ARM64
+	select ARMV8_SPL_EXCEPTION_VECTORS
+	default y
+	help
+	  Normally, if U-Boot makes a semihosting call and no debugger is
+	  attached, then it will panic due to a synchronous abort
+	  exception. This config adds an exception handler which will allow
+	  U-Boot to recover. Say 'y' if unsure.
+
 config PRINTF
 	bool
 	default y
diff --git a/lib/Makefile b/lib/Makefile
index e3deb15287..134c4319cd 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_$(SPL_TPL_)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);
+}
-- 
2.34.1


  reply	other threads:[~2022-09-23  7:04 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-23  7:03 [PATCH v5 0/3] Add riscv semihosting support in u-boot Kautuk Consul
2022-09-23  7:03 ` Kautuk Consul [this message]
2022-10-10 15:39   ` [PATCH v5 1/3] lib: Add common semihosting library Sean Anderson
2022-09-23  7:03 ` [PATCH v5 2/3] arch/riscv: add semihosting support for RISC-V Kautuk Consul
2022-10-10 15:43   ` Sean Anderson
     [not found]   ` <HK0PR03MB2994013C655E85AF1F3D2CFBC1229@HK0PR03MB2994.apcprd03.prod.outlook.com>
2022-10-12  1:40     ` Rick Chen
2022-09-23  7:03 ` [PATCH v5 3/3] board: qemu-riscv: enable semihosting Kautuk Consul
2022-10-05  6:17   ` Leo Liang
2022-10-06  5:13     ` Kautuk Consul
     [not found]   ` <HK0PR03MB29949257906C387D549119EBC1229@HK0PR03MB2994.apcprd03.prod.outlook.com>
2022-10-12  1:33     ` Rick Chen
2022-12-03  4:14   ` Bin Meng
2022-12-05  5:51     ` Kautuk Consul
2022-12-05 13:54       ` Bin Meng
2022-12-05 15:16       ` Sean Anderson
2022-12-06  5:42         ` Kautuk Consul
2022-12-06 10:58           ` Leo Liang
2022-12-06 11:32             ` Kautuk Consul
2022-12-07  7:01               ` Leo Liang
2022-12-07 11:47                 ` Kautuk Consul
2022-12-06 15:16           ` Sean Anderson
2022-11-29  6:29 ` [PATCH v5 0/3] Add riscv semihosting support in u-boot Kautuk Consul
2022-11-29  6:36   ` Bin Meng
2022-11-29  6:57     ` Kautuk Consul
2022-12-02  8:46       ` Leo Liang
2022-12-02  9:52         ` Kautuk Consul
2022-12-02 12:01           ` Leo Liang
2022-12-03  4:28       ` Bin Meng
2022-12-03  6:01         ` Bin Meng
2022-12-05  5:50           ` Kautuk Consul

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=20220923070320.617623-2-kconsul@ventanamicro.com \
    --to=kconsul@ventanamicro.com \
    --cc=bmeng.cn@gmail.com \
    --cc=eugen.hristev@microchip.com \
    --cc=ilias.apalodimas@linaro.org \
    --cc=loic.poulain@linaro.org \
    --cc=michal.simek@amd.com \
    --cc=mr.nuke.me@gmail.com \
    --cc=peng.fan@nxp.com \
    --cc=philippe.reynes@softathome.com \
    --cc=rasmus.villemoes@prevas.dk \
    --cc=rayagonda.kokatanur@broadcom.com \
    --cc=rick@andestech.com \
    --cc=sean.anderson@seco.com \
    --cc=sjg@chromium.org \
    --cc=sr@denx.de \
    --cc=u-boot@lists.denx.de \
    --cc=xypron.glpk@gmx.de \
    --cc=ycliang@andestech.com \
    /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.