Skip to content

Commit 95ad7e0

Browse files
committed
Merge branch 'for-next/semihosting' into next
2 parents 6ffdcf2 + 1d2df6d commit 95ad7e0

File tree

18 files changed

+227
-88
lines changed

18 files changed

+227
-88
lines changed

arch/arm/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ config ARM_UNWIND
372372

373373
config ARM_SEMIHOSTING
374374
bool "enable ARM semihosting support"
375-
depends on !CPU_V8
375+
select SEMIHOSTING
376376
help
377377
This option enables ARM semihosting support in barebox. ARM
378378
semihosting is a communication discipline that allows code

arch/arm/cpu/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ obj-pbl-y += setupc_$(S64_32).o cache_$(S64_32).o
2323

2424
obj-$(CONFIG_ARM_PSCI_CLIENT) += psci-client.o
2525

26+
obj-$(CONFIG_ARM_SEMIHOSTING) += semihosting-trap_$(S64_32).o
27+
2628
#
2729
# Any variants can be called as start-armxyz.S
2830
#

arch/arm/lib32/semihosting-trap.S renamed to arch/arm/cpu/semihosting-trap_32.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/* SPDX-FileCopyrightText: 2015 Zodiac Inflight Innovations */
33

44
/*
5-
* semihosting-trap.S -- Assembly code needed to make a semihosting call
5+
* semihosting-trap_32.S -- Assembly code needed to make a semihosting call
66
*
77
* Author: Andrey Smirnov <[email protected]>
88
*/

arch/arm/cpu/semihosting-trap_64.S

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
3+
#include <linux/linkage.h>
4+
#include <asm/unified.h>
5+
6+
.section .text.semihosting_trap
7+
ENTRY(semihosting_trap)
8+
hlt #0xf000
9+
ret
10+
ENDPROC(semihosting_trap)

arch/arm/include/asm/debug_ll.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@
3535
#include <mach/layerscape/debug_ll.h>
3636
#endif
3737

38+
#ifdef CONFIG_DEBUG_SEMIHOSTING
39+
#include <debug_ll/semihosting.h>
40+
#endif
41+
3842
#ifdef CONFIG_DEBUG_QEMU_ARM64_VIRT
3943
#define DEBUG_LL_UART_ADDR 0x9000000
4044
#include <debug_ll/pl011.h>

arch/arm/include/asm/semihosting.h

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,38 @@
33
#ifndef __ASM_ARM_SEMIHOSTING_H
44
#define __ASM_ARM_SEMIHOSTING_H
55

6-
int semihosting_open(const char *fname, int flags);
7-
int semihosting_close(int fd);
8-
int semihosting_writec(char c);
9-
int semihosting_write0(const char *str);
10-
ssize_t semihosting_write(int fd, const void *buf, size_t count);
11-
ssize_t semihosting_read(int fd, void *buf, size_t count);
12-
int semihosting_readc(void);
13-
int semihosting_isatty(int fd);
14-
int semihosting_seek(int fd, loff_t pos);
15-
int semihosting_flen(int fd);
16-
int semihosting_remove(const char *fname);
17-
int semihosting_rename(const char *fname1, const char *fname2);
18-
int semihosting_errno(void);
19-
int semihosting_system(const char *command);
6+
#include <asm-generic/semihosting.h>
7+
#include <asm/unified.h>
8+
9+
static inline void semihosting_putc(void *unused, int c)
10+
{
11+
/* We may not be relocated yet here, so we push
12+
* to stack and take address of that
13+
*/
14+
#ifdef CONFIG_CPU_64
15+
asm volatile (
16+
"stp %0, xzr, [sp, #-16]!\n"
17+
"mov x1, sp\n"
18+
"mov x0, #0x03\n"
19+
"hlt #0xf000\n"
20+
"add sp, sp, #16\n"
21+
: /* No outputs */
22+
: "r" ((long)c)
23+
: "x0", "x1", "x2", "x3", "x12", "memory"
24+
);
25+
#else
26+
asm volatile (
27+
"push {%0}\n"
28+
"mov r1, sp\n"
29+
"mov r0, #0x03\n"
30+
ARM( "bkpt #0x123456\n")
31+
THUMB( "bkpt #0xAB\n")
32+
"pop {%0}\n"
33+
: /* No outputs */
34+
: "r" (c)
35+
: "r0", "r1", "r2", "r3", "r12", "memory"
36+
);
37+
#endif
38+
}
2039

