Creating a spec for semihosting

535 views
Skip to first unread message

Keith Packard

unread,
Mar 8, 2020, 12:23:44 AM3/8/20
to RISC-V SW Dev
I'm trying to get semihosting support upstreamed to qemu so that I can test the C library without requiring a large amount of additional software. After posting the patch to QEMU, the developers suggested that perhaps a slightly more formal specification than the current footnote in the risc-v spec might be nice.

My hope is that we can create a simple spec that references the existing ARM semihosting spec (version 2.0) so that any implementation for RISC-V can use an existing ARM implementation.

I've written some ideas down in a github repo; comments and suggestions would be welcome.


Here's the current asciidoc draft; it's not very long, and I'm hoping it doesn't need to grow a great deal longer.

== License

Copyright © 2020 {author}

This document is released under a Creative Commons Attribution 4.0
International License.

[abstract]
== Abstract

Semihosting is a technique where an application running in a debug or
simulation environment can access elements of the system hosting the
debugger or simulator including console, file system, time and other
functions. This allows for diagnostics, interaction and measurement of
a target system without requiring significant infrastructure to exist
in that target environment.

== RISC-V Semihosting

RISC-V semihosting borrows from the design of the ARM semihosting
mechanism to minimize the development effort required. The RISC-V
semihosting is based on the "Semihosting for AArch32 and AArch64:
Release 2.0" specification available here:

    https://static.docs.arm.com/100863/0200/semihosting.pdf

Referring to Chapter Three in that document, the following extensions
are needed to provide RISC-V support.

=== Semihosting Trap Instruction Sequence

Semihosting operations are requested using a sequence of instructions
including EBREAK. Because the RISC-V base ISA does not provide more than
one EBREAK instruction, RISC-V semihosting uses a special sequence of
instructions to distinguish a semihosting EBREAK from a debugger
inserted EBREAK. <<trap>> shows the instruction sequence used to
invoke a Semihosting operation.

