[OpenBIOS] [PATCH 08/11] ppc: use proper context when pre-loading kernels
Mark Cave-Ayland
mark.cave-ayland at ilande.co.uk
Sat May 26 21:29:53 CEST 2018
Before the introduction of proper init-program contexts, OpenBIOS
used a simple assembler call_elf() function to execute the guest
kernel directly.
Switch over to using proper contexts via arch_init_program() which
enables us to remove the legacy call_elf() completely.
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland at ilande.co.uk>
---
arch/ppc/qemu/kernel.h | 1 -
arch/ppc/qemu/main.c | 11 ++++++++++-
arch/ppc/qemu/switch.S | 43 -------------------------------------------
3 files changed, 10 insertions(+), 45 deletions(-)
diff --git a/arch/ppc/qemu/kernel.h b/arch/ppc/qemu/kernel.h
index 3e25a56..0ded835 100644
--- a/arch/ppc/qemu/kernel.h
+++ b/arch/ppc/qemu/kernel.h
@@ -23,7 +23,6 @@ extern void exit( int status ) __attribute__ ((noreturn));
extern void flush_icache_range( char *start, char *stop );
extern void flush_dcache_range( char *start, char *stop );
extern char of_rtas_start[], of_rtas_end[];
-extern void call_elf( unsigned long arg1, unsigned long arg2, unsigned long elf_entry );
/* methods.c */
extern void node_methods_init( const char *cpuname );
diff --git a/arch/ppc/qemu/main.c b/arch/ppc/qemu/main.c
index 44b1666..3c76e41 100644
--- a/arch/ppc/qemu/main.c
+++ b/arch/ppc/qemu/main.c
@@ -24,6 +24,8 @@
#include "kernel.h"
#include "drivers/drivers.h"
#include "libopenbios/ofmem.h"
+#include "libopenbios/initprogram.h"
+#include "context.h"
#define NO_QEMU_PROTOS
#include "arch/common/fw_cfg.h"
@@ -45,6 +47,7 @@ static void check_preloaded_kernel(void)
unsigned long kernel_image, kernel_size;
unsigned long initrd_image, initrd_size;
const char * kernel_cmdline;
+ volatile struct context *ctx = __context;
kernel_size = fw_cfg_read_i32(FW_CFG_KERNEL_SIZE);
if (kernel_size) {
@@ -61,7 +64,13 @@ static void check_preloaded_kernel(void)
ph = find_dev("/chosen");
set_property(ph, "bootargs", strdup(kernel_cmdline), strlen(kernel_cmdline) + 1);
}
- call_elf(initrd_image, initrd_size, kernel_image);
+
+ arch_init_program();
+ ctx->regs[REG_R3] = initrd_image;
+ ctx->regs[REG_R4] = initrd_size;
+ ctx->pc = kernel_image;
+
+ start_elf();
}
}
diff --git a/arch/ppc/qemu/switch.S b/arch/ppc/qemu/switch.S
index f1b120d..32a7bbf 100644
--- a/arch/ppc/qemu/switch.S
+++ b/arch/ppc/qemu/switch.S
@@ -17,49 +17,6 @@
#endif
#endif
- /* According to IEEE 1275, PPC bindings:
- *
- * MSR = FP, ME + (DR|IR)
- * r1 = stack (32 K + 32 bytes link area above)
- * r5 = client interface handler
- * r6 = address of client program arguments (unused)
- * r7 = length of client program arguments (unused)
- *
- * Yaboot and Linux use r3 and r4 for initrd address and size
- */
-
- /* void call_elf( arg1, arg2, entry ) */
-_GLOBAL(call_elf):
- mflr r0
- PPC_STLU r1, -STACKFRAME_MINSIZE(r1)
- PPC_STL r0, (STACKFRAME_MINSIZE + PPC_LR_STKOFF)(r1)
- mtlr r5
- LOAD_REG_IMMEDIATE(r8, saved_stack) // save our stack pointer
- PPC_STL r1,0(r8)
- mfsdr1 r1
- addi r1, r1, -32768 /* - 32 KiB exception stack */
- addis r1, r1, -1 /* - 64 KiB stack */
- LOAD_REG_IMMEDIATE(r5, of_client_callback) // r5 = callback
- li r6,0 // r6 = address of client program arguments (unused)
- li r7,0 // r7 = length of client program arguments (unused)
- li r0,MSR_FP | MSR_ME | MSR_DR | MSR_IR
- MTMSRD(r0)
- blrl
-
-#ifdef CONFIG_PPC64
- /* Restore SF bit */
- LOAD_REG_IMMEDIATE(r0, MSR_SF | MSR_FP | MSR_ME | MSR_DR | MSR_IR)
- MTMSRD(r0)
-#endif
- LOAD_REG_IMMEDIATE(r8, saved_stack) // restore stack pointer
- mr r1,r8
- PPC_LL r0, (STACKFRAME_MINSIZE + PPC_LR_STKOFF)(r1)
- mtlr r0
- addi r1, r1, STACKFRAME_MINSIZE
- // XXX: should restore r12-r31 etc..
- // we should not really come here though
- blrl
-
/*
* Switch execution context
* This saves registers in the stack, then
--
2.11.0
More information about the OpenBIOS
mailing list