From ec14811d1bf1454f3434be70a24831201216ec1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Marques?= Date: Mon, 13 May 2024 20:28:29 +0000 Subject: [PATCH] Port chip_sw_sleep_pin_mio_dio_val to SiVal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Luís Marques --- hw/top_earlgrey/data/chip_testplan.hjson | 1 + hw/top_earlgrey/dv/chip_sim_cfg.hjson | 2 +- sw/device/tests/BUILD | 35 ++++ sw/device/tests/sim_dv/BUILD | 20 --- .../{sim_dv => }/sleep_pin_mio_dio_val_test.c | 1 + sw/host/tests/chip/gpio/BUILD | 16 ++ .../chip/gpio/src/sleep_pin_mio_dio_val.rs | 157 ++++++++++++++++++ 7 files changed, 211 insertions(+), 21 deletions(-) rename sw/device/tests/{sim_dv => }/sleep_pin_mio_dio_val_test.c (99%) create mode 100644 sw/host/tests/chip/gpio/src/sleep_pin_mio_dio_val.rs diff --git a/hw/top_earlgrey/data/chip_testplan.hjson b/hw/top_earlgrey/data/chip_testplan.hjson index adfbca7b949a0..4dfb6827b9723 100644 --- a/hw/top_earlgrey/data/chip_testplan.hjson +++ b/hw/top_earlgrey/data/chip_testplan.hjson @@ -163,6 +163,7 @@ si_stage: SV3 lc_states: ["PROD"] tests: ["chip_sw_sleep_pin_mio_dio_val"] + bazel: ["//sw/device/tests:sleep_pin_mio_dio_val_test"] } { name: chip_sw_sleep_pin_wake diff --git a/hw/top_earlgrey/dv/chip_sim_cfg.hjson b/hw/top_earlgrey/dv/chip_sim_cfg.hjson index f7c36471304cf..336a1c8689da2 100644 --- a/hw/top_earlgrey/dv/chip_sim_cfg.hjson +++ b/hw/top_earlgrey/dv/chip_sim_cfg.hjson @@ -486,7 +486,7 @@ { name: chip_sw_sleep_pin_mio_dio_val uvm_test_seq: chip_sw_sleep_pin_mio_dio_val_vseq - sw_images: ["//sw/device/tests/sim_dv:sleep_pin_mio_dio_val_test:1:new_rules"] + sw_images: ["//sw/device/tests:sleep_pin_mio_dio_val_test:1:new_rules"] en_run_modes: ["sw_test_mode_test_rom"] // Starting the chip in prod LC state frees up all MIOs for this test. run_opts: ["+use_otp_image=OtpTypeLcStProd"] diff --git a/sw/device/tests/BUILD b/sw/device/tests/BUILD index 31e3fe3462853..0f2e490545661 100644 --- a/sw/device/tests/BUILD +++ b/sw/device/tests/BUILD @@ -5893,3 +5893,38 @@ opentitan_test( "//sw/device/silicon_creator/lib/drivers:retention_sram", ], ) + +opentitan_test( + name = "sleep_pin_mio_dio_val_test", + srcs = ["sleep_pin_mio_dio_val_test.c"], + exec_env = dicts.add( + EARLGREY_TEST_ENVS, + EARLGREY_SILICON_OWNER_ROM_EXT_ENVS, + ), + fpga = fpga_params( + test_cmd = """ + --bootstrap="{firmware}" + """, + test_harness = "//sw/host/tests/chip/gpio:sleep_pin_mio_dio_val", + ), + silicon = silicon_params( + test_cmd = """ + --bootstrap="{firmware}" + """, + test_harness = "//sw/host/tests/chip/gpio:sleep_pin_mio_dio_val", + ), + deps = [ + "//hw/top_earlgrey/sw/autogen:top_earlgrey", + "//sw/device/lib/base:mmio", + "//sw/device/lib/dif:pinmux", + "//sw/device/lib/dif:pwrmgr", + "//sw/device/lib/dif:rv_plic", + "//sw/device/lib/runtime:irq", + "//sw/device/lib/runtime:log", + "//sw/device/lib/testing:isr_testutils", + "//sw/device/lib/testing:pwrmgr_testutils", + "//sw/device/lib/testing:rand_testutils", + "//sw/device/lib/testing:rv_plic_testutils", + "//sw/device/lib/testing/test_framework:ottf_main", + ], +) diff --git a/sw/device/tests/sim_dv/BUILD b/sw/device/tests/sim_dv/BUILD index 4669bb7b41bc6..93111c91c4ddf 100644 --- a/sw/device/tests/sim_dv/BUILD +++ b/sw/device/tests/sim_dv/BUILD @@ -488,26 +488,6 @@ opentitan_test( ], ) -opentitan_test( - name = "sleep_pin_mio_dio_val_test", - srcs = ["sleep_pin_mio_dio_val_test.c"], - exec_env = {"//hw/top_earlgrey:sim_dv": None}, - deps = [ - "//hw/top_earlgrey/sw/autogen:top_earlgrey", - "//sw/device/lib/base:mmio", - "//sw/device/lib/dif:pinmux", - "//sw/device/lib/dif:pwrmgr", - "//sw/device/lib/dif:rv_plic", - "//sw/device/lib/runtime:irq", - "//sw/device/lib/runtime:log", - "//sw/device/lib/testing:isr_testutils", - "//sw/device/lib/testing:pwrmgr_testutils", - "//sw/device/lib/testing:rand_testutils", - "//sw/device/lib/testing:rv_plic_testutils", - "//sw/device/lib/testing/test_framework:ottf_main", - ], -) - opentitan_test( name = "sleep_pin_wake_test", srcs = ["sleep_pin_wake_test.c"], diff --git a/sw/device/tests/sim_dv/sleep_pin_mio_dio_val_test.c b/sw/device/tests/sleep_pin_mio_dio_val_test.c similarity index 99% rename from sw/device/tests/sim_dv/sleep_pin_mio_dio_val_test.c rename to sw/device/tests/sleep_pin_mio_dio_val_test.c index bc6cc82f18f9e..6f1a9786e0c22 100644 --- a/sw/device/tests/sim_dv/sleep_pin_mio_dio_val_test.c +++ b/sw/device/tests/sleep_pin_mio_dio_val_test.c @@ -228,6 +228,7 @@ bool lowpower_prep(dif_pwrmgr_t *pwrmgr, dif_pinmux_t *pinmux, bool deepsleep) { CHECK_DIF_OK(dif_pwrmgr_low_power_set_enabled(pwrmgr, kDifToggleEnabled, kDifToggleEnabled)); + LOG_INFO("Going to sleep"); wait_for_interrupt(); // Entering deep power down. return result; diff --git a/sw/host/tests/chip/gpio/BUILD b/sw/host/tests/chip/gpio/BUILD index 1ef485b54432f..20d0657c27642 100644 --- a/sw/host/tests/chip/gpio/BUILD +++ b/sw/host/tests/chip/gpio/BUILD @@ -21,3 +21,19 @@ rust_binary( "@crate_index//:serde_json", ], ) + +rust_binary( + name = "sleep_pin_mio_dio_val", + srcs = [ + "src/sleep_pin_mio_dio_val.rs", + ], + deps = [ + "//sw/host/opentitanlib", + "@crate_index//:anyhow", + "@crate_index//:clap", + "@crate_index//:humantime", + "@crate_index//:log", + "@crate_index//:once_cell", + "@crate_index//:serde_json", + ], +) diff --git a/sw/host/tests/chip/gpio/src/sleep_pin_mio_dio_val.rs b/sw/host/tests/chip/gpio/src/sleep_pin_mio_dio_val.rs new file mode 100644 index 0000000000000..3d53e10bff785 --- /dev/null +++ b/sw/host/tests/chip/gpio/src/sleep_pin_mio_dio_val.rs @@ -0,0 +1,157 @@ +// 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::{ensure, Result}; +use clap::Parser; +use std::time::Duration; + +use opentitanlib::app::TransportWrapper; +use opentitanlib::execute_test; +use opentitanlib::io::gpio::PinMode; +use opentitanlib::io::gpio::PullMode; +use opentitanlib::test_utils::init::InitializeTest; +use opentitanlib::uart::console::UartConsole; + +struct Pad { + name: &'static str, + valid_cw310: bool, + valid_silicon: bool, +} + +// Valid on CW310: IOR6/7, IOR10-13 +// Valid on Silicon: IOA6, IOB6, IOC9-12, IOR5-7, IOR10-13. +#[rustfmt::skip] +const MIO_PADS: &[Pad] = &[ + Pad { name: "IOA0", valid_cw310: false, valid_silicon: false }, // MIO Pad 0 + Pad { name: "IOA1", valid_cw310: false, valid_silicon: false }, // MIO Pad 1 + Pad { name: "IOA2", valid_cw310: false, valid_silicon: false }, // MIO Pad 2 + Pad { name: "IOA3", valid_cw310: false, valid_silicon: false }, // MIO Pad 3 + Pad { name: "IOA4", valid_cw310: false, valid_silicon: false }, // MIO Pad 4 + Pad { name: "IOA5", valid_cw310: false, valid_silicon: false }, // MIO Pad 5 + Pad { name: "IOA6", valid_cw310: false, valid_silicon: true }, // MIO Pad 6 + Pad { name: "IOA7", valid_cw310: false, valid_silicon: false }, // MIO Pad 7 + Pad { name: "IOA8", valid_cw310: false, valid_silicon: false }, // MIO Pad 8 + Pad { name: "IOB0", valid_cw310: false, valid_silicon: false }, // MIO Pad 9 + Pad { name: "IOB1", valid_cw310: false, valid_silicon: false }, // MIO Pad 10 + Pad { name: "IOB2", valid_cw310: false, valid_silicon: false }, // MIO Pad 11 + Pad { name: "IOB3", valid_cw310: false, valid_silicon: false }, // MIO Pad 12 + Pad { name: "IOB4", valid_cw310: false, valid_silicon: false }, // MIO Pad 13 + Pad { name: "IOB5", valid_cw310: false, valid_silicon: false }, // MIO Pad 14 + Pad { name: "IOB6", valid_cw310: false, valid_silicon: true }, // MIO Pad 15 + Pad { name: "IOB7", valid_cw310: false, valid_silicon: false }, // MIO Pad 16 + Pad { name: "IOB8", valid_cw310: false, valid_silicon: false }, // MIO Pad 17 + Pad { name: "IOB9", valid_cw310: false, valid_silicon: false }, // MIO Pad 18 + Pad { name: "IOB10", valid_cw310: false, valid_silicon: false }, // MIO Pad 19 + Pad { name: "IOB11", valid_cw310: false, valid_silicon: false }, // MIO Pad 20 + Pad { name: "IOB12", valid_cw310: false, valid_silicon: false }, // MIO Pad 21 + Pad { name: "IOC0", valid_cw310: false, valid_silicon: false }, // MIO Pad 22 + Pad { name: "IOC1", valid_cw310: false, valid_silicon: false }, // MIO Pad 23 + Pad { name: "IOC2", valid_cw310: false, valid_silicon: false }, // MIO Pad 24 + Pad { name: "IOC3", valid_cw310: false, valid_silicon: false }, // MIO Pad 25 + Pad { name: "IOC4", valid_cw310: false, valid_silicon: false }, // MIO Pad 26 + Pad { name: "IOC5", valid_cw310: false, valid_silicon: false }, // MIO Pad 27 + Pad { name: "IOC6", valid_cw310: false, valid_silicon: false }, // MIO Pad 28 + Pad { name: "IOC7", valid_cw310: false, valid_silicon: false }, // MIO Pad 29 + Pad { name: "IOC8", valid_cw310: false, valid_silicon: false }, // MIO Pad 30 + Pad { name: "IOC9", valid_cw310: false, valid_silicon: true }, // MIO Pad 31 + Pad { name: "IOC10", valid_cw310: false, valid_silicon: true }, // MIO Pad 32 + Pad { name: "IOC11", valid_cw310: false, valid_silicon: true }, // MIO Pad 33 + Pad { name: "IOC12", valid_cw310: false, valid_silicon: true }, // MIO Pad 34 + Pad { name: "IOR0", valid_cw310: false, valid_silicon: false }, // MIO Pad 35 + Pad { name: "IOR1", valid_cw310: false, valid_silicon: false }, // MIO Pad 36 + Pad { name: "IOR2", valid_cw310: false, valid_silicon: false }, // MIO Pad 37 + Pad { name: "IOR3", valid_cw310: false, valid_silicon: false }, // MIO Pad 38 + Pad { name: "IOR4", valid_cw310: false, valid_silicon: false }, // MIO Pad 39 + Pad { name: "IOR5", valid_cw310: false, valid_silicon: true }, // MIO Pad 40 + Pad { name: "IOR6", valid_cw310: true, valid_silicon: true }, // MIO Pad 41 + Pad { name: "IOR7", valid_cw310: true, valid_silicon: true }, // MIO Pad 42 + Pad { name: "IOR10", valid_cw310: true, valid_silicon: true }, // MIO Pad 43 + Pad { name: "IOR11", valid_cw310: true, valid_silicon: true }, // MIO Pad 44 + Pad { name: "IOR12", valid_cw310: true, valid_silicon: true }, // MIO Pad 45 + Pad { name: "IOR13", valid_cw310: true, valid_silicon: true }, // MIO Pad 46 +]; + +#[derive(Debug, Parser)] +struct Opts { + #[command(flatten)] + init: InitializeTest, + + /// Console receive timeout. + #[arg(long, value_parser = humantime::parse_duration, default_value = "600s")] + timeout: Duration, +} + +fn is_valid_pad(pad: &Pad, interface: &str) -> bool { + match interface { + "hyper310" => pad.valid_cw310, + "teacup" => pad.valid_silicon, + _ => false, + } +} + +fn sleep_pin_mio_dio_test(opts: &Opts, transport: &TransportWrapper) -> Result<()> { + let interface = opts.init.backend_opts.interface.as_str(); + let uart = transport.uart("console")?; + log::info!("Starting host side"); + + let mut expected_pin_values: [u8; 47] = [0; 47]; + for _ in 0..MIO_PADS.len() { + let msg = UartConsole::wait_for(&*uart, r"MIO \[(\d+)\]: (\d+)", opts.timeout)?; + let index: usize = msg[1].parse()?; + expected_pin_values[index] = msg[2].parse()?; + } + + UartConsole::wait_for(&*uart, r"Going to sleep", opts.timeout)?; + + for (index, pad) in MIO_PADS.iter().enumerate() { + if is_valid_pad(pad, interface) { + transport.gpio_pin(pad.name)?.set_mode(PinMode::Input)?; + let expected_value = expected_pin_values[index]; + + // Retention value 0 or 1. + if expected_value < 2 { + let pin_value = transport.gpio_pin(pad.name)?.read()? as u8; + log::info!("Pad {index:?}: expected {expected_value:?}, read {pin_value:?}"); + ensure!( + pin_value == expected_value, + "Pad {index:?}: expected {expected_value:?}, read {pin_value:?}" + ); + continue; + } + + // Retention value High-Z. First test with a pull up. + transport + .gpio_pin(pad.name)? + .set_pull_mode(PullMode::PullDown)?; + let pin_value = transport.gpio_pin(pad.name)?.read()? as u8; + log::info!("Pad {index:?}: expected pulled down to 0, read {pin_value:?}"); + ensure!( + pin_value == 0, + "Pad {index:?}: expected pulled down to 0, read {pin_value:?}" + ); + + // Next test the same pad/pin with a pull down. + transport + .gpio_pin(pad.name)? + .set_pull_mode(PullMode::PullUp)?; + let pin_value = transport.gpio_pin(pad.name)?.read()? as u8; + log::info!("Pad {index:?}: expected pulled up to 1, read {pin_value:?}"); + ensure!( + pin_value == 1, + "Pad {index:?}: expected pulled up to 1, read {pin_value:?}" + ); + } + } + + Ok(()) +} + +fn main() -> Result<()> { + let opts = Opts::parse(); + opts.init.init_logging(); + let transport = opts.init.init_target()?; + + execute_test!(sleep_pin_mio_dio_test, &opts, &transport); + Ok(()) +}