.RISC-V Semihosting Trap Sequence
[#trap]
----
slli x0, x0, 0x1f       # 0x01f01013    Entry NOP
ebreak                  # 0x00100073    Break to debugger
srai x0, x0, 7          # 0x40705013    NOP encoding the semihosting call number 7
----

These three instructions must be 32-bit-wide instructions, they may
not be compressed 16-bit instructions. This same sequence is used on
all RISC-V architectures. On systems with paging support, this
sequence must not cross a page boundary as the semihosting system must
be able to check for the semihosting sequence without needing data
from potentially missing pages.

=== Semihosting Register Definitions

<<register>> shows the specific registers that are used, and the size of
the fields in the data block, which depend on whether the caller is
32-bit or 64-bit.

.RISC-V Registers and field size
[#register]
[cols="3,^1,^1"]
|===
|                                   | 32-bit | 64-bit
| OPERATION NUMBER REGISTER         |  A0    |   A0 
| PARAMETER REGISTER                |  A1    |   A1 
| RETURN REGISTER                   |  A0    |   A0 
| Data block field size             | 32 bits| 64 bits
|===

Liviu Ionescu

unread,
Mar 8, 2020, 1:18:25 AM3/8/20
to Keith Packard, sw-...@groups.riscv.org


> On 8 Mar 2020, at 07:23, Keith Packard <keith....@sifive.com> wrote:
>
> ... Copyright © 2020 Keith Packard

Hi Keith,

If you search the archive, you'll find out that it took me many months of discussions with Krste and his team to have all agree on a solution for semihosting, and then also it took me some time to implement it in OpenOCD, so I don't think it is fair to assume copyrights for this idea.


Regards,

Liviu

Keith Packard

unread,
Mar 8, 2020, 1:32:04 AM3/8/20
to RISC-V SW Dev, keith....@sifive.com
Thanks for the pointers; I'd be pleased to be able to add names of all people who have contributed. I'll start with these.

Keith Packard

unread,
Mar 8, 2020, 1:41:29 AM3/8/20
to RISC-V SW Dev, keith....@sifive.com
Ok, I've identified the following people who contributed to the design that went into OpenOCD. Please let me know if there are more.
These are sorted alphabetically by surname.

Krste Asanovic <kr...@sifive.com>
Palmer Dabbelt <pal...@dabbelt.com>
Liviu Ionescu <i...@livius.net>
Megan Wachs <me...@sifive.com>

kr...@berkeley.edu

unread,
Mar 8, 2020, 1:44:40 AM3/8/20
to Keith Packard, RISC-V SW Dev

Keith,

You should take this up with debug and trace steering committee at
Foundation so they can push process to have this ratified as official
standard. It is probably worth including commentary/rationale
harvested from the email thread Liviu mentions.

As you'll see in the thread, we actually wanted to have ECALL be the
instruction triggering the semihosting call, but at the time, the
standard debug interface could not drop into debugger on an ECALL so
we needed something that worked with existing hardware. I haven't
been tracking debug standard but hopefully this feature is in there
now, so maybe we can add that for newer debug interfaces.

ARM also moved to using SVC instead of BKPT for semihosting interface.

Krste
| --
| You received this message because you are subscribed to the Google Groups
| "RISC-V SW Dev" group.
| To unsubscribe from this group and stop receiving emails from it, send an
| email to sw-dev+un...@groups.riscv.org.
| To view this discussion on the web visit
| https://groups.google.com/a/groups.riscv.org/d/msgid/sw-dev/5435d077-86a1-4fdc-93e6-a1d0479f8178%40groups.riscv.org
| .

Liviu Ionescu

unread,
Mar 8, 2020, 3:44:50 AM3/8/20
to kr...@berkeley.edu, Keith Packard, RISC-V SW Dev


> On 8 Mar 2020, at 08:44, kr...@berkeley.edu wrote:
>
> ARM also moved to using SVC instead of BKPT for semihosting interface.

Actually things are a bit more complicated.

According to Chapter 3 of "Semihosting for AArch32 and AArch64", Release 2.0":

"The trap instruction can be SVC, HLT, or BKPT, as indicated in Table 3.1: ... These trap instructions are HLT for A64, SVC on A+R profile A32 or T32, and BKPT on M profile. However, it is necessary to change from SVC to HLT instructions to support AArch32 semihosting properly in a mixed AArch32/AArch64 system."

In practical terms, it does not matter what the instruction is, as long as it is defined to break into the debugger and it is possible to distinguish it from debugger breakpoints.

As far as I know, in the current RISC-V ISA only EBKPT is defined to break into the debugger.


Regards,

Liviu

kr...@berkeley.edu

unread,
Mar 8, 2020, 4:27:25 AM3/8/20
to Liviu Ionescu, kr...@berkeley.edu, Keith Packard, RISC-V SW Dev

>>>>> On Sun, 8 Mar 2020 09:44:45 +0200, Liviu Ionescu <i...@livius.net> said:
|| On 8 Mar 2020, at 08:44, kr...@berkeley.edu wrote:
|| ARM also moved to using SVC instead of BKPT for semihosting interface.
| Actually things are a bit more complicated.
| According to Chapter 3 of "Semihosting for AArch32 and AArch64", Release 2.0":

| "The trap instruction can be SVC, HLT, or BKPT, as indicated in Table 3.1: ... These trap instructions are HLT for A64, SVC on A+R profile A32 or T32, and BKPT on M profile. However, it is necessary to change from SVC to HLT instructions to support AArch32 semihosting properly in a mixed AArch32/AArch64 system."

Yes indeed, you're quite correct. It's a little hard to imagine how
it got that convoluted.

| In practical terms, it does not matter what the instruction is, as long as it is defined to break into the debugger and it is possible to distinguish it from debugger breakpoints.
| As far as I know, in the current RISC-V ISA only EBKPT is defined to break into the debugger.

Yes, (actually EBREAK).

Now that original ISA and 0.13 debug spec are through ratification, it
might be worth reopening the discussion about expanding set of EBREAKs
as an extension and/or figuring out if ECALL chains are better way of
supporting semihosting (these were some of the things that were
discussed at the time). But I'll leave that to debug and tracing
steering committee.

Krste

Liviu Ionescu

unread,
Mar 8, 2020, 4:35:58 AM3/8/20
to kr...@berkeley.edu, Keith Packard, RISC-V SW Dev


> On 8 Mar 2020, at 10:27, kr...@berkeley.edu wrote:
>
> ... Now that original ISA and 0.13 debug spec are through ratification, it
> might be worth reopening the discussion about expanding set of EBREAKs
> as an extension and/or figuring out if ECALL chains are better way of
> supporting semihosting (these were some of the things that were
> discussed at the time).

Yes, probably it is the right time to do it.

> But I'll leave that to debug and tracing
> steering committee.

Keith, if you are interested in this, please feel free to contact the debug and tracing team.

If you think I can be of any help, please Cc to my address, I'm no longer subscribed to their lists.


Regards,

Liviu

Michael Chapman

unread,
Mar 8, 2020, 4:37:15 AM3/8/20
to sw-...@groups.riscv.org

On 08/03/2020 08:44, Liviu Ionescu wrote:
> In practical terms, it does not matter what the instruction is, as long as it is defined to break into the debugger and it is possible to distinguish it from debugger breakpoints.
>
> As far as I know, in the current RISC-V ISA only EBKPT is defined to break into the debugger.

In previous discussions there were several ways around this:-

1) The debugger looks at the symbol attached to the EBKPT instruction
and uses that to distinguish it from a normal breakpoint or a
semihosting call.

2) The debugger has a record of breakpoints it placed, and looks up the
location to see if the EBKPT corresponds to a breakpoint it placed. 
This is more problematic than the first case, because in a multicore non
cache coherent and non SMP system (these are quite common in embedded)
where the harts share the code memory, the EBKPT might come from another
debugger which is working to debug a different hart. So the debugger
itself might not be aware that another debugger placed the break point.
The workaround is to make all debuggers pass through a common openOCD
and it is openOCD which manages this (potentially skipping over
breakpoints which belong to a different debugger).

3) A special segment of relocation information is stored in the ELF
binary which contains the location of all the semihosting calls.

