From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 32662ECAAD8 for ; Fri, 16 Sep 2022 12:24:28 +0000 (UTC) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 5197984BD4; Fri, 16 Sep 2022 14:23:20 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=ventanamicro.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=ventanamicro.com header.i=@ventanamicro.com header.b="o4N/4SUo"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 4AF54849D8; Fri, 16 Sep 2022 10:13:14 +0200 (CEST) Received: from mail-pf1-x42b.google.com (mail-pf1-x42b.google.com [IPv6:2607:f8b0:4864:20::42b]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 0237B84A02 for ; Fri, 16 Sep 2022 10:13:11 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=ventanamicro.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=kconsul@ventanamicro.com Received: by mail-pf1-x42b.google.com with SMTP id y127so20524024pfy.5 for ; Fri, 16 Sep 2022 01:13:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date; bh=x84Ku8rulDyYfETGnnOilTVqV6CVXnS40URCRWllKYg=; b=o4N/4SUoiO/J8N84ypKpbeiG2HDJaQYGY4cauLq7OIuZ5CrLTDZz60IA3GXYqmR7vk +4dY1u72wEs5TfPMprpop3RzPE3CRn/rN01cQ4BAMwd/e4DXtw78d8mlA7CQtmjE3fLv mf+yAM4EHVwVENzoP6PWySRronBmdbDlY8ev+Tkq5y9xElZKhvDyDFeOA/9y+mQeI9LU Il6AWnC0I8objnrZXTK2b93O1IZs/f21ekRdhuPBxDqWDkiVbabWmhZtwcVQaaYqf8GB o+GZcWR1IdKfJbYEbTqVeNYhux2cbpFlsuCUKjqz40fb2HQNyjOZkM4xi3HVr7reiQAu mtkQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date; bh=x84Ku8rulDyYfETGnnOilTVqV6CVXnS40URCRWllKYg=; b=AIBwQMcTnpHZEKs/xJ9Obw479I1m0xIn8ZMEHqFq/rBXTQIMkiTt5wnCZ4VOIMzaCz ZwUgenqjFzi/MTubvTSlnAAr7TVjFzawcBFdg34cgLAClxiLLP6knPXNG4Vo4J/lhmJu PA10XBJKJc9dZlM49D8SKfgx1ABvD8LWs4Kp3vJmmxQv0OcknJaxpEnJvgo/aI8IglhD PrYkm+VbKkBvg41YKw8UTntM8iQVf3mMqzTPbmmY/8EuzpI3mUy4Cup3Zxv+t7HbmNDc o/e0L6Uc2IKpBFZrSvxUBQedh3Z42+UZUbCDeRp4U1iSKNRPrcDEQMmwTqlYDvi7/B6b Ph+Q== X-Gm-Message-State: ACrzQf2f2dbOUeEvdoGn5u/aG9ZyEY1W4RbeERxQ9+PwJ/Xi87Cl812s BUTibWb/H2X13ZnwfzOzK0xNRg== X-Google-Smtp-Source: AMsMyM65rUKfozfaXBt5+oeVc9d4fckk7TEdC7eQVcZ1kCufS1NpiySvNtQ0bTGY6t7h8sn+tKm35g== X-Received: by 2002:a63:2a89:0:b0:439:398f:cb43 with SMTP id q131-20020a632a89000000b00439398fcb43mr3440556pgq.187.1663315989149; Fri, 16 Sep 2022 01:13:09 -0700 (PDT) Received: from performance-PowerEdge-T440.. ([103.97.165.210]) by smtp.googlemail.com with ESMTPSA id y22-20020aa78f36000000b0052d200c8040sm13964488pfr.211.2022.09.16.01.13.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Sep 2022 01:13:08 -0700 (PDT) From: Kautuk Consul To: Rick Chen , Leo , Sean Anderson , Bin Meng , Anup Patel , Heinrich Schuchardt , Simon Glass , Ilias Apalodimas , Alexandru Gagniuc , Philippe Reynes , Rasmus Villemoes , Eugen Hristev , Stefan Roese , =?UTF-8?q?Pali=20Roh=C3=A1r?= , Qu Wenruo , Loic Poulain , Patrick Delaunay Cc: u-boot@lists.denx.de, Kautuk Consul Subject: [PATCH v2 1/3] lib: Add common semihosting library Date: Fri, 16 Sep 2022 13:42:31 +0530 Message-Id: <20220916081233.1970135-2-kconsul@ventanamicro.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220916081233.1970135-1-kconsul@ventanamicro.com> References: <20220916081233.1970135-1-kconsul@ventanamicro.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Mailman-Approved-At: Fri, 16 Sep 2022 14:22:08 +0200 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.6 at phobos.denx.de X-Virus-Status: Clean 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 --- 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 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 #include -#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 + * Copyright 2014 Broadcom Corporation + */ + +#include +#include +#include + +#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