2023-11-22 11:47 AM
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
Solved! Go to Solution.
2023-12-05 03:53 AM
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?
2023-12-05 01:54 PM
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
2023-12-06 01:12 AM
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
2023-12-07 02:06 AM
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
2023-12-07 05:39 AM
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