From 3dbab02fc20c5e3e23af49e19ad24ce511da00d8 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Mon, 18 Oct 2010 19:32:16 +0000 Subject: [PATCH] Fix the placing of Forth arguments on the stack when calling obp_fortheval_v2() via romvec on SPARC32. The extra stack arguments are actually placed within %o1-%o5 but unfortunately there doesn't seem to be a way of passing the number of parameters using the romvec API. Hence we go through the argument list and start pushing arguments onto the Forth stack from the first non-zero argument before executing the Forth string. Signed-off-by: Mark Cave-Ayland git-svn-id: svn://coreboot.org/openbios/trunk/openbios-devel@915 f158a5a8-5612-0410-a976-696ce0be7e32 --- arch/sparc32/openprom.h | 2 +- arch/sparc32/romvec.c | 40 ++++++++++++++++++++++++++++++++-------- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/arch/sparc32/openprom.h b/arch/sparc32/openprom.h index fe4cd8d..0a2074b 100644 --- a/arch/sparc32/openprom.h +++ b/arch/sparc32/openprom.h @@ -124,7 +124,7 @@ struct linux_romvec { /* Evaluate a forth string, not different proto for V0 and V2->up. */ union { void (*v0_eval)(int len, char *str); - void (*v2_eval)(char *str); + void (*v2_eval)(char *str, int arg0, int arg1, int arg2, int arg3, int arg4); } pv_fortheval; const struct linux_arguments_v0 * const *pv_v0bootargs; diff --git a/arch/sparc32/romvec.c b/arch/sparc32/romvec.c index c33e748..f6e0ca6 100644 --- a/arch/sparc32/romvec.c +++ b/arch/sparc32/romvec.c @@ -412,15 +412,39 @@ static int obp_cpuresume(__attribute__((unused)) unsigned int whichcpu) return 0; } -static void obp_fortheval_v2(char *str) +static void obp_fortheval_v2(char *str, int arg0, int arg1, int arg2, int arg3, int arg4) { - // for now, move something to the stack so we - // don't get a stack underrun. - // - // FIXME: find out why solaris doesnt put its stuff on the stack - // - fword("0"); - fword("0"); + int pusharg = 0; + + // It seems Solaris passes up to 5 arguments which should be pushed onto the Forth + // stack for execution. However the API doesn't provide for a way to pass the number + // of arguments actually passed. Hence we start at arg4 and then starting from the + // first non-zero argument, we push all subsequent arguments onto the stack down to + // arg0. + + if (arg4) { + PUSH(arg4); + pusharg = 1; + } + + if (arg3 || pusharg == 1 ) { + PUSH(arg3); + pusharg = 1; + } + + if (arg2 || pusharg == 1) { + PUSH(arg2); + pusharg = 1; + } + + if (arg1 || pusharg == 1 ) { + PUSH(arg1); + pusharg = 1; + } + + if (arg0 || pusharg == 1) { + PUSH(arg0); + } DPRINTF("obp_fortheval_v2(%s)\n", str); push_str(str);