I'm doing some testing on Exynos5422 SoC which implements big.LITTLE architecture (A7 + A15), I'm running bare metal application which starts in HYP mode. I haven't returned from HYP mode by accident and then software delay which I implemented by simple for loop was significantly (about 40 times) longer than in SVC mode. Compiler settings are same in both cases. And only difference is in boot code. This is code for loop:
void delay_some_time(){ for (int i = 0; i < 100000000; i++) { __asm("nop");}
void delay_some_time()
{
for (int i = 0; i < 100000000; i++)
__asm("nop");
}
This is boot code:
mrs r0, apsr and r1, r0, #0x1f @ Get processor mode teq r1, #0x1a @ Check for hypervisor mode a: bne x @ Escape if not in hypervisor mode bic r0, r0, #0x1f @ clear all mode bits orr r0, r0, #0x13 @ set SVC mode ldr r1, =x msr elr_hyp, r1 msr spsr_hyp, r0 eret
mrs r0, apsr
and r1, r0, #0x1f @ Get processor mode
teq r1, #0x1a @ Check for hypervisor mode
a: bne x @ Escape if not in hypervisor mode
bic r0, r0, #0x1f @ clear all mode bits
orr r0, r0, #0x13 @ set SVC mode
ldr r1, =x
msr elr_hyp, r1
msr spsr_hyp, r0
eret
x: [BOOT PROCESS CONTINUES]
On label "a" in case where I run in HYP mode is BEQ instead of BNE. This is the only difference.
Yes, caching and MMU are disabled in HYP, after I disabled caching in SVC mode timing is almost the same, but still SVC is little bit faster (about 2 times). Another phenomena happens when I'm turning dcache and MMU off in SVC mode. I cleared bits for I cache, D cache, and MMU in SCTLR. But SCTLR doesn't change accordingly. For instance:
With MCR I moved value 0xc5087a in SCTLR.With MRC I read value 0xc52879 from SCTLR.
According to this MMU is still on. But suddenly bit 13 flipped. Is this affecting performance? Why does this happen?
A register does not "just" change value. I guess you do not control all the SW running.
I don't control anything from secure world. There is no hypervisor. I jump from uboot in Hyp mode to my application. Therefore, I presume that my application is in control in Normal World (PL0, PL1, PL2).