4) Add anotheer EBKPT instruction!!


Liviu Ionescu

unread,
Mar 8, 2020, 5:00:01 AM3/8/20
to Michael Chapman, RISC-V SW Dev


> On 8 Mar 2020, at 10:37, Michael Chapman <michael.c...@gmail.com> wrote:
>
>
> 1) The debugger looks at the symbol attached to the EBKPT instruction
> and uses that to distinguish it from a normal breakpoint or a
> semihosting call.

Expensive, since it requires extending the functionality of all existing debuggers (none that I know do this).

> 2) The debugger has a record of breakpoints it placed, ...
> and looks up the
> location to see if the EBKPT corresponds to a breakpoint it placed.

Not reliable, since EBKPT can also be placed explicitly in software, not by the debugger.

> 3) A special segment of relocation information is stored in the ELF
> binary which contains the location of all the semihosting calls.

See 1.

> 4) Add another EBKPT instruction!!

Yes, but hopefully this will be a one time change in the specs, since debuggers will need to support both the new instruction and the current hack.

Doing it in multiple steps and we'll get to the convoluted Arm solution.

Regards,

Liviu

Keith Packard

unread,
Mar 8, 2020, 3:37:34 PM3/8/20
to kr...@berkeley.edu, RISC-V SW Dev
kr...@berkeley.edu writes:

> ARM also moved to using SVC instead of BKPT for semihosting interface.

Frankly, given that we have a working mechanism, I don't see much
benefit to creating something "better" as we'll have to support what
works on existing hardware anyways. A single cross-system mechanism
seems like a neater overall solution than having to pick from a range of
mechanisms which depend on support from the hardware and execution
environment.

I'll write up a section that describes how the existing mechanism was
developed. My goal is to create enough of a standard that the QEMU team
will accept my patches so I don't have to continue to carry a custom
QEMU version around for testing...

--
-keith
signature.asc

Liviu Ionescu

unread,
Mar 8, 2020, 4:23:05 PM3/8/20
to Keith Packard, kr...@berkeley.edu, RISC-V SW Dev


> On 8 Mar 2020, at 21:36, Keith Packard <keith....@sifive.com> wrote:
>
> kr...@berkeley.edu writes:
>
>> ARM also moved to using SVC instead of BKPT for semihosting interface.
>
> Frankly, given that we have a working mechanism, I don't see much
> benefit to creating something "better" as we'll have to support what
> works on existing hardware anyways. A single cross-system mechanism
> seems like a neater overall solution than having to pick from a range of
> mechanisms which depend on support from the hardware and execution
> environment.

Fully agree. Unfortunately this argument did not work in the first round of discussions. The solution implemented in the RISC-V libgloss, which assumes the presence of an ECALL handler (which obviously crashes on bare-metal) was considered a better starting point.

> I'll write up a section that describes how the existing mechanism was
> developed. My goal is to create enough of a standard that the QEMU team
> will accept my patches so I don't have to continue to carry a custom
> QEMU version around for testing...

Good luck with this.

Liviu

Jim Wilson

unread,
Mar 8, 2020, 5:19:41 PM3/8/20
to Liviu Ionescu, Keith Packard, Krste Asanovic, RISC-V SW Dev
On Sun, Mar 8, 2020 at 1:23 PM Liviu Ionescu <i...@livius.net> wrote:
> Fully agree. Unfortunately this argument did not work in the first round of discussions. The solution implemented in the RISC-V libgloss, which assumes the presence of an ECALL handler (which obviously crashes on bare-metal) was considered a better starting point.

libgloss is designed to support multiple targets. The current sole
riscv port using ecall is only intended for simulator support. I've
been waiting for someone to add bare metal support as a second riscv
port. I was hoping that someone would implement a rom monitor
interface that we could then support in libgloss for bare metal
support, but that hasn't happened. Maybe rom monitors have fallen out
of favor? The semihosting scheme using ebreak looks as useful as a
rom monitor interface, and could be supported in libgloss as a second
riscv port for bare metal support.

Jim

Liviu Ionescu

unread,
Mar 8, 2020, 5:32:40 PM3/8/20
to Jim Wilson, Keith Packard, Krste Asanovic, RISC-V SW Dev


> On 8 Mar 2020, at 23:19, Jim Wilson <ji...@sifive.com> wrote:
>
> ... Maybe rom monitors have fallen out of favor?

Do you have any rough estimate of the size of a fully fledged rom monitor?


Liviu


Keith Packard

unread,
Mar 8, 2020, 5:52:38 PM3/8/20
to Jim Wilson, Liviu Ionescu, Krste Asanovic, RISC-V SW Dev
Jim Wilson <ji...@sifive.com> writes:

> The semihosting scheme using ebreak looks as useful as a rom monitor
> interface, and could be supported in libgloss as a second riscv port
> for bare metal support.

I've already got the current semihosting scheme working in a fork of
newlib which doesn't use libgloss (picolibc). Very useful for testing.

--
-keith
signature.asc

Jim Wilson

