Reputation: 415
I have a pretty weird thing I need to do: Access some "secure" instructions for things that don't really need to be done in a secure context. In short: I need to get in to Secure Mode, but not because I want Hardware TPM-ish functionality or anything. I just need access to certain instructions that I wouldn't otherwise have.
We're doing this on Gumstix Overo FireSTORM COMs. It is my understanding these boot securely, but then somewhere (MLO? u-boot?) they switch to non-secure mode, but I could be wrong. The point is that we're certainly doing this from nonsecure (but privileged, see below) mode.
(I authored this question, about direct access to the GHB/BTB of the A8 branch predictor, if you're curious about what I'm looking to do: Write directly to the global history buffer (GHB) or BTB in the branch predictor of a ARM Cortex A8?)
Now, all of this will be done from u-boot (we've got Overo FireSTORM COMs), so luckily I have "privileged" execution. No worries there. And I've looked at other StackOverflow questions, but there doesn't seem to be anything on how, exactly, to get to secure mode. All I really wanna do is access some CP15 registers, and then go back to non-secure mode (and potentially repeat the process).
I've looked into the SMC instruction, but I can't find any documentation on how to appropriately trap the call/where the call goes to/how to set that up, etc.
Is that information anywhere?
To recap, here's what I want to do:
FROM PRIVILEGED EXECUTION:
Do stuff
Tweak GHB // requires secure execution
Do more stuff
Tweak GHB
Do more stuff
...
...
...
Do stuff
Any help would CERTAINLY be appreciated!
Thanks to @artlessnoise, I found this file in the u-boot source: /u-boot/arch/arm/cpu/armv7/nonsec_virt.S.
It contains the following code:
/*
* secure monitor handler
* U-boot calls this "software interrupt" in start.S
* This is executed on a "smc" instruction, we use a "smc #0" to switch
* to non-secure state.
* We use only r0 and r1 here, due to constraints in the caller.
*/
.align 5
_secure_monitor:
mrc p15, 0, r1, c1, c1, 0 @ read SCR
bic r1, r1, #0x4e @ clear IRQ, FIQ, EA, nET bits
orr r1, r1, #0x31 @ enable NS, AW, FW bits
#ifdef CONFIG_ARMV7_VIRT
mrc p15, 0, r0, c0, c1, 1 @ read ID_PFR1
and r0, r0, #CPUID_ARM_VIRT_MASK @ mask virtualization bits
cmp r0, #(1 << CPUID_ARM_VIRT_SHIFT)
orreq r1, r1, #0x100 @ allow HVC instruction
#endif
mcr p15, 0, r1, c1, c1, 0 @ write SCR (with NS bit set)
#ifdef CONFIG_ARMV7_VIRT
mrceq p15, 0, r0, c12, c0, 1 @ get MVBAR value
mcreq p15, 4, r0, c12, c0, 0 @ write HVBAR
#endif
movs pc, lr @ return to non-secure SVC
Presumably if I modified the mask for the mcr p15 instruction, I could simply "turn off" the move to nonsecure mode. This will probably kill u-boot, however.
So the question is, then: How do I set the appropriate vector so when I make the SMC call, I jump back into secure mode, and am able to do my GHB/BTB tinkering?
Any other help is appreciated!
Upvotes: 2
Views: 847
Reputation: 4914
The DM3730 on the Gumstix is a GP (general purpose) device, which means it has TrustZone disabled. There's no way you can get in to it.
See https://stackoverflow.com/a/8028948/6839
Upvotes: 1