Skip to content

Commit f0dcfbd

Browse files
timothytrippelpamaury
authored andcommitted
[ujson] enable skipping CRC sent with UJSON payloads
In manufacturing ATE environments, constant sized UJSON strings are preferred. CRCs are variable in length. Therefore, we enable setting the CRC to a fixed value of 0 and skipping the check on the host side. Signed-off-by: Tim Trippel <[email protected]> (cherry picked from commit 9a66cc2)
1 parent dac9866 commit f0dcfbd

File tree

45 files changed

+158
-92
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+158
-92
lines changed

sw/device/lib/testing/test_framework/ujson_ottf.h

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,22 @@ ujson_t ujson_ottf_console(void);
6060
err; \
6161
})
6262

63+
/**
64+
* Adds an empty CRC field to the response.
65+
*
66+
* Should not be used directly.
67+
* It is used by other macros such as `RESP_OK_NO_CRC`.
68+
*
69+
* @param uj_ctx_ A `ujson_t` representing the IO context.
70+
*/
71+
#define RESP_NO_CRC(uj_ctx_) \
72+
({ \
73+
TRY(ujson_putbuf(uj_ctx_, " CRC:", 5)); \
74+
TRY(ujson_putbuf(uj_ctx_, "0\n", 2)); \
75+
TRY(ujson_flushbuf(uj)); \
76+
OK_STATUS(); \
77+
})
78+
6379
/**
6480
* Add a CRC to the response.
6581
* Should not be used directly.
@@ -78,7 +94,22 @@ ujson_t ujson_ottf_console(void);
7894
})
7995

8096
/**
81-
* Respond with an OK result and JSON encoded data.
97+
* Respond with an OK result, JSON encoded data, and empty CRC.
98+
*
99+
* @param responder_ A ujson serializer function for `data_`.
100+
* @param uj_ctx_ A `ujson_t` representing the IO context.
101+
* @param data_ A pointer to the data to send.
102+
*/
103+
#define RESP_OK_NO_CRC(responder_, uj_ctx_, data_) \
104+
({ \
105+
TRY(ujson_putbuf(uj_ctx_, "RESP_OK:", 8)); \
106+
TRY(responder_(uj_ctx_, data_)); \
107+
RESP_NO_CRC(uj_ctx_); \
108+
OK_STATUS(); \
109+
})
110+
111+
/**
112+
* Respond with an OK result, JSON encoded data, and valid CRC.
82113
*
83114
* @param responder_ A ujson serializer function for `data_`.
84115
* @param uj_ctx_ A `ujson_t` representing the IO context.

sw/device/silicon_creator/manuf/tests/ujson_msg_size_functest.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,11 @@ static status_t send_ujson_msgs(ujson_t *uj) {
7575
memset(&perso_blob_msg.body, UINT8_MAX, sizeof(perso_blob_msg.body));
7676

7777
// 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);
78+
RESP_OK_NO_CRC(ujson_serialize_serdes_sha256_hash_t, uj, &sha256_hash_msg);
79+
RESP_OK_NO_CRC(ujson_serialize_lc_token_hash_t, uj, &lc_token_hash_msg);
80+
RESP_OK_NO_CRC(ujson_serialize_manuf_certgen_inputs_t, uj,
81+
&certgen_inputs_msg);
82+
RESP_OK_NO_CRC(ujson_serialize_perso_blob_t, uj, &perso_blob_msg);
8283

8384
// RX payloads echoed back by host.
8485
TRY(ujson_deserialize_serdes_sha256_hash_t(uj, &sha256_hash_msg));

sw/host/opentitanlib/src/test_utils/gpio.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ impl GpioSet {
1717
fn execute(&self, uart: &dyn Uart) -> Result<()> {
1818
TestCommand::GpioSet.send(uart)?;
1919
self.send(uart)?;
20-
Status::recv(uart, Duration::from_secs(300), false)?;
20+
Status::recv(uart, Duration::from_secs(300), false, false)?;
2121
Ok(())
2222
}
2323

@@ -148,7 +148,7 @@ impl GpioSet {
148148
impl GpioGet {
149149
pub fn read_all(uart: &dyn Uart) -> Result<u32> {
150150
TestCommand::GpioGet.send(uart)?;
151-
let data = GpioGet::recv(uart, Duration::from_secs(300), false)?;
151+
let data = GpioGet::recv(uart, Duration::from_secs(300), false, false)?;
152152
Ok(data.state)
153153
}
154154
}

sw/host/opentitanlib/src/test_utils/i2c_target.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ impl I2cTargetAddress {
1717
pub fn write(&self, uart: &dyn Uart) -> Result<()> {
1818
TestCommand::I2cTargetAddress.send_with_crc(uart)?;
1919
self.send_with_crc(uart)?;
20-
Status::recv(uart, Duration::from_secs(300), false)?;
20+
Status::recv(uart, Duration::from_secs(300), false, false)?;
2121
Ok(())
2222
}
2323
}
@@ -42,7 +42,7 @@ impl I2cTransferStart {
4242
TestCommand::I2cStartTransferRead.send_with_crc(uart)?;
4343
self.send_with_crc(uart)?;
4444
f()?;
45-
Status::recv(uart, Duration::from_secs(300), false)?;
45+
Status::recv(uart, Duration::from_secs(300), false, false)?;
4646
Ok(())
4747
}
4848

@@ -52,7 +52,7 @@ impl I2cTransferStart {
5252
{
5353
TestCommand::I2cStartTransferWrite.send_with_crc(uart)?;
5454
f()?;
55-
Self::recv(uart, Duration::from_secs(300), false)
55+
Self::recv(uart, Duration::from_secs(300), false, false)
5656
}
5757

5858
pub fn execute_write_slow<F>(uart: &dyn Uart, f: F) -> Result<Self>
@@ -61,7 +61,7 @@ impl I2cTransferStart {
6161
{
6262
TestCommand::I2cStartTransferWriteSlow.send_with_crc(uart)?;
6363
f()?;
64-
Self::recv(uart, Duration::from_secs(300), false)
64+
Self::recv(uart, Duration::from_secs(300), false, false)
6565
}
6666

6767
pub fn execute_write_read<F>(&self, uart: &dyn Uart, f: F) -> Result<Self>
@@ -71,15 +71,15 @@ impl I2cTransferStart {
7171
TestCommand::I2cStartTransferWriteRead.send_with_crc(uart)?;
7272
self.send_with_crc(uart)?;
7373
f()?;
74-
Self::recv(uart, Duration::from_secs(300), false)
74+
Self::recv(uart, Duration::from_secs(300), false, false)
7575
}
7676
}
7777

7878
impl I2cTestConfig {
7979
pub fn write(&self, uart: &dyn Uart) -> Result<()> {
8080
TestCommand::I2cTestConfig.send_with_crc(uart)?;
8181
self.send_with_crc(uart)?;
82-
Status::recv(uart, Duration::from_secs(300), false)?;
82+
Status::recv(uart, Duration::from_secs(300), false, false)?;
8383
Ok(())
8484
}
8585
}

sw/host/opentitanlib/src/test_utils/mem.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ impl MemRead32Req {
2222
TestCommand::MemRead32.send_with_crc(device)?;
2323
let op = MemRead32Req { address };
2424
op.send_with_crc(device)?;
25-
let resp = MemRead32Resp::recv(device, Duration::from_secs(300), false)?;
25+
let resp = MemRead32Resp::recv(device, Duration::from_secs(300), false, false)?;
2626
Ok(resp.value)
2727
}
2828
}
@@ -46,7 +46,7 @@ impl MemReadReq {
4646
data_len: op_size.try_into().unwrap(),
4747
};
4848
op.send_with_crc(device)?;
49-
let resp = MemReadResp::recv(device, Duration::from_secs(300), false)?;
49+
let resp = MemReadResp::recv(device, Duration::from_secs(300), false, false)?;
5050
data[bytes_read..(bytes_read + op_size)].copy_from_slice(resp.data.as_slice());
5151
bytes_read += op_size;
5252
}
@@ -62,7 +62,7 @@ impl MemWrite32Req {
6262
TestCommand::MemWrite32.send_with_crc(device)?;
6363
let op = MemWrite32Req { address, value };
6464
op.send_with_crc(device)?;
65-
Status::recv(device, Duration::from_secs(300), false)?;
65+
Status::recv(device, Duration::from_secs(300), false, false)?;
6666
Ok(())
6767
}
6868
}
@@ -86,7 +86,7 @@ impl MemWriteReq {
8686
.try_extend_from_slice(&data[bytes_written..(bytes_written + op_size)])?;
8787
op.data_len = op_size.try_into().unwrap();
8888
op.send_with_crc(device)?;
89-
let _ = Status::recv(device, Duration::from_secs(300), false)?;
89+
let _ = Status::recv(device, Duration::from_secs(300), false, false)?;
9090
bytes_written += op_size;
9191
}
9292
Ok(())

sw/host/opentitanlib/src/test_utils/pinmux_config.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ impl PinmuxConfig {
8989

9090
TestCommand::PinmuxConfig.send(uart)?;
9191
config.send(uart)?;
92-
Status::recv(uart, Duration::from_secs(300), false)?;
92+
Status::recv(uart, Duration::from_secs(300), false, false)?;
9393
}
9494

9595
Ok(())

sw/host/opentitanlib/src/test_utils/rpc.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ pub trait ConsoleRecv<T>
5151
where
5252
T: ConsoleDevice + ?Sized,
5353
{
54-
fn recv(device: &T, timeout: Duration, quiet: bool) -> Result<Self>
54+
fn recv(device: &T, timeout: Duration, quiet: bool, skip_crc: bool) -> Result<Self>
5555
where
5656
Self: Sized;
5757
}
@@ -61,7 +61,7 @@ where
6161
T: ConsoleDevice + ?Sized,
6262
U: DeserializeOwned,
6363
{
64-
fn recv(device: &T, timeout: Duration, quiet: bool) -> Result<Self>
64+
fn recv(device: &T, timeout: Duration, quiet: bool, skip_crc: bool) -> Result<Self>
6565
where
6666
Self: Sized,
6767
{
@@ -78,7 +78,9 @@ where
7878
PassFailResult::Pass(cap) => {
7979
let json_str = &cap[1];
8080
let crc_str = &cap[2];
81-
check_crc(json_str, crc_str)?;
81+
if !skip_crc {
82+
check_crc(json_str, crc_str)?;
83+
}
8284
Ok(serde_json::from_str::<Self>(json_str)?)
8385
}
8486
PassFailResult::Fail(cap) => {

sw/host/opentitanlib/src/test_utils/spi_passthru.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,21 @@ impl ConfigJedecId {
1717
pub fn execute(&self, uart: &dyn Uart) -> Result<()> {
1818
TestCommand::SpiConfigureJedecId.send_with_crc(uart)?;
1919
self.send_with_crc(uart)?;
20-
Status::recv(uart, Duration::from_secs(300), false)?;
20+
Status::recv(uart, Duration::from_secs(300), false, false)?;
2121
Ok(())
2222
}
2323
}
2424

2525
impl StatusRegister {
2626
pub fn read(uart: &dyn Uart) -> Result<Self> {
2727
TestCommand::SpiReadStatus.send_with_crc(uart)?;
28-
Self::recv(uart, Duration::from_secs(300), false)
28+
Self::recv(uart, Duration::from_secs(300), false, false)
2929
}
3030

3131
pub fn write(&self, uart: &dyn Uart) -> Result<()> {
3232
TestCommand::SpiWriteStatus.send_with_crc(uart)?;
3333
self.send_with_crc(uart)?;
34-
Status::recv(uart, Duration::from_secs(300), false)?;
34+
Status::recv(uart, Duration::from_secs(300), false, false)?;
3535
Ok(())
3636
}
3737
}
@@ -40,7 +40,7 @@ impl SfdpData {
4040
pub fn write(&self, uart: &dyn Uart) -> Result<()> {
4141
TestCommand::SpiWriteSfdp.send_with_crc(uart)?;
4242
self.send_with_crc(uart)?;
43-
Status::recv(uart, Duration::from_secs(300), false)?;
43+
Status::recv(uart, Duration::from_secs(300), false, false)?;
4444
Ok(())
4545
}
4646
}
@@ -52,14 +52,14 @@ impl UploadInfo {
5252
{
5353
TestCommand::SpiWaitForUpload.send_with_crc(uart)?;
5454
f()?;
55-
Self::recv(uart, Duration::from_secs(300), false)
55+
Self::recv(uart, Duration::from_secs(300), false, false)
5656
}
5757
}
5858

5959
impl SpiFlashReadId {
6060
pub fn execute(uart: &dyn Uart) -> Result<Self> {
6161
TestCommand::SpiFlashReadId.send_with_crc(uart)?;
62-
let data = SpiFlashReadId::recv(uart, Duration::from_secs(300), false)?;
62+
let data = SpiFlashReadId::recv(uart, Duration::from_secs(300), false, false)?;
6363
Ok(data)
6464
}
6565
}
@@ -68,7 +68,7 @@ impl SpiFlashReadSfdp {
6868
pub fn execute(&self, uart: &dyn Uart) -> Result<SfdpData> {
6969
TestCommand::SpiFlashReadSfdp.send_with_crc(uart)?;
7070
self.send_with_crc(uart)?;
71-
let sfdp = SfdpData::recv(uart, Duration::from_secs(300), false)?;
71+
let sfdp = SfdpData::recv(uart, Duration::from_secs(300), false, false)?;
7272
Ok(sfdp)
7373
}
7474
}
@@ -77,7 +77,7 @@ impl SpiFlashEraseSector {
7777
pub fn execute(&self, uart: &dyn Uart) -> Result<()> {
7878
TestCommand::SpiFlashEraseSector.send_with_crc(uart)?;
7979
self.send_with_crc(uart)?;
80-
Status::recv(uart, Duration::from_secs(300), false)?;
80+
Status::recv(uart, Duration::from_secs(300), false, false)?;
8181
Ok(())
8282
}
8383
}
@@ -86,7 +86,7 @@ impl SpiFlashWrite {
8686
pub fn execute(&self, uart: &dyn Uart) -> Result<()> {
8787
TestCommand::SpiFlashWrite.send_with_crc(uart)?;
8888
self.send_with_crc(uart)?;
89-
Status::recv(uart, Duration::from_secs(300), false)?;
89+
Status::recv(uart, Duration::from_secs(300), false, false)?;
9090
Ok(())
9191
}
9292
}
@@ -95,7 +95,7 @@ impl SpiPassthruSwapMap {
9595
pub fn apply_address_swap(&self, uart: &dyn Uart) -> Result<()> {
9696
TestCommand::SpiPassthruSetAddressMap.send_with_crc(uart)?;
9797
self.send_with_crc(uart)?;
98-
Status::recv(uart, Duration::from_secs(300), false)?;
98+
Status::recv(uart, Duration::from_secs(300), false, false)?;
9999
Ok(())
100100
}
101101
}
@@ -104,13 +104,13 @@ impl SpiMailboxMap {
104104
pub fn apply(&self, uart: &dyn Uart) -> Result<()> {
105105
TestCommand::SpiMailboxMap.send_with_crc(uart)?;
106106
self.send_with_crc(uart)?;
107-
Status::recv(uart, Duration::from_secs(300), false)?;
107+
Status::recv(uart, Duration::from_secs(300), false, false)?;
108108
Ok(())
109109
}
110110

111111
pub fn disable(uart: &dyn Uart) -> Result<()> {
112112
TestCommand::SpiMailboxUnmap.send_with_crc(uart)?;
113-
Status::recv(uart, Duration::from_secs(300), false)?;
113+
Status::recv(uart, Duration::from_secs(300), false, false)?;
114114
Ok(())
115115
}
116116
}
@@ -119,7 +119,7 @@ impl SpiMailboxWrite {
119119
pub fn execute(&self, uart: &dyn Uart) -> Result<()> {
120120
TestCommand::SpiMailboxWrite.send_with_crc(uart)?;
121121
self.send_with_crc(uart)?;
122-
Status::recv(uart, Duration::from_secs(300), false)?;
122+
Status::recv(uart, Duration::from_secs(300), false, false)?;
123123
Ok(())
124124
}
125125
}

sw/host/provisioning/cp_lib/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ pub fn run_sram_cp_provision(
127127

128128
// Wait to receive CP device ID, and encode in big-endian in response.
129129
let _ = UartConsole::wait_for(spi_console, r"Exporting CP device ID ...", timeout)?;
130-
response.cp_device_id = ManufCpProvisioningDataOut::recv(spi_console, timeout, true)?
130+
response.cp_device_id = ManufCpProvisioningDataOut::recv(spi_console, timeout, true, false)?
131131
.cp_device_id
132132
.iter()
133133
.rev()

sw/host/provisioning/ft_lib/src/lib.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,12 @@ fn provision_certificates(
349349
// Wait until the device exports the TBS certificates.
350350
let t0 = Instant::now();
351351
let _ = UartConsole::wait_for(spi_console, r"Exporting TBS certificates ...", timeout)?;
352-
let perso_blob = PersoBlob::recv(spi_console, timeout, /*quite=*/ true)?;
352+
let perso_blob = PersoBlob::recv(
353+
spi_console,
354+
timeout,
355+
/*quiet=*/ true,
356+
/*skip_crc=*/ true,
357+
)?;
353358
response.stats.log_elapsed_time("perso-tbs-export", t0);
354359

355360
// Extract certificate byte vectors, endorse TBS certs, and ensure they parse with OpenSSL.
@@ -537,7 +542,13 @@ fn provision_certificates(
537542

538543
// Check the integrity of the certificates written to the device's flash by comparing a
539544
// SHA256 over all certificates computed on the host and device sides.
540-
let device_computed_certs_hash = SerdesSha256Hash::recv(spi_console, timeout, false)?;
545+
let device_computed_certs_hash = SerdesSha256Hash::recv(
546+
spi_console,
547+
timeout,
548+
/*quiet=*/ false,
549+
/*skip_crc=*/ true,
550+
)?;
551+
541552
if !device_computed_certs_hash
542553
.data
543554
.as_bytes()

0 commit comments

Comments
 (0)