unread,
Mar 8, 2020, 7:15:15 PM3/8/20
to Liviu Ionescu, Keith Packard, Krste Asanovic, RISC-V SW Dev
On Sun, Mar 8, 2020 at 2:32 PM Liviu Ionescu <i...@livius.net> wrote:
> Do you have any rough estimate of the size of a fully fledged rom monitor?

I have no idea.

Jim

Liviu Ionescu

unread,
Mar 9, 2020, 3:15:23 AM3/9/20
to Jim Wilson, Keith Packard, Krste Asanovic, RISC-V SW Dev
Ok. Assuming the flash is not a major limitation, why would a bare-metal applications use a rom monitor?

Except pathological cases like Arduino, where there is no hardware support to write the flash (or debug), so a small bootloader is needed, a typical device would use a JTAG or similar probe and everything is done through there.

For small devices, a fully fledged rom monitor would probably be larger and more complex than the entire application.

The minimal debug trace output code via semihosting is a few instructions. Even if the full semihosting features are used, the stubs to pass the calls to the debugger are minimal; the complexity of the rom monitor is supported by the debugger (or emulator, in QEMU case), not the application.

> The current sole
> riscv port using ecall is only intended for simulator support.

Then perhaps you have an idea why the toolchain where this specific libgloss is distributed is labeled 'embedded', when it has nothing to do with bare-metal embedded?


Liviu

Jim Wilson

unread,
Mar 9, 2020, 6:36:59 PM3/9/20
to Liviu Ionescu, Keith Packard, Krste Asanovic, RISC-V SW Dev
On Mon, Mar 9, 2020 at 12:15 AM Liviu Ionescu <i...@livius.net> wrote:
> Ok. Assuming the flash is not a major limitation, why would a bare-metal applications use a rom monitor?
> Except pathological cases like Arduino, where there is no hardware support to write the flash (or debug), so a small bootloader is needed, a typical device would use a JTAG or similar probe and everything is done through there.
> For small devices, a fully fledged rom monitor would probably be larger and more complex than the entire application.
> The minimal debug trace output code via semihosting is a few instructions. Even if the full semihosting features are used, the stubs to pass the calls to the debugger are minimal; the complexity of the rom monitor is supported by the debugger (or emulator, in QEMU case), not the application.

Obviously there are tradeoffs. A ROM monitor increases the cost of
the board. But a ROM monitor allows code to port from one board to
another where the ROM monitor can hide board specific details.
Semihosting avoids the cost of the ROM, but requires special code on
the host to use the board. What happens if you disconnect the host?
Who handles the breakpoints? With a ROM monitor, code can continue
running even if the host is disconnected and no special host software
is required. They are both good solutions, with different pros and
cons.

> > The current sole
> > riscv port using ecall is only intended for simulator support.
>
> Then perhaps you have an idea why the toolchain where this specific libgloss is distributed is labeled 'embedded', when it has nothing to do with bare-metal embedded?

Repeatedly asking the same question is not going to change the answer.
All it does is annoy me. Anyways, the answer as I've told you many
times before is that because it *is* an embedded toolchain, and it
*does* work with bare-metal embedded applications ... provided it is
used in tandem with an appropriate vendor specific BSP.

Jim

Tommy Murphy

unread,
Mar 9, 2020, 6:41:16 PM3/9/20
to Jim Wilson, Liviu Ionescu, Keith Packard, Krste Asanovic, RISC-V SW Dev
Sorry - first reply sent only to Jim...

>  What happens if you disconnect the host?
> Who handles the breakpoints?  

That can be dealt with without having to resort to a ROM monitor - e.g.



From: Jim Wilson <ji...@sifive.com>
Sent: Monday 9 March 2020 22:36
To: Liviu Ionescu <i...@livius.net>
Cc: Keith Packard <keith....@sifive.com>; Krste Asanovic <kr...@berkeley.edu>; RISC-V SW Dev <sw-...@groups.riscv.org>
Subject: Re: [sw-dev] Creating a spec for semihosting
 
--
You received this message because you are subscribed to the Google Groups "RISC-V SW Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sw-dev+un...@groups.riscv.org.

Jim Wilson

unread,
Mar 9, 2020, 6:52:48 PM3/9/20
to Tommy Murphy, Liviu Ionescu, Keith Packard, Krste Asanovic, RISC-V SW Dev
On Mon, Mar 9, 2020 at 3:41 PM Tommy Murphy <tommy_...@hotmail.com> wrote:
> > What happens if you disconnect the host?
> > Who handles the breakpoints?
>
> That can be dealt with without having to resort to a ROM monitor - e.g.
> https://wiki.segger.com/Semihosting#Ways_to_halt_the_target_CPU

That talks about skipping the breakpoint with a trap handler. That
keeps the device running, but the I/O doesn't happen anymore. There
are applications where that doesn't matter. And other applications
where that would be inconvenient. Anyways, as I said, both
semihosting and rom monitors have pros and cons.

Jim

Tommy Murphy

unread,
Mar 9, 2020, 6:59:19 PM3/9/20
to Jim Wilson, Liviu Ionescu, Keith Packard, Krste Asanovic, RISC-V SW Dev
> That talks about skipping the breakpoint with a trap handler.  That
> keeps the device running, but the I/O doesn't happen anymore. 