2140
#endif

arch/arm/lib32/Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ pbl-y += runtime-offset.o
2323
obj-$(CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS) += memcpy.o
2424
obj-$(CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS) += memset.o
2525
obj-$(CONFIG_ARM_UNWIND) += unwind.o
26-
obj-$(CONFIG_ARM_SEMIHOSTING) += semihosting-trap.o semihosting.o
2726
obj-$(CONFIG_MODULES) += module.o
2827
obj-$(CONFIG_ARM_MODULE_PLTS) += module-plts.o
2928
extra-y += barebox.lds

common/Kconfig.debug_ll

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,19 @@ config DEBUG_QEMU_ARM64_VIRT
337337
bool "QEMU ARM64 Virt PL011 console"
338338
depends on ARCH_ARM64_VIRT
339339

340+
config DEBUG_SEMIHOSTING
341+
bool "Semihosting console"
342+
depends on SEMIHOSTING
343+
help
344+
Semihosting enables code to use the I/O facilities on a
345+
host debugger/emulator through a simple supervisor call.
346+
The host debugger or emulator must have semihosting enabled
347+
for the supervisor call to be trapped, otherwise barebox
348+
will crash.
349+
350+
Say Y here if you want low-level debugging support
351+
using semihosting writec.
352+
340353
endchoice
341354

342355
config DEBUG_LL_NS16550

drivers/firmware/Kconfig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# SPDX-License-Identifier: GPL-2.0-only
22
menu "Firmware Drivers"
33

4+
config SEMIHOSTING
5+
bool
6+
select HAS_DEBUG_LL
7+
48
config FIRMWARE_ALTERA_SERIAL
59
bool "Altera SPI programming"
610
depends on OFDEVICE

drivers/firmware/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# SPDX-License-Identifier: GPL-2.0-only
2+
obj-$(CONFIG_SEMIHOSTING) += semihosting.o
23
obj-$(CONFIG_FIRMWARE_ALTERA_SERIAL) += altera_serial.o
34
obj-$(CONFIG_FIRMWARE_ALTERA_SOCFPGA) += socfpga.o socfpga_sdr.o
45
obj-$(CONFIG_FIRMWARE_ZYNQMP_FPGA) += zynqmp-fpga.o

arch/arm/lib32/semihosting.c renamed to drivers/firmware/semihosting.c

Lines changed: 55 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,15 @@ enum {
4141
SEMIHOSTING_SYS_SYSTEM = 0x12,
4242
};
4343

44-
uint32_t semihosting_trap(uint32_t sysnum, void *addr);
44+
long semihosting_trap(ulong sysnum, void *addr);
4545

