Hello,
I am studying Cortex-M33 TrustZone with Armv8-M_security sample code coming from ARM Development Studio 2023.1. When I add following code into main_s.c to test cmse_check_address_range intrinsic, but it seems does not work when running it in Armv8-M_security_FVP_M33, it always prints not in non-secure region, and checked its disassembly code, that intrinsic does not get called. Please help.
The source code ( cmse_check_address_range is added within #if 1... #endif) is:
int __attribute__((cmse_nonsecure_entry)) ns_callable_fn1(int x){ printf("Hello from Non-secure Callable Function 1!\n\r");#if 1 //Check a memory range is entirely in non-secure region or not uint32_t *p = (uint32_t *)0x00200000; uint32_t size = 4; uint32_t * vRet = 1; vRet = cmse_check_address_range( p, size, CMSE_MPU_NONSECURE);
if (vRet == NULL) printf(" NULL returned, (%p, size=%d) is not entirely in non-secure region!\n", p, size); else printf(" (%p, size=%d) is entirely in non-secure region!\n", p, size);#endif return secure_fn1(x);}
This disassembly code is:
ns_callable_fn10x100012B2 : MOV r0,#0x14230x100012B6 : MOVT r0,#0x10000x100012BA : BL __2printf ; 0x1000034C0x100012BE : MOVS r0,#10x100012C0 : LSLS r1,r0,#210x100012C2 : MOV r0,#0x13de0x100012C6 : MOVT r0,#0x10000x100012CA : MOVS r2,#40x100012CC : BL __2printf ; 0x1000034C0x100012D0 : B {pc}+14 ; 0x100012DEns_callable_fn2 + 0x36
Thanks
More experiment:
1) Copy arm_cmse.h into project directory, rename it to my_arm_cmse.h
2) Modify cmse_check_address_range(..) by adding a printf statement as below:
static void *cmse_check_address_range(void *__pb, size_t __s, int __flags) { uintptr_t __begin = (uintptr_t)__pb; uintptr_t __end = __begin + __s - 1; printf("__pb = %p\n", __pb); //<----------------------- added by me to make sure cmse_check_address_range gets called !! if (__end < __begin) return NULL; /* wrap around check */
/* Check whether the range crosses a 32-bytes aligned address */ const int __single_check = (__begin ^ __end) < 0x20u;
..
3) In the main_s.c, do the following changes to make sure my_arm_cmse.h is included and explicitly define __ARM_FEATURE_CMSE to 3
#include <stdio.h>//#include <arm_cmse.h>#define __ARM_FEATURE_CMSE 3#include "my_arm_cmse.h"
4) When int __attribute__((cmse_nonsecure_entry)) ns_callable_fn1(int x) is executed, I can see the output of "__pb=200000" from cmse_check_address_range(), but the result of cmse_check_address_range is still wrong, check the disassembly code, there is no TT instruction generated from intrinsics cmse_TT/cmse_TTT/cmse_TTA/cmse_TTAT.
So what causes ARM CC not generating compete assembly code for cmse_check_address_range?
Is this a bug in ARM CC (v6.21 for ADS 2023.1 and v6.18 for ADS 2022.1) which is similar to GCC Bugzilla - Bug 99157 ?
HiMy name is Stephen and I work at Arm. Thanks for your interest in Cortex-M33 TrustZone.I can reproduce what you see with cmse_check_address_range(), and I'm investigating further.Stephen
Hi againFYI: your code that calls cmse_check_address_range() didn't compile for me. I had to change: uint32_t * vRet = 1;to: void * vRet;An additional flag is required on the call, for example, change: vRet = cmse_check_address_range( p, size, CMSE_MPU_NONSECURE);to: vRet = cmse_check_address_range( p, size, CMSE_MPU_NONSECURE | CMSE_MPU_READ ); With that change, I see a TTA instruction being generated, and get:Hello from Non-secure Callable Function 1! (00200000, size=4) is entirely in non-secure region!
See developer.arm.com/.../TT-instruction-intrinsicsandarm-software.github.io/.../cmse.htmlHope this helpsStephen
Hi Stephen,
Thank you for the supports on this issue.
I tried with flag CMSE_MPU_NONSECURE | CMSE_MPU_READ, and the result was as expected.
The disassembly code for following branch in cms_check_address_range(void *__pb, size_t __s, int __flags) is optimized by AC6 with compiler option "-O1"
...
#if __ARM_CMSE_SECURE_MODE case CMSE_MPU_NONSECURE: __permb = cmse_TTA(__pb); __perme = __single_check ? __permb : cmse_TTA(__pe); break;...
If changing to use "-O0", the disassembly code matches with C code even with flags set to CMSE_MPU_NONSECURE only.
This issue can be closed.