From 6373b9c7e69ad5993b5d613b3f880355b44211ca Mon Sep 17 00:00:00 2001 From: Douglas Reis Date: Mon, 18 Dec 2023 15:34:21 +0000 Subject: [PATCH] [spi_dev, dv] Adapt the tpm test for sival Signed-off-by: Douglas Reis --- .../seq_lib/chip_sw_spi_device_tpm_vseq.sv | 1 - .../tests/sim_dv/spi_device_tpm_tx_rx_test.c | 25 +++--- sw/host/tests/chip/spi_device_tpm_test/BUILD | 24 ++++++ .../chip/spi_device_tpm_test/src/main.rs | 79 +++++++++++++++++++ 4 files changed, 117 insertions(+), 12 deletions(-) create mode 100644 sw/host/tests/chip/spi_device_tpm_test/BUILD create mode 100644 sw/host/tests/chip/spi_device_tpm_test/src/main.rs diff --git a/hw/top_earlgrey/dv/env/seq_lib/chip_sw_spi_device_tpm_vseq.sv b/hw/top_earlgrey/dv/env/seq_lib/chip_sw_spi_device_tpm_vseq.sv index 6f9f5ef258387..b949bf7a996b8 100644 --- a/hw/top_earlgrey/dv/env/seq_lib/chip_sw_spi_device_tpm_vseq.sv +++ b/hw/top_earlgrey/dv/env/seq_lib/chip_sw_spi_device_tpm_vseq.sv @@ -65,7 +65,6 @@ class chip_sw_spi_device_tpm_vseq extends chip_sw_base_vseq; `DV_WAIT(cfg.sw_logger_vif.printed_log == "SYNC: Waiting Read", "Timedout waiting for read config.") - // Read transaction tpm_txn (.wr(0), .addr(addr), .len(data_q.size()), .rdata_q(rdata_q)); foreach (rdata_q[i]) begin diff --git a/sw/device/tests/sim_dv/spi_device_tpm_tx_rx_test.c b/sw/device/tests/sim_dv/spi_device_tpm_tx_rx_test.c index 85c67892c6782..13289edc29f97 100644 --- a/sw/device/tests/sim_dv/spi_device_tpm_tx_rx_test.c +++ b/sw/device/tests/sim_dv/spi_device_tpm_tx_rx_test.c @@ -28,6 +28,7 @@ static dif_rv_plic_t plic; typedef enum { kTpmWriteCommand = 0x0, kTpmReadCommand = 0x80, + kTpmCommandMask = 0xbf } tpm_cmd_t; enum { @@ -167,16 +168,18 @@ bool test_main(void) { &pinmux, kTopEarlgreyPinmuxPeripheralInSpiDeviceTpmCsb, kTopEarlgreyPinmuxInselIoa7)); - dif_pinmux_pad_attr_t out_attr; - dif_pinmux_pad_attr_t in_attr = { - .slew_rate = 0, - .drive_strength = 0, - .flags = kDifPinmuxPadAttrPullResistorEnable | - kDifPinmuxPadAttrPullResistorUp}; - - CHECK_DIF_OK(dif_pinmux_pad_write_attrs(&pinmux, kTopEarlgreyMuxedPadsIoa7, - kDifPinmuxPadKindMio, in_attr, - &out_attr)); + if (kDeviceType == kDeviceSimDV) { + dif_pinmux_pad_attr_t out_attr; + dif_pinmux_pad_attr_t in_attr = { + .slew_rate = 0, + .drive_strength = 0, + .flags = kDifPinmuxPadAttrPullResistorEnable | + kDifPinmuxPadAttrPullResistorUp}; + + CHECK_DIF_OK(dif_pinmux_pad_write_attrs(&pinmux, kTopEarlgreyMuxedPadsIoa7, + kDifPinmuxPadKindMio, in_attr, + &out_attr)); + } CHECK_DIF_OK( dif_spi_device_tpm_configure(&spi_device, kDifToggleEnabled, kTpmConfig)); @@ -219,7 +222,6 @@ bool test_main(void) { LOG_INFO("SYNC: Waiting Read"); // Send the written data right back out for reads. - // Wait for read interrupt. atomic_wait_for_interrupt(); // Send the written data right back out for reads. @@ -232,6 +234,7 @@ bool test_main(void) { ack_spi_tpm_header_irq(&spi_device); // Make sure the received command matches expectation + read_command &= kTpmCommandMask; LOG_INFO("Expected 0x%x, received 0x%x", (kTpmReadCommand | (num_bytes - 1)), read_command); CHECK((kTpmReadCommand | (num_bytes - 1)) == read_command, diff --git a/sw/host/tests/chip/spi_device_tpm_test/BUILD b/sw/host/tests/chip/spi_device_tpm_test/BUILD new file mode 100644 index 0000000000000..da7010e5cdefa --- /dev/null +++ b/sw/host/tests/chip/spi_device_tpm_test/BUILD @@ -0,0 +1,24 @@ +# Copyright lowRISC contributors. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +load("@rules_rust//rust:defs.bzl", "rust_binary") + +package(default_visibility = ["//visibility:public"]) + +rust_binary( + name = "spi_device_tpm_test", + srcs = [ + "src/main.rs", + ], + deps = [ + "//sw/host/opentitanlib", + "//third_party/rust/crates:anyhow", + "//third_party/rust/crates:clap", + "//third_party/rust/crates:humantime", + "//third_party/rust/crates:log", + "//third_party/rust/crates:rand", + "//third_party/rust/crates:regex", + "@crate_index//:object", + ], +) diff --git a/sw/host/tests/chip/spi_device_tpm_test/src/main.rs b/sw/host/tests/chip/spi_device_tpm_test/src/main.rs new file mode 100644 index 0000000000000..7625a20aa788c --- /dev/null +++ b/sw/host/tests/chip/spi_device_tpm_test/src/main.rs @@ -0,0 +1,79 @@ +// Copyright lowRISC contributors. +// 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 regex::Regex; +use std::path::PathBuf; +use std::time::Duration; + +use opentitanlib::app::TransportWrapper; +use opentitanlib::execute_test; +use opentitanlib::test_utils::init::InitializeTest; +use opentitanlib::tpm::{self, Driver}; +use opentitanlib::uart::console::{ExitStatus, UartConsole}; + +#[derive(Debug, Parser)] +struct Opts { + #[command(flatten)] + init: InitializeTest, + + /// Console receive timeout. + #[arg(long, value_parser = humantime::parse_duration, default_value = "600s")] + timeout: Duration, + + /// Name of the SPI interface to connect to the OTTF console. + #[arg(long, default_value = "TPM")] + spi: String, + + /// Path to the firmware's ELF file, for querying symbol addresses. + #[arg(value_name = "FIRMWARE_ELF")] + firmware_elf: PathBuf, +} + +fn tpm_read_test(opts: &Opts, transport: &TransportWrapper) -> Result<()> { + let uart = transport.uart("console")?; + let spi = transport.spi(&opts.spi)?; + transport.pin_strapping("SPI_TPM")?.apply()?; + + /* Wait sync message. */ + let _ = UartConsole::wait_for(&*uart, r"SYNC: Begin TPM Test\r\n", opts.timeout)?; + let tpm = tpm::SpiDriver::new(spi); + const SIZE: usize = 10; + + for _ in 0..10 { + let test_data: Vec = (0..SIZE).map(|_| rand::random()).collect(); + tpm.write_register(tpm::Register::DATA_FIFO, &test_data)?; + let _ = UartConsole::wait_for(&*uart, r"SYNC: Waiting Read\r\n", opts.timeout)?; + let mut buffer = [0xFFu8; SIZE]; + tpm.read_register(tpm::Register::DATA_FIFO, &mut buffer)?; + assert_eq!(buffer, &test_data[0..SIZE]); + } + + Ok(()) +} + +fn main() -> Result<()> { + let opts = Opts::parse(); + opts.init.init_logging(); + + let transport = opts.init.init_target()?; + execute_test!(tpm_read_test, &opts, &transport,); + + let uart = transport.uart("console")?; + let mut console = UartConsole { + timeout: Some(opts.timeout), + exit_success: Some(Regex::new(r"PASS!\r\n")?), + exit_failure: Some(Regex::new(r"FAIL:")?), + ..Default::default() + }; + + // Now watch the console for the exit conditions. + let result = console.interact(&*uart, None, Some(&mut std::io::stdout()))?; + if result != ExitStatus::ExitSuccess { + bail!("FAIL: {:?}", result); + }; + + Ok(()) +}