[PATCH 2/6] firmware: semihosting: add ARMv8-A semihosting support
Ahmad Fatoum
a.fatoum at pengutronix.de
Mon Jun 10 23:59:19 PDT 2024
The semihosting code was assuming registers and pointers to be 32-bit in
size. To enable usage for ARM64, switch to long-sized types where
appropriate and add a trap implementation for ARMv8.
Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
arch/arm/Kconfig | 1 -
arch/arm/cpu/semihosting-trap_64.S | 10 ++++++
drivers/firmware/semihosting.c | 55 +++++++++++++++---------------
fs/smhfs.c | 4 +--
include/asm-generic/semihosting.h | 4 +--
5 files changed, 41 insertions(+), 33 deletions(-)
create mode 100644 arch/arm/cpu/semihosting-trap_64.S
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 26547cd3ba71..89125ca576ea 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -372,7 +372,6 @@ config ARM_UNWIND
config ARM_SEMIHOSTING
bool "enable ARM semihosting support"
- depends on !CPU_V8
select SEMIHOSTING
help
This option enables ARM semihosting support in barebox. ARM
diff --git a/arch/arm/cpu/semihosting-trap_64.S b/arch/arm/cpu/semihosting-trap_64.S
new file mode 100644
index 000000000000..0f52094fc46b
--- /dev/null
+++ b/arch/arm/cpu/semihosting-trap_64.S
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <linux/linkage.h>
+#include <asm/unified.h>
+
+.section .text.semihosting_trap
+ENTRY(semihosting_trap)
+ hlt #0xf000
+ ret
+ENDPROC(semihosting_trap)
diff --git a/drivers/firmware/semihosting.c b/drivers/firmware/semihosting.c
index 57b412e08ded..a037a95a1077 100644
--- a/drivers/firmware/semihosting.c
+++ b/drivers/firmware/semihosting.c
@@ -41,9 +41,9 @@ enum {
SEMIHOSTING_SYS_SYSTEM = 0x12,
};
-uint32_t semihosting_trap(uint32_t sysnum, void *addr);
+long semihosting_trap(ulong sysnum, void *addr);
-static uint32_t semihosting_flags_to_mode(int flags)
+static ulong semihosting_flags_to_mode(int flags)
{
static const int semihosting_open_modeflags[12] = {
O_RDONLY,
@@ -72,11 +72,11 @@ static uint32_t semihosting_flags_to_mode(int flags)
int semihosting_open(const char *fname, int flags)
{
struct __packed {
- uint32_t fname;
- uint32_t mode;
- uint32_t len;
+ ulong fname;
+ ulong mode;
+ ulong len;
} open = {
- .fname = (uint32_t)fname,
+ .fname = virt_to_phys(fname),
.len = strlen(fname),
.mode = semihosting_flags_to_mode(flags),
};
@@ -104,16 +104,16 @@ int semihosting_write0(const char *str)
EXPORT_SYMBOL(semihosting_write0);
struct __packed semihosting_file_io {
- uint32_t fd;
- uint32_t memp;
- uint32_t len;
+ ulong fd;
+ ulong memp;
+ ulong len;
};
ssize_t semihosting_write(int fd, const void *buf, size_t count)
{
struct semihosting_file_io write = {
.fd = fd,
- .memp = (uint32_t)buf,
+ .memp = virt_to_phys(buf),
.len = count,
};
@@ -125,7 +125,7 @@ ssize_t semihosting_read(int fd, void *buf, size_t count)
{
struct semihosting_file_io read = {
.fd = fd,
- .memp = (uint32_t)buf,
+ .memp = virt_to_phys(buf),
.len = count,
};
@@ -145,11 +145,11 @@ int semihosting_isatty(int fd)
}
EXPORT_SYMBOL(semihosting_isatty);
-int semihosting_seek(int fd, loff_t pos)
+off_t semihosting_seek(int fd, off_t pos)
{
struct __packed {
- uint32_t fd;
- uint32_t pos;
+ ulong fd;
+ ulong pos;
} seek = {
.fd = fd,
.pos = pos,
@@ -158,8 +158,7 @@ int semihosting_seek(int fd, loff_t pos)
return semihosting_trap(SEMIHOSTING_SYS_SEEK, &seek);
}
EXPORT_SYMBOL(semihosting_seek);
-
-int semihosting_flen(int fd)
+off_t semihosting_flen(int fd)
{
return semihosting_trap(SEMIHOSTING_SYS_FLEN, &fd);
}
@@ -168,10 +167,10 @@ EXPORT_SYMBOL(semihosting_flen);
int semihosting_remove(const char *fname)
{
struct __packed {
- uint32_t fname;
- uint32_t fname_length;
+ ulong fname;
+ ulong fname_length;
} remove = {
- .fname = (uint32_t)fname,
+ .fname = virt_to_phys(fname),
.fname_length = strlen(fname),
};
@@ -182,14 +181,14 @@ EXPORT_SYMBOL(semihosting_remove);
int semihosting_rename(const char *fname1, const char *fname2)
{
struct __packed {
- uint32_t fname1;
- uint32_t fname1_length;
- uint32_t fname2;
- uint32_t fname2_length;
+ ulong fname1;
+ ulong fname1_length;
+ ulong fname2;
+ ulong fname2_length;
} rename = {
- .fname1 = (uint32_t)fname1,
+ .fname1 = virt_to_phys(fname1),
.fname1_length = strlen(fname1),
- .fname2 = (uint32_t)fname2,
+ .fname2 = virt_to_phys(fname2),
.fname2_length = strlen(fname2),
};
@@ -207,10 +206,10 @@ EXPORT_SYMBOL(semihosting_errno);
int semihosting_system(const char *command)
{
struct __packed {
- uint32_t cmd;
- uint32_t cmd_len;
+ ulong cmd;
+ ulong cmd_len;
} system = {
- .cmd = (uint32_t)command,
+ .cmd = virt_to_phys(command),
.cmd_len = strlen(command),
};
diff --git a/fs/smhfs.c b/fs/smhfs.c
index 5165bf939406..da285b5be52f 100644
--- a/fs/smhfs.c
+++ b/fs/smhfs.c
@@ -26,7 +26,7 @@
static int file_to_fd(const FILE *f)
{
- return (int)f->priv;
+ return (int)(uintptr_t)f->priv;
}
static int smhfs_create(struct device __always_unused *dev,
@@ -72,7 +72,7 @@ static int smhfs_open(struct device __always_unused *dev,
if (fd < 0)
goto error;
- file->priv = (void *)fd;
+ file->priv = (void *)(uintptr_t)fd;
file->size = semihosting_flen(fd);
if (file->size < 0)
goto error;
diff --git a/include/asm-generic/semihosting.h b/include/asm-generic/semihosting.h
index d337c33ff486..b745f8831977 100644
--- a/include/asm-generic/semihosting.h
+++ b/include/asm-generic/semihosting.h
@@ -13,8 +13,8 @@ ssize_t semihosting_write(int fd, const void *buf, size_t count);
ssize_t semihosting_read(int fd, void *buf, size_t count);
int semihosting_readc(void);
int semihosting_isatty(int fd);
-int semihosting_seek(int fd, loff_t pos);
-int semihosting_flen(int fd);
+off_t semihosting_seek(int fd, off_t pos);
+off_t semihosting_flen(int fd);
int semihosting_remove(const char *fname);
int semihosting_rename(const char *fname1, const char *fname2);
int semihosting_errno(void);
--
2.39.2
More information about the barebox
mailing list