cancel
Showing results for 
Search instead for 
Did you mean: 

NETXDUO not working with enabled TrustZone

funkii
Associate III

Hi everyone,

i'm currently facing some issues while using NetXDuo (in the NonSecure World) with TrustZone.

My current goal: Use Network stuff, i.e. be able to ping the board from my PC with NetXDuo running in the NonSecure World with activated TrustZone.

 

With an empty project, i do the following steps and assign the ETH to the NS world. Apart from that, the project is empty.
The steps are more or less taken from this example.

- ETH: `RMII` mode. Set RxBuffLen to `1536`
- ICACHE: (optional to disable the IDE warnings) `2-ways set associative cache` mode
- ThreadX: `Core`
- NetXDuo: NX Core, DHCP Client, Network Interfaces > Ethernet Interfacea and LAN8472. In the configuration:
        - Platform Settings > chose lan8742 for both options
        - Enable Interface Capability true
        - Memory Pool Size 30 * 1024
        - Generate Init Code true
        - IP Instance Thread Size 2 * 1024
        - Pool Size in number of Packets 10
        - Application Thread Stack Size 2 * 1024
- NVIC: Enable Ethernet Global Interrupt to Preemption Prio 7
- SYS: Timebase Source TIM6
- RCC: Enable High Speed Clock > DIGBYPASS Clock Source
- Pinout: Set Pin PG12 to `ETH_TXD1`. (By doing this, PG14 should be cleared)

 

If i run the project like this, the wati until an IP Address is ready semaphore get in app_netxduo.c does not return to TX_SUCCESS, i.e. the board is not pingable. 

 

What kinda confuses me is that if i do the steps above in an Project without TrustZone, everything works.

 

Anyone got an idea what might be my issue? I also tried to compare the .ioc files by hand in an editor and did not spot anything what might be a problem.

 

I'd appreciate any help or hints 🙂

Best,

funkii

14 REPLIES 14
funkii
Associate III

Hi everyone,

some more additional information that might be relevant:

If I activate e.g. the "RCC non-secure global interrupt" in the ioc file, the file "Secure/Core/Inc/partition_stm32h573xx.h" gets changed correctly. -> I attached the git diff

@@ -386,7 +386,7 @@
 //   <o.6>  FLASH_IRQn            <0=> Secure state
 //   <o.7>  FLASH_S_IRQn          <0=> Secure state
 //   <o.8>  GTZC_IRQn             <0=> Secure state
-//   <o.9>  RCC_IRQn              <0=> Secure state
+//   <o.9>  RCC_IRQn              <1=> Non-Secure state^M
 //   <o.10> RCC_S_IRQn            <0=> Secure state
 //   <o.11> EXTI0_IRQn            <0=> Secure state
 //   <o.12> EXTI1_IRQn            <0=> Secure state
@@ -410,7 +410,7 @@
 //   <o.30> GPDMA1_Channel1_IRQn  <0=> Secure state
 //   <o.31> GPDMA1_Channel2_IRQn  <0=> Secure state
 */
-#define NVIC_INIT_ITNS0_VAL      0x00000000
+#define NVIC_INIT_ITNS0_VAL      0x00000200^M

But if I activate the "Ethernet global interrupt", nothing changes in that file. I do not see any Interrupts for the ETH there at all that could be configured by hand.

Overall between activated and deactivated Interrupt, nothing at all changes in the secure subproject.

 

I think that might be the problem that I do not receive Interrupts with activated TrustZone. 

Since I'm not 100% sure that this is the problem, can anyone with more experience confirm that this is the case?

 

 

funkii
Associate III

Hi,

there seems to be a bug in the code generation:

I looked up the Ethernet Interrupt Number in the reference manual, which is 106.

If I modify the Secure/Core/Inc/partition_stm32h573xx.h by hand and set the bits by hand my breakpoint finally gets triggered. In NVIC_INIT_ITNS3_VAL the 12th bit needs to be set.

#define NVIC_INIT_ITNS3_VAL 0x00000400

Unfortunately this does not fix my problem...

The Interrupt gets triggered once, and with a DMA Error. More accurate the Receive Buffer Unavailable (RBU) Bit gets set, together with the Abnormal Interrupt Summary (AIS). The AIS gets always set when RBU gets set.

I found this description of RBU:

