lib: Add common semihosting library

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>
Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 3f68d09..cac4fa0 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -413,52 +413,6 @@
 	  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 939c0f7..7b7669b 100644
--- a/arch/arm/lib/semihosting.c
+++ b/arch/arm/lib/semihosting.c
@@ -5,20 +5,6 @@
  */
 
 #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
 
 /*
  * Macro to force the compiler to *populate* memory (for an array or struct)
@@ -39,7 +25,7 @@
 /*
  * Call the handler
  */
-static long smh_trap(unsigned int sysnum, void *addr)
+long smh_trap(unsigned int sysnum, void *addr)
 {
 	register long result asm("r0");
 	register void *_addr asm("r1") = addr;
@@ -59,168 +45,3 @@
 
 	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);
-}