Skip to content

Commit 14ff715

Browse files
[test] turn on flash scrambling and ECC in power virus test
Since these parameters are toggled on by the ROM via an OTP setting, this adds a custom OTP image for the power virus test. While these settings could be configured directly in the test, doing so via OTP enables a more realistic test scenario. Signed-off-by: Timothy Trippel <[email protected]>
1 parent e7c1018 commit 14ff715

File tree

5 files changed

+107
-7
lines changed

5 files changed

+107
-7
lines changed

hw/ip/otp_ctrl/data/otp_ctrl_img_creator_sw_cfg.hjson

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@
3333
},
3434
{
3535
name: "CREATOR_SW_CFG_FLASH_DATA_DEFAULT_CFG",
36-
// Default value for flash scramble / ecc / he_en
36+
// Default values for flash scramble / ecc / he_en. This OTP
37+
// word contains byte-aligned, packed, 4-bit mubi values.
38+
// See the flash_ctrl driver bitfield definitions in
39+
// sw/device/silicon_creator/lib/drivers/flash_ctrl.h.
3740
value: "0x0",
3841
},
3942
{

sw/device/tests/BUILD

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ load(
1111
"opentitan_functest",
1212
"verilator_params",
1313
)
14+
load("//rules:splice.bzl", "bitstream_splice")
15+
load("//rules:otp.bzl", "STD_OTP_OVERLAYS", "otp_image", "otp_json", "otp_partition")
1416

1517
package(default_visibility = ["//visibility:public"])
1618

@@ -2051,10 +2053,41 @@ opentitan_functest(
20512053
],
20522054
)
20532055

