aboutsummaryrefslogtreecommitdiff
path: root/src/flash
diff options
context:
space:
mode:
authorTomas Vanek <vanekt@fbl.cz>2020-04-12 10:15:00 +0200
committerTomas Vanek <vanekt@fbl.cz>2020-10-28 10:50:49 +0000
commitc97ccc8971b44fbce28438cb926990a6e5a63450 (patch)
tree5006763a772fb32428b7dc6b1ea2c3484f5756c2 /src/flash
parent895d4a599585543155dd4a7559489cf126e02c4c (diff)
downloadriscv-openocd-c97ccc8971b44fbce28438cb926990a6e5a63450.zip
riscv-openocd-c97ccc8971b44fbce28438cb926990a6e5a63450.tar.gz
riscv-openocd-c97ccc8971b44fbce28438cb926990a6e5a63450.tar.bz2
flash/nor/nrf5: fix protection setting on nRF51
Protection setting has not ever worked. UICR CLENR0 register cannot be simply written but has to programmed because it resides in UICR page of the flash. Enable flash programming before writing CLENR0 and set back to r/o afterwards. Inform the user that reset might be required. Change-Id: Ib0f96c74ba3583ac33f4394ddb57d8c8895adf53 Signed-off-by: Tomas Vanek <vanekt@fbl.cz> Reviewed-on: http://openocd.zylin.com/5586 Tested-by: jenkins
Diffstat (limited to 'src/flash')
-rw-r--r--src/flash/nor/nrf5.c76
1 files changed, 50 insertions, 26 deletions
diff --git a/src/flash/nor/nrf5.c b/src/flash/nor/nrf5.c
index 0ceb8d7..657af9b 100644
--- a/src/flash/nor/nrf5.c
+++ b/src/flash/nor/nrf5.c
@@ -512,25 +512,13 @@ static int nrf5_protect_check(struct flash_bank *bank)
return ERROR_OK;
}
-static int nrf5_protect(struct flash_bank *bank, int set, unsigned int first,
+static int nrf5_protect_clenr0(struct flash_bank *bank, int set, unsigned int first,
unsigned int last)
{
int res;
uint32_t clenr0, ppfc;
- struct nrf5_info *chip;
-
- /* UICR cannot be write protected so just bail out early */
- if (bank->base == NRF5_UICR_BASE)
- return ERROR_FAIL;
-
- res = nrf5_get_probed_chip_if_halted(bank, &chip);
- if (res != ERROR_OK)
- return res;
-
- if (!(chip->features & NRF5_FEATURE_SERIES_51)) {
- LOG_ERROR("Flash protection setting of this nRF device is not supported");
- return ERROR_FLASH_OPER_UNSUPPORTED;
- }
+ struct nrf5_bank *nbank = bank->driver_priv;
+ struct nrf5_info *chip = nbank->chip;
if (first != 0) {
LOG_ERROR("Code region 0 must start at the beginning of the bank");
@@ -552,25 +540,61 @@ static int nrf5_protect(struct flash_bank *bank, int set, unsigned int first,
res = target_read_u32(chip->target, NRF51_UICR_CLENR0,
&clenr0);
if (res != ERROR_OK) {
- LOG_ERROR("Couldn't read code region 0 size[UICR]");
+ LOG_ERROR("Couldn't read code region 0 size from UICR");
return res;
}
- if (clenr0 == 0xFFFFFFFF) {
- res = target_write_u32(chip->target, NRF51_UICR_CLENR0,
- clenr0);
- if (res != ERROR_OK) {
- LOG_ERROR("Couldn't write code region 0 size[UICR]");
- return res;
- }
-
- } else {
+ if (!set || clenr0 != 0xFFFFFFFF) {
LOG_ERROR("You need to perform chip erase before changing the protection settings");
+ return ERROR_FAIL;
}
+ res = nrf5_nvmc_write_enable(chip);
+ if (res != ERROR_OK)
+ goto error;
+
+ clenr0 = bank->sectors[last].offset + bank->sectors[last].size;
+ res = target_write_u32(chip->target, NRF51_UICR_CLENR0, clenr0);
+
+ int res2 = nrf5_wait_for_nvmc(chip);
+
+ if (res == ERROR_OK)
+ res = res2;
+
+ if (res == ERROR_OK)
+ LOG_INFO("A reset or power cycle is required for the new protection settings to take effect.");
+ else
+ LOG_ERROR("Couldn't write code region 0 size to UICR");
+
+error:
+ nrf5_nvmc_read_only(chip);
+
nrf5_protect_check(bank);
- return ERROR_OK;
+ return res;
+}
+
+static int nrf5_protect(struct flash_bank *bank, int set, unsigned int first,
+ unsigned int last)
+{
+ int res;
+ struct nrf5_info *chip;
+
+ /* UICR cannot be write protected so just bail out early */
+ if (bank->base == NRF5_UICR_BASE) {
+ LOG_ERROR("UICR page does not support protection");
+ return ERROR_FLASH_OPER_UNSUPPORTED;
+ }
+
+ res = nrf5_get_probed_chip_if_halted(bank, &chip);
+ if (res != ERROR_OK)
+ return res;
+
+ if (chip->features & NRF5_FEATURE_SERIES_51)
+ return nrf5_protect_clenr0(bank, set, first, last);
+
+ LOG_ERROR("Flash protection setting is not supported on this nRF5 device");
+ return ERROR_FLASH_OPER_UNSUPPORTED;
}
static bool nrf5_info_variant_to_str(uint32_t variant, char *bf)