This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Secure Monitor Call code example in AM335x Technical Reference Manual

I have a couple of questions about the example code in the AM335x TRM (section 3.1.4.2.2) demonstrating the use of a Secure Monitor Call to enable the L2 cache ECC.  This is the code:

_enableL2ECC:
STMFD sp!, {r0 - r4} ; save context of R0-R4, which secure monitor call may use
MRC p15, #1, r0, c9, c0, #2 ; Read L2 Cache Auxiliary Control Reg into R0
MOV r1, #0 ; Clear R1
MOVT r1, #0x1020 ; enable mask for ECC (set bits 21 and 28 to enable ECC)
ORR r0, r0, r1 ; OR with original register value
MOV r12, #0x0102 ; setup service ID in R12
MCR p15,#0x0,r1,c7,c5,#6 ; invalidate entire branch predictor array
DSB ; data synchronization barrier operation
ISB ; instruction synchronization barrier operation
DMB ; data memory barrier operation
SMC #1 ; secure monitor call SMC (previously SMI)
LDMFD sp!, {r0 - r4} ; after returning from SMC, restore R0-R4
MOV pc, lr ; return

My questions are:

- The code uses register r12, yet this isn't saved nor restored at the start/end of the code.  Is this an error?

- In the MCR command used to invalidate the branch predictor array, does register r1 serve any purpose? Does its value matter?

Thanks.

  • Hi Chris,

    I will forward this to the factory team.

  • Hi Chris, the R12 register is just used as a parameter to send to the secure monitor.  Since the secure monitor can perform various functions, R12 is used for the ID of the function you want it to perform.  i think you are correct in that to be complete, the function should save/restore R12.

    For invalidate the branch predictor array, the value of Rx is unused.  Refer to the ARM Architectural Reference Manual for more details on this command.

    Regards,

    James

  • MCR p15,0,r1,c7,c5,6 // invalidate branch predictor array
    DSB // data synchronization barrier
    ISB // instruction synchronization barrier
    DMB // data memory barrier
    SMC 1

    This is a bizarre sequence.  Invalidating the branch predictor is never needed on the Cortex-A8 (except for very old revisions due to an erratum, fixed in r2p1).  Both entry into and exit from an exception (including an SMC) already implicitly act like an instruction sync barriers.  A data sync barrier is a superset of a data memory barrier, so including them both is pointless.

    The only barrier needed is a DSB, and even then only if you're making a change that affects the memory system.

    The only register you need to save is R4 since it should be preserved by functions calls according to the EABI.  R0-R3 are used for arguments and return value, and if not used for that purpose may be freely clobbered by the callee.  R12 is available for use by linker glue and may likewise be clobbered by callee.

  • Unfortunately that's an exact quote of the code recommended in the AM335x TRM.  I'm not experienced enough in the low-level inner workings of the ARM A8 to want to risk altering it. 

    Presumably the sync barrier instructions and BP invalidation, even if not needed, won't have any ill effects?

     

  • Chris Kessell said:
    Unfortunately that's an exact quote of the code recommended in the AM335x TRM.

    Yes I'm aware of that, sorry if it felt like my rant was directed towards you.

    They won't have any ill effect (other than wasting some cpu cycles and producing strange facial expressions in anyone familiar with the ARM architecture who happens to read the code in the future).