Surely it's obvious that when the debugger is not connected then the semihosting operations become "nops"?
I was just addressing the question of how the semihosting would not stop the target operating when the debugger was not connected.

I agree that any potential solution has its own pros and cons.
But semihosting without the need for a ROM monitor is definitely something that many (most?) bare metal embedded developers will expect to have.

Liviu Ionescu

unread,
Mar 9, 2020, 7:04:51 PM3/9/20
to Tommy Murphy, Jim Wilson, Keith Packard, Krste Asanovic, RISC-V SW Dev


> On 10 Mar 2020, at 00:41, Tommy Murphy <tommy_...@hotmail.com> wrote:
>
> Sorry - first reply sent only to Jim...
>
> > What happens if you disconnect the host?
> > Who handles the breakpoints?
>
> That can be dealt with without having to resort to a ROM monitor - e.g.
>
> https://wiki.segger.com/Semihosting#Ways_to_halt_the_target_CPU

And also all Cortex-M projects generated by the GNU MCU Eclipse used a similar solution:

https://github.com/gnu-mcu-eclipse/eclipse-plugins/blob/e8bbf7598c05b3bb7ddab4f9a66a9e9623e684a9/bundles/ilg.gnumcueclipse.templates.core/templates/common/system/src/cortexm/exception_handlers.c#L385

However please note that, according to the specs, this question is hypothetical, since by design no semihosted application should be executed without a debugger connection.

Regular release images **do not** and **should not** use semihosting. Semihosting is intended for running tests, usually unit tests, not applications.


Regards,

Liviu


Liviu Ionescu

unread,
Mar 9, 2020, 7:08:01 PM3/9/20
to Tommy Murphy, Jim Wilson, Keith Packard, Krste Asanovic, RISC-V SW Dev


> On 10 Mar 2020, at 00:59, Tommy Murphy <tommy_...@hotmail.com> wrote:
>
> ... semihosting without the need for a ROM monitor is definitely something that many (most?) bare metal embedded developers will expect to have.

absolutely. at least any embedded developer who ever touched a Cortex-M.

Liviu


Thomas Hornschuh

unread,
Apr 3, 2020, 3:23:56 PM4/3/20
to RISC-V SW Dev, i...@livius.net, keith....@sifive.com, kr...@berkeley.edu
At least for me ROM Monitors has not fallen out favor :-)

In my FPGA based RISC-V implementation I have implemened a ROM Monitor which also supports the ebreak based syscall interface (shamelessly copied from RISC-V pk).
My memory map (DRAM at address 0) is organized in a way that I can run programs compiled for spike/pk directly on the hardware. I'm not using this often anymore, but at the beginning it helped me a lot. 
I also created a gdbstub which can be linked to the programs to allow debugging over a serial port. This is all much easier on an FPGA than jtag/OpenOCD, etc. 
The ROM comes also "for free" in an FPGA with Block RAMs: 

Liviu Ionescu

unread,
Apr 3, 2020, 5:23:38 PM4/3/20
to Thomas Hornschuh, RISC-V SW Dev, keith....@sifive.com, kr...@berkeley.edu


> On 3 Apr 2020, at 22:23, Thomas Hornschuh <thomas.h...@googlemail.com> wrote:
>
> In my FPGA based RISC-V implementation I have implemened a ROM Monitor which also supports the ebreak based syscall interface

If you think that this solution scales, and is generic enough for all RISC-V devices, then make a proposal to use it instead of the Arm semihosting specs.

If approved, ask all embedded tools developers (debuggers, GDB servers, IDEs, etc) to implement it.


Good luck,

Liviu

Jim Wilson

unread,
Apr 3, 2020, 5:36:22 PM4/3/20
to Liviu Ionescu, Thomas Hornschuh, RISC-V SW Dev, Keith Packard, Krste Asanovic
On Fri, Apr 3, 2020 at 2:23 PM Liviu Ionescu <i...@livius.net> wrote:
> If you think that this solution scales, and is generic enough for all RISC-V devices, then make a proposal to use it instead of the Arm semihosting specs.

It isn't a replacement for semihosting. It is an additional option.
ARM has both rom monitors and semihosting. We can too.

Jim

Liviu Ionescu

unread,
Apr 3, 2020, 5:46:38 PM4/3/20
to Jim Wilson, Thomas Hornschuh, RISC-V SW Dev, Keith Packard, Krste Asanovic


> On 4 Apr 2020, at 00:36, Jim Wilson <ji...@sifive.com> wrote:
>
> It isn't a replacement for semihosting. It is an additional option.
> ARM has both rom monitors and semihosting. We can too.

Sure. But the title is "Creating a spec for semihosting". And none of the Cortex-M devices need rom monitors for semihosting.

I guess Keith would appreciate some help in creating these specs, preferably reusing the Arm v2.0 specs, and I doubt these discussions about legacy solutions are of great help for him.


Regards,

Liviu

Thomas Hornschuh

