blob: 6d8b8e9e6ef08b4a1142371c1a562bc432255b64 [file]
#!/usr/bin/env bash
# Licensed under the Apache-2.0 license
# SPDX-License-Identifier: Apache-2.0
#
# Launch qemu-system-riscv32 for the ot-earlgrey machine and daemonize it.
# The CPU starts paused (-S); the runner must send `cont` to $QEMU_MONITOR
# before any firmware output appears.
#
# Ported from opentitan/hw/top_earlgrey/sw/util/qemu.sh.
# Stripped for v1: JTAG sockets, GPIO socket, I2C, USB, extra UARTs.
# UART0 uses a Unix socket (not PTY) for Bazel sandbox hermeticity.
#
# Required environment variables:
# QEMU_BIN path to qemu-system-riscv32
# QEMU_CONFIG path to QEMU readconfig INI (from cfggen.py)
# QEMU_ROM path to test ROM ELF
# QEMU_OTP path to mutable raw OTP image (from otptool.py)
# QEMU_FLASH path to mutable flash image (from flashgen.py)
# QEMU_SPIFLASH path to mutable 32 MiB SPI-flash backing store
# QEMU_PIDFILE path where QEMU writes its PID after daemonizing
# QEMU_LOG path for QEMU's -D log output
# QEMU_ICOUNT icount shift value (default: 6)
# QEMU_MONITOR path for the QEMU monitor Unix socket (HMP mode)
# QEMU_UART_SOCKET path for the UART0 Unix socket
set -e
_fail() {
echo "qemu_start.sh: $1" >&2
exit 1
}
# Mandatory checks — all must be non-empty strings pointing at real files.
[ -n "$QEMU_BIN" ] || _fail "QEMU_BIN is unset"
[ -f "$QEMU_BIN" ] || _fail "QEMU_BIN not found: $QEMU_BIN"
[ -n "$QEMU_CONFIG" ] || _fail "QEMU_CONFIG is unset"
[ -f "$QEMU_CONFIG" ] || _fail "QEMU_CONFIG not found: $QEMU_CONFIG"
[ -n "$QEMU_ROM" ] || _fail "QEMU_ROM is unset"
[ -f "$QEMU_ROM" ] || _fail "QEMU_ROM not found: $QEMU_ROM"
[ -n "$QEMU_OTP" ] || _fail "QEMU_OTP is unset"
[ -f "$QEMU_OTP" ] || _fail "QEMU_OTP not found: $QEMU_OTP"
[ -n "$QEMU_FLASH" ] || _fail "QEMU_FLASH is unset"
[ -f "$QEMU_FLASH" ] || _fail "QEMU_FLASH not found: $QEMU_FLASH"
[ -n "$QEMU_SPIFLASH" ] || _fail "QEMU_SPIFLASH is unset"
[ -f "$QEMU_SPIFLASH" ] || _fail "QEMU_SPIFLASH not found: $QEMU_SPIFLASH"
[ -n "$QEMU_PIDFILE" ] || _fail "QEMU_PIDFILE is unset"
[ -n "$QEMU_LOG" ] || _fail "QEMU_LOG is unset"
[ -n "$QEMU_MONITOR" ] || _fail "QEMU_MONITOR is unset"
[ -n "$QEMU_UART_SOCKET" ] || _fail "QEMU_UART_SOCKET is unset"
QEMU_ICOUNT="${QEMU_ICOUNT:-6}"
qemu_args=(
# No GUI.
"-display" "none"
# Earlgrey 1.0.0 machine.
"-M" "ot-earlgrey"
# RTL constants from cfggen.
"-readconfig" "$QEMU_CONFIG"
# Daemonize after initialization; write PID to file.
"-daemonize"
"-pidfile" "$QEMU_PIDFILE"
# Start CPU paused — runner sends `cont` via monitor before tailing UART.
"-S"
# Log guest errors and unimplemented peripheral access (invaluable on failures).
"-D" "$QEMU_LOG"
"-d" "guest_errors,unimp"
# ROM image.
"-object" "ot-rom_img,id=rom,file=${QEMU_ROM}"
# OTP backing store (pflash).
"-drive" "if=pflash,file=${QEMU_OTP},format=raw"
# Firmware flash (mtd bus 2 = eflash).
"-drive" "if=mtd,id=eflash,bus=2,file=${QEMU_FLASH},format=raw"
# SPI Host 0 backing store — ot-earlgrey machine requires this drive even
# when the test does not exercise SPI. W25Q256 = 32 MiB, matches the dd
# image created by the runner.
"-global" "ot-earlgrey-board.spiflash0=w25q256"
"-drive" "if=mtd,file=${QEMU_SPIFLASH},format=raw,bus=0"
# Virtual-time pacing: 1 GHz >> icount ns/insn ≈ wall-clock alignment.
"-icount" "shift=${QEMU_ICOUNT},align=on,sleep=on"
# Disable fatal-reset so tests that trigger a reset don't kill QEMU.
"-global" "ot-rstmgr.fatal_reset=0"
# Disable keymgr flash-seed check (info pages not spliced; would error).
"-global" "ot-keymgr.disable-flash-seed-check=true"
# Suppress test-status-register exit so multiple resets are possible.
"-global" "ot-ibex_wrapper.dv-sim-status-exit=off"
# Monitor socket in HMP (readline) mode — runner writes plain `cont\n`.
"-chardev" "socket,id=monitor,path=${QEMU_MONITOR},server=on,wait=off"
"-mon" "chardev=monitor,mode=readline"
# UART0 as a Unix socket (not PTY) for hermeticity inside Bazel sandboxes.
"-chardev" "socket,path=${QEMU_UART_SOCKET},server=on,wait=off,id=uart0"
"-serial" "chardev:uart0"
# UART1 — no external endpoint needed for software-loopback tests.
"-serial" "null"
)
echo "qemu_start.sh: launching ${QEMU_BIN} with ${#qemu_args[@]} args" >&2
exec "$QEMU_BIN" "${qemu_args[@]}"