46-
static uint32_t semihosting_flags_to_mode(int flags)
46+
static long semihosting_call(ulong sysnum, void *addr)
47+
{
48+
long ret = semihosting_trap(sysnum, addr);
49+
return ret >= 0 ? ret : -semihosting_errno();
50+
}
51+
52+
static ulong semihosting_flags_to_mode(int flags)
4753
{
4854
static const int semihosting_open_modeflags[12] = {
4955
O_RDONLY,
@@ -72,148 +78,153 @@ static uint32_t semihosting_flags_to_mode(int flags)
7278
int semihosting_open(const char *fname, int flags)
7379
{
7480
struct __packed {
75-
uint32_t fname;
76-
uint32_t mode;
77-
uint32_t len;
81+
ulong fname;
82+
ulong mode;
83+
ulong len;
7884
} open = {
79-
.fname = (uint32_t)fname,
85+
.fname = virt_to_phys(fname),
8086
.len = strlen(fname),
8187
.mode = semihosting_flags_to_mode(flags),
8288
};
8389

84-
return semihosting_trap(SEMIHOSTING_SYS_OPEN, &open);
90+
return semihosting_call(SEMIHOSTING_SYS_OPEN, &open);
8591
}
8692
EXPORT_SYMBOL(semihosting_open);
8793

8894
int semihosting_close(int fd)
8995
{
90-
return semihosting_trap(SEMIHOSTING_SYS_CLOSE, &fd);
96+
return semihosting_call(SEMIHOSTING_SYS_CLOSE, &fd);
9197
}
9298
EXPORT_SYMBOL(semihosting_close);
9399

94-
int semihosting_writec(char c)
100+
void semihosting_writec(char c)
95101
{
96-
return semihosting_trap(SEMIHOSTING_SYS_WRITEC, &c);
102+
(void)semihosting_trap(SEMIHOSTING_SYS_WRITEC, &c);
97103
}
98104
EXPORT_SYMBOL(semihosting_writec);
99105

100-
int semihosting_write0(const char *str)
106+
void semihosting_write0(const char *str)
101107
{
102-
return semihosting_trap(SEMIHOSTING_SYS_WRITE0, (void *)str);
108+
(void)semihosting_trap(SEMIHOSTING_SYS_WRITE0, (void *)str);
103109
}
104110
EXPORT_SYMBOL(semihosting_write0);
105111

106112
struct __packed semihosting_file_io {
107-
uint32_t fd;
108-
uint32_t memp;
109-
uint32_t len;
113+
ulong fd;
114+
ulong memp;
115+
ulong len;
110116
};
111117

112118
ssize_t semihosting_write(int fd, const void *buf, size_t count)
113119
{
120+
ssize_t ret;
114121
struct semihosting_file_io write = {
115122
.fd = fd,
116-
.memp = (uint32_t)buf,
123+
.memp = virt_to_phys(buf),
117124
.len = count,
118125
};
119126

120-
return semihosting_trap(SEMIHOSTING_SYS_WRITE, &write);
127+
ret = semihosting_call(SEMIHOSTING_SYS_WRITE, &write);
128+
129+
return ret >= 0 ? count - ret : ret;
121130
}
122131
EXPORT_SYMBOL(semihosting_write);
123132

124133
ssize_t semihosting_read(int fd, void *buf, size_t count)
125134
{
135+
ssize_t ret;
126136
struct semihosting_file_io read = {
127137
.fd = fd,
128-
.memp = (uint32_t)buf,
138+
.memp = virt_to_phys(buf),
129139
.len = count,
130140
};
131141

132-
return semihosting_trap(SEMIHOSTING_SYS_READ, &read);
142+
ret = semihosting_call(SEMIHOSTING_SYS_READ, &read);
143+
144+
return ret >= 0 ? count - ret : ret;
133145
}
134146
EXPORT_SYMBOL(semihosting_read);
135147

136148
int semihosting_readc(void)
137149
{
138-
return semihosting_trap(SEMIHOSTING_SYS_READC, NULL);
150+
return semihosting_call(SEMIHOSTING_SYS_READC, NULL);
139151
}
140152
EXPORT_SYMBOL(semihosting_readc);
141153

142154
int semihosting_isatty(int fd)
143155
{
144-
return semihosting_trap(SEMIHOSTING_SYS_ISATTY, &fd);
156+
return semihosting_call(SEMIHOSTING_SYS_ISATTY, &fd);
145157
}
146158
EXPORT_SYMBOL(semihosting_isatty);
147159

148-
int semihosting_seek(int fd, loff_t pos)
160+
off_t semihosting_seek(int fd, off_t pos)
149161
{
150162
struct __packed {
151-
uint32_t fd;
152-
uint32_t pos;
163+
ulong fd;
164+
ulong pos;
153165
} seek = {
154166
.fd = fd,
155167
.pos = pos,
156168
};
157169

158-
return semihosting_trap(SEMIHOSTING_SYS_SEEK, &seek);
170+
return semihosting_call(SEMIHOSTING_SYS_SEEK, &seek);
159171
}
160172
EXPORT_SYMBOL(semihosting_seek);
161-
162-
int semihosting_flen(int fd)
173+
off_t semihosting_flen(int fd)
163174
{
164-
return semihosting_trap(SEMIHOSTING_SYS_FLEN, &fd);
175+
return semihosting_call(SEMIHOSTING_SYS_FLEN, &fd);
165176
}
166177
EXPORT_SYMBOL(semihosting_flen);
167178

168179
int semihosting_remove(const char *fname)
169180
{
170181
struct __packed {
171-
uint32_t fname;
172-
uint32_t fname_length;
182+
ulong fname;
183+
ulong fname_length;
173184
} remove = {
174-
.fname = (uint32_t)fname,
185+
.fname = virt_to_phys(fname),
175186
.fname_length = strlen(fname),
176187
};
177188

178-
return semihosting_trap(SEMIHOSTING_SYS_REMOVE, &remove);
189+
return semihosting_call(SEMIHOSTING_SYS_REMOVE, &remove);
179190
}
180191
EXPORT_SYMBOL(semihosting_remove);
181192

182193
int semihosting_rename(const char *fname1, const char *fname2)
183194
{
184195
struct __packed {
185-
uint32_t fname1;
186-
uint32_t fname1_length;
187-
uint32_t fname2;
188-
uint32_t fname2_length;
196+
ulong fname1;
197+
ulong fname1_length;
198+
ulong fname2;
199+
ulong fname2_length;
189200
} rename = {
190-
.fname1 = (uint32_t)fname1,
201+
.fname1 = virt_to_phys(fname1),
191202
.fname1_length = strlen(fname1),
192-
.fname2 = (uint32_t)fname2,
203+
.fname2 = virt_to_phys(fname2),
193204
.fname2_length = strlen(fname2),
194205
};
195206

196-
return semihosting_trap(SEMIHOSTING_SYS_RENAME, &rename);
207+
return semihosting_call(SEMIHOSTING_SYS_RENAME, &rename);
197208
}
198209
EXPORT_SYMBOL(semihosting_rename);
199210

200211
int semihosting_errno(void)
201212
{
202-
return semihosting_trap(SEMIHOSTING_SYS_ERRNO, NULL);
213+
return semihosting_call(SEMIHOSTING_SYS_ERRNO, NULL);
203214
}
204215
EXPORT_SYMBOL(semihosting_errno);
205216

206217

207218
int semihosting_system(const char *command)
208219
{
209220
struct __packed {
210-
uint32_t cmd;
211-
uint32_t cmd_len;
221+
ulong cmd;
222+
ulong cmd_len;
212223
} system = {
213-
.cmd = (uint32_t)command,
224+
.cmd = virt_to_phys(command),
214225
.cmd_len = strlen(command),
215226
};
216227

217-
return semihosting_trap(SEMIHOSTING_SYS_SYSTEM, &system);
228+
return semihosting_call(SEMIHOSTING_SYS_SYSTEM, &system);
218229
}
219230
EXPORT_SYMBOL(semihosting_system);

drivers/serial/Kconfig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,4 +151,12 @@ config SERIAL_SBI
151151
Select this option if you are building barebox for a RISCV platform
152152
that implements a serial over SBI.
153153

154+
config SERIAL_SEMIHOSTING
155+
bool "Semihosting console"
156+
depends on SEMIHOSTING
157+
help
158+
Select this option if you want barebox to be able to output to
159+
the semihosting console implemented by a debugger or emulator.
160+
This console can not be read from.
161+
154162
endmenu

drivers/serial/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,4 @@ obj-$(CONFIG_VIRTIO_CONSOLE) += virtio_console.o
2525
obj-$(CONFIG_SERIAL_SIFIVE) += serial_sifive.o
2626
obj-$(CONFIG_SERIAL_SBI) += serial_sbi.o
2727
obj-$(CONFIG_SOC_LITEX) += serial_litex.o
28+
obj-$(CONFIG_SERIAL_SEMIHOSTING) += serial_semihosting.o

0 commit comments

Comments
 (0)