From 02e936fe350372801edc5846fc2dc135470d86e3 Mon Sep 17 00:00:00 2001 From: Douglas Reis Date: Fri, 29 Nov 2024 16:04:16 +0000 Subject: [PATCH] [SiVal, usbdev] Add harness to usbdev_test Signed-off-by: Douglas Reis --- sw/device/tests/BUILD | 8 ++- sw/host/tests/chip/usb/BUILD | 17 +++++ sw/host/tests/chip/usb/usbdev_smoketest.rs | 76 ++++++++++++++++++++++ 3 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 sw/host/tests/chip/usb/usbdev_smoketest.rs diff --git a/sw/device/tests/BUILD b/sw/device/tests/BUILD index 68711ba5dd4f9..09bad196eeff1 100644 --- a/sw/device/tests/BUILD +++ b/sw/device/tests/BUILD @@ -4442,7 +4442,13 @@ opentitan_test( EARLGREY_TEST_ENVS, EARLGREY_SILICON_OWNER_ROM_EXT_ENVS, ), - fpga = fpga_params(tags = ["manual"]), + fpga = fpga_params( + tags = ["manual"], + test_cmd = """ + --bootstrap="{firmware}" + """, + test_harness = "//sw/host/tests/chip/usb:usbdev_smoketest", + ), verilator = verilator_params(timeout = "long"), deps = [ "//hw/top_earlgrey/sw/autogen:top_earlgrey", diff --git a/sw/host/tests/chip/usb/BUILD b/sw/host/tests/chip/usb/BUILD index a5babf53e81fc..bba76b2d34ea7 100644 --- a/sw/host/tests/chip/usb/BUILD +++ b/sw/host/tests/chip/usb/BUILD @@ -51,3 +51,20 @@ rust_binary( "@crate_index//:log", ], ) + +rust_binary( + name = "usbdev_smoketest", + srcs = [ + "usbdev_smoketest.rs", + ], + deps = [ + ":usb", + "//sw/host/opentitanlib", + "@crate_index//:anyhow", + "@crate_index//:clap", + "@crate_index//:humantime", + "@crate_index//:log", + "@crate_index//:rusb", + "@crate_index//:serialport", + ], +) diff --git a/sw/host/tests/chip/usb/usbdev_smoketest.rs b/sw/host/tests/chip/usb/usbdev_smoketest.rs new file mode 100644 index 0000000000000..95c9f13f5c537 --- /dev/null +++ b/sw/host/tests/chip/usb/usbdev_smoketest.rs @@ -0,0 +1,76 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +use anyhow::{bail, Result}; +use clap::Parser; +use std::time::Duration; + +use opentitanlib::execute_test; +use opentitanlib::io::uart::Uart; +use opentitanlib::test_utils::init::InitializeTest; +use opentitanlib::transport::common::uart::SerialPortUart; +use opentitanlib::uart::console::UartConsole; + +use usb::UsbOpts; + +#[derive(Debug, Parser)] +struct Opts { + #[command(flatten)] + init: InitializeTest, + + /// Console/USB timeout. + #[arg(long, value_parser = humantime::parse_duration, default_value = "10s")] + timeout: Duration, + + /// USB options. + #[command(flatten)] + usb: UsbOpts, +} + +fn usbdev_echo(opts: &Opts, uart: &dyn Uart) -> Result<()> { + log::info!("waiting for device..."); + let devices = opts.usb.wait_for_device(opts.timeout)?; + if devices.is_empty() { + bail!("no USB device found"); + } + + let ports = serialport::available_ports()?; + // In CI it is possible for several devices to match because we don't use a unique + // VID and PID, and all devices are visible (but not accessible) to every program. + // So with filter all vid:pid matches to try to open them: the ones belonging to + // other containers cannot be opened. + let usb_uart = ports + .iter() + .find_map(|port| { + let serialport::SerialPortType::UsbPort(info) = &port.port_type else { + return None; + }; + if info.vid != opts.usb.vid || info.pid != opts.usb.pid { + return None; + } + SerialPortUart::open(&port.port_name, 115200).ok() + }) + .ok_or(anyhow::anyhow!("Could not open any tty port"))?; + + let mut buffer = [0u8; 256]; + let len = usb_uart.read(&mut buffer)?; + + usb_uart.write(&buffer[0..len])?; + + let _ = UartConsole::wait_for(uart, r"PASS!", opts.timeout)?; + Ok(()) +} + +fn main() -> Result<()> { + let opts = Opts::parse(); + opts.init.init_logging(); + let transport = opts.init.init_target()?; + + let uart = transport.uart("console")?; + let _ = UartConsole::wait_for(&*uart, r"Running [^\r\n]*", opts.timeout)?; + + execute_test!(usbdev_echo, &opts, &*uart); + + Ok(()) +}