mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-03-27 13:35:44 +00:00
feat(core/prodtest): support writing device ID into OTP memory
This commit is contained in:
parent
eccf4e6e72
commit
879c08c9f1
@ -26,3 +26,4 @@
|
|||||||
#define FLASH_OTP_BLOCK_RANDOMNESS 3
|
#define FLASH_OTP_BLOCK_RANDOMNESS 3
|
||||||
#define FLASH_OTP_BLOCK_DEVICE_VARIANT 4
|
#define FLASH_OTP_BLOCK_DEVICE_VARIANT 4
|
||||||
#define FLASH_OTP_BLOCK_FIRMWARE_VERSION 5
|
#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:
|
Example:
|
||||||
```
|
```
|
||||||
|
otp-batch-read
|
||||||
# Reading device OTP memory...
|
# Reading device OTP memory...
|
||||||
# Bytes read: <hexadecimal string>
|
# Bytes read: <hexadecimal string>
|
||||||
ERROR no-data "OTP block is empty."
|
ERROR no-data "OTP block is empty."
|
||||||
@ -493,6 +494,39 @@ otp-batch-write T2B1-231231 --dry-run
|
|||||||
# Locking OTP block...
|
# 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
|
### 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.
|
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 <rtl/cli.h>
|
||||||
#include <util/flash_otp.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) {
|
if (cli_arg_count(cli) > 0) {
|
||||||
cli_error_arg_count(cli);
|
cli_error_arg_count(cli);
|
||||||
return;
|
return;
|
||||||
@ -33,8 +33,7 @@ static void prodtest_otp_batch_read(cli_t* cli) {
|
|||||||
|
|
||||||
cli_trace(cli, "Reading device OTP memory...");
|
cli_trace(cli, "Reading device OTP memory...");
|
||||||
|
|
||||||
if (sectrue !=
|
if (sectrue != flash_otp_read(block_num, 0, block, sizeof(block))) {
|
||||||
flash_otp_read(FLASH_OTP_BLOCK_BATCH, 0, block, sizeof(block))) {
|
|
||||||
cli_error(cli, CLI_ERROR, "Failed to read OTP memory.");
|
cli_error(cli, CLI_ERROR, "Failed to read OTP memory.");
|
||||||
return;
|
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");
|
const char* data = cli_arg(cli, "text");
|
||||||
|
|
||||||
if (strlen(data) == 0 || strlen(data) > FLASH_OTP_BLOCK_SIZE - 1) {
|
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;
|
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,
|
cli_error(cli, CLI_ERROR_LOCKED,
|
||||||
"OTP block is locked and cannot be written again.");
|
"OTP block is locked and cannot be written again.");
|
||||||
return;
|
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);
|
cli_trace(cli, "Bytes written: %s", block_hex);
|
||||||
|
|
||||||
if (!dry_run) {
|
if (!dry_run) {
|
||||||
if (sectrue !=
|
if (sectrue != flash_otp_write(block_num, 0, block, sizeof(block))) {
|
||||||
flash_otp_write(FLASH_OTP_BLOCK_BATCH, 0, block, sizeof(block))) {
|
|
||||||
cli_error(cli, CLI_ERROR, "Failed to write OTP block.");
|
cli_error(cli, CLI_ERROR, "Failed to write OTP block.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -131,7 +129,7 @@ static void prodtest_otp_batch_write(cli_t* cli) {
|
|||||||
cli_trace(cli, "Locking OTP block...");
|
cli_trace(cli, "Locking OTP block...");
|
||||||
|
|
||||||
if (!dry_run) {
|
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.");
|
cli_error(cli, CLI_ERROR, "Failed to lock the OTP block.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -141,6 +139,22 @@ static void prodtest_otp_batch_write(cli_t* cli) {
|
|||||||
cli_ok(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
|
// clang-format off
|
||||||
|
|
||||||
PRODTEST_CLI_CMD(
|
PRODTEST_CLI_CMD(
|
||||||
@ -156,3 +170,17 @@ PRODTEST_CLI_CMD(
|
|||||||
.info = "Write the device batch info into OTP memory",
|
.info = "Write the device batch info into OTP memory",
|
||||||
.args = "<text> [--execute | --dry-run]"
|
.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