-
-
Notifications
You must be signed in to change notification settings - Fork 774
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
target/nrf91: add mass_erase and recovery probe #1785
base: main
Are you sure you want to change the base?
Conversation
@dragonmux I added most of the missing parts for nrf91. Maybe you could give me pointers on how to handle the TODOs? The UICR APPROTECT part basically needs to do a flash write after each mass-erase to tell the "hardenend APPROTECT" system not to lock down the device after the next reset. This is also relevant for nRF53 support. |
The post-Flash write and mass-erase UICR fix-up sounds like something that should be a target |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done an initial review, there are a lot of interesting details here that we're very grateful to get to know about, like the TARGETID revision number being used for once in a part and having bearing on the part number.
Please don't forget to run clang-format
on the contribution and fix the few hex constant capitalisation lints - the clang-format
lint pass is currently broken but we are still enforcing it.
src/target/nrf91.c
Outdated
} | ||
|
||
bool nrf91_probe(target_s *target) | ||
{ | ||
adiv5_access_port_s *ap = cortex_ap(target); | ||
|
||
if (ap->dp->version < 2U) | ||
if (ap->dp->version < 2U || ap->dp->target_partno != 0x90U) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please avoid a magic number here - 0x90U
should ideally be #define
'd above as, eg, ID_NRF91
so it's clearer what it is and where it comes from. Ideally a reference to the TRM section and page this information can be found from would be great, but we know that's not always possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please note that the choice of suggesting ID_NRF91
is for consistency with all the other target support implementations - while this is at least now a define that describes what the magic number is, it would be best to have it use the same style as the other target implementations.
Thanks! Got it to work now. Just putting it in exit_flash_mode is enough IMO because a blank app will also cause the protection to engage. |
2d81846
to
b1391c6
Compare
The reason we said "and at the end of the mass erase function" is that it's up to the target support too override |
|
I got to check the flash write function again - we can skip the readynext wait if the page is erased beforehand. |
b1391c6
to
a7a9b63
Compare
@dragonmux I managed to make the app image much smaller and include it here - the target is now unprotected after mass-erase. :) |
Signed-off-by: Maximilian Deubel <[email protected]>
a7a9b63
to
8941178
Compare
It might actually be better to implement target commands and show the CTRL-AP in any case. There is also a rarely-used feature that could lock mass-erase with a password. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apologies this PR got neglected and the code review we'd started some time back in March didn't get posted. If you could please rebase this PR on main
and fix the lint pass issues along with this new review, that would be greatly appreciated as we would like to be able to land this before v2.0
0x5a, 0x02, 0xc3, 0xf8, 0x10, 0x2e, 0x03, 0x4b, 0x4f, 0xf0, 0x5a, 0x02, | ||
0xc3, 0xf8, 0x00, 0x2e, 0xfe, 0xe7, 0x00, 0x00, 0x00, 0x90, 0x03, 0x50 | ||
}; | ||
unsigned int empty_app_len = 36; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use ARRAY_LENGTH()
and make this a #define
. This is not a constant expression in C and so uses Flash space unnecessarily to store a full variable. something like #define NRF91_EMPTY_APP_LEN ARRAY_LENGTH(empty_app)
would be appropriate.
#define NRF91_UICR_APPROTECT_UNPROTECT_VAL 0x50FA50FAU | ||
#define NRF91_UICR_ERASED_VAL 0xFFFFFFFFU | ||
|
||
unsigned char empty_app[] = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please do not use raw types. uint8_t
if you want to make this unsigned (and then U-suffix every value in the array initialisation so they're unsigned and won't get sign extended).
.apsel = 0x4U, | ||
}; | ||
|
||
if (!nrf91_ctrl_ap_mass_erase(&ctrl_ap)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please drop these braces as they are unnecessary. The code base style is for single statement bodies of conditional block to not be enclosed in braces.
return false; | ||
|
||
switch (ap->dp->target_partno) { | ||
case 0x90: | ||
#ifndef ENABLE_DEBUG |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This wants to be #ifndef DEBUG_INFO_IS_NOOP
to correctly guard these memory read-backs.
#define NRF91_CTRL_IDR_EXPECTED 0x12880000 | ||
#define NRF91_AHB_AP_IDR_EXPECTED 0x84770001 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are missing their U
suffixes to ensure they're defined as unsigned values. Because the AP IDR value (as an example) sets the sign bit on 32-bit platforms, if this value is then widened for any reason, then the upper bytes of the new value will be all set high, and if it is narrowed, this invokes UB (due to changing the value of the sign bit). Neither of these problems occur with unsigned constants.
if (erase_needed) { | ||
gdb_out("Skipping UICR erase, mass erase might be needed\n"); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The braces are superfluous, please drop them.
Detailed description
Your checklist for this pull request
Closing issues
fixes #1778