Skip to content

Commit f018f89

Browse files
committed
Add permission handling to OTP dump
Prints XXs for any rows with permissions failures Also, add `--pages` option to index by page & row (eg 63:56) rather than hex (eg 0ff8)
1 parent 61bf7c3 commit f018f89

File tree

1 file changed

+51
-9
lines changed

1 file changed

+51
-9
lines changed

main.cpp

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ static __forceinline int __builtin_ctz(unsigned x) {
8282
#define OTP_PAGE_COUNT 64
8383
#define OTP_PAGE_ROWS 64
8484
#define OTP_ROW_COUNT (OTP_PAGE_COUNT * OTP_PAGE_ROWS)
85+
#define OTP_SPECIAL_PAGES 3
8586

8687
using std::string;
8788
using std::vector;
@@ -476,6 +477,7 @@ struct _settings {
476477
std::vector<std::string> selectors;
477478
uint32_t row = 0;
478479
std::vector<std::string> extra_files;
480+
bool dump_pages = false;
479481
} otp;
480482

481483
struct {
@@ -1098,7 +1100,8 @@ struct otp_dump_command : public cmd {
10981100
return (
10991101
(
11001102
option('r', "--raw").set(settings.otp.raw) % "Get raw 24 bit values" +
1101-
option('e', "--ecc").set(settings.otp.ecc) % "Use error correction"
1103+
option('e', "--ecc").set(settings.otp.ecc) % "Use error correction" +
1104+
option('p', "--pages").set(settings.otp.dump_pages) % "Index by page number & row number"
11021105
).min(0).doc_non_optional(true) % "Row/field options" +
11031106
(
11041107
device_selection % "Target device selection"
@@ -6108,7 +6111,7 @@ bool otp_get_command::execute(device_map &devices) {
61086111
if (m.reg_row / OTP_PAGE_ROWS != last_page) {
61096112
// todo pre-check page lock
61106113
struct picoboot_otp_cmd otp_cmd;
6111-
if (m.reg_row / OTP_PAGE_ROWS >= 62) {
6114+
if (m.reg_row / OTP_PAGE_ROWS >= OTP_PAGE_COUNT - OTP_SPECIAL_PAGES) {
61126115
// Read individual rows for lock words
61136116
otp_cmd.wRow = m.reg_row;
61146117
otp_cmd.wRowCount = 1;
@@ -6262,20 +6265,59 @@ bool otp_dump_command::execute(device_map &devices) {
62626265
auto con = get_single_rp2350_bootsel_device_connection(devices, false);
62636266
// todo pre-check page lock
62646267
struct picoboot_otp_cmd otp_cmd;
6265-
otp_cmd.wRow = 0;
6266-
otp_cmd.wRowCount = OTP_ROW_COUNT;
62676268
otp_cmd.bEcc = settings.otp.ecc && !settings.otp.raw;
62686269
vector<uint8_t> raw_buffer;
6269-
raw_buffer.resize(otp_cmd.wRowCount * (otp_cmd.bEcc ? 2 : 4));
6270+
uint8_t row_size = otp_cmd.bEcc ? 2 : 4;
6271+
raw_buffer.resize(OTP_ROW_COUNT * row_size);
62706272
picoboot_memory_access raw_access(con);
6271-
con.otp_read(&otp_cmd, raw_buffer.data(), raw_buffer.size());
6273+
std::map<int, string> page_errors;
6274+
std::map<int, string> row_errors;
6275+
6276+
// Read most pages by page, as permissions are per page
6277+
otp_cmd.wRowCount = OTP_PAGE_ROWS;
6278+
for (int i=0; i < OTP_PAGE_COUNT - OTP_SPECIAL_PAGES; i++) {
6279+
otp_cmd.wRow = i * OTP_PAGE_ROWS;
6280+
try {
6281+
con.otp_read(&otp_cmd, raw_buffer.data() + i*(raw_buffer.size() / OTP_PAGE_COUNT), raw_buffer.size() / OTP_PAGE_COUNT);
6282+
} catch (picoboot::command_failure& e) {
6283+
if (e.get_code() == PICOBOOT_NOT_PERMITTED) {
6284+
page_errors[i] = e.what();
6285+
} else {
6286+
throw e;
6287+
}
6288+
}
6289+
}
6290+
6291+
// Read special pages by row, as permissions are special
6292+
otp_cmd.wRowCount = 1;
6293+
for (int i=(OTP_PAGE_COUNT - OTP_SPECIAL_PAGES) * OTP_PAGE_ROWS; i < OTP_PAGE_COUNT * OTP_PAGE_ROWS; i++) {
6294+
otp_cmd.wRow = i;
6295+
try {
6296+
con.otp_read(&otp_cmd, raw_buffer.data() + i * row_size, row_size);
6297+
} catch (picoboot::command_failure& e) {
6298+
if (e.get_code() == PICOBOOT_NOT_PERMITTED) {
6299+
row_errors[i] = e.what();
6300+
} else {
6301+
throw e;
6302+
}
6303+
}
6304+
}
6305+
62726306
fos.first_column(0);
62736307
char buf[256];
62746308
for(int i=0;i<OTP_ROW_COUNT;i+=8) {
6275-
snprintf(buf, sizeof(buf), "%04x: ", i);
6276-
fos << buf;
6309+
if (settings.otp.dump_pages) {
6310+
snprintf(buf, sizeof(buf), "%02d:%02d: ", i / OTP_PAGE_ROWS, i % OTP_PAGE_ROWS);
6311+
fos << buf;
6312+
} else {
6313+
snprintf(buf, sizeof(buf), "%04x: ", i);
6314+
fos << buf;
6315+
}
6316+
62776317
for (int j = i; j < i + 8; j++) {
6278-
if (otp_cmd.bEcc) {
6318+
if (row_errors.find(j) != row_errors.end() || page_errors.find(j / OTP_PAGE_ROWS) != page_errors.end()) {
6319+
snprintf(buf, sizeof(buf), "%s, ", otp_cmd.bEcc ? "XXXX" : "XXXXXXXX");
6320+
} else if (otp_cmd.bEcc) {
62796321
snprintf(buf, sizeof(buf), "%04x, ", ((uint16_t *) raw_buffer.data())[j]);
62806322
} else {
62816323
snprintf(buf, sizeof(buf), "%08x, ", ((uint32_t *) raw_buffer.data())[j]);

0 commit comments

Comments
 (0)