And switch start_elf() over to use it.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- arch/sparc32/context.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-)
diff --git a/arch/sparc32/context.c b/arch/sparc32/context.c index 50b9edf..0a5b370 100644 --- a/arch/sparc32/context.c +++ b/arch/sparc32/context.c @@ -6,6 +6,8 @@ #include "config.h" #include "kernel/kernel.h" #include "context.h" +#include "libopenbios/bindings.h" +#include "libopenbios/initprogram.h" #include "libopenbios/sys_info.h" #include "boot.h" #include "openbios.h" @@ -63,6 +65,8 @@ static void start_main(void) __context = boot_ctx; }
+#define CTX_OFFSET(n) (sizeof(struct context) + n * sizeof(uint32_t)) + /* Setup a new context using the given stack. */ struct context * @@ -71,7 +75,7 @@ init_context(uint8_t *stack, uint32_t stack_size, int num_params) struct context *ctx;
ctx = (struct context *) - (stack + stack_size - (sizeof(*ctx) + num_params*sizeof(uint32_t))); + (stack + stack_size - CTX_OFFSET(num_params)); /* Use valid window state from startup */ memcpy(ctx, &main_ctx, sizeof(struct context));
@@ -82,6 +86,24 @@ init_context(uint8_t *stack, uint32_t stack_size, int num_params) return ctx; }
+/* init-program */ +int +arch_init_program(void) +{ + volatile struct context *ctx = __context; + ucell entry; + + ctx->regs[REG_O0] = (unsigned long)romvec; + ctx->regs[REG_SP] = (unsigned long)malloc(IMAGE_STACK_SIZE) + IMAGE_STACK_SIZE - CTX_OFFSET(1); + + /* Set entry point */ + feval("load-state >ls.entry @"); + entry = POP(); + ctx->pc = entry; + + return 0; +} + /* Switch to another context. */ struct context *switch_to(struct context *ctx) { @@ -111,8 +133,7 @@ unsigned int start_elf(unsigned long entry_point, unsigned long param) { struct context *ctx = client_ctx;
- ctx->pc = entry_point; - ctx->regs[REG_O0] = param; + arch_init_program();
ctx = switch_to(ctx); return ctx->regs[REG_O0];