Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions rules/opentitan/qemu.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,12 @@ def _test_dispatch(ctx, exec_env, firmware):
# to run, finish, and exit, which we don't want to happen.
qemu_args += ["-global", "ot-ibex_wrapper.dv-sim-status-exit=off"]

# To enable limited support for UART rescue in the ROM_EXT, we need to
# be able to toggle break signals on/off in QEMU's UART and mock this
# in the oversampled `VAL` register.
qemu_args += ["-global", "ot-uart.oversample-break=true"]
qemu_args += ["-global", "ot-uart.toggle-break=true"]

# Add parameter-specified globals.
if param["globals"]:
globals = json.decode(param["globals"])
Expand Down
58 changes: 58 additions & 0 deletions sw/device/silicon_creator/rom_ext/e2e/boot_svc/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ load(
"fpga_params",
"opentitan_binary",
"opentitan_test",
"qemu_params",
)
load("//rules:manifest.bzl", "manifest")

Expand Down Expand Up @@ -40,13 +41,19 @@ opentitan_test(
exec_env = {
"//hw/top_earlgrey:fpga_hyper310_rom_ext": None,
"//hw/top_earlgrey:fpga_cw340_rom_ext": None,
"//hw/top_earlgrey:sim_qemu_rom_ext": None,
},
fpga = fpga_params(
assemble = "{rom_ext}@{rom_ext_slot_a} {firmware}@{owner_slot_a} {firmware}@{owner_slot_b}",
exit_failure = "BFV|PASS|FAIL",
exit_success = "FinalBootLog: 4:AAAA\r\n",
),
linker_script = "//sw/device/lib/testing/test_framework:ottf_ld_silicon_owner_slot_virtual",
qemu = qemu_params(
assemble = "{rom_ext}@{rom_ext_slot_a} {firmware}@{owner_slot_a} {firmware}@{owner_slot_b}",
exit_failure = "BFV|PASS|FAIL",
exit_success = "FinalBootLog: 4:AAAA\r\n",
),
deps = [
":boot_svc_test_lib",
"//sw/device/lib/base:status",
Expand All @@ -66,6 +73,7 @@ opentitan_test(
exec_env = {
"//hw/top_earlgrey:fpga_hyper310_rom_ext": None,
"//hw/top_earlgrey:fpga_cw340_rom_ext": None,
"//hw/top_earlgrey:sim_qemu_rom_ext": None,
},
fpga = fpga_params(
timeout = "moderate",
Expand All @@ -83,6 +91,20 @@ opentitan_test(
""",
),
linker_script = "//sw/device/lib/testing/test_framework:ottf_ld_silicon_owner_slot_virtual",
qemu = qemu_params(
timeout = "moderate",
assemble = "{rom_ext}@{rom_ext_slot_a} {firmware}@{owner_slot_a} {firmware}@{owner_slot_b}",
exit_failure = "BFV|PASS|FAIL",
exit_success = "mode: RESQ\r\n",
# TODO: add bootstrap when QEMU bootstraps instead of splicing firmware
test_cmd = """
--exec="transport init"
--exec="console --non-interactive --exit-success='{exit_success}' --exit-failure='{exit_failure}'"
# Try the `REBO` mode and make sure it works.
--exec="rescue no-op --reset-target=reboot"
no-op
""",
),
deps = [
":boot_svc_test_lib",
"//sw/device/lib/base:status",
Expand All @@ -102,6 +124,7 @@ opentitan_test(
exec_env = {
"//hw/top_earlgrey:fpga_hyper310_rom_ext": None,
"//hw/top_earlgrey:fpga_cw340_rom_ext": None,
# Not supported in QEMU whilst low power is not modelled
},
fpga = fpga_params(
assemble = "{rom_ext}@{rom_ext_slot_a} {firmware}@{owner_slot_a}",
Expand Down Expand Up @@ -139,6 +162,7 @@ NEXT_TEST_SEQUENCES = [
exec_env = {
"//hw/top_earlgrey:fpga_hyper310_rom_ext": None,
"//hw/top_earlgrey:fpga_cw340_rom_ext": None,
"//hw/top_earlgrey:sim_qemu_rom_ext": None,
},
fpga = fpga_params(
assemble = "{rom_ext}@{rom_ext_slot_a} {firmware}@{owner_slot_a} {firmware}@{owner_slot_b}",
Expand All @@ -147,6 +171,11 @@ NEXT_TEST_SEQUENCES = [
exit_success = "FinalBootLog: 3:{}\r\n".format(test_sequence),
),
linker_script = "//sw/device/lib/testing/test_framework:ottf_ld_silicon_owner_slot_virtual",
qemu = qemu_params(
assemble = "{rom_ext}@{rom_ext_slot_a} {firmware}@{owner_slot_a} {firmware}@{owner_slot_b}",
exit_failure = "BFV:.*|PASS|FAIL",
exit_success = "FinalBootLog: 3:{}\r\n".format(test_sequence),
),
deps = [
":boot_svc_test_lib",
"//sw/device/lib/base:status",
Expand All @@ -169,6 +198,7 @@ opentitan_test(
exec_env = {
"//hw/top_earlgrey:fpga_hyper310_rom_ext": None,
"//hw/top_earlgrey:fpga_cw340_rom_ext": None,
"//hw/top_earlgrey:sim_qemu_rom_ext": None,
},
fpga = fpga_params(
assemble = "{rom_ext}@{rom_ext_slot_a} {firmware}@{owner_slot_a} {firmware}@{owner_slot_b}",
Expand All @@ -184,6 +214,12 @@ opentitan_test(
""",
),
linker_script = "//sw/device/lib/testing/test_framework:ottf_ld_silicon_owner_slot_virtual",
qemu = qemu_params(
assemble = "{rom_ext}@{rom_ext_slot_a} {firmware}@{owner_slot_a} {firmware}@{owner_slot_b}",
exit_failure = "BFV:.*|PASS|FAIL",
exit_success = "FinalBootLog: 5:ABBBA\r\n",
# TODO: add bootstrap when QEMU bootstraps instead of splicing firmware
),
deps = [
":boot_svc_test_lib",
"//sw/device/lib/base:status",
Expand All @@ -204,13 +240,19 @@ opentitan_test(
exec_env = {
"//hw/top_earlgrey:fpga_hyper310_rom_ext": None,
"//hw/top_earlgrey:fpga_cw340_rom_ext": None,
"//hw/top_earlgrey:sim_qemu_rom_ext": None,
},
fpga = fpga_params(
assemble = "{rom_ext}@{rom_ext_slot_a} {firmware}@{owner_slot_a} {firmware}@{owner_slot_b}",
exit_failure = "BFV:.*|PASS|FAIL",
exit_success = "FinalBootLog: 3:AAA\r\n",
),
linker_script = "//sw/device/lib/testing/test_framework:ottf_ld_silicon_owner_slot_virtual",
qemu = qemu_params(
assemble = "{rom_ext}@{rom_ext_slot_a} {firmware}@{owner_slot_a} {firmware}@{owner_slot_b}",
exit_failure = "BFV:.*|PASS|FAIL",
exit_success = "FinalBootLog: 3:AAA\r\n",
),
deps = [
":boot_svc_test_lib",
"//sw/device/lib/base:status",
Expand All @@ -231,13 +273,19 @@ opentitan_test(
exec_env = {
"//hw/top_earlgrey:fpga_hyper310_rom_ext": None,
"//hw/top_earlgrey:fpga_cw340_rom_ext": None,
"//hw/top_earlgrey:sim_qemu_rom_ext": None,
},
fpga = fpga_params(
assemble = "{rom_ext}@{rom_ext_slot_a} {firmware}@{owner_slot_a} {firmware}@{owner_slot_b}",
exit_failure = "BFV:.*|PASS|FAIL",
exit_success = "FinalBootLog: 3:ABA\r\n",
),
linker_script = "//sw/device/lib/testing/test_framework:ottf_ld_silicon_owner_slot_virtual",
qemu = qemu_params(
assemble = "{rom_ext}@{rom_ext_slot_a} {firmware}@{owner_slot_a} {firmware}@{owner_slot_b}",
exit_failure = "BFV:.*|PASS|FAIL",
exit_success = "FinalBootLog: 3:ABA\r\n",
),
deps = [
":boot_svc_test_lib",
"//sw/device/lib/base:status",
Expand Down Expand Up @@ -273,6 +321,7 @@ opentitan_binary(
exec_env = [
"//hw/top_earlgrey:fpga_hyper310_rom_ext",
"//hw/top_earlgrey:fpga_cw340_rom_ext",
"//hw/top_earlgrey:sim_qemu_rom_ext",
],
linker_script = "//sw/device/lib/testing/test_framework:ottf_ld_silicon_owner_slot_virtual",
manifest = ":manifest_version_5",
Expand Down Expand Up @@ -302,6 +351,7 @@ MIN_SEC_VER_SLOTS = [
exec_env = {
"//hw/top_earlgrey:fpga_hyper310_rom_ext": None,
"//hw/top_earlgrey:fpga_cw340_rom_ext": None,
"//hw/top_earlgrey:sim_qemu_rom_ext": None,
},
fpga = fpga_params(
assemble = "{rom_ext}@{rom_ext_slot_a} {firmware}@{v0_slot} {min_sec_ver_5:signed_bin}@{v5_slot}",
Expand All @@ -322,6 +372,14 @@ MIN_SEC_VER_SLOTS = [
),
linker_script = "//sw/device/lib/testing/test_framework:ottf_ld_silicon_owner_slot_virtual",
manifest = ":manifest_version_4",
qemu = qemu_params(
assemble = "{rom_ext}@{rom_ext_slot_a} {firmware}@{v0_slot} {min_sec_ver_5:signed_bin}@{v5_slot}",
binaries = {
":min_sec_ver_5": "min_sec_ver_5",
},
v0_slot = "{{owner_slot_{}}}".format(slots[0]),
v5_slot = "{{owner_slot_{}}}".format(slots[1]),
),
deps = [
":boot_svc_test_lib",
"//sw/device/lib/base:status",
Expand Down
1 change: 1 addition & 0 deletions sw/host/opentitanlib/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ rust_library(
"src/transport/qemu/monitor.rs",
"src/transport/qemu/reset.rs",
"src/transport/qemu/spi.rs",
"src/transport/qemu/uart.rs",
"src/transport/ti50emulator/emu.rs",
"src/transport/ti50emulator/gpio.rs",
"src/transport/ti50emulator/i2c.rs",
Expand Down
11 changes: 11 additions & 0 deletions sw/host/opentitanlib/src/app/config/opentitan_qemu.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,17 @@
"level": true,
},
],
"strappings": [
{
"name": "RESET",
"pins": [
{
"name": "RESET",
"level": false
}
]
}
],
"uarts": [
{
"name": "console",
Expand Down
31 changes: 11 additions & 20 deletions sw/host/opentitanlib/src/transport/qemu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
pub mod monitor;
pub mod reset;
pub mod spi;
pub mod uart;

use std::cell::RefCell;
use std::rc::Rc;
Expand All @@ -20,6 +21,7 @@ use crate::transport::common::uart::SerialPortUart;
use crate::transport::qemu::monitor::{Chardev, ChardevKind, Monitor};
use crate::transport::qemu::reset::QemuReset;
use crate::transport::qemu::spi::QemuSpi;
use crate::transport::qemu::uart::QemuUart;
use crate::transport::{
Capabilities, Capability, Transport, TransportError, TransportInterfaceType,
};
Expand Down Expand Up @@ -48,9 +50,6 @@ pub struct Qemu {

/// QEMU log modelled as a UART.
log: Option<Rc<dyn Uart>>,

/// Whether to quit QEMU when dropped.
quit: bool,
}

impl Qemu {
Expand All @@ -66,10 +65,13 @@ impl Qemu {
/// to a device using one of the flags in the list above. The kind must
/// match what OpenTitanLib expects to be accepted.
pub fn from_options(options: QemuOpts) -> anyhow::Result<Self> {
let mut monitor = Monitor::new(options.qemu_monitor_tty.unwrap())?;
let monitor = Rc::new(RefCell::new(Monitor::new(
options.qemu_monitor_tty.unwrap(),
options.qemu_quit,
)?));

// Get list of configured chardevs from QEMU.
let chardevs = monitor.query_chardevs()?;
let chardevs = monitor.borrow_mut().query_chardevs()?;
fn find_chardev<'a>(chardevs: &'a [Chardev], id: &str) -> Option<&'a ChardevKind> {
chardevs
.iter()
Expand All @@ -79,10 +81,11 @@ impl Qemu {
// Console UART:
let console = match find_chardev(&chardevs, "console") {
Some(ChardevKind::Pty { path }) => {
let uart: Rc<dyn Uart> = Rc::new(
let serial_port =
SerialPortUart::open_pseudo(path.to_str().unwrap(), CONSOLE_BAUDRATE)
.context("failed to open QEMU console PTY")?,
);
.context("failed to open QEMU console PTY")?;
let uart: Rc<dyn Uart> =
Rc::new(QemuUart::new(Rc::clone(&monitor), "console", serial_port));
Some(uart)
}
_ => {
Expand Down Expand Up @@ -119,8 +122,6 @@ impl Qemu {
}
};

let monitor = Rc::new(RefCell::new(monitor));

// Resetting is done over the monitor, but we model it like a pin to enable strapping it.
let reset = QemuReset::new(Rc::clone(&monitor));
let reset = Rc::new(reset);
Expand All @@ -131,20 +132,10 @@ impl Qemu {
console,
log,
spi,
quit: options.qemu_quit,
})
}
}

impl Drop for Qemu {
fn drop(&mut self) {
// Quit QEMU when dropped if requested.
if self.quit {
self.monitor.borrow_mut().quit().ok();
}
}
}

impl Transport for Qemu {
fn capabilities(&self) -> anyhow::Result<Capabilities> {
// We have to unconditionally claim to support GPIO because of the reset
Expand Down
Loading
Loading