From 2a02fc90b3618b3d62b473b6e020f4bd2b7a6972 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 | 16 ++++ sw/host/tests/chip/usb/usbdev_smoketest.rs | 97 ++++++++++++++++++++++ 3 files changed, 120 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 a02331de85fb1b..a3d253af8c4be2 100644 --- a/sw/device/tests/BUILD +++ b/sw/device/tests/BUILD @@ -4403,7 +4403,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 a5babf53e81fcb..80da151eb648d1 100644 --- a/sw/host/tests/chip/usb/BUILD +++ b/sw/host/tests/chip/usb/BUILD @@ -51,3 +51,19 @@ 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", + ], +) 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 00000000000000..3965bc6f100fac --- /dev/null +++ b/sw/host/tests/chip/usb/usbdev_smoketest.rs @@ -0,0 +1,97 @@ +// 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, ensure, Context, Result}; +use clap::{Parser, ValueEnum}; +use std::time::Duration; + +use opentitanlib::app::TransportWrapper; +use opentitanlib::execute_test; +use opentitanlib::io::uart::Uart; +use opentitanlib::test_utils::init::InitializeTest; +use opentitanlib::uart::console::UartConsole; +use opentitanlib::transport::common::uart::SerialPortUart; + +use usb::{UsbHub, UsbHubOp, 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, +} + +// Wait for a device to appear and then return the parent device and port number. +fn wait_for_device_and_get_parent(opts: &Opts) -> Result<(rusb::Device, u8)> { + // Wait for USB device to appear. + log::info!("waiting for device..."); + let devices = opts.usb.wait_for_device(opts.timeout)?; + if devices.is_empty() { + bail!("no USB device found"); + } + if devices.len() > 1 { + bail!("several USB devices found"); + } + let device = &devices[0]; + dbg!(&device); + log::info!( + "device found at bus={} address={}", + device.device().bus_number(), + device.device().address() + ); + + // Important note: here the handle will be dropped and the device handle + // will be closed. + Ok(( + device + .device() + .get_parent() + .context("device has no parent, you need to connect it via a hub for this test")?, + device.device().port_number(), + )) +} + +fn usbdev_echo(opts: &Opts, transport: &TransportWrapper, uart: &dyn Uart) -> Result<()> { + // Wait for device to appear. + let (parent, port) = wait_for_device_and_get_parent(opts)?; + log::info!( + "parent hub at bus={}, address={}, port numbers={:?}", + parent.bus_number(), + parent.address(), + parent.port_numbers()? + ); + log::info!("device under test is on port {}", port); + + // let uart_name = format!("/dev/ttyUSB{port}"); + let uart_name = format!("/dev/ttyUSB5"); + let usb_uart = SerialPortUart::open(&uart_name, 115200)?; + + 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, &transport, &*uart); + + Ok(()) +}