This bit indicates that the application owns the next descriptor in the Receive list, and the
DMA cannot acquire it. The Rx process is suspended. To resume processing Rx descriptors,
the application should change the ownership of the descriptor and issue a Receive Poll
Demand command. If this command is not issued, the Rx process resumes when the next
recognized incoming packet is received. In ring mode, the application should advance the
Receive Descriptor Tail Pointer register of a channel. This bit is set only when the DMA owns
the previous Rx descriptor.

 

Anyone got an idea why this is happening? Do i need to change any addresses because I use TrustZone? 

Best,

funkii

Hello @funkii ,

When TZ enabled the ETHERNET DMA cannot acquire the descriptors (Tx Descriptor Unavailable / Rx Descriptor Unavailable) placed in SRAM. And thus whether the ETH is placed in secure or not-secure project. so you need to reconfigure the memory layout to get the descriptors out of the protected area .

BR

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
funkii
Associate III

Hi,

i finally managed to get it working! Thanks @STea for your help, I really appreciate it.

Steps to get it working:

Start Board Project with Trustzone enabled
Firmware Version v1.1.1

Clear pinout

ETH
        Mode RMII
        RxBuffLen 1536
        Set Pin PG12 to ETH_TXD1 (By doing this, PG14 should be cleared)

THREADX
        Core

NETXDUO
        NX Core
        Addons > DHCP > Client
        Network Interfaces > Ethernet interface, Ethernet Phy Interface > LAN8742
        Platform Settings > both lan8742

        Enable Interface Capability true
        memory pool size 30 * 1024
        Genreate Init Code true
        IP Instance Thread Size 2 * 1024
        Pool Size in number of Packets 10
        Application Thread Stack Size 2 * 1024

NVIC_NS
        Ethernet global Interupt > Enable, Preemption Priority 7

SYS
        Timebase Source TIM6 (Assign TIM6 to NS before)

RCC
        High speed Clock DIGBYPASS Clock source

GTZC_S
        Block-Based Memory Controller > MPCBB3 (SRAM3) > Memory Privilege Attributes Settings > Configure Memory > from full Not privileged
        (Setting the whole SRAM3 to not priviliged might not be the best idea from an security standpoint if you do other stuff on the board)

Manual change in Secure/Core/Inc/partition_stm32h573xx.h:
Set the 10th bit in NVIC_INIT_ITNS3_VAL (in my case line 554), so the line should look like this:
`#define NVIC_INIT_ITNS3_VAL      0x00000400`
IMPORTANT: After each code-generation check if the bit is still set or overwritten by the code-generation. 

Build and run like normal trustzone project e.g. described here https://github.com/STMicroelectronics/STM32CubeH5/tree/main/Projects/STM32H573I-DK/Examples/GTZC/GTZC_MPCWM_IllegalAccess_TrustZone

You should now be able to ping the board!

 

One last question: 

I need to manually change the Pinlayout of ETH to get it working, i.e. assign ETH_TXD1 to PG12.

Additionally my issue with the Interrupt where i manually need to set a bit in the files.

Are these known issues or can I report them somewhere?

Same goes for the MPCBB config, i understand that you might expect developers to do this by themselfs, but a small note when assigning ETH to NonSecure would be really nice as debugging this is kinda pain.

 

Again, thanks for your help.

Best,

funkii

Hello @funkii ,

thank you for your feedback glade that you were able to solve your issue .

answering your request regarding the issue with code generated by cube MX we are aware of the issue and it is internally reported 

Internal ticket number: 168204 (This is an internal tracking number and is not accessible or usable by customers).

answering this point 

GTZC_S
        Block-Based Memory Controller > MPCBB3 (SRAM3) > Memory Privilege Attributes Settings > Configure Memory > from full Not privileged
        (Setting the whole SRAM3 to not priviliged might not be the best idea from an security standpoint if you do other stuff on the board)

 

You can  give the IP ETH (which is non-secure) the access to the memory, the following instruction should be added in MX_GTZC_S_Init :

if (HAL_GTZC_TZSC_ConfigPeriphAttributes(GTZC_PERIPH_ETHERNET,GTZC_TZSC_PERIPH_PRIV) != HAL_OK)

{

Error_Handler();

This avoids setting the whole SRAM3 to not privileged .

This also will be taken into consideration and it is trucked internally 

Internal ticket number: 168201 (This is an internal tracking number and is not accessible or usable by customers).

BR

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.