Skip to content

Commit 855538e

Browse files
timothytrippelpamaury
authored andcommitted
[test] add test to print UJSON payload max sizes
This adds a test to print the max UJSON payload sizes for a subset of the payloads transmitted during personalization. Signed-off-by: Tim Trippel <[email protected]> (cherry picked from commit 66f9a75)
1 parent 93aee4a commit 855538e

File tree

5 files changed

+231
-0
lines changed

5 files changed

+231
-0
lines changed

sw/device/lib/testing/json/provisioning_data.c

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

55
#define UJSON_SERDE_IMPL 1
66
#include "sw/device/lib/testing/json/provisioning_data.h"
7+
8+
/**
9+
* Max sizes of the UJSON structs below when they are serialized.
10+
*
11+
* The are obtained by running the following FPGA test:
12+
* bazel test --test_output=streamed \
13+
* //sw/device/silicon_creator/manuf/tests:ujson_msg_size_functest
14+
*/
15+
enum {
16+
kSerdesSha256HashSerializedMaxSize = 98,
17+
kLcTokenHashSerializedMaxSize = 52,
18+
kManufCertgenInputsSerializedMaxSize = 210,
19+
kPersoBlobSerializedMaxSize = 20535,
20+
};

sw/device/silicon_creator/manuf/tests/BUILD

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,3 +550,26 @@ alias(
550550
name = "multislot_empty_test_sim_dv",
551551
actual = "multislot_empty_test",
552552
)
553+
554+
opentitan_test(
555+
name = "ujson_msg_size_functest",
556+
srcs = ["ujson_msg_size_functest.c"],
557+
exec_env = {
558+
"//hw/top_earlgrey:fpga_cw340_sival": None,
559+
"//hw/top_earlgrey:fpga_cw310_rom_with_fake_keys": None,
560+
},
561+
fpga = fpga_params(
562+
tags = ["manuf"],
563+
test_cmd = """
564+
--clear-bitstream
565+
--bootstrap={firmware}
566+
""",
567+
test_harness = "//sw/host/tests/manuf/manuf_ujson_msg_size",
568+
),
569+
deps = [
570+
"//sw/device/lib/runtime:log",
571+
"//sw/device/lib/testing/json:provisioning_data",
572+
"//sw/device/lib/testing/test_framework:ottf_main",
573+
"//sw/device/lib/testing/test_framework:ujson_ottf",
574+
],
575+
)
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// Copyright lowRISC contributors (OpenTitan project).
2+
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
#include <stdint.h>
6+
7+
#include "sw/device/lib/dif/dif_gpio.h"
8+
#include "sw/device/lib/dif/dif_pinmux.h"
9+
#include "sw/device/lib/runtime/log.h"
10+
#include "sw/device/lib/testing/json/provisioning_data.h"
11+
#include "sw/device/lib/testing/test_framework/check.h"
12+
#include "sw/device/lib/testing/test_framework/ottf_main.h"
13+
#include "sw/device/lib/testing/test_framework/ujson_ottf.h"
14+
15+
#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
16+
17+
/**
18+
* Peripheral handles.
19+
*/
20+
static dif_gpio_t gpio;
21+
static dif_pinmux_t pinmux;
22+
23+
/**
24+
* ATE Indicator GPIOs.
25+
*/
26+
static const dif_gpio_pin_t kGpioPinSpiConsoleTxReady = 0;
27+
static const dif_gpio_pin_t kGpioPinSpiConsoleRxReady = 1;
28+
29+
/**
30+
* UJSON payloads.
31+
*/
32+
static serdes_sha256_hash_t sha256_hash_msg;
33+
static lc_token_hash_t lc_token_hash_msg;
34+
static manuf_certgen_inputs_t certgen_inputs_msg;
35+
static perso_blob_t perso_blob_msg;
36+
37+
OTTF_DEFINE_TEST_CONFIG(
38+
.console.type = kOttfConsoleSpiDevice,
39+
.console.base_addr = TOP_EARLGREY_SPI_DEVICE_BASE_ADDR,
40+
.console.test_may_clobber = false, .console.putbuf_buffered = true,
41+
.silence_console_prints = true, .console_tx_indicator.enable = true,
42+
.console_tx_indicator.spi_console_tx_ready_mio = kDtPadIoa5,
43+
.console_tx_indicator.spi_console_tx_ready_gpio =
44+
kGpioPinSpiConsoleTxReady);
45+
46+
static status_t peripheral_handles_init(void) {
47+
TRY(dif_gpio_init(mmio_region_from_addr(TOP_EARLGREY_GPIO_BASE_ADDR), &gpio));
48+
TRY(dif_pinmux_init(mmio_region_from_addr(TOP_EARLGREY_PINMUX_AON_BASE_ADDR),
49+
&pinmux));
50+
return OK_STATUS();
51+
}
52+
53+
static status_t configure_ate_gpio_indicators(void) {
54+
// IOA6 / GPIO4 is for SPI console RX ready signal.
55+
TRY(dif_pinmux_output_select(
56+
&pinmux, kTopEarlgreyPinmuxMioOutIoa6,
57+
kTopEarlgreyPinmuxOutselGpioGpio0 + kGpioPinSpiConsoleRxReady));
58+
// IOA5 / GPIO3 is for SPI console TX ready signal.
59+
TRY(dif_pinmux_output_select(
60+
&pinmux, kTopEarlgreyPinmuxMioOutIoa5,
61+
kTopEarlgreyPinmuxOutselGpioGpio0 + kGpioPinSpiConsoleTxReady));
62+
TRY(dif_gpio_output_set_enabled_all(&gpio, 0x3)); // Enable first 2 GPIOs.
63+
TRY(dif_gpio_write_all(&gpio, /*write_val=*/0)); // Intialize all to 0.
64+
return OK_STATUS();
65+
}
66+
67+
static status_t send_ujson_msgs(ujson_t *uj) {
68+
// Set all fields in each UJSON payload to the max value
69+
memset(&sha256_hash_msg.data, UINT8_MAX, sizeof(sha256_hash_msg));
70+
memset(&lc_token_hash_msg.hash, UINT8_MAX, sizeof(lc_token_hash_msg));
71+
memset(&certgen_inputs_msg, UINT8_MAX, sizeof(certgen_inputs_msg));
72+
memset(&perso_blob_msg.num_objs, UINT8_MAX, sizeof(perso_blob_msg.num_objs));
73+
memset(&perso_blob_msg.next_free, UINT8_MAX,
74+
sizeof(perso_blob_msg.next_free));
75+
memset(&perso_blob_msg.body, UINT8_MAX, sizeof(perso_blob_msg.body));
76+
77+
// TX payloads to the host.
78+
RESP_OK(ujson_serialize_serdes_sha256_hash_t, uj, &sha256_hash_msg);
79+
RESP_OK(ujson_serialize_lc_token_hash_t, uj, &lc_token_hash_msg);
80+
RESP_OK(ujson_serialize_manuf_certgen_inputs_t, uj, &certgen_inputs_msg);
81+
RESP_OK(ujson_serialize_perso_blob_t, uj, &perso_blob_msg);
82+
83+
// RX payloads echoed back by host.
84+
TRY(ujson_deserialize_serdes_sha256_hash_t(uj, &sha256_hash_msg));
85+
TRY(ujson_deserialize_lc_token_hash_t(uj, &lc_token_hash_msg));
86+
TRY(ujson_deserialize_manuf_certgen_inputs_t(uj, &certgen_inputs_msg));
87+
TRY(ujson_deserialize_perso_blob_t(uj, &perso_blob_msg));
88+
89+
return OK_STATUS();
90+
};
91+
92+
bool test_main(void) {
93+
CHECK_STATUS_OK(peripheral_handles_init());
94+
CHECK_STATUS_OK(configure_ate_gpio_indicators());
95+
ujson_t uj = ujson_ottf_console();
96+
CHECK_STATUS_OK(send_ujson_msgs(&uj));
97+
return true;
98+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Copyright lowRISC contributors (OpenTitan project).
2+
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
load("@rules_rust//rust:defs.bzl", "rust_binary")
6+
7+
package(default_visibility = ["//visibility:public"])
8+
9+
rust_binary(
10+
name = "manuf_ujson_msg_size",
11+
srcs = ["src/main.rs"],
12+
deps = [
13+
"//sw/host/opentitanlib",
14+
"//sw/host/provisioning/ujson_lib",
15+
"@crate_index//:anyhow",
16+
"@crate_index//:arrayvec",
17+
"@crate_index//:clap",
18+
"@crate_index//:humantime",
19+
"@crate_index//:log",
20+
],
21+
)
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright lowRISC contributors (OpenTitan project).
2+
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
use std::time::Duration;
6+
7+
use anyhow::Result;
8+
//use arrayvec::ArrayVec;
9+
use clap::Parser;
10+
11+
use opentitanlib::console::spi::SpiConsoleDevice;
12+
use opentitanlib::io::gpio::{PinMode, PullMode};
13+
use opentitanlib::test_utils::init::InitializeTest;
14+
use opentitanlib::test_utils::rpc::{ConsoleRecv, ConsoleSend};
15+
use ujson_lib::provisioning_data::{LcTokenHash, ManufCertgenInputs, PersoBlob, SerdesSha256Hash};
16+
17+
#[derive(Debug, Parser)]
18+
struct Opts {
19+
#[command(flatten)]
20+
init: InitializeTest,
21+
22+
/// Console receive timeout.
23+
#[arg(long, value_parser = humantime::parse_duration, default_value = "20s")]
24+
timeout: Duration,
25+
26+
/// Name of the SPI interface to connect to the OTTF console.
27+
#[arg(long, default_value = "BOOTSTRAP")]
28+
console_spi: String,
29+
30+
/// Name of the SPI interface to connect to the OTTF console.
31+
#[arg(long, default_value = "IOA5")]
32+
console_tx_indicator_pin: String,
33+
}
34+
35+
fn main() -> Result<()> {
36+
// Load bitstream and bootstrap test.
37+
let opts = Opts::parse();
38+
opts.init.init_logging();
39+
let transport = opts.init.init_target()?;
40+
41+
// Initialize the console.
42+
let spi = transport.spi(&opts.console_spi)?;
43+
let device_console_tx_ready_pin = &transport.gpio_pin(&opts.console_tx_indicator_pin)?;
44+
device_console_tx_ready_pin.set_mode(PinMode::Input)?;
45+
device_console_tx_ready_pin.set_pull_mode(PullMode::None)?;
46+
let spi_console = SpiConsoleDevice::new(
47+
&*spi,
48+
Some(device_console_tx_ready_pin),
49+
/*ignore_frame_num=*/ false,
50+
)?;
51+
52+
// Receive the payloads from the device.
53+
let sha256_hash = SerdesSha256Hash::recv(&spi_console, opts.timeout, /*quiet=*/ true)?;
54+
let lc_token_hash = LcTokenHash::recv(&spi_console, opts.timeout, /*quiet=*/ true)?;
55+
let certgen_inputs =
56+
ManufCertgenInputs::recv(&spi_console, opts.timeout, /*quiet=*/ true)?;
57+
let perso_blob = PersoBlob::recv(&spi_console, opts.timeout, /*quiet=*/ true)?;
58+
59+
// Send the payloads back to the device.
60+
let sha256_hash_str = sha256_hash.send(&spi_console)?;
61+
let lc_token_hash_str = lc_token_hash.send(&spi_console)?;
62+
let certgen_inputs_str = certgen_inputs.send(&spi_console)?;
63+
let perso_blob_str = perso_blob.send(&spi_console)?;
64+
65+
// Print UJSON payload sizes to the console.
66+
println!("Sha256Hash Size: {} bytes", sha256_hash_str.len());
67+
println!("LcTokenHash Size: {} bytes", lc_token_hash_str.len());
68+
println!(
69+
"ManufCertgenInputs Size: {} bytes",
70+
certgen_inputs_str.len()
71+
);
72+
println!("PersoBlob Size: {} bytes", perso_blob_str.len());
73+
74+
Ok(())
75+
}

0 commit comments

Comments
 (0)