unread,
Apr 3, 2020, 5:48:11 PM4/3/20
to RISC-V SW Dev, thomas.h...@googlemail.com, keith....@sifive.com, kr...@berkeley.edu
I'm not sure what you want to say with your sarcastic statement.

I only commented on the idea of using the ecall interface for a ROM monitor. I think I mentioned it already more than a year ago in the SiFive forum on s discussion about libgloss.
I'm aware that the ROM monitor approach is a niche use case, I'm not sure if it is worth an official spec. Nevertheless the interface already exists in the proxy kernel. 
Also my gdbstub is just an adaption of the gdbstub code from the standard gdb distribution and it is based on standard RISC-V privilege spec.
For my own convenience I have implemented a special single step CSR in my core, but it may also be possible to implement single step solely in software. 

Nevertheless FPGA RISC-V cores are popular, for example the LiteX project has various setups based on the  VexRISCV ported to several FPGA boards. It uses also a boot ROM approach, as I already said for typical FPGA dev boards this is often more convenient than JTAG. 

Thomas


Am Freitag, 3. April 2020 23:23:38 UTC+2 schrieb Liviu Ionescu:

Liviu Ionescu

unread,
Apr 3, 2020, 6:03:47 PM4/3/20
to Thomas Hornschuh, RISC-V SW Dev, keith....@sifive.com, kr...@berkeley.edu


> On 4 Apr 2020, at 00:48, 'Thomas Hornschuh' via RISC-V SW Dev <sw-...@groups.riscv.org> wrote:
>
> ... a boot ROM approach ... for typical FPGA dev boards this is often more convenient than JTAG.

Ok, but how can this help Keith upstream his QEMU semihosting patches?

Not to mention, how does this help those who use real devices? Does the HiFive1 board come with such a ROM monitor that developers can use during software development and for running tests? Does any of the other SiFive Freedom E/S cores come with such a monitor? Does any other RISC-V real microcontroller class devices from other vendors come with such monitors?


Regards,

Liviu


Keith Packard

unread,
Apr 3, 2020, 7:24:37 PM4/3/20
to Thomas Hornschuh, RISC-V SW Dev, thomas.h...@googlemail.com, kr...@berkeley.edu
Thomas Hornschuh <thomas.h...@googlemail.com> writes:

> I only commented on the idea of using the ecall interface for a ROM
> monitor. I think I mentioned it already more than a year ago in the SiFive
> forum on s discussion about libgloss.

Seems like building a ROM monitor is a fine activity and would be really
useful for many environments. Not having to use JTAG for debugging is
really cool, and something I wish I had in more environments. I can only
imagine how much better 8-bit MCU debugging would have been if I had GDB
available.

I'm currently using semihosting to run picolibc tests under QEMU, and I
need semihosting instead of just a ROM monitor to be useful.
Semihosting allows me to get the exit status from the tests. When the
app-under-test invokes the semihosting exit call, QEMU exits with the
provided status. As an added bonus, I get stdout from the test reported
in QEMU output, without requiring a virtual device in QEMU and an
associated device driver in the test setup.

Semihosting is also necessary for building a software stack without
having circular dependencies. With semihosting support, picolibc does
not depend on a driver library (e.g. freedom-metal) to be able to build
and test the code, and freedom-metal uses many libc calls in its
implementation.

I suspect even your ROM monitor includes calls to basic libc functions
like memset and memcpy, so you'll need libc to be built before you can
build that.

--
-keith
signature.asc

Maciej W. Rozycki

unread,
Apr 3, 2020, 7:25:54 PM4/3/20
to Liviu Ionescu, Jim Wilson, Thomas Hornschuh, RISC-V SW Dev, Keith Packard, Krste Asanovic
On Sat, 4 Apr 2020, Liviu Ionescu wrote:

> > It isn't a replacement for semihosting. It is an additional option.
> > ARM has both rom monitors and semihosting. We can too.
>
> Sure. But the title is "Creating a spec for semihosting". And none of
> the Cortex-M devices need rom monitors for semihosting.

Hmm, semihosting is supposed to be neutral to a debug stub it has been
implemented along with. You can have semihosting implemented in a JTAG
probe driver or firmware talking over serial/USB/Ethernet/whatever, or you
can have it in a ROM monitor talking over serial, or you can have it in a
simulator. All such use cases ought to be supported by a semihosting
solution, just as they can support a debug stub (at least for GDB, which
is what I have experience with).

Maciej

Keith Packard

unread,
Apr 3, 2020, 7:35:03 PM4/3/20
to Liviu Ionescu, Jim Wilson, Thomas Hornschuh, RISC-V SW Dev, Krste Asanovic
Liviu Ionescu <i...@livius.net> writes:

> I guess Keith would appreciate some help in creating these specs,
> preferably reusing the Arm v2.0 specs, and I doubt these discussions
> about legacy solutions are of great help for him.

Yes, I'm really interested in having any feedback about the approach
we've proposed for semihosting -- adapting the ARM v2.0 semihosting spec
for the RISC-V ISA.

The QEMU community is reviewing my patches adding support for this and
have requested that we provide something a bit more 'official' than the
current footnotes in the ISA docs before they'll be willing to merge the
code. Picolibc CI testing needs this support; right now I'm hosting
a QEMU fork for that.

