MCU i.MXRT 1051 encrypted XIP boot fails after software reset in case if SJC is disabled

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MCU i.MXRT 1051 encrypted XIP boot fails after software reset in case if SJC is disabled

Jump to solution
4,812 Views
georgemakarov
Contributor III

We use MCU i.MXRT 1051 (MIMXRT1051CVL5B) in our devices. For security purposes we use HAB and BEE (burn fuses BEE_KEY0=0b10, BEE_KEY1=0b10, DIR_BT_DIS, SEC_CONFIG[1], BT_FUSE_SEL). When device passes all tests we burn fuses that lock SerialDownloader and debug support (burn fuses SDP_DISABLE,  SJC_DISABLE, JTAG_SMODE=0b11). After this if I reset MCU using NVIC_SystemReset.

In case if encrypted XIP is not used then system resets successfully
In case if System JTAG Controller is not disabled then system resets as well

Despite i burnt the fuse BT_FUSE_SEL, it goes to serial downloader after software reset. Also i noticed it doesn't try to boot from NOR Flash at all, meaning no activity on flash pins such as CLK and CS.

The behaviour is similar to the one described in Errata (ERR011119, ERR011120). But we use both FAC regions and we don't lock them

Best regards, George Makarov
Labels (1)
Tags (2)
0 Kudos
Reply
1 Solution
4,588 Views
martin_hrncarek
NXP Employee
NXP Employee

Hi @georgemakarov,
this issue was reported on RT1060 and it is also present on RT1050.

The RT1064 seems to be not affected.

Unfortunately, the issue description has not been incorporated into the RT1050 errata yet.
The RT1050 errata docs will be updated accordingly.

ERR050538:

SOC: Potential boot failure on system reset if SJC_DISABLE fuse is blown Description: By default, the JTAG/SWD clock is pulled high reset. When the SJC_DISABLE fuse is blown the clock is low. The fuses are reloaded during a system reset, so there is a window between the system reset assertion and fuse loading completion, during which the clock is high. When the fuses are loaded the clock will go low, causing a transition from high to low. There is another clock transition from low to high on a subsequent system reset. The clock toggles can cause the system to think JTAG/SWD is active. This causes a security violation leading to HAB boot failure.

 Workaround: Configure the appropriate IOMUXC_SW_PAD_CTL register’s PUE and PUS fields to enable a pull resistor on one of the following signals:

∙ Pull JTAG_TCK/SWD_CLK low
∙ Pull JTAG_TRST low
∙ Pull JTAG_TMS/SWD_DIO high

The IOMUXC registers retain state on a system reset, so this only needs to be done one time after each POR.

JTAG_TRTS (GPIO_AD_B0_11) pin is unconnected on your board. The pin can be used to implement the workaround.

Best Regards,
Martin H.

View solution in original post

16 Replies
4,600 Views
georgemakarov
Contributor III

We have tried many ways to commit correct reboot with keeping data in RAM.
So in case if SJC_DISABLE fuse is blown you have only one way to reboot system. It's set core0_rst bit in SRC_SCR register (this way reset the core only but not peripheral).
Another workaround to commit reliable reset is using SNVS_LP. We adjust SNVS LP SRTC alarm time enable interrupt and then go to sleep mode. When alarm goes off MCU will startup. But in this case you have to be sure that SNVS LP keeps powered up and keep in mind that you will lose your data in RAM. 

uint32_t sec = SNVS_LP_SRTC_GetSeconds(SNVS);
sec += secondsToWakeUp;
snvs_lp_srtc_datetime_t alarmTime;
SNVS_LP_ConvertSecondsToDatetime(sec, &alarmTime);
if (SNVS_LP_SRTC_SetAlarm(SNVS, &alarmTime) == kStatus_Success)
{
 SNVS->LPCR |= kSNVS_SRTC_AlarmInterrupt;
 SNVS->LPSR |= kSNVS_SRTC_AlarmInterruptFlag;
 SNVS->LPCR |= SNVS_LPCR_TOP_MASK;
 }

 

Best regards, George Makarov
0 Kudos
Reply
4,589 Views
martin_hrncarek
NXP Employee
NXP Employee

Hi @georgemakarov,
this issue was reported on RT1060 and it is also present on RT1050.

The RT1064 seems to be not affected.

Unfortunately, the issue description has not been incorporated into the RT1050 errata yet.
The RT1050 errata docs will be updated accordingly.

ERR050538:

SOC: Potential boot failure on system reset if SJC_DISABLE fuse is blown Description: By default, the JTAG/SWD clock is pulled high reset. When the SJC_DISABLE fuse is blown the clock is low. The fuses are reloaded during a system reset, so there is a window between the system reset assertion and fuse loading completion, during which the clock is high. When the fuses are loaded the clock will go low, causing a transition from high to low. There is another clock transition from low to high on a subsequent system reset. The clock toggles can cause the system to think JTAG/SWD is active. This causes a security violation leading to HAB boot failure.

 Workaround: Configure the appropriate IOMUXC_SW_PAD_CTL register’s PUE and PUS fields to enable a pull resistor on one of the following signals:

∙ Pull JTAG_TCK/SWD_CLK low
∙ Pull JTAG_TRST low
∙ Pull JTAG_TMS/SWD_DIO high

The IOMUXC registers retain state on a system reset, so this only needs to be done one time after each POR.

JTAG_TRTS (GPIO_AD_B0_11) pin is unconnected on your board. The pin can be used to implement the workaround.

Best Regards,
Martin H.

3,248 Views
jtavares
Contributor I

Hello,

I believe we are having this problem intermittently.  We have HAB enabled, and SJC_DISABLE burned, on our i.MX RT 1060. We are resetting with the following, and occasionally the system does not come back after reset.

      SRC->SCR |= SRC_SCR_CORE0_RST_MASK;

I am attempting to apply this errata, but the curious thing is that both the Reference Manual AND my probe of the pad config registers show that TCK and TMS are already in the desired state, by default (TCK=pull low 100kOhm, TMS=pull-high 47kOHm).  It is only the TRST pad that is wrong (it is pulled high by default, whereas the errata says to pull it low)

The errata, and this thread, strongly suggests that ONLY one of these three pins has to be in the desired state in order to work around this issue, but that of course does not make sense if 2 of the 3 are already in the desired state by default.

So, could you please clarify if TCK and TMS have anything to do with this problem?

Regards,

James

0 Kudos
Reply
4,565 Views
georgemakarov
Contributor III

Hello Martin!
I have checked the suggested solution and I confirm that it works. When I pull the JTAG_TRST pin down then soft reset works properly and MCU boots successfully.

Mnohokrát děkuji!

Best regards, George Makarov
0 Kudos
Reply
4,794 Views
jeremyzhou
NXP Employee
NXP Employee

Hi,
Thank you for your interest in NXP Semiconductor products and for the opportunity to serve you.
Before answering your question, I have some inquires that need you to clarify
1) Which boot mode did you select? Internal boot or Boot From Fuses?
2) Which tool did you use to implement the Encrypt XIP (BEE)?
3) Which board did you test with?
4) Can you tell the version number of the i. MX RT1051 MCU?
5) Did you enable the Recover boot?
Looking forward to your reply.
Have a great day,
TIC

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
Reply
4,781 Views
georgemakarov
Contributor III

1. I use  Boot From Fuses mode (BOOT_MODE[1:0] = 00b). Both pins BOOT_MODE0 and BOOT_MODE1 are connected to GND.
2. I use NXP Code Signing Tool and elftosb for signing and generating certificates and keys
3. It's an device we develop. 
4. MIMXRT1051CVL5B
5. No, it's not enabled

If I use SRC_SCR register and set core0_rst bit, then the system resets and boots successfully
Also I noticed if i reset the system using POR_B then after this the first reset and boot via NVIC_SystemReset completes well, but the second time it ends in SerialDownloader.
Also I tried to disable and invalidate I- and D-Caches, tried to disable interrupts before going to NVIC reset, but unfortunately it didn't help.

Best regards, George Makarov
0 Kudos
Reply
4,758 Views
jeremyzhou
NXP Employee
NXP Employee

Hi,
Thanks for your reply and information.
Firstly, the phenomenon is none related to the ERR011119, ERR011120, as the MIMXRT1051CVL5B is the A1 version, next, whether you mean that the NVIC_SystemReset can only work once after the board power-up, however, the set core0_rst bit can always work well.
TIC

 

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
Reply
4,751 Views
georgemakarov
Contributor III

whether you mean that the NVIC_SystemReset can only work once after the board power-up, however, the set core0_rst bit can always work well.

Yes, set the core0_rst bit always lead to correct restart
SystemReset works only once after POR_B and never after board power-up
And I'd like to remind you SystemReset doesn't work properly only in case if SJC_DISABLE fuse is burnt.
How may disabling of the System JTAG Controller affect to COLD RESET?

Best regards, George Makarov
0 Kudos
Reply
4,743 Views
jeremyzhou
NXP Employee
NXP Employee

Thanks for your reply.
1) How may disabling of the System JTAG Controller effect to COLD RESET?
-- Frankly, I've not encountered this phenomenon before, so I'd like to suggest that you can print the value of the Application Interrupt and Reset Control Register (AIRCR) prior to calling the NVIC_SystemReset(), I think it can give some information to help us to figure this phenomenon out.
Looking forward to your reply.
TIC

 

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

 

0 Kudos
Reply
4,738 Views
georgemakarov
Contributor III

The value of AIRC Register is 0xFA050000

