@@ -82,6 +82,7 @@ static __forceinline int __builtin_ctz(unsigned x) {
82
82
#define OTP_PAGE_COUNT 64
83
83
#define OTP_PAGE_ROWS 64
84
84
#define OTP_ROW_COUNT (OTP_PAGE_COUNT * OTP_PAGE_ROWS)
85
+ #define OTP_SPECIAL_PAGES 3
85
86
86
87
using std::string;
87
88
using std::vector;
@@ -476,6 +477,7 @@ struct _settings {
476
477
std::vector<std::string> selectors;
477
478
uint32_t row = 0 ;
478
479
std::vector<std::string> extra_files;
480
+ bool dump_pages = false ;
479
481
} otp;
480
482
481
483
struct {
@@ -1098,7 +1100,8 @@ struct otp_dump_command : public cmd {
1098
1100
return (
1099
1101
(
1100
1102
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"
1102
1105
).min (0 ).doc_non_optional (true ) % " Row/field options" +
1103
1106
(
1104
1107
device_selection % " Target device selection"
@@ -6108,7 +6111,7 @@ bool otp_get_command::execute(device_map &devices) {
6108
6111
if (m.reg_row / OTP_PAGE_ROWS != last_page) {
6109
6112
// todo pre-check page lock
6110
6113
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 ) {
6112
6115
// Read individual rows for lock words
6113
6116
otp_cmd.wRow = m.reg_row ;
6114
6117
otp_cmd.wRowCount = 1 ;
@@ -6262,20 +6265,59 @@ bool otp_dump_command::execute(device_map &devices) {
6262
6265
auto con = get_single_rp2350_bootsel_device_connection (devices, false );
6263
6266
// todo pre-check page lock
6264
6267
struct picoboot_otp_cmd otp_cmd;
6265
- otp_cmd.wRow = 0;
6266
- otp_cmd.wRowCount = OTP_ROW_COUNT;
6267
6268
otp_cmd.bEcc = settings.otp .ecc && !settings.otp .raw ;
6268
6269
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);
6270
6272
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
+
6272
6306
fos.first_column (0 );
6273
6307
char buf[256 ];
6274
6308
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
+
6277
6317
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 ) {
6279
6321
snprintf (buf, sizeof (buf), " %04x, " , ((uint16_t *) raw_buffer.data ())[j]);
6280
6322
} else {
6281
6323
snprintf (buf, sizeof (buf), " %08x, " , ((uint32_t *) raw_buffer.data ())[j]);
0 commit comments