This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

cmse_check_address_range does not work for CortexM33 code built with ARM CC 6.0

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_fn1
0x100012B2 : MOV r0,#0x1423
0x100012B6 : MOVT r0,#0x1000
0x100012BA : BL __2printf ; 0x1000034C
0x100012BE : MOVS r0,#1
0x100012C0 : LSLS r1,r0,#21
0x100012C2 : MOV r0,#0x13de
0x100012C6 : MOVT r0,#0x1000
0x100012CA : MOVS r2,#4
0x100012CC : BL __2printf ; 0x1000034C
0x100012D0 : B {pc}+14 ; 0x100012DE
ns_callable_fn2 + 0x36

Thanks

Parents Reply Children
  • Hi

    My 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 again

    FYI: 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-intrinsics
    and
    arm-software.github.io/.../cmse.html

    Hope this helps

    Stephen

  • 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.

    Thanks