mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-03-06 10:16:07 +00:00
feat(core/prodtest): support writing device ID into OTP memory
This commit is contained in:
parent
a18abd8e54
commit
d0684a5e28
@ -26,3 +26,4 @@
|
||||
#define FLASH_OTP_BLOCK_RANDOMNESS 3
|
||||
#define FLASH_OTP_BLOCK_DEVICE_VARIANT 4
|
||||
#define FLASH_OTP_BLOCK_FIRMWARE_VERSION 5
|
||||
#define FLASH_OTP_BLOCK_DEVICE_ID 6
|
||||
|
1
core/embed/projects/prodtest/.changelog.d/4735.added
Normal file
1
core/embed/projects/prodtest/.changelog.d/4735.added
Normal file
@ -0,0 +1 @@
|
||||
Added device ID write/read commands.
|
@ -469,6 +469,7 @@ If the OTP memory has not been written yet, it returns error code `no-data`.
|
||||
|
||||
Example:
|
||||
```
|
||||
otp-batch-read
|
||||
# Reading device OTP memory...
|
||||
# Bytes read: <hexadecimal string>
|
||||
ERROR no-data "OTP block is empty."
|
||||
@ -493,6 +494,39 @@ otp-batch-write T2B1-231231 --dry-run
|
||||
# Locking OTP block...
|
||||
```
|
||||
|
||||
|
||||
### otp-device-id-read
|
||||
Retrieves the device ID string from the device's OTP memory. The device ID string is unique for each device.
|
||||
|
||||
If the OTP memory has not been written yet, it returns error code `no-data`.
|
||||
|
||||
Example:
|
||||
```
|
||||
otp-device-id-read
|
||||
# Reading device OTP memory...
|
||||
# Bytes read: <hexadecimal string>
|
||||
ERROR no-data "OTP block is empty."
|
||||
```
|
||||
|
||||
### otp-device-id-write
|
||||
Writes the device ID string to the device's OTP memory. The device ID string is unique for each device.
|
||||
|
||||
The batch string can be up to 31 characters in length.
|
||||
|
||||
In non-production firmware, you must include `--execute` as the last parameter to write the data to the OTP memory. Conversely, in production firmware, you can use `--dry-run` as the last parameter to simulate the command without actually writing to the OTP memory.
|
||||
|
||||
Example:
|
||||
```
|
||||
otp-device-id-write 123456ABCD --dry-run
|
||||
#
|
||||
# !!! It's a dry run, OTP will be left unchanged.
|
||||
# !!! Use '--execute' switch to write to OTP memory.
|
||||
#
|
||||
# Writing device batch info into OTP memory...
|
||||
# Bytes written: 3132333435364142434400000000000000000000000000000000000000000000
|
||||
# Locking OTP block...
|
||||
```
|
||||
|
||||
### otp-variant-write
|
||||
Writes up to 31 decimal values, each representing device variant options, to device's OTP memory. Each value must range from 0 to 255.
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include <rtl/cli.h>
|
||||
#include <util/flash_otp.h>
|
||||
|
||||
static void prodtest_otp_batch_read(cli_t* cli) {
|
||||
static void prodtest_otp_read(cli_t* cli, uint8_t block_num) {
|
||||
if (cli_arg_count(cli) > 0) {
|
||||
cli_error_arg_count(cli);
|
||||
return;
|
||||
@ -33,8 +33,7 @@ static void prodtest_otp_batch_read(cli_t* cli) {
|
||||
|
||||
cli_trace(cli, "Reading device OTP memory...");
|
||||
|
||||
if (sectrue !=
|
||||
flash_otp_read(FLASH_OTP_BLOCK_BATCH, 0, block, sizeof(block))) {
|
||||
if (sectrue != flash_otp_read(block_num, 0, block, sizeof(block))) {
|
||||
cli_error(cli, CLI_ERROR, "Failed to read OTP memory.");
|
||||
return;
|
||||
}
|
||||
@ -64,7 +63,7 @@ static void prodtest_otp_batch_read(cli_t* cli) {
|
||||
}
|
||||
}
|
||||
|
||||
static void prodtest_otp_batch_write(cli_t* cli) {
|
||||
static void prodtest_otp_write(cli_t* cli, uint8_t block_num) {
|
||||
const char* data = cli_arg(cli, "text");
|
||||
|
||||
if (strlen(data) == 0 || strlen(data) > FLASH_OTP_BLOCK_SIZE - 1) {
|
||||
@ -111,18 +110,17 @@ static void prodtest_otp_batch_write(cli_t* cli) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sectrue == flash_otp_is_locked(FLASH_OTP_BLOCK_BATCH)) {
|
||||
if (sectrue == flash_otp_is_locked(block_num)) {
|
||||
cli_error(cli, CLI_ERROR_LOCKED,
|
||||
"OTP block is locked and cannot be written again.");
|
||||
return;
|
||||
}
|
||||
|
||||
cli_trace(cli, "Writing device batch info into OTP memory...");
|
||||
cli_trace(cli, "Writing info into OTP memory...");
|
||||
cli_trace(cli, "Bytes written: %s", block_hex);
|
||||
|
||||
if (!dry_run) {
|
||||
if (sectrue !=
|
||||
flash_otp_write(FLASH_OTP_BLOCK_BATCH, 0, block, sizeof(block))) {
|
||||
if (sectrue != flash_otp_write(block_num, 0, block, sizeof(block))) {
|
||||
cli_error(cli, CLI_ERROR, "Failed to write OTP block.");
|
||||
return;
|
||||
}
|
||||
@ -131,7 +129,7 @@ static void prodtest_otp_batch_write(cli_t* cli) {
|
||||
cli_trace(cli, "Locking OTP block...");
|
||||
|
||||
if (!dry_run) {
|
||||
if (sectrue != flash_otp_lock(FLASH_OTP_BLOCK_BATCH)) {
|
||||
if (sectrue != flash_otp_lock(block_num)) {
|
||||
cli_error(cli, CLI_ERROR, "Failed to lock the OTP block.");
|
||||
return;
|
||||
}
|
||||
@ -141,6 +139,22 @@ static void prodtest_otp_batch_write(cli_t* cli) {
|
||||
cli_ok(cli, "");
|
||||
}
|
||||
|
||||
static void prodtest_otp_batch_read(cli_t* cli) {
|
||||
prodtest_otp_read(cli, FLASH_OTP_BLOCK_BATCH);
|
||||
}
|
||||
|
||||
static void prodtest_otp_batch_write(cli_t* cli) {
|
||||
prodtest_otp_write(cli, FLASH_OTP_BLOCK_BATCH);
|
||||
}
|
||||
|
||||
static void prodtest_otp_device_id_read(cli_t* cli) {
|
||||
prodtest_otp_read(cli, FLASH_OTP_BLOCK_DEVICE_ID);
|
||||
}
|
||||
|
||||
static void prodtest_otp_device_id_write(cli_t* cli) {
|
||||
prodtest_otp_write(cli, FLASH_OTP_BLOCK_DEVICE_ID);
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
|
||||
PRODTEST_CLI_CMD(
|
||||
@ -156,3 +170,17 @@ PRODTEST_CLI_CMD(
|
||||
.info = "Write the device batch info into OTP memory",
|
||||
.args = "<text> [--execute | --dry-run]"
|
||||
);
|
||||
|
||||
PRODTEST_CLI_CMD(
|
||||
.name = "otp-device-id-read",
|
||||
.func = prodtest_otp_device_id_read,
|
||||
.info = "Read the device ID from OTP memory",
|
||||
.args = ""
|
||||
);
|
||||
|
||||
PRODTEST_CLI_CMD(
|
||||
.name = "otp-device-id-write",
|
||||
.func = prodtest_otp_device_id_write,
|
||||
.info = "Write the device ID into OTP memory",
|
||||
.args = "<text> [--execute | --dry-run]"
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user