This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Can't change ERASEPROTECT.DISABLE value

If I write a value to ERASEPROTECT.DISABLE -- which itself works, as I'm fully able to perform the mass erase by writing the same value using the debugger -- I can't seem to write a new value to the register during the same boot. It presumably isn't flash-based, since it needs to be written each boot. Is this specifically being prevented by the core? Is there a way to "reset" the value and write a new one, assuming ERASEPROTECT.LOCK hasn't been set?

Parents
  • Hello, 

    I've found the following in modules\hal\nordic\nrfx\mdk\nrf9160.h

    /**
      * @brief CTRLAPPERI_ERASEPROTECT [ERASEPROTECT] (Unspecified)
      */
    typedef struct {
      __IOM uint32_t  LOCK;                         /*!< (@ 0x00000000) Lock register ERASEPROTECT.DISABLE from being
                                                                        written until next reset                                   */
      __IOM uint32_t  DISABLE;                      /*!< (@ 0x00000004) Disable ERASEPROTECT and perform ERASEALL                  */
    } CTRLAPPERI_ERASEPROTECT_Type;                 /*!< Size = 8 (0x8)    

    Kind regards,
    Øyvind

  • Looks like DISABLE is being read as zero, even after writing to it (which I've verified is working, since I can write from the debugger to trigger the mass erase). The register description in the datasheet indicates it should be read/write.

    So, clearly there's some under-the-hood handling of this register in the core that makes it act a little differently than other registers. This isn't any kind of a show-stopper, but it doesn't seem to behave the way I'd expect it to having read the datasheet.

  • The issue in this ticket isn't impacted by nrfjprog, since it's just code execution that's doing the reading/writing, but regarding the previous ticket, it looks like 10.7.0 has an issue with recognizing my device, which I don't think I've ever seen in 10.9.0. I've seen two behaviors when trying to reprogram the Non-Secure flash with 10.7.0:

    nrfjprog.exe --program build/at_widget/zephyr/app_signed.hex --sectorerase
    Parsing hex file.
    ERROR: The operation attempted is unavailable due to readback protection in
    ERROR: your device. Please use --recover to unlock the device.

    and:

    nrfjprog.exe --program build/at_widget/zephyr/app_signed.hex --sectorerase
    ERROR: nrfjprog could not identify the target device. This may be due to an
    ERROR: invalid family argument, a problem with your device, or nrfjprog may
    ERROR: not yet support your device.
    ERROR: Please check the family argument passed, or upgrade nrfjprog to a more
    ERROR: recent version.

    The first one occurs more often, but I've seen the second one show up a few times. I'm wondering if the first is occurring when the ARM core is running Secure flash firmware and the second is when the ARM core is running Non-Secure firmware. I'm going to play with that more to see if I can confirm it, and I'm also going to go back to 10.9.0 to see if I can reproduce the different behaviors.

    At any rate, it seems like 10.7.0 still has issues with reprogramming Non-Secure firmware when APPROTECT has _not_ been set but SECUREAPPROTECT has been. It also seemed to have trouble reprogramming at all when SECUREAPPROTECT hadn't been set.

    Another variable I didn't think to bring up is that ERASEPROTECT (in the UICR) is also being set to avoid allowing a mass erase of flash and the UICR (and only allowing a mass erase using the ERASEPROTECT.DISABLE register). It doesn't seem like this should prevent the debugger from being able to reprogram flash, though, since nrfjprog --program <file> --sectorerase should be doing individual page erases and writes.

  • Looks like not enabling ERASEPROTECT has no effect on the access to the Non-Secure flash. I removed that part of our setup (when enabling SECUREAPPROTECT) and nothing changed for either 10.7.0 or 10.9.0.

  • Ahh, it appears there is an entire section I didn't know about in the NVMC section of the datasheet about specific steps to enable Non-Secure erase operations when Secure access is blocked. Hopefully all of this is my fault!

    Although the debugger should have access to these registers, since there are Non-Secure sets for them, so I would hope nrfjprog would already be setting these up if needed.

  • So, looks like we weren't setting NVMC to Non-Secure-accessible in the peripheral permission registers, which was preventing the debugger from using those registers at all. I found that, if I allow Non-Secure access to them and didn't use ERASEPROTECT, I could set SECUREAPPROTECT and the debugger could still do its nrfjprog --recover process. But, if I turn ERASEPROTECT back on, nrfjprog will no longer do anything, including --program <file> --sectorerase, since it doesn't like that "readback protection" is on.

    Since we don't want to allow anyone to erase our UICR and our Secure flash, we have to use ERASEPROTECT. Both 10.7.0 and 10.9.0 will not do the --sectorerase operation nor a manual --erasepage operation. Do you know what the "readback protection" is conditioned on? Is it something that could be bypassed in order to still do the page erase/flash write operations? I would think with NVMC now being Non-Secure-accessible this should work from the debugger.

  • Thanks for the feedback! This is valuable information that I will forward to our R&D team to verify behavior. 

    Investigating some more around the ERASEPROTECT, I found the following from modules\hal\nordic\nrfx\mdk\nrf9160_bitfields.h

    /* Register: CTRLAPPERI_ERASEPROTECT_LOCK */
    /* Description: Lock register ERASEPROTECT.DISABLE from being written until next reset */
    
    /* Bit 0 : Lock register ERASEPROTECT.DISABLE from being written until next reset */
    #define CTRLAPPERI_ERASEPROTECT_LOCK_LOCK_Pos (0UL) /*!< Position of LOCK field. */
    #define CTRLAPPERI_ERASEPROTECT_LOCK_LOCK_Msk (0x1UL << CTRLAPPERI_ERASEPROTECT_LOCK_LOCK_Pos) /*!< Bit mask of LOCK field. */
    #define CTRLAPPERI_ERASEPROTECT_LOCK_LOCK_Unlocked (0UL) /*!< Register ERASEPROTECT.DISABLE is writeable */
    #define CTRLAPPERI_ERASEPROTECT_LOCK_LOCK_Locked (1UL) /*!< Register ERASEPROTECT.DISABLE is read-only */
    
    /* Register: CTRLAPPERI_ERASEPROTECT_DISABLE */
    /* Description: Disable ERASEPROTECT and perform ERASEALL */
    
    /* Bits 31..0 : The ERASEALL sequence will be initiated if value of KEY fields are non-zero and KEY fields match on both CPU and debugger side */
    #define CTRLAPPERI_ERASEPROTECT_DISABLE_KEY_Pos (0UL) /*!< Position of KEY field. */
    #define CTRLAPPERI_ERASEPROTECT_DISABLE_KEY_Msk (0xFFFFFFFFUL << CTRLAPPERI_ERASEPROTECT_DISABLE_KEY_Pos) /*!< Bit mask of KEY field. */
     

    erik.johnson said:
    Ahh, it appears there is an entire section I didn't know about in the NVMC section of the datasheet about specific steps to enable Non-Secure erase operations when Secure access is blocked. Hopefully all of this is my fault!

     I assume it was the nAN41 you found? The NVMC field (along with APPROTECT and SECUREAPPOTECT) is described in the application note nAN41 - nRF9160 Production Programming under Troubleshooting, and the chapter Enabling device protection.

    Will get back to you with more information as soon as I know more.

