Each CPU saves its general-purpose registers on the stack, switches to
the hypervisor stack and saves the return context in the per-cpu datas.
After that, it jumps to the core entry which will do the necessary
initialisation to setup EL2.
Clusters are not supported yet: they will require the entry code to
fetch the total number of possible CPUs from the header, in order to
deduce an efficient base address for the per-cpu datas.
Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
.text
.globl arch_entry
arch_entry:
- mvn %r0,#~-38
- bx %lr
+ /* r0: cpuid */
+ push {r0 - r12}
+ ldr r1, =__page_pool
+ mov r2, #1
+ lsl r2, #PERCPU_SIZE_SHIFT
+ /*
+ * percpu data = pool + cpuid * shift
+ * TODO: handle aff1 and aff2
+ */
+ mla r1, r2, r0, r1
+ add r2, r1, #PERCPU_LINUX_SP
-/* Fix up Global Offset Table with absolute hypervisor address */
- .globl got_init
-got_init:
- bx %lr
+ /* Save SP, LR, CPSR */
+ str sp, [r2], #4
+ str lr, [r2], #4
+ mrs r3, cpsr
+ str r3, [r2]
+
+ mov sp, r1
+ add sp, #PERCPU_STACK_END
+ /* Call entry(cpuid, struct per_cpu*) */
+ b entry
#include <jailhouse/types.h>
#include <asm/paging.h>
-#define NUM_ENTRY_REGS 6
+#define NUM_ENTRY_REGS 13
/* Keep in sync with struct per_cpu! */
#define PERCPU_SIZE_SHIFT 13
/* Keep these two in sync with defines above! */
u8 stack[PAGE_SIZE];
unsigned long linux_sp;
+ unsigned long linux_ret;
+ unsigned long linux_flags;
struct per_cpu *cpu_data;
unsigned int cpu_id;