2056+
otp_json(
2057+
name = "power_virus_systemtest_otp_overlay",
2058+
partitions = [
2059+
otp_partition(
2060+
name = "CREATOR_SW_CFG",
2061+
items = {
2062+
"CREATOR_SW_CFG_FLASH_DATA_DEFAULT_CFG": "0000090606",
2063+
},
2064+
),
2065+
],
2066+
)
2067+
2068+
otp_image(
2069+
name = "power_virus_systemtest_otp_img_rma",
2070+
src = "//hw/ip/otp_ctrl/data:otp_json_rma",
2071+
overlays = STD_OTP_OVERLAYS + [":power_virus_systemtest_otp_overlay"],
2072+
visibility = ["//visibility:private"],
2073+
)
2074+
2075+
bitstream_splice(
2076+
name = "power_virus_systemtest_bitstream",
2077+
src = "//hw/bitstream:test_rom",
2078+
data = ":power_virus_systemtest_otp_img_rma",
2079+
meminfo = "//hw/bitstream:otp_mmi",
2080+
tags = ["vivado"],
2081+
update_usr_access = True,
2082+
visibility = ["//visibility:private"],
2083+
)
2084+
20542085
opentitan_functest(
20552086
name = "power_virus_systemtest",
20562087
srcs = ["power_virus_systemtest.c"],
20572088
cw310 = cw310_params(
2089+
bitstream = ":power_virus_systemtest_bitstream",
2090+
tags = ["vivado"],
20582091
test_cmds = [
20592092
"--rom-kind={rom_kind}",
20602093
"--bitstream=\"$(location {bitstream})\"",
@@ -2080,12 +2113,14 @@ opentitan_functest(
20802113
"//hw/ip/uart/data:uart_regs",
20812114
"//hw/top_earlgrey/sw/autogen:top_earlgrey",
20822115
"//sw/device/lib/base:math",
2116+
"//sw/device/lib/base:multibits",
20832117
"//sw/device/lib/dif:adc_ctrl",
20842118
"//sw/device/lib/dif:aes",
20852119
"//sw/device/lib/dif:csrng",
20862120
"//sw/device/lib/dif:csrng_shared",
20872121
"//sw/device/lib/dif:edn",
20882122
"//sw/device/lib/dif:entropy_src",
2123+
"//sw/device/lib/dif:flash_ctrl",
20892124
"//sw/device/lib/dif:gpio",
20902125
"//sw/device/lib/dif:hmac",
20912126
"//sw/device/lib/dif:i2c",

sw/device/tests/power_virus_systemtest.c

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44

55
#include "hw/ip/aes/model/aes_modes.h"
66
#include "sw/device/lib/base/math.h"
7+
#include "sw/device/lib/base/multibits.h"
78
#include "sw/device/lib/dif/dif_adc_ctrl.h"
89
#include "sw/device/lib/dif/dif_aes.h"
910
#include "sw/device/lib/dif/dif_csrng.h"
1011
#include "sw/device/lib/dif/dif_csrng_shared.h"
1112
#include "sw/device/lib/dif/dif_edn.h"
1213
#include "sw/device/lib/dif/dif_entropy_src.h"
14+
#include "sw/device/lib/dif/dif_flash_ctrl.h"
1315
#include "sw/device/lib/dif/dif_gpio.h"
1416
#include "sw/device/lib/dif/dif_hmac.h"
1517
#include "sw/device/lib/dif/dif_i2c.h"
@@ -68,6 +70,7 @@ static dif_uart_t uart_2;
6870
static dif_uart_t uart_3;
6971
static dif_pattgen_t pattgen;
7072
static dif_pwm_t pwm;
73+
static dif_flash_ctrl_state_t flash_ctrl;
7174

7275
static const dif_i2c_t *i2c_handles[] = {&i2c_0, &i2c_1, &i2c_2};
7376
static const dif_uart_t *uart_handles[] = {&uart_1, &uart_2, &uart_3};
@@ -274,6 +277,9 @@ static void init_peripheral_handles(void) {
274277
mmio_region_from_addr(TOP_EARLGREY_PATTGEN_BASE_ADDR), &pattgen));
275278
CHECK_DIF_OK(dif_pwm_init(
276279
mmio_region_from_addr(TOP_EARLGREY_PWM_AON_BASE_ADDR), &pwm));
280+
CHECK_DIF_OK(dif_flash_ctrl_init_state(
281+
&flash_ctrl,
282+
mmio_region_from_addr(TOP_EARLGREY_FLASH_CTRL_CORE_BASE_ADDR)));
277283
}
278284

279285
static void configure_pinmux(void) {
@@ -827,9 +833,8 @@ static void max_power_task(void *task_parameters) {
827833
dif_uart_rx_bytes_available(uart_handles[i], &num_uart_rx_bytes));
828834
// Note, we don't care if all bytes have been transmitted out of the UART
829835
// by the time the fastest processing crypto block (i.e., the AES) has
830-
// completed. Likely, we won't have transimitted all data since the UART
831-
// is quite a bit slower. We just check that what was transmitted is
832-
// correct.
836+
// completed. Likely, we won't have transmitted all data since the UART is
837+
// quite a bit slower. We just check that what was transmitted is correct.
833838
memset((void *)received_uart_data, 0, kUartFifoDepth);
834839
CHECK_DIF_OK(dif_uart_bytes_receive(uart_handles[i], num_uart_rx_bytes,
835840
received_uart_data, NULL));
@@ -839,6 +844,15 @@ static void max_power_task(void *task_parameters) {
839844
OTTF_TASK_DELETE_SELF_OR_DIE;
840845
}
841846

847+
static void check_otp_csr_configs(void) {
848+
dif_flash_ctrl_region_properties_t default_properties;
849+
CHECK_DIF_OK(dif_flash_ctrl_get_default_region_properties(
850+
&flash_ctrl, &default_properties));
851+
CHECK(default_properties.scramble_en == kMultiBitBool4True);
852+
CHECK(default_properties.ecc_en == kMultiBitBool4True);
853+
CHECK(default_properties.high_endurance_en == kMultiBitBool4False);
854+
}
855+
842856
bool test_main(void) {
843857
peripheral_clock_period_ns =
844858
udiv64_slow(1000000000, kClockFreqPeripheralHz, NULL);
@@ -871,6 +885,11 @@ bool test_main(void) {
871885
configure_pwm();
872886
LOG_INFO("All IPs configured.");
873887

888+
// ***************************************************************************
889+
// Check OTP configurations propagated to CSRs.
890+
// ***************************************************************************
891+
check_otp_csr_configs();
892+
874893
// ***************************************************************************
875894
// Kick off test tasks.
876895
// ***************************************************************************

sw/host/tests/chip/power_virus/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ rust_binary(
1616
"//third_party/rust/crates:anyhow",
1717
"//third_party/rust/crates:humantime",
1818
"//third_party/rust/crates:log",
19+
"//third_party/rust/crates:regex",
1920
"//third_party/rust/crates:structopt",
2021
],
2122
)

sw/host/tests/chip/power_virus/src/main.rs

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@
22
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
33
// SPDX-License-Identifier: Apache-2.0
44

5-
use anyhow::Result;
5+
use anyhow::{anyhow, Result};
6+
use regex::Regex;
67
use std::time::Duration;
78
use structopt::StructOpt;
89

10+
use opentitanlib::app::TransportWrapper;
11+
use opentitanlib::execute_test;
912
use opentitanlib::test_utils::init::InitializeTest;
10-
use opentitanlib::uart::console::UartConsole;
13+
use opentitanlib::uart::console::{ExitStatus, UartConsole};
1114

1215
#[derive(Debug, StructOpt)]
1316
struct Opts {
@@ -22,13 +25,52 @@ struct Opts {
2225
timeout: Duration,
2326
}
2427

28+
fn power_virus_systemtest(opts: &Opts, transport: &TransportWrapper) -> Result<()> {
29+
// Below is temporary until this test implements the command / response
30+
// ujson framework.
31+
let uart = transport.uart("console")?;
32+
let mut console = UartConsole {
33+
timeout: Some(opts.timeout),
34+
exit_success: Some(Regex::new(r"PASS.*\n")?),
35+
exit_failure: Some(Regex::new(r"(FAIL|FAULT).*\n")?),
36+
newline: true,
37+
..Default::default()
38+
};
39+
let mut stdout = std::io::stdout();
40+
let result = console.interact(&*uart, None, Some(&mut stdout))?;
41+
match result {
42+
ExitStatus::None | ExitStatus::CtrlC => Ok(()),
43+
ExitStatus::Timeout => {
44+
if console.exit_success.is_some() {
45+
Err(anyhow!("Console timeout exceeded"))
46+
} else {
47+
Ok(())
48+
}
49+
}
50+
ExitStatus::ExitSuccess => {
51+
log::info!(
52+
"ExitSuccess({:?})",
53+
console.captures(result).unwrap().get(0).unwrap().as_str()
54+
);
55+
Ok(())
56+
}
57+
ExitStatus::ExitFailure => {
58+
log::info!(
59+
"ExitFailure({:?})",
60+
console.captures(result).unwrap().get(0).unwrap().as_str()
61+
);
62+
Err(anyhow!("Matched exit_failure expression"))
63+
}
64+
}
65+
}
66+
2567
fn main() -> Result<()> {
2668
let opts = Opts::from_args();
2769
opts.init.init_logging();
2870
let transport = opts.init.init_target()?;
29-
3071
let uart = transport.uart("console")?;
3172
let _ = UartConsole::wait_for(&*uart, r"Running [^\r\n]*", opts.timeout)?;
3273

74+
execute_test!(power_virus_systemtest, &opts, &transport);
3375
Ok(())
3476
}

0 commit comments

Comments
 (0)