Hi Dean,
> On 16/07/2018, at 9:31 AM, Dean Ancajas <
dban...@gmail.com> wrote:
>
> Hi guys,
> I am writing a baremetal program just for fun. I want to create a simple shell program and build it to something bigger eventually. Would like to know how do you access the input characters from keyboard? It seems there is no inb/outb instructions like x86. The build environment I am using is QEMU + virt machine. This uses the Virtio MMIO but I have no idea how to proceed from here. I am looking for info such as this:
https://wiki.osdev.org/Interrupts#From_the_keyboard.27s_perspective but for riscv qemu virt machine.
Here’s some simple bare metal M-mode only code that has polled IO routines printf, getchar and putchar for all of the RISC-V boards in QEMU (spike, sifive_e, sifive_u and virt) for both rv32 and rv64:
-
https://github.com/michaeljclark/riscv-probe
The code is lifted from riscv-pk/bbl [1]. I factored out a subset of the IO routines from BBL so that I could query controls and status registers in spike and QEMU. riscv-pk is not really configured to be used as a library but it contains polled IO routines for a variety of output devices (HTIF, SiFive UART, NS16550A) so it’s a useful starting point for bare metal code. riscv-probe has printf, getchar and putchar, but not much else i.e. no malloc. You just need a multilib toolchain in your path and it should build.
For interrupts, you can take a look at some of the examples from SiFive’s Freedom-E-SDK [2] as it contains a PLIC driver [9]. The binaries targeted for the HiFive1 will run on QEMU's ’sifive_e’ machine. There is a blog post with how to invoke the examples from the Freedom-E-SDK in QEMU [3]. The Freedom-U-SDK [4] builds and runs Linux in QEMU however it uses Linux VirtIO for disk and network, and BBL’s SBI (Supervisor Binary Interface) or 16550A UART for console IO i.e. it depends on an SBI trap handler set up by BBL and for the S-mode (Supervisor), Linux, to use ECALL to call into these boot time IO routines supported by the Monitor. BBL is both a monitor and a loader as it stays resident to handle timer interrupts and emulation (misaligned accesses, floating point, rdtime via timecmp MMIO register from device-tree, etc).
Palmer’s blog post [5] explains more about booting a Supervisor on the U-series which is the same as the ‘virt’ machine in QEMU. Booting a Supervisor is slightly more complex as it requires coordination across multiple protection domains, M-mode (BBL monitor and potentially trust management functions if using PMPs), an S-mode Supervisor that manages Virtual Memory, IO and Processes, etc, which calls into the monitor (BBL) using ECALL, and of course U-mode for User processes which are isolated from each other using Virtual Memory protection (VM vs PMP which is a simpler Physical Memory Protection scheme for protecting physical address regions, that are accessible to M-mode monitors).
If you want to use VirtIO from a bare metal program, that will be quite a bit of work as VirtIO is a relatively complex protocol [6]. The QEMU virt machine has an NS16550A UART at 0x1000_1000 [7] on irq 10 [8], and DRAM is located at 0x8000_0000. You could just used polled IO or interrupt IO and talk directly to the UART for keyboard input. If you want interrupt driven IO in M-mode on the ‘virt’ machine, you’ll need a PLIC driver [9] and to configure interrupts via the PLIC, set the mie.MEIP and mstatus.MIE bits. You can find the bit masks for the CSR control bits in encoding.h [10] (there are multiple copies of this file floating around various RISC-V projects).
Lastly, the QEMU wiki has an overview of each of its RISC-V machines and their supported IO mechanisms and interrupt controllers [11].
Michael.
[1]
https://github.com/riscv/riscv-pk
[2]
https://github.com/sifive/freedom-e-sdk/
[3[
https://www.sifive.com/blog/2017/12/20/risc-v-qemu-part-1-privileged-isa-hifive1-virtio/
[4]
https://github.com/sifive/freedom-u-sdk/
[5]
https://www.sifive.com/blog/2017/10/09/all-aboard-part-6-booting-a-risc-v-linux-kernel/
[6]
http://docs.oasis-open.org/virtio/virtio/v1.0/virtio-v1.0.html
[7]
https://github.com/riscv/riscv-qemu/blob/360a7809d235ba0e8178daa2785f7932acc5df71/hw/riscv/virt.c#L46-L58
[8]
https://github.com/riscv/riscv-qemu/blob/360a7809d235ba0e8178daa2785f7932acc5df71/include/hw/riscv/virt.h#L44-L49
[9]
https://github.com/sifive/freedom-e-sdk/tree/master/bsp/drivers/plic
[10]
https://github.com/riscv/riscv-pk/blob/master/machine/encoding.h
[11]
https://github.com/riscv/riscv-qemu/wiki