Skip to content

Commit 2af35ab

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 9283925 commit 2af35ab

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"
@@ -6100,7 +6103,7 @@ bool otp_get_command::execute(device_map &devices) {
61006103
if (m.reg_row / OTP_PAGE_ROWS != last_page) {
61016104
// todo pre-check page lock
61026105
struct picoboot_otp_cmd otp_cmd;
6103-
if (m.reg_row / OTP_PAGE_ROWS >= 62) {
6106+
if (m.reg_row / OTP_PAGE_ROWS >= OTP_PAGE_COUNT - OTP_SPECIAL_PAGES) {
61046107
// Read individual rows for lock words
61056108
otp_cmd.wRow = m.reg_row;
61066109
otp_cmd.wRowCount = 1;
@@ -6254,20 +6257,59 @@ bool otp_dump_command::execute(device_map &devices) {
62546257
auto con = get_single_rp2350_bootsel_device_connection(devices, false);
62556258
// todo pre-check page lock
62566259
struct picoboot_otp_cmd otp_cmd;
6257-
otp_cmd.wRow = 0;
6258-
otp_cmd.wRowCount = OTP_ROW_COUNT;
62596260
otp_cmd.bEcc = settings.otp.ecc && !settings.otp.raw;
62606261
vector<uint8_t> raw_buffer;
6261-
raw_buffer.resize(otp_cmd.wRowCount * (otp_cmd.bEcc ? 2 : 4));
6262+
uint8_t row_size = otp_cmd.bEcc ? 2 : 4;
6263+
raw_buffer.resize(OTP_ROW_COUNT * row_size);
62626264
picoboot_memory_access raw_access(con);
6263-
con.otp_read(&otp_cmd, raw_buffer.data(), raw_buffer.size());
6265+
std::map<int, string> page_errors;
6266+
std::map<int, string> row_errors;
6267+
6268+
// Read most pages by page, as permissions are per page
6269+
otp_cmd.wRowCount = OTP_PAGE_ROWS;
6270+
for (int i=0; i < OTP_PAGE_COUNT - OTP_SPECIAL_PAGES; i++) {
6271+
otp_cmd.wRow = i * OTP_PAGE_ROWS;
6272+
try {
6273+
con.otp_read(&otp_cmd, raw_buffer.data() + i*(raw_buffer.size() / OTP_PAGE_COUNT), raw_buffer.size() / OTP_PAGE_COUNT);
6274+
} catch (picoboot::command_failure& e) {
6275+
if (e.get_code() == PICOBOOT_NOT_PERMITTED) {
6276+
page_errors[i] = e.what();
6277+
} else {
6278+
throw e;
6279+
}
6280+
}
6281+
}
6282+
6283+
// Read special pages by row, as permissions are special
6284+
otp_cmd.wRowCount = 1;
6285+
for (int i=(OTP_PAGE_COUNT - OTP_SPECIAL_PAGES) * OTP_PAGE_ROWS; i < OTP_PAGE_COUNT * OTP_PAGE_ROWS; i++) {
6286+
otp_cmd.wRow = i;
6287+
try {
6288+
con.otp_read(&otp_cmd, raw_buffer.data() + i * row_size, row_size);
6289+
} catch (picoboot::command_failure& e) {
6290+
if (e.get_code() == PICOBOOT_NOT_PERMITTED) {
6291+
row_errors[i] = e.what();
6292+
} else {
6293+
throw e;
6294+
}
6295+
}
6296+
}
6297+
62646298
fos.first_column(0);
62656299
char buf[256];
62666300
for(int i=0;i<OTP_ROW_COUNT;i+=8) {
6267-
snprintf(buf, sizeof(buf), "%04x: ", i);
6268-
fos << buf;
6301+
if (settings.otp.dump_pages) {
6302+
snprintf(buf, sizeof(buf), "%02d:%02d: ", i / OTP_PAGE_ROWS, i % OTP_PAGE_ROWS);
6303+
fos << buf;
6304+
} else {
6305+
snprintf(buf, sizeof(buf), "%04x: ", i);
6306+
fos << buf;
6307+
}
6308+
62696309
for (int j = i; j < i + 8; j++) {
6270-
if (otp_cmd.bEcc) {
6310+
if (row_errors.find(j) != row_errors.end() || page_errors.find(j / OTP_PAGE_ROWS) != page_errors.end()) {
6311+
snprintf(buf, sizeof(buf), "%s, ", otp_cmd.bEcc ? "XXXX" : "XXXXXXXX");
6312+
} else if (otp_cmd.bEcc) {
62716313
snprintf(buf, sizeof(buf), "%04x, ", ((uint16_t *) raw_buffer.data())[j]);
62726314
} else {
62736315
snprintf(buf, sizeof(buf), "%08x, ", ((uint32_t *) raw_buffer.data())[j]);

0 commit comments

Comments
 (0)