Reply
  • Thanks for the feedback! This is valuable information that I will forward to our R&D team to verify behavior. 

    Investigating some more around the ERASEPROTECT, I found the following from modules\hal\nordic\nrfx\mdk\nrf9160_bitfields.h

    /* Register: CTRLAPPERI_ERASEPROTECT_LOCK */
    /* Description: Lock register ERASEPROTECT.DISABLE from being written until next reset */
    
    /* Bit 0 : Lock register ERASEPROTECT.DISABLE from being written until next reset */
    #define CTRLAPPERI_ERASEPROTECT_LOCK_LOCK_Pos (0UL) /*!< Position of LOCK field. */
    #define CTRLAPPERI_ERASEPROTECT_LOCK_LOCK_Msk (0x1UL << CTRLAPPERI_ERASEPROTECT_LOCK_LOCK_Pos) /*!< Bit mask of LOCK field. */
    #define CTRLAPPERI_ERASEPROTECT_LOCK_LOCK_Unlocked (0UL) /*!< Register ERASEPROTECT.DISABLE is writeable */
    #define CTRLAPPERI_ERASEPROTECT_LOCK_LOCK_Locked (1UL) /*!< Register ERASEPROTECT.DISABLE is read-only */
    
    /* Register: CTRLAPPERI_ERASEPROTECT_DISABLE */
    /* Description: Disable ERASEPROTECT and perform ERASEALL */
    
    /* Bits 31..0 : The ERASEALL sequence will be initiated if value of KEY fields are non-zero and KEY fields match on both CPU and debugger side */
    #define CTRLAPPERI_ERASEPROTECT_DISABLE_KEY_Pos (0UL) /*!< Position of KEY field. */
    #define CTRLAPPERI_ERASEPROTECT_DISABLE_KEY_Msk (0xFFFFFFFFUL << CTRLAPPERI_ERASEPROTECT_DISABLE_KEY_Pos) /*!< Bit mask of KEY field. */
     

    erik.johnson said:
    Ahh, it appears there is an entire section I didn't know about in the NVMC section of the datasheet about specific steps to enable Non-Secure erase operations when Secure access is blocked. Hopefully all of this is my fault!

     I assume it was the nAN41 you found? The NVMC field (along with APPROTECT and SECUREAPPOTECT) is described in the application note nAN41 - nRF9160 Production Programming under Troubleshooting, and the chapter Enabling device protection.

    Will get back to you with more information as soon as I know more.

Children
Related