@@ -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"
@@ -6100,7 +6103,7 @@ bool otp_get_command::execute(device_map &devices) {
6100
6103
if (m.reg_row / OTP_PAGE_ROWS != last_page) {
6101
6104
// todo pre-check page lock
6102
6105
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 ) {
6104
6107
// Read individual rows for lock words
6105
6108
otp_cmd.wRow = m.reg_row ;
6106
6109
otp_cmd.wRowCount = 1 ;
@@ -6254,20 +6257,59 @@ bool otp_dump_command::execute(device_map &devices) {
6254
6257
auto con = get_single_rp2350_bootsel_device_connection (devices, false );
6255
6258
// todo pre-check page lock
6256
6259
struct picoboot_otp_cmd otp_cmd;
6257
- otp_cmd.wRow = 0 ;
6258
- otp_cmd.wRowCount = OTP_ROW_COUNT;
6259
6260
otp_cmd.bEcc = settings.otp .ecc && !settings.otp .raw ;
6260
6261
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);
6262
6264
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
+
6264
6298
fos.first_column (0 );
6265
6299
char buf[256 ];
6266
6300
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
+
6269
6309
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 ) {
6271
6313
snprintf (buf, sizeof (buf), " %04x, " , ((uint16_t *) raw_buffer.data ())[j]);
6272
6314
} else {
6273
6315
snprintf (buf, sizeof (buf), " %08x, " , ((uint32_t *) raw_buffer.data ())[j]);
0 commit comments