Skip to content

Commit

Permalink
[test] add example spi_device OTTF console test
Browse files Browse the repository at this point in the history
This tests the OTTF spi_device console, which uses the OT spi_device in
flash mode, along with the flash read buffer and a lightweight framing
protocol to implement a one-way (RX) console.

Signed-off-by: Anthony Chen <[email protected]>
  • Loading branch information
anthonychen1251 committed Aug 16, 2024
1 parent a929411 commit 0703e30
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 0 deletions.
24 changes: 24 additions & 0 deletions sw/device/tests/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -3593,6 +3593,30 @@ cc_library(
],
)

opentitan_test(
name = "spi_device_ottf_console_test",
srcs = ["spi_device_ottf_console_test.c"],
exec_env = dicts.add(
EARLGREY_TEST_ENVS,
EARLGREY_CW340_TEST_ENVS,
),
fpga = fpga_params(
tags = ["manual"],
test_cmd = """
--bootstrap="{firmware}"
"{firmware:elf}"
""",
test_harness = "//sw/host/tests/chip/spi_device_ottf_console",
),
deps = [
"//hw/top_earlgrey/sw/autogen:top_earlgrey",
"//sw/device/lib/dif:spi_device",
"//sw/device/lib/runtime:log",
"//sw/device/lib/testing:spi_flash_testutils",
"//sw/device/lib/testing/test_framework:ottf_main",
],
)

opentitan_test(
name = "sram_ctrl_sleep_sram_ret_contents_no_scramble_test",
srcs = ["sram_ctrl_sleep_sram_ret_contents_no_scramble_test.c"],
Expand Down
24 changes: 24 additions & 0 deletions sw/device/tests/spi_device_ottf_console_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright lowRISC contributors (OpenTitan project).
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#include "sw/device/lib/dif/dif_spi_device.h"
#include "sw/device/lib/runtime/log.h"
#include "sw/device/lib/testing/test_framework/check.h"
#include "sw/device/lib/testing/test_framework/ottf_main.h"

#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"

OTTF_DEFINE_TEST_CONFIG(.console.type = kOttfConsoleSpiDevice,
.console.base_addr = TOP_EARLGREY_SPI_DEVICE_BASE_ADDR,
.console.test_may_clobber = false, );

static const char test_str[] = "This is a SPI device OTTF console test.";

bool test_main(void) {
for (int i = 0; i < 100; i++) {
LOG_INFO("%s round: %d", test_str, i);
}

return true;
}
22 changes: 22 additions & 0 deletions sw/host/tests/chip/spi_device_ottf_console/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright lowRISC contributors (OpenTitan project).
# 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_ottf_console",
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:regex",
],
)
83 changes: 83 additions & 0 deletions sw/host/tests/chip/spi_device_ottf_console/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// 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::{anyhow, Result};
use clap::Parser;
use regex::Regex;
use std::path::PathBuf;
use std::time::Duration;

use opentitanlib::app::TransportWrapper;
use opentitanlib::console::spi::SpiConsoleDevice;
use opentitanlib::execute_test;
use opentitanlib::test_utils::init::InitializeTest;
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 = "20s")]
timeout: Duration,

/// Name of the SPI interface to connect to the OTTF console.
#[arg(long, default_value = "BOOTSTRAP")]
console_spi: String,

/// Path to the firmware's ELF file, for querying symbol addresses.
#[arg(value_name = "FIRMWARE_ELF")]
firmware_elf: PathBuf,
}

fn spi_device_console_test(opts: &Opts, transport: &TransportWrapper) -> Result<()> {
let mut console = UartConsole {
timeout: Some(opts.timeout),
exit_success: Some(Regex::new(r"PASS.*\n")?),
exit_failure: Some(Regex::new(r"(FAIL|FAULT).*\n")?),
newline: true,
..Default::default()
};
let mut stdout = std::io::stdout();
let spi = transport.spi(&opts.console_spi)?;


let spi_console_device = SpiConsoleDevice::new(&*spi)?;
let _ = UartConsole::wait_for(&spi_console_device, r"Running [^\r\n]*", opts.timeout)?;

let result = console.interact(&spi_console_device, None, Some(&mut stdout))?;
match result {
ExitStatus::None | ExitStatus::CtrlC => Ok(()),
ExitStatus::Timeout => {
if console.exit_success.is_some() {
Err(anyhow!("Console timeout exceeded"))
} else {
Ok(())
}
}
ExitStatus::ExitSuccess => {
log::info!(
"ExitSuccess({:?})",
console.captures(result).unwrap().get(0).unwrap().as_str()
);
Ok(())
}
ExitStatus::ExitFailure => {
log::info!(
"ExitFailure({:?})",
console.captures(result).unwrap().get(0).unwrap().as_str()
);
Err(anyhow!("Matched exit_failure expression"))
}
}
}

fn main() -> Result<()> {
let opts = Opts::parse();
opts.init.init_logging();
let transport = opts.init.init_target()?;
execute_test!(spi_device_console_test, &opts, &transport);
Ok(())
}

0 comments on commit 0703e30

Please sign in to comment.