11-02-2017 10:09 AM
Board boots up (uboot), transfers control to a custom OS via CPU0 at EL1.
CPU0 performs reset on CPUs 1-3, and they do indeed jump to the designated
address and begin execution. The problem is that they are at EL0.
Is there a way to boot cores 1-3 directly into EL1?
I've tried setting up interrupts, and having the cores make an SVC call,
which they do, however, the interrupt goes to CPU0, which doesn't help.
I am trying to have all four cores in EL1 before they jump into our custom kernel,
because, well, memory maps... Cores 1-3 at EL0 do not have access to
the kernel memory maps which were set up at EL1.
Help? How can I get interrupts from cores 1-3 to actually be delivered to
and executed by cores 1-3, and/or, can I boot cores 1-3 directly into
11-02-2017 06:06 PM
SVC should do the trick.
In our RTOS, this is what we do:
MOV64 x1, _vector_table // Set the vector table base address
msr VBAR_EL1, x1
cbz x0, StartEL0 // EL0 can only use SVC, not SMC nor HVC
smc #0xAA53 // EL1/EL2 ---> EL3 / is not coming back here
b . // Safety
svc #0xAA53 // EL0 ---> EL1 / is not coming back here
b . // Safety
There is a bit more, but at the end our RTOS goes through the same steps you describe and all cores end up operating at EL3.
From there it's easy to put them down to EL1 if desired.
11-03-2017 07:13 AM
Thanks! This is what I've been trying to do.
But when I print the cpu number while in the interrupt, it is 0.
(mrs x1, mpidr_el1)
Is there some magic to the #0xAA53 number?
Or is there some setup to the GICC & GICD to enable
interrupts to separate CPUs?
And something that confuses me, is why an el0 cpu is
able to set its vector table so it can get to el1...
Is this disabled somewhere down the road via another
security register somewhere?
11-03-2017 09:04 AM
I gave you the code from the old stuff I had on my laptop yesterday night
The set VBAR is in fact after the cbz.
You have to set the VBAR of all cores (including CPU #0's VBAR) with CPU #0 before it releases them from reset.
Check the RVBAR register in the Zynq / UltraScale+ register map
The SVC / SMC / HVC instructions don't involve the GIC; they are software interrupts (the core interrupts itself by software)
0xAA53 is a just a number pick like that, it's used to check the syndrome to know it is a request to switch ELn level.
11-03-2017 10:23 AM
Yes, I set the RVBAR registers, which are the reset vector address for the cores.
Each core comes up and runs in the designated location at el0. Except core 0 which
is already running at el1 and is the core that resets the others.
For each core reset, I get TWO interrupts on core 0, one presumably from the reset,
and the other presumably from the SVC instruction that the core is trying to perform.
So, 3 cores get reset, and I get a total of 6 interrupts on core 0.