I have tried to burn following fuses and result is the same, it can't boot from NOR flash after system reset:
FORCE_COLD_BOOT (0x460[5])
FORCE_INTERNAL_BOOT (0x460[16])
L1 I-Cache DISABLE (0x470[2])

Also I enabled "Boot Failure Indicator Pin" and when it stuck, the selected pin goes high.

We can't reset via SRC_SCR[core0_rst] because we need to proceed the reset of all peripherial blocks in MCU, but not ARM core only. We have faced some issuies and full reset is the only way to recover proper operating of these peripherial blocks.

Looking forward to your reply.

Best regards, George Makarov
0 Kudos
Reply
4,726 Views
jeremyzhou
NXP Employee
NXP Employee

Thank you for your interest in NXP Semiconductor products and for the opportunity to serve you.
Firstly, Is the value of the AIRC Register always 0xFA050000 in two times calling?
Secondly, maybe you can consider another to reset the MCU, just like the below figures show, the MCU will be reset after output a low pulse via the WDOG_B pin.

7748584-e6fcb5b16e073595.png
Have a great day,
TIC

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
Reply
4,708 Views
georgemakarov
Contributor III

I tried to run the same code on another MCU. I replaced 1051 with 1064 (MIMXRT1064CVL5A) (they are pin-to-pin compatible). Ported firmware to this MCU (i use internal flash and address starts from 0x70000000). Burnt SJC_DISABLE fuse and when i use NVIC_SystemReset() it always reboots properly. 
By the way i noticed one difference between 1051 and 1064. While SRC_GPR1 and SRC_GPR2 on MXRT 1051 always equal 0x0, on MXRT1064 these registers always contains data, though each boot  it's random

1051

always these values

GPR1: 00000000
GPR2: 00000000
GPR3: 00000000
GPR4: 00000000
GPR5: 00000000
GPR6: 00000000
GPR7: 00000000
GPR8: 00000000
GPR9: 00000000
GPR10: 00000000
BOOT1: 00000002
BOOT2: 0000001B



1064

GPR1: BA44EF96
GPR2: 016E3600
GPR3: 00000000
GPR4: 00000000
GPR5: 00000000
GPR6: 00000000
GPR7: 00000000
GPR8: 00000000
GPR9: 00000000
GPR10: 00000000
BOOT1: 00000002
BOOT2: 0000001B

next boot

GPR1: 9D8A113E
GPR2: 016E3600
GPR3: 00000000
GPR4: 00000000
GPR5: 00000000
GPR6: 00000000
GPR7: 00000000
GPR8: 00000000
GPR9: 00000000
GPR10: 00000000
BOOT1: 00000002
BOOT2: 0000001B


 and it doesn't look like PERSISTENT_ENTRY0 and PERSISTENT_ARG0 registers have valid values

Best regards, George Makarov
0 Kudos
Reply
4,700 Views
jeremyzhou
NXP Employee
NXP Employee

Hi,
In my opinion, I don't think the phenomenon is related to SRC_GPR1 and SRC_GPR2 registers, as these two registers are used to demonstrates the information about the entry function for wake up.
In further, you can consider using the Watchdog instead of calling the NVIC_SystemReset() to reset the MCU, in addition, it doesn't need to change the circuit.
TIC

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
Reply
4,690 Views
georgemakarov
Contributor III

Reboot using WDOG_B doesn't work either. It stucks as well
I initialized wdog with following values:

const wdog_config_t WDOG_config = {
  .timeoutValue = 11,
  .enablePowerDown = false,
  .softwareResetExtension = true,
  .enableTimeOutAssert = true,
  .enableWdog = true,
  .workMode = {
    .enableWait = true,
    .enableStop = true,
    .enableDebug = true
  }, 
  .enableInterrupt = true,
  .interruptTimeValue = 3
};


and then tried to reset using this register

WDOG_PERIPHERAL->WCR &= ~(WDOG_WCR_SRE_MASK | WDOG_WCR_WDA_MASK | WDOG_WCR_SRS_MASK);
Best regards, George Makarov
0 Kudos
Reply
4,684 Views
jeremyzhou
NXP Employee
NXP Employee

Hi,
I think you may misunderstand my suggestion, you can use the Watchdog timer to generate a system reset manually, just like the below figure shows.

jeremyzhou_0-1611037192885.png

 


In further, you can refer to the wdog01 demo in the SDK library to make it.
TIC

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
Reply
4,723 Views
georgemakarov
Contributor III

Hi!
Yes, AIRC register always has this value, no matter if it's first boot or has been reset by POR_B.
Regarding Wdog_b pin. The problem that we have produced 24k devices and they have been delivered to clients around the world. All of these devices have such issue.
Of course we won't burn SJC_DISABLE fuse anymore, but how we can resolve the problem for these 24k devices?

Best regards, George Makarov
0 Kudos
Reply