Here's a link to the current draft on its github page:

https://github.com/keith-packard/riscv-semihosting-spec/blob/main/riscv-semihosting-spec.adoc

I'd love to get this ready for integration into the main RISC-V ISA spec
so that I can point the QEMU people at that so that the QEMU support can
land upstream and I can get picolibc CI running without requiring a
home-brew QEMU fork.

--
-keith
signature.asc

Jim Wilson

unread,
Apr 3, 2020, 8:31:22 PM4/3/20
to Keith Packard, Liviu Ionescu, Thomas Hornschuh, RISC-V SW Dev, Krste Asanovic
On Fri, Apr 3, 2020 at 4:34 PM Keith Packard <keith....@sifive.com> wrote:
> The QEMU community is reviewing my patches adding support for this and
> have requested that we provide something a bit more 'official' than the
> current footnotes in the ISA docs before they'll be willing to merge the
> code. Picolibc CI testing needs this support; right now I'm hosting
> a QEMU fork for that.

I would suggest just creating a github.com/riscv/riscv-semihosting
tree and call it official. Krste suggested adding it to another spec
like the debug and trace spec. I'm not a part of that task group, and
don't know if anyone has tried formally submitting the semihosting
spec there. Going through the debug and trace group may take longer,
as presumably they have a process that needs to be followed, and it
doesn't really become official until they vote on it.

Jim

Keith Packard

unread,
Apr 4, 2020, 1:58:32 AM4/4/20
to Maciej W. Rozycki, Liviu Ionescu, Jim Wilson, Thomas Hornschuh, RISC-V SW Dev, Krste Asanovic
"Maciej W. Rozycki" <ma...@wdc.com> writes:

> Hmm, semihosting is supposed to be neutral to a debug stub it has been
> implemented along with.

That's a good point. The current semihosting design uses a special
sequence containing an ebreak. A ROM monitor should be set up to trap
exceptions and can be changed to look for a breakpoint trap and check
for the special semihosting sequence around the trap address. Anyone see
any holes in that plan?

--
-keith
signature.asc

Keith Packard

unread,
Apr 4, 2020, 2:01:35 AM4/4/20
to Jim Wilson, Liviu Ionescu, Thomas Hornschuh, RISC-V SW Dev, Krste Asanovic
Jim Wilson <ji...@sifive.com> writes:

> I would suggest just creating a github.com/riscv/riscv-semihosting
> tree and call it official.

That seems like a fine process; I'd like to have a bit of review here
before I mark it "official" so that it doesn't turn out to have some
horrible problems.

One question I've got -- does semihosting work only in M mode, or does
it work in less privileged modes as well?

--
-keith
signature.asc

Liviu Ionescu

unread,
Apr 4, 2020, 3:33:57 AM4/4/20
to Keith Packard, Jim Wilson, Thomas Hornschuh, RISC-V SW Dev, Krste Asanovic


> On 4 Apr 2020, at 02:34, Keith Packard <keith....@sifive.com> wrote:
>
> Yes, I'm really interested in having any feedback about the approach
> we've proposed for semihosting -- adapting the ARM v2.0 semihosting spec
> for the RISC-V ISA.

+1

Liviu

Liviu Ionescu

unread,
Apr 4, 2020, 3:56:54 AM4/4/20
to Keith Packard, Jim Wilson, Thomas Hornschuh, RISC-V SW Dev, Krste Asanovic


> On 4 Apr 2020, at 09:01, Keith Packard <keith....@sifive.com> wrote:
>
> Jim Wilson <ji...@sifive.com> writes:
>
>> I would suggest just creating a github.com/riscv/riscv-semihosting
>> tree and call it official.
>
> That seems like a fine process;

I suggest you arrange to transfer your existing project to github.com/riscv; due to GitHub specifics, it might be a bit convoluted, but manageable (I just did this with the GNU MCU Eclipse project, which is now part of Eclipse Foundation). Be sure you get enough rights at destination, to be able to further manage the project.

> I'd like to have a bit of review here
> before I mark it "official" so that it doesn't turn out to have some
> horrible problems.

It is good to be careful, but I don't expect any horrible problems.

And even if marked "official", this does not mean that the specs cannot be improved in case of further developments.

>
> One question I've got -- does semihosting work only in M mode, or does
> it work in less privileged modes as well?

Do you have any specific concerns related to less privileged modes?

I don't think that the Arm specs mention any restrictions; break instructions always break into the debugger, and if the debugger is semihosting aware, it might provide some services, otherwise execution will stop, like for any breakpoint. This, for example, might allow any program, in any mode, to use the separate trace debug channel (when connected to the debugger, of course).


But I agree that tests, which use the full semihosting API, will most likely run in M mode.


Regards,

Liviu







Thomas Hornschuh

unread,
Apr 4, 2020, 10:56:28 AM4/4/20
to RISC-V SW Dev, thomas.h...@googlemail.com, kr...@berkeley.edu


Am Samstag, 4. April 2020 01:24:37 UTC+2 schrieb Keith Packard:
Thomas Hornschuh <thomas....@googlemail.com> writes:

