diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-01-29 22:48:03 +1100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-01-29 22:48:03 +1100 |
commit | 21af0297c7e56024a5ccc4d8ad2a590f9ec371ba (patch) | |
tree | 5d288c1877b1ae9fbe24aa7fabd79565e73d3d2f /arch/mips/fw/lib | |
parent | 5ea293a9048d3a58cb0c840fa719d85ad14cba47 (diff) | |
parent | a9d2517c7a5c8028fbc5296d3af3c75597d3d180 (diff) | |
download | blackbird-op-linux-21af0297c7e56024a5ccc4d8ad2a590f9ec371ba.tar.gz blackbird-op-linux-21af0297c7e56024a5ccc4d8ad2a590f9ec371ba.zip |
Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus: (68 commits)
[MIPS] remove Documentation/mips/GT64120.README
[MIPS] Malta: remaining bits of the board support code cleanup
[MIPS] Malta: make the helper function static
[MIPS] Malta: fix braces at single statement blocks
[MIPS] Malta, Atlas: move an extern function declaration to the header file
[MIPS] Malta: Use C89 style for comments
[MIPS] Malta: else should follow close brace in malta_int.c
[MIPS] Malta: remove a superfluous comment
[MIPS] Malta: include <linux/cpu.h> instead of <asm/cpu.h>
[MIPS] Malta, Atlas, Sead: remove an extern from .c files
[MIPS] Malta: fix oversized lines in malta_int.c
[MIPS] Malta: remove a dead function declaration
[MIPS] Malta: use tabs not spaces
[MIPS] Malta: set up the screen info in a separate function
[MIPS] Malta: check the PCI clock frequency in a separate function
[MIPS] Malta: use the KERN_ facility level in printk()
[MIPS] Malta: use Linux kernel style for structure initialization
[MIPS]: constify function pointer tables
[MIPS] compat: handle argument endianess of sys32_(f)truncate64 with merge_64
[MIPS] Cobalt 64-bits kernels can be safely unmarked experimental
...
Diffstat (limited to 'arch/mips/fw/lib')
-rw-r--r-- | arch/mips/fw/lib/Makefile | 5 | ||||
-rw-r--r-- | arch/mips/fw/lib/call_o32.S | 97 |
2 files changed, 102 insertions, 0 deletions
diff --git a/arch/mips/fw/lib/Makefile b/arch/mips/fw/lib/Makefile new file mode 100644 index 000000000000..84befc968fc4 --- /dev/null +++ b/arch/mips/fw/lib/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for generic prom monitor library routines under Linux. +# + +lib-$(CONFIG_64BIT) += call_o32.o diff --git a/arch/mips/fw/lib/call_o32.S b/arch/mips/fw/lib/call_o32.S new file mode 100644 index 000000000000..bdf7d1d4081a --- /dev/null +++ b/arch/mips/fw/lib/call_o32.S @@ -0,0 +1,97 @@ +/* + * arch/mips/dec/prom/call_o32.S + * + * 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. + */ + +#include <asm/asm.h> +#include <asm/regdef.h> + +/* Maximum number of arguments supported. Must be even! */ +#define O32_ARGC 32 +/* 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) + + .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. + */ +NESTED(call_o32, O32_FRAMESZ, ra) + REG_SUBU sp,O32_FRAMESZ + + REG_S ra,O32_FRAMESZ-1*SZREG(sp) + REG_S fp,O32_FRAMESZ-2*SZREG(sp) + REG_S gp,O32_FRAMESZ-3*SZREG(sp) + REG_S s7,O32_FRAMESZ-4*SZREG(sp) + REG_S s6,O32_FRAMESZ-5*SZREG(sp) + REG_S s5,O32_FRAMESZ-6*SZREG(sp) + REG_S s4,O32_FRAMESZ-7*SZREG(sp) + REG_S s3,O32_FRAMESZ-8*SZREG(sp) + REG_S s2,O32_FRAMESZ-9*SZREG(sp) + REG_S s1,O32_FRAMESZ-10*SZREG(sp) + 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) + + sll a0,a2,zero + sll a1,a3,zero + sll a2,a4,zero + sll a3,a5,zero + sw a6,0x10(s0) + sw a7,0x14(s0) + + PTR_LA t0,O32_FRAMESZ(sp) + PTR_LA t1,0x18(s0) + li t2,O32_ARGC-6 +1: + lw t3,(t0) + REG_ADDU t0,SZREG + sw t3,(t1) + REG_SUBU t2,1 + REG_ADDU t1,4 + bnez t2,1b + + move sp,s0 + + jalr jp + + REG_L sp,O32_FRAMESZ_NEW-1*SZREG(sp) + + REG_L s0,O32_FRAMESZ-11*SZREG(sp) + REG_L s1,O32_FRAMESZ-10*SZREG(sp) + REG_L s2,O32_FRAMESZ-9*SZREG(sp) + REG_L s3,O32_FRAMESZ-8*SZREG(sp) + REG_L s4,O32_FRAMESZ-7*SZREG(sp) + REG_L s5,O32_FRAMESZ-6*SZREG(sp) + REG_L s6,O32_FRAMESZ-5*SZREG(sp) + REG_L s7,O32_FRAMESZ-4*SZREG(sp) + REG_L gp,O32_FRAMESZ-3*SZREG(sp) + REG_L fp,O32_FRAMESZ-2*SZREG(sp) + REG_L ra,O32_FRAMESZ-1*SZREG(sp) + + REG_ADDU sp,O32_FRAMESZ + jr ra +END(call_o32) |