diff options
Diffstat (limited to 'arch/mips/fw/lib')
| -rw-r--r-- | arch/mips/fw/lib/Makefile | 1 | ||||
| -rw-r--r-- | arch/mips/fw/lib/call_o32.S | 63 | ||||
| -rw-r--r-- | arch/mips/fw/lib/cmdline.c | 12 |
3 files changed, 44 insertions, 32 deletions
diff --git a/arch/mips/fw/lib/Makefile b/arch/mips/fw/lib/Makefile index 529150516777..cf9634548c98 100644 --- a/arch/mips/fw/lib/Makefile +++ b/arch/mips/fw/lib/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only # # Makefile for generic prom monitor library routines under Linux. # diff --git a/arch/mips/fw/lib/call_o32.S b/arch/mips/fw/lib/call_o32.S index b308b2a0613e..ee856709e0b6 100644 --- a/arch/mips/fw/lib/call_o32.S +++ b/arch/mips/fw/lib/call_o32.S @@ -1,39 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * O32 interface for the 64 (or N32) ABI. * - * Copyright (C) 2002 Maciej W. Rozycki - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. + * Copyright (C) 2002, 2014 Maciej W. Rozycki */ #include <asm/asm.h> #include <asm/regdef.h> +/* O32 register size. */ +#define O32_SZREG 4 /* Maximum number of arguments supported. Must be even! */ #define O32_ARGC 32 -/* Number of static registers we save. */ +/* Number of static registers we save. */ #define O32_STATC 11 -/* Frame size for static register */ -#define O32_FRAMESZ (SZREG * O32_STATC) -/* Frame size on new stack */ -#define O32_FRAMESZ_NEW (SZREG + 4 * O32_ARGC) +/* Argument area frame size. */ +#define O32_ARGSZ (O32_SZREG * O32_ARGC) +/* Static register save area frame size. */ +#define O32_STATSZ (SZREG * O32_STATC) +/* Stack pointer register save area frame size. */ +#define O32_SPSZ SZREG +/* Combined area frame size. */ +#define O32_FRAMESZ (O32_ARGSZ + O32_SPSZ + O32_STATSZ) +/* Switched stack frame size. */ +#define O32_NFRAMESZ (O32_ARGSZ + O32_SPSZ) .text /* * O32 function call dispatcher, for interfacing 32-bit ROM routines. * - * The standard 64 (N32) calling sequence is supported, with a0 - * holding a function pointer, a1 a new stack pointer, a2-a7 -- its - * first six arguments and the stack -- remaining ones (up to O32_ARGC, - * including a2-a7). Static registers, gp and fp are preserved, v0 holds - * a result. This code relies on the called o32 function for sp and ra - * restoration and this dispatcher has to be placed in a KSEGx (or KUSEG) - * address space. Any pointers passed have to point to addresses within - * one of these spaces as well. + * The standard 64 (N32) calling sequence is supported, with a0 holding + * a function pointer, a1 a pointer to the new stack to call the + * function with or 0 if no stack switching is requested, a2-a7 -- the + * function call's first six arguments, and the stack -- the remaining + * arguments (up to O32_ARGC, including a2-a7). Static registers, gp + * and fp are preserved, v0 holds the result. This code relies on the + * called o32 function for sp and ra restoration and this dispatcher has + * to be placed in a KSEGx (or KUSEG) address space. Any pointers + * passed have to point to addresses within one of these spaces as well. */ NESTED(call_o32, O32_FRAMESZ, ra) REG_SUBU sp,O32_FRAMESZ @@ -51,32 +56,36 @@ NESTED(call_o32, O32_FRAMESZ, ra) REG_S s0,O32_FRAMESZ-11*SZREG(sp) move jp,a0 - REG_SUBU s0,a1,O32_FRAMESZ_NEW - REG_S sp,O32_FRAMESZ_NEW-1*SZREG(s0) + + move fp,sp + beqz a1,0f + REG_SUBU fp,a1,O32_NFRAMESZ +0: + REG_S sp,O32_NFRAMESZ-1*SZREG(fp) sll a0,a2,zero sll a1,a3,zero sll a2,a4,zero sll a3,a5,zero - sw a6,0x10(s0) - sw a7,0x14(s0) + sw a6,4*O32_SZREG(fp) + sw a7,5*O32_SZREG(fp) PTR_LA t0,O32_FRAMESZ(sp) - PTR_LA t1,0x18(s0) + PTR_LA t1,6*O32_SZREG(fp) li t2,O32_ARGC-6 1: lw t3,(t0) REG_ADDU t0,SZREG sw t3,(t1) REG_SUBU t2,1 - REG_ADDU t1,4 + REG_ADDU t1,O32_SZREG bnez t2,1b - move sp,s0 + move sp,fp jalr jp - REG_L sp,O32_FRAMESZ_NEW-1*SZREG(sp) + REG_L sp,O32_NFRAMESZ-1*SZREG(sp) REG_L s0,O32_FRAMESZ-11*SZREG(sp) REG_L s1,O32_FRAMESZ-10*SZREG(sp) diff --git a/arch/mips/fw/lib/cmdline.c b/arch/mips/fw/lib/cmdline.c index ffd0345780ae..892765b742bb 100644 --- a/arch/mips/fw/lib/cmdline.c +++ b/arch/mips/fw/lib/cmdline.c @@ -16,6 +16,7 @@ int fw_argc; int *_fw_argv; int *_fw_envp; +#ifndef CONFIG_HAVE_PLAT_FW_INIT_CMDLINE void __init fw_init_cmdline(void) { int i; @@ -41,6 +42,7 @@ void __init fw_init_cmdline(void) strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE); } } +#endif char * __init fw_getcmdline(void) { @@ -51,7 +53,7 @@ char *fw_getenv(char *envname) { char *result = NULL; - if (_fw_envp != NULL) { + if (_fw_envp != NULL && fw_envp(0) != NULL) { /* * Return a pointer to the given environment variable. * YAMON uses "name", "value" pairs, while U-Boot uses @@ -68,7 +70,7 @@ char *fw_getenv(char *envname) result = fw_envp(index + 1); break; } else if (fw_envp(index)[i] == '=') { - result = (fw_envp(index + 1) + i); + result = fw_envp(index) + i + 1; break; } } @@ -88,13 +90,13 @@ unsigned long fw_getenvl(char *envname) { unsigned long envl = 0UL; char *str; - long val; int tmp; str = fw_getenv(envname); if (str) { - tmp = kstrtol(str, 0, &val); - envl = (unsigned long)val; + tmp = kstrtoul(str, 0, &envl); + if (tmp) + envl = 0; } return envl; |