> I only commented on the idea of using the ecall interface for a ROM
> monitor. I think I mentioned it already more than a year ago in the SiFive
> forum on s discussion about libgloss.

Seems like building a ROM monitor is a fine activity and would be really
useful for many environments. Not having to use JTAG for debugging is
really cool, and something I wish I had in more environments. I can only
imagine how much better 8-bit MCU debugging would have been if I had GDB
available.


Thanks for your feedback. My initial intention for posting here was mainly for answering Jim Wilson. I'm sorry when my post may not directly helping you with writing a semi hosting spec, as Liviu pointed out. B


 
I'm currently using semihosting to run picolibc tests under QEMU, and I
need semihosting instead of just a ROM monitor to be useful.

What I have done with my monitor is indeed not really semi hosting, it is just implementing a syscall interface. But nothing speaks against implementing the proposed semihosting sequence in a software monitor. I like the idea, maybe I give it a try. The only real disadvantage of a monitor firmware is that it is not transparent in M-Mode. There is only one mtvec register and therefore a common trap handler for the monitor and the "user" program. Somewhere in the RISC-V spec it was mentioned that M-Mode could be used as a firmware / microcode level interface to e.g. emulate features not handled by the hardware like misaligned load/stores. For code in S and U mode this works, but unfortunately not for simple MCUs that use M mode as regulare mode of operation. To support hardware debugging an extra D mode had to be introduced. 
 
Semihosting allows me to get the exit status from the tests. When the
app-under-test invokes the semihosting exit call, QEMU exits with the
provided status. As an added bonus, I get stdout from the test reported
in QEMU output, without requiring a virtual device in QEMU and an
associated device driver in the test setup.

I have taken a look into picolibc, I really like it. Especially I appreciate your documentation about startup code, linker scripts, etc. When I started with bare metal RISC-V this were exactly the topics where I got a lot of struggle at the beginning. As normal userland application developer you normally do not need to bother with these things. I think I will give picolib a try when I have time. 
BTW: Is there a good channel to chat about picolib C, I don't want to hijack this discussion for it?




I suspect even your ROM monitor includes calls to basic libc functions
like memset and memcpy, so you'll need libc to be built before you can
build that.

Yes indeed. My monitor uses newlib with custom startup code and it does not use any calls which will end up in libgloss. It also has some local implementations, e.g. for vsprintf and friends. 
Also thinks like isalpha() blew up the rodata segment with locale tables.  


Thomas

Keith Packard

unread,
Apr 4, 2020, 5:42:32 PM4/4/20
to 'Thomas Hornschuh' via RISC-V SW Dev, thomas.h...@googlemail.com, kr...@berkeley.edu
"'Thomas Hornschuh' via RISC-V SW Dev" <sw-...@groups.riscv.org> writes:

> I have taken a look into picolibc, I really like it. Especially I
> appreciate your documentation about startup code, linker scripts, etc. When
> I started with bare metal RISC-V this were exactly the topics where I got a
> lot of struggle at the beginning. As normal userland application developer
> you normally do not need to bother with these things. I think I will give
> picolib a try when I have time.

Thanks for your kind words. If you're already using newlib, switching to
picolibc should be straightforward; they share a bunch of code, except
for stdio and TLS support.

> BTW: Is there a good channel to chat about picolib C, I don't want to
> hijack this discussion for it?

picolibc has a separate email list and github page; you're welcome to
use either to communicate with picolibc developers.

github page:

https://github.com/keith-packard/picolibc/

mailing list:

http://keithp.com/mailman/listinfo/picolibc

> Yes indeed. My monitor uses newlib with custom startup code and it does
> not use any calls which will end up in libgloss. It also has some local
> implementations, e.g. for vsprintf and friends.

I suspect you'll find the picolibc implementations of those functions to
be a bit more friendly in a rom-monitor. Picolibc has a stdio that
doesn't need an allocator and uses only a few bytes of ram for a FILE
object (20 on 32-bit machines).

> Also thinks like isalpha() blew up the rodata segment with locale tables.

Picolibc defaults to having only the C locale, and not including
multi-byte support. That means using isalpha costs only 257 bytes of
memory for the ASCII _ctype_ table (it's not even ISO Latin-1).

You can build it with wider locale support, but that seems incompatible
with the expected usage model.

--
-keith
signature.asc

Keith Packard

unread,
Apr 6, 2020, 1:00:49 AM4/6/20
to Jim Wilson, Liviu Ionescu, Thomas Hornschuh, RISC-V SW Dev, Krste Asanovic
Jim Wilson <ji...@sifive.com> writes:

> I would suggest just creating a github.com/riscv/riscv-semihosting
> tree and call it official.

Done. I got Andrew Waterman's help to create a new project and give me
write access:

https://github.com/riscv/riscv-semihosting-spec

I've tagged the current contents as version 0.2, you can get a PDF
version of this from the github release:

https://github.com/riscv/riscv-semihosting-spec/releases/download/0.2/riscv-semihosting-spec.pdf

--
-keith
signature.asc
Reply all
Reply to author
Forward
0 new messages