EarlGrey 2.5.2-RC0
- ePMP
- Zbr ISA extension (crc32 instructions)
- AES
- missing side-loading
- AON Timer
- CSRNG
- EDN
- HMAC
- OTBN
- missing side-loading
- SPI data flash (from QEMU upstream w/ fixes)
- SPI Host controller
- Timer
- UART
- missing RX timeout, break support
- bitrate is not paced vs. selected baurate
Devices in this group implement subset(s) of the real HW.
- Flash controller
- read-only features only
- OTP controller
- read-only features only, ECC is ignored
- Entropy Src
- test/health features are not supported
- AES CTR not supported (uses xoroshiro128++ reseeded from entropy src)
- GPIO
- A CharDev backend can be used to get GPIO outputs and update GPIO inputs,
- KMAC
- Side loading is not supported
- ROM controller
- SRAM controller
- Initialization and scrambling with dummy key supported
- Wait for init completion (bus stall) emulated
In this group, device CSRs are supported (w/ partial or full access control & masking) but only some features are implemented.
- AST
- entropy source only (from host source)
- Clock Manager
- Clock hints only
- Ibex wrapper
- random source (connected to CSR), FPGA version, virtual remapper
- Lifecycle controller
- only forwards LC state from OTP
- Power Manager
- Fast FSM is partially supported, Slow FSM is bypassed
- Interactions with other devices (such as the Reset Manager) are limited
Devices in this group are mostly implemented with a RAM backend or real CSRs but do not implement any useful feature (only allow guest test code to execute as expected).
- Alert controller
- Key manager
- KMAC (in development)
- GPIO
- Pinmux
- Power Manager
- Sensor
qemu-system-riscv32 -M ot-earlgrey,no_epmp_cfg=true -display none -serial mon:stdio \
-kernel hello.elf
See the section "Useful execution options" for documentation about the no_epmp_cfg
option.
qemu-system-riscv32 -M ot-earlgrey -display none -serial mon:stdio \
-object ot-rom_img,id=rom,file=rom_with_fake_keys_fpga_cw310.elf \
-drive if=pflash,file=otp-rma.raw,format=raw \
-drive if=mtd,bus=2,file=flash.raw,format=raw
where otp-rma.raw
contains the RMA OTP image and flash.raw
contains the signed binary file of the
ROM_EXT and the BL0. See otptool.py
and flashgen.py
tools to
generate the .raw
image files.
See rom_ctrl.md
for information on ROM option.
See tools.md
-
-icount 6
reduces the execution speed of the vCPU (Ibex core) to 1GHz >> 6, i.e. ~15MHz, which should roughly match the expected speed of the Ibex core running on the CW310 FPGA, which is set to 10 MHz. This option is very useful/mandatory to run many OpenTitan tests that rely on time or CPU cycle to validate features. Using-icount
option slows down execution speed though, so it is not recommended to use it when the main goal is to develop SW to run on the virtual machine. -
no_epmp_cfg=true
can be appended to the machine option switch, i.e.-M ot-earlgrey,no_epmp_cfg=true
to disable the initial ePMP configuration, which can be very useful to execute arbitrary code on the Ibex core without requiring an OT ROM image to boot up. -
ignore_elf_entry=true
can be appended to the machine option switch, i.e.-M ot-earlgrey,ignore_elf_entry=true
to prevent the ELF entry point of a loaded application to update the vCPU reset vector at startup. When this option is used, with-kernel
option for example, the application is loaded in memory but the default machine reset vector is used. -
verilator=true
can be appended to the machine option switch, to select Verilator lowered clocks: i.e.-M ot-earlgrey,verilator=true
to select Verilator reduced clock rates. -
-cpu lowrisc-ibex,x-zbr=false
can be used to force disable the Zbr experimental-and-deprecated RISC-V bitmap extension for CRC32 extension.
-global ot-aes.fast-mode=false
can be used to better emulate AES HW IP, as some OT tests expect the Ibex core to execute while the HW is performing AES rounds. Without this option, the virtual HW may only give back execution to the vCPU once the AES operation is complete, which make those OT tests to fail. Disabling fast mode better emulates the HW to the expense of higher AES latency and throughput.
-display none
can be used to prevent QEMU to open a semi-graphical windows as the default console, and use the current shell instead.
-
-drive if=mtd,id=eflash,bus=2,file=<filename>,format=raw
should be used to specify a path to a QEMU RAW image file used as the OpenTitan internal flash controller image. This RAW file should have been generated with theflashgen.py
tool.Note: MTD bus 2 is assigned to the internal controller with the embedded flash storage. See also the SPI Host section.
-
-global ot-otbn.logfile=<filename>
output OTBN execution message to the specified logfile. When logasm option (see below) is not enabled, only execution termination and error messages are logged.stderr
can be used to log the messages to the standard error stream instead of a file. -
-global ot-otbn.logasm=<true|false>
dumps executed instructions on OTBN core into the logfile filename. Beware that this further slows down execution speed, which could likely result in the guest application on the Ibex core to time out.
-drive if=pflash,file=otp.raw,format=raw
should be used to specify a path to a QEMU RAW image file used as the OpenTitan OTP image. This RAW file should have been generated with theotptool.py
tool.
-
-drive if=mtd,bus=0,file=<filename>,format=raw
should be used to specify a path to a QEMU RAW image file used as the SPI data flash backend file. This RAW file should have been created with the qemu-img tool. There is no dedicated tool to populate this image file for now.qemu-img create -f raw spi.raw 16M
MTD bus 0 is assigned to the SPI0 Host controller and MTD bus 1 is assigned to the SPI1 Host controller. See also Embedded Flash controller section.
-
-global ot-earlgrey-board.spiflash<bus>=<flash_type>
should be used to instanciate a SPI dataflash device of the specified type to the first device (/CS0) of the specified bus. Any SPI dataflash device supported by QEMU can be used. To list the supported devices, usegrep -F 'INFO("' hw/block/m25p80.c | cut -d'"' -f2
-
-global ot-spi_host.start-delay=<time>
may be used to change the default SPI Host FSM start delay. This delay is used to yield back the control to the vCPU before kicking of the execution of a new SPI Host command, so that the guest code gets a chance to check the statuses of the SPI Host right after pushing the command. Without this delay, the SPI Host state may change quickly and report statuses that might be different than the real HW, e.g. a command may already be completed when the guest code reads back the SPI Host status. Time should be specified in ns, and defaults to 20000 (20 µs). -
-
global ot-spi_host.completion-delay=<time>
may be forced to discard the experimental SPI Host clock pacing, which helps to achieve the requested bandwidth on the SPI Host bus, which is always caped with the performances of the QEMU host. Forcing a small value here can help achieving the best SPI Host transfer performances, but decreases accuracy of the SPI Host clock settings. Time should be specified in ns, and defaults to 0 that indicates automatic SPI bus clock management.
-
-serial mon:stdio
, used as the first-serial
option, redirects the virtual UART0 to the current console/shell. -
-chardev socket,id=serial1,host=localhost,port=8001,server=on,wait=off
and-serial chardev:serial1
can be used to redirect UART1 (in this example) to a TCP socket. These options are not specific to OpenTitan emulation, but are useful to communicate over a UART. Note that QEMU offers manychardev
backends, please check QEMU documentation for details.
Most OpenTitan virtual devices can emit log traces. To select which traces should be logged, a plain
text file can be used along with QEMU -trace
option.
To populate this file, the easiest way is to dump all available traces and filter them with a pattern, for example to get all OpenTitan trace messages:
qemu-system-riscv32 -trace help | grep -E '^ot_' > ot_trace.log
qemu-system-riscv32 -trace events=ot_trace.log -D qemu.log ...
- It is highly recommended to use the
-D
option switch when any-trace
or-d
(see below) is selected, to avoid saturating the standard output stream with traces and redirect them into the specified log file.
QEMU provides another way of logging execution of the virtual machine using the -d
option. Those
log messages are not tied to a specific device but rather to QEMU features. -d help
can be used
to enumerate these log features, however the most useful ones are enumerated here:
unimp
reports log messages for unimplemented features, e.g. when the vCPU attempts to read from or write into a memory mapped device that has not been implemented.guest_errors
reports log messages of invalid guest software requests, e.g. attempts to perform an invalid configuration.int
reports all interruptions and exceptions handled by the vCPU. It may be quite verbose but also very useful to track down an invalid memory or I/O access for example. This is the first option to use if the virtual machine seems to stall on start up.in_asm
reports the decoded vCPU instructions that are translated by the QEMU TCG, i.e. here the RISC-V instructions. Note that transcoded instructions are cached and handled by blocks, so the flow of transcoded instruction do not exactly reflect the stream of the executed guest instruction, e.g. may only appear once in a loop. Use the next log option,exec
, to get more detailed but also much more verbose log traces.exec
reports the vCPU execution stream.
Those options should be combined with a comma separator, e.g. -d unimp,guest_errors,int
in_asm
option may be able to report the name of the guest executed function, as long as the guest
application symbols have been loaded. This is the case when the -kernel
option is used to load
an ELF non-stripped file. Unfortunately, this feature is not available for guest applications that
are loaded from a raw binary file (.bin
, .signed.bin
, ...). However the
flashgen.py
script implements a workaround for this feature, please refer to this
script for more details.
Finally, a Rust demangler has been added to QEMU, which enables the QEMU integrated dissambler to emit the demangled names of the Rust symbols for Rust-written guest applications rather than their mangled versions as stored in the ELF file.