diff options
Diffstat (limited to 'arch/mips')
45 files changed, 696 insertions, 316 deletions
diff --git a/arch/mips/jazz/g364.c b/arch/mips/jazz/g364.c index 92522dcd1..3b9788133 100644 --- a/arch/mips/jazz/g364.c +++ b/arch/mips/jazz/g364.c @@ -10,6 +10,8 @@ * Olivetti M700-10 ie. an Inmos G364 based card in a dedicated video slot, * 2MB dual ported VRAM with a 64 bit data path, 256 color lookup table, * palette of 16.7M and a user definable 64x64 hardware cursor. + * + * $Id: g364.c,v 1.7 1998/03/27 08:53:38 ralf Exp $ */ #include <linux/config.h> #include <linux/sched.h> diff --git a/arch/mips/jazz/hw-access.c b/arch/mips/jazz/hw-access.c index 8765be1a7..c9c423a66 100644 --- a/arch/mips/jazz/hw-access.c +++ b/arch/mips/jazz/hw-access.c @@ -7,9 +7,10 @@ * * Copyright (C) 1995, 1996, 1997 by Ralf Baechle * - * $Id: hw-access.c,v 1.5 1997/12/29 00:06:49 tsbogend Exp $ + * $Id: hw-access.c,v 1.6 1998/03/04 08:29:09 ralf Exp $ */ #include <linux/delay.h> +#include <linux/init.h> #include <linux/linkage.h> #include <linux/types.h> #include <linux/mm.h> @@ -173,7 +174,7 @@ static unsigned char jazz_read_status(void) return jazz_kh->command; } -void jazz_keyboard_setup(void) +__initfunc(void jazz_keyboard_setup(void)) { kbd_read_input = jazz_read_input; kbd_write_output = jazz_write_output; diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S index afabc6156..413eb8a2f 100644 --- a/arch/mips/kernel/entry.S +++ b/arch/mips/kernel/entry.S @@ -7,7 +7,7 @@ * * Copyright (C) 1994, 1995 by Ralf Baechle * - * $Id: entry.S,v 1.10 1998/03/26 07:39:09 ralf Exp $ + * $Id: entry.S,v 1.8 1998/03/27 04:47:53 ralf Exp $ */ /* @@ -104,7 +104,8 @@ LEAF(spurious_interrupt) cfc1 a1,fcr31; \ li a2,~(0x3f<<12); \ and a2,a1; \ - ctc1 a2,fcr31; + ctc1 a2,fcr31; \ + STI #define __BUILD_clear_ade(exception) \ MFC0 t0,CP0_BADVADDR; \ REG_S t0,PT_BVADDR(sp); \ diff --git a/arch/mips/kernel/fpe.c b/arch/mips/kernel/fpe.c index ee47f016f..8491c95d1 100644 --- a/arch/mips/kernel/fpe.c +++ b/arch/mips/kernel/fpe.c @@ -6,7 +6,7 @@ * * Copyright (C) 1997 Ralf Baechle * - * $Id: fpe.c,v 1.1 1997/08/11 04:17:18 ralf Exp $ + * $Id: fpe.c,v 1.2 1997/12/01 17:57:26 ralf Exp $ */ #include <linux/kernel.h> #include <linux/module.h> @@ -18,7 +18,7 @@ #include <asm/branch.h> #include <asm/ptrace.h> -MODULE_AUTHOR("Ralf Baechle <ralf@gnu.ai.mit.edu>"); +MODULE_AUTHOR("Ralf Baechle <ralf@gnu.org>"); MODULE_DESCRIPTION("Experimental floating point exception handler"); MODULE_SUPPORTED_DEVICE("MIPS FPU"); diff --git a/arch/mips/kernel/irixinv.c b/arch/mips/kernel/irixinv.c index 3fa785b1d..105b29f23 100644 --- a/arch/mips/kernel/irixinv.c +++ b/arch/mips/kernel/irixinv.c @@ -5,9 +5,10 @@ * * Miguel de Icaza, 1997. * - * $Id$ + * $Id: irixinv.c,v 1.2 1997/12/06 23:52:04 ralf Exp $ */ #include <linux/mm.h> +#include <linux/init.h> #include <linux/slab.h> #include <asm/uaccess.h> #include <asm/inventory.h> @@ -52,8 +53,7 @@ dump_inventory_to_user (void *userbuf, int size) return inventory_items * sizeof (inventory_t); } -void -init_inventory (void) +__initfunc(void init_inventory (void)) { /* gross hack while we put the right bits all over the kernel * most likely this will not let just anyone run the X server diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 45d58730c..64c8cff16 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -7,7 +7,7 @@ * * Copyright (C) 1994 - 1998 by Ralf Baechle and others. * - * $Id: process.c,v 1.7 1998/03/22 20:43:43 ralf Exp $ + * $Id: process.c,v 1.7 1998/03/27 04:47:55 ralf Exp $ */ #include <linux/config.h> #include <linux/errno.h> @@ -51,10 +51,22 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) void exit_thread(void) { + /* Forget lazy fpu state */ + if (last_task_used_math == current) { + set_cp0_status(ST0_CU1, ST0_CU1); + __asm__ __volatile__("cfc1\t$0,$31"); + last_task_used_math = NULL; + } } void flush_thread(void) { + /* Forget lazy fpu state */ + if (last_task_used_math == current) { + set_cp0_status(ST0_CU1, ST0_CU1); + __asm__ __volatile__("cfc1\t$0,$31"); + last_task_used_math = NULL; + } } void release_thread(struct task_struct *dead_task) @@ -69,6 +81,10 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, childksp = (unsigned long)p + KERNEL_STACK_SIZE - 32; + if (last_task_used_math == current) { + set_cp0_status(ST0_CU1, ST0_CU1); + r4xx0_save_fp(p); + } /* set up new TSS. */ childregs = (struct pt_regs *) childksp - 1; *childregs = *regs; @@ -84,14 +100,13 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, regs->regs[3] = 0; } if (childregs->cp0_status & ST0_CU0) { - childregs->regs[28] = p; + childregs->regs[28] = (unsigned long) p; childregs->regs[29] = childksp; p->tss.current_ds = KERNEL_DS; } else { childregs->regs[29] = usp; p->tss.current_ds = USER_DS; } - p->tss.ksp = childksp; p->tss.reg29 = (unsigned long) childregs; p->tss.reg31 = (unsigned long) ret_from_sys_call; @@ -100,7 +115,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, * switching for most programs since they don't use the fpu. */ p->tss.cp0_status = read_32bit_cp0_register(CP0_STATUS) & - ~(ST0_CU3|ST0_CU2|ST0_CU1|ST0_KSU|ST0_ERL|ST0_EXL); + ~(ST0_CU3|ST0_CU2|ST0_CU1|ST0_KSU); childregs->cp0_status &= ~(ST0_CU3|ST0_CU2|ST0_CU1); p->mm->context = 0; diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index ebd657d4c..b8d604d2d 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c @@ -342,8 +342,8 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) struct pt_regs *regs; unsigned long tmp; - regs = (struct pt_regs *) - (child->tss.ksp - sizeof(struct pt_regs)); + regs = (struct pt_regs *) ((unsigned long) child + + KERNEL_STACK_SIZE - 32 - sizeof(struct pt_regs)); tmp = 0; /* Default return value. */ if(addr < 32 && addr >= 0) { tmp = regs->regs[addr]; @@ -398,8 +398,8 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) struct pt_regs *regs; int res = 0; - regs = (struct pt_regs *) - (child->tss.ksp - sizeof(struct pt_regs)); + regs = (struct pt_regs *) ((unsigned long) child + + KERNEL_STACK_SIZE - 32 - sizeof(struct pt_regs)); if(addr < 32 && addr >= 0) { regs->regs[addr] = data; } else if(addr >= 32 && addr < 64) { diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S index f4470e54d..b2b55bf0b 100644 --- a/arch/mips/kernel/r2300_switch.S +++ b/arch/mips/kernel/r2300_switch.S @@ -6,7 +6,7 @@ * Multi-cpu abstraction and macros for easier reading: * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: r2300_switch.S,v 1.3 1998/03/23 06:34:37 ralf Exp $ + * $Id: r2300_switch.S,v 1.3 1998/03/27 04:47:55 ralf Exp $ */ #include <asm/asm.h> #include <asm/bootinfo.h> @@ -83,8 +83,8 @@ MODE_ALIAS = 0x00e0 # uncachable, dirty, valid FPU_RESTORE($28, t0) 1: CPU_RESTORE_NONSCRATCH($28) - lw t0,THREAD_KSP($28) # Restore status register + addiu t0, $28, KERNEL_STACK_SIZE-32 sw t0,kernelsp jr ra - mtc0 a2,CP0_STATUS + mtc0 a2,CP0_STATUS # Restore status register END(r2300_resume) diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S index 72638d462..c37b90612 100644 --- a/arch/mips/kernel/r4k_fpu.S +++ b/arch/mips/kernel/r4k_fpu.S @@ -5,12 +5,12 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1996 by Ralf Baechle + * Copyright (C) 1996, 1998 by Ralf Baechle * * Multi-arch abstraction and asm macros for easier reading: * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: r4k_fpu.S,v 1.3 1997/12/01 16:56:06 ralf Exp $ + * $Id: r4k_fpu.S,v 1.3 1997/12/01 17:57:30 ralf Exp $ */ #include <asm/asm.h> #include <asm/fpregdef.h> @@ -18,65 +18,63 @@ #include <asm/offset.h> #include <asm/regdef.h> +#define EX(a,b) \ +9: a,##b; \ + .section __ex_table,"a"; \ + PTR 9b,bad_stack; \ + .previous + .set noreorder .set mips3 /* Save floating point context */ LEAF(r4k_save_fp_context) mfc0 t1,CP0_STATUS - sll t2,t1,2 - bgez t2,2f sll t2,t1,5 - cfc1 t1,fcr31 bgez t2,1f - nop + cfc1 t1,fcr31 /* Store the 16 odd double precision registers */ - sdc1 $f1,(SC_FPREGS+8)(a0) - sdc1 $f3,(SC_FPREGS+24)(a0) - sdc1 $f5,(SC_FPREGS+40)(a0) - sdc1 $f7,(SC_FPREGS+56)(a0) - sdc1 $f9,(SC_FPREGS+72)(a0) - sdc1 $f11,(SC_FPREGS+88)(a0) - sdc1 $f13,(SC_FPREGS+104)(a0) - sdc1 $f15,(SC_FPREGS+120)(a0) - sdc1 $f17,(SC_FPREGS+136)(a0) - sdc1 $f19,(SC_FPREGS+152)(a0) - sdc1 $f21,(SC_FPREGS+168)(a0) - sdc1 $f23,(SC_FPREGS+184)(a0) - sdc1 $f25,(SC_FPREGS+200)(a0) - sdc1 $f27,(SC_FPREGS+216)(a0) - sdc1 $f29,(SC_FPREGS+232)(a0) - sdc1 $f31,(SC_FPREGS+248)(a0) + EX(sdc1 $f1,(SC_FPREGS+8)(a0)) + EX(sdc1 $f3,(SC_FPREGS+24)(a0)) + EX(sdc1 $f5,(SC_FPREGS+40)(a0)) + EX(sdc1 $f7,(SC_FPREGS+56)(a0)) + EX(sdc1 $f9,(SC_FPREGS+72)(a0)) + EX(sdc1 $f11,(SC_FPREGS+88)(a0)) + EX(sdc1 $f13,(SC_FPREGS+104)(a0)) + EX(sdc1 $f15,(SC_FPREGS+120)(a0)) + EX(sdc1 $f17,(SC_FPREGS+136)(a0)) + EX(sdc1 $f19,(SC_FPREGS+152)(a0)) + EX(sdc1 $f21,(SC_FPREGS+168)(a0)) + EX(sdc1 $f23,(SC_FPREGS+184)(a0)) + EX(sdc1 $f25,(SC_FPREGS+200)(a0)) + EX(sdc1 $f27,(SC_FPREGS+216)(a0)) + EX(sdc1 $f29,(SC_FPREGS+232)(a0)) + EX(sdc1 $f31,(SC_FPREGS+248)(a0)) /* Store the 16 even double precision registers */ 1: - sdc1 $f0,(SC_FPREGS+0)(a0) - sdc1 $f2,(SC_FPREGS+16)(a0) - sdc1 $f4,(SC_FPREGS+32)(a0) - sdc1 $f6,(SC_FPREGS+48)(a0) - sdc1 $f8,(SC_FPREGS+64)(a0) - sdc1 $f10,(SC_FPREGS+80)(a0) - sdc1 $f12,(SC_FPREGS+96)(a0) - sdc1 $f14,(SC_FPREGS+112)(a0) - sdc1 $f16,(SC_FPREGS+128)(a0) - sdc1 $f18,(SC_FPREGS+144)(a0) - sdc1 $f20,(SC_FPREGS+160)(a0) - sdc1 $f22,(SC_FPREGS+176)(a0) - sdc1 $f24,(SC_FPREGS+192)(a0) - sdc1 $f26,(SC_FPREGS+208)(a0) - sdc1 $f28,(SC_FPREGS+224)(a0) - sdc1 $f30,(SC_FPREGS+240)(a0) - sw t1,SC_FPC_CSR(a0) + EX(sdc1 $f0,(SC_FPREGS+0)(a0)) + EX(sdc1 $f2,(SC_FPREGS+16)(a0)) + EX(sdc1 $f4,(SC_FPREGS+32)(a0)) + EX(sdc1 $f6,(SC_FPREGS+48)(a0)) + EX(sdc1 $f8,(SC_FPREGS+64)(a0)) + EX(sdc1 $f10,(SC_FPREGS+80)(a0)) + EX(sdc1 $f12,(SC_FPREGS+96)(a0)) + EX(sdc1 $f14,(SC_FPREGS+112)(a0)) + EX(sdc1 $f16,(SC_FPREGS+128)(a0)) + EX(sdc1 $f18,(SC_FPREGS+144)(a0)) + EX(sdc1 $f20,(SC_FPREGS+160)(a0)) + EX(sdc1 $f22,(SC_FPREGS+176)(a0)) + EX(sdc1 $f24,(SC_FPREGS+192)(a0)) + EX(sdc1 $f26,(SC_FPREGS+208)(a0)) + EX(sdc1 $f28,(SC_FPREGS+224)(a0)) + EX(sdc1 $f30,(SC_FPREGS+240)(a0)) + EX(sw t1,SC_FPC_CSR(a0)) cfc1 t0,$0 # implementation/version jr ra .set nomacro - sw t0,SC_FPC_EIR(a0) - .set macro -2: - jr ra - .set nomacro - nop + EX(sw t0,SC_FPC_EIR(a0)) .set macro END(r4k_save_fp_context) @@ -90,56 +88,51 @@ LEAF(r4k_save_fp_context) * stack frame which might have been changed by the user. */ LEAF(r4k_restore_fp_context) - mfc0 t1,CP0_STATUS - sll t0,t1,2 - bgez t0,2f - sll t0,t1,5 - + mfc0 t1, CP0_STATUS + sll t0,t1,5 bgez t0,1f - lw t0,SC_FPC_CSR(a0) + EX(lw t0,SC_FPC_CSR(a0)) + /* Restore the 16 odd double precision registers only * when enabled in the cp0 status register. */ - ldc1 $f1,(SC_FPREGS+8)(a0) - ldc1 $f3,(SC_FPREGS+24)(a0) - ldc1 $f5,(SC_FPREGS+40)(a0) - ldc1 $f7,(SC_FPREGS+56)(a0) - ldc1 $f9,(SC_FPREGS+72)(a0) - ldc1 $f11,(SC_FPREGS+88)(a0) - ldc1 $f13,(SC_FPREGS+104)(a0) - ldc1 $f15,(SC_FPREGS+120)(a0) - ldc1 $f17,(SC_FPREGS+136)(a0) - ldc1 $f19,(SC_FPREGS+152)(a0) - ldc1 $f21,(SC_FPREGS+168)(a0) - ldc1 $f23,(SC_FPREGS+184)(a0) - ldc1 $f25,(SC_FPREGS+200)(a0) - ldc1 $f27,(SC_FPREGS+216)(a0) - ldc1 $f29,(SC_FPREGS+232)(a0) - ldc1 $f31,(SC_FPREGS+248)(a0) + EX(ldc1 $f1,(SC_FPREGS+8)(a0)) + EX(ldc1 $f3,(SC_FPREGS+24)(a0)) + EX(ldc1 $f5,(SC_FPREGS+40)(a0)) + EX(ldc1 $f7,(SC_FPREGS+56)(a0)) + EX(ldc1 $f9,(SC_FPREGS+72)(a0)) + EX(ldc1 $f11,(SC_FPREGS+88)(a0)) + EX(ldc1 $f13,(SC_FPREGS+104)(a0)) + EX(ldc1 $f15,(SC_FPREGS+120)(a0)) + EX(ldc1 $f17,(SC_FPREGS+136)(a0)) + EX(ldc1 $f19,(SC_FPREGS+152)(a0)) + EX(ldc1 $f21,(SC_FPREGS+168)(a0)) + EX(ldc1 $f23,(SC_FPREGS+184)(a0)) + EX(ldc1 $f25,(SC_FPREGS+200)(a0)) + EX(ldc1 $f27,(SC_FPREGS+216)(a0)) + EX(ldc1 $f29,(SC_FPREGS+232)(a0)) + EX(ldc1 $f31,(SC_FPREGS+248)(a0)) /* * Restore the 16 even double precision registers * when cp1 was enabled in the cp0 status register. */ -1: ldc1 $f0,(SC_FPREGS+0)(a0) - ldc1 $f2,(SC_FPREGS+16)(a0) - ldc1 $f4,(SC_FPREGS+32)(a0) - ldc1 $f6,(SC_FPREGS+48)(a0) - ldc1 $f8,(SC_FPREGS+64)(a0) - ldc1 $f10,(SC_FPREGS+80)(a0) - ldc1 $f12,(SC_FPREGS+96)(a0) - ldc1 $f14,(SC_FPREGS+112)(a0) - ldc1 $f16,(SC_FPREGS+128)(a0) - ldc1 $f18,(SC_FPREGS+144)(a0) - ldc1 $f20,(SC_FPREGS+160)(a0) - ldc1 $f22,(SC_FPREGS+176)(a0) - ldc1 $f24,(SC_FPREGS+192)(a0) - ldc1 $f26,(SC_FPREGS+208)(a0) - ldc1 $f28,(SC_FPREGS+224)(a0) - ldc1 $f30,(SC_FPREGS+240)(a0) +1: EX(ldc1 $f0,(SC_FPREGS+0)(a0)) + EX(ldc1 $f2,(SC_FPREGS+16)(a0)) + EX(ldc1 $f4,(SC_FPREGS+32)(a0)) + EX(ldc1 $f6,(SC_FPREGS+48)(a0)) + EX(ldc1 $f8,(SC_FPREGS+64)(a0)) + EX(ldc1 $f10,(SC_FPREGS+80)(a0)) + EX(ldc1 $f12,(SC_FPREGS+96)(a0)) + EX(ldc1 $f14,(SC_FPREGS+112)(a0)) + EX(ldc1 $f16,(SC_FPREGS+128)(a0)) + EX(ldc1 $f18,(SC_FPREGS+144)(a0)) + EX(ldc1 $f20,(SC_FPREGS+160)(a0)) + EX(ldc1 $f22,(SC_FPREGS+176)(a0)) + EX(ldc1 $f24,(SC_FPREGS+192)(a0)) + EX(ldc1 $f26,(SC_FPREGS+208)(a0)) + EX(ldc1 $f28,(SC_FPREGS+224)(a0)) + EX(ldc1 $f30,(SC_FPREGS+240)(a0)) jr ra ctc1 t0,fcr31 - -2: jr ra - nop END(r4k_restore_fp_context) diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S index cb7f9891f..765de0d85 100644 --- a/arch/mips/kernel/r4k_switch.S +++ b/arch/mips/kernel/r4k_switch.S @@ -5,6 +5,8 @@ * * Multi-cpu abstraction and macros for easier reading: * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * + * $Id: r4k_switch.S,v 1.3 1998/04/04 13:59:38 ralf Exp $ */ #include <asm/asm.h> #include <asm/bootinfo.h> @@ -13,6 +15,7 @@ #include <asm/fpregdef.h> #include <asm/mipsconfig.h> #include <asm/mipsregs.h> +#include <asm/offset.h> #include <asm/page.h> #include <asm/pgtable.h> #include <asm/processor.h> @@ -25,43 +28,139 @@ .set mips3 .align 5 LEAF(r4xx0_resume) - mfc0 t1, CP0_STATUS - sw t1, THREAD_STATUS($28) - ori t2, t1, 0x1f - xori t2, t2, 0x1e - mtc0 t2, CP0_STATUS + mfc0 t1, CP0_STATUS # fp exception boundary + sll t0, t1, 2 + bgez t0, 1f + nop + cfc1 zero, fcr31 +1: sw t1, THREAD_STATUS($28) CPU_SAVE_NONSCRATCH($28) - sll t2, t1, 2 # Save floating point state - bgez t2, 2f - sw ra, THREAD_REG31($28) - sll t2, t1, 5 - bgez t2, 1f - swc1 $f0, (THREAD_FPU + 0x00)($28) - FPU_SAVE_16ODD($28) -1: - FPU_SAVE_16EVEN($28, t1) # clobbers t1 -2: + sw ra, THREAD_REG31($28) + + /* + * The order of restoring the registers takes care of the race + * updating $28, $29 and kernelsp without disabling ints. + */ move $28, a0 + CPU_RESTORE_NONSCRATCH($28) + addiu t0, $28, KERNEL_STACK_SIZE-32 + sw t0, kernelsp lw a3, TASK_MM($28) lw a2, THREAD_STATUS($28) lw a3, MM_CONTEXT(a3) - ori t1, a2, 1 # restore fpu, pipeline magic + mtc0 a2, CP0_STATUS andi a3, a3, 0xff - xori t1, t1, 1 - mtc0 a3, CP0_ENTRYHI - mtc0 t1, CP0_STATUS - sll t0, a2, 2 - bgez t0, 2f - sll t0, a2, 5 + jr ra + mtc0 a3, CP0_ENTRYHI + END(r4xx0_resume) + +/* + * Do lazy fpu context switch. Saves FPU context to the process in a0 + * and loads the new context of the current process. + */ + +#define ST_OFF (KERNEL_STACK_SIZE - 32 - PT_SIZE + PT_STATUS) + +LEAF(r4xx0_lazy_fpu_switch) + mfc0 t0, CP0_STATUS # enable cp1 + li t3, 0x20000000 + or t0, t3 + mtc0 t0, CP0_STATUS + + beqz a0, 2f # Save floating point state + nor t3, zero, t3 + lw t1, ST_OFF(a0) # last thread looses fpu + and t1, t3 + sw t1, ST_OFF(a0) + sll t2, t1, 5 + bgez t2, 1f + sdc1 $f0, (THREAD_FPU + 0x00)(a0) + FPU_SAVE_16ODD(a0) +1: + FPU_SAVE_16EVEN(a0, t1) # clobbers t1 +2: + + sll t0, t0, 5 # load new fp state bgez t0, 1f - lwc1 $f0, (THREAD_FPU + 0x00)($28) + ldc1 $f0, (THREAD_FPU + 0x00)($28) FPU_RESTORE_16ODD($28) 1: - FPU_RESTORE_16EVEN($28, t0) # clobbers t0 -2: - CPU_RESTORE_NONSCRATCH($28) - lw t0, THREAD_KSP($28) - sw t0, kernelsp + .set reorder + FPU_RESTORE_16EVEN($28, t0) # clobbers t0 jr ra - mtc0 a2, CP0_STATUS - END(r4xx0_resume) + END(r4xx0_lazy_fpu_switch) + +/* + * Save a thread's fp context. + */ + .set noreorder +LEAF(r4xx0_save_fp) + mfc0 t0, CP0_STATUS + sll t1, t0, 5 + bgez t1, 1f # 16 register mode? + nop + FPU_SAVE_16ODD(a0) +1: + FPU_SAVE_16EVEN(a0, t1) # clobbers t1 + jr ra + sdc1 $f0, (THREAD_FPU + 0x00)(a0) + END(r4xx0_save_fp) + +/* + * Load the FPU with signalling NANS. This bit pattern we're using has + * the property that no matter wether considered as single or as double + * precission represents signaling NANS. + * + * We initialize fcr31 to rounding to nearest, no exceptions. + */ + +#define FPU_DEFAULT 0x00000600 + +LEAF(r4xx0_init_fpu) + mfc0 t0, CP0_STATUS + li t1, 0x20000000 + or t0, t1 + mtc0 t0, CP0_STATUS + sll t0, t0, 5 + + li t1, FPU_DEFAULT + ctc1 t1, fcr31 + + bgez t0, 1f # 16 / 32 register mode? + li t0, -1 + + dmtc1 t0, $f1 + dmtc1 t0, $f3 + dmtc1 t0, $f5 + dmtc1 t0, $f7 + dmtc1 t0, $f9 + dmtc1 t0, $f11 + dmtc1 t0, $f13 + dmtc1 t0, $f15 + dmtc1 t0, $f17 + dmtc1 t0, $f19 + dmtc1 t0, $f21 + dmtc1 t0, $f23 + dmtc1 t0, $f25 + dmtc1 t0, $f27 + dmtc1 t0, $f29 + dmtc1 t0, $f31 + +1: dmtc1 t0, $f0 + dmtc1 t0, $f2 + dmtc1 t0, $f4 + dmtc1 t0, $f6 + dmtc1 t0, $f8 + dmtc1 t0, $f10 + dmtc1 t0, $f12 + dmtc1 t0, $f14 + dmtc1 t0, $f16 + dmtc1 t0, $f18 + dmtc1 t0, $f20 + dmtc1 t0, $f22 + dmtc1 t0, $f24 + dmtc1 t0, $f26 + dmtc1 t0, $f28 + jr ra + dmtc1 t0, $f30 + END(r4xx0_init_fpu) diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index 007e95452..954e8bfb0 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c @@ -4,7 +4,9 @@ * Copyright (C) 1991, 1992 Linus Torvalds * Copyright (C) 1994, 1995, 1996 Ralf Baechle * - * $Id: signal.c,v 1.17 1998/03/26 07:39:10 ralf Exp $ + * $Id: signal.c,v 1.11 1998/03/27 04:47:55 ralf Exp $ + * + * XXX Handle lazy fp context switches correctly. */ #include <linux/config.h> #include <linux/sched.h> @@ -125,17 +127,10 @@ asmlinkage void restore_sigcontext(struct pt_regs *regs, struct sigcontext *context) { long long reg; - int i; + int owned_fp; __get_user(regs->cp0_epc, &context->sc_pc); - /* - * Restore all integer registers. - */ - for(i = 31;i >= 0;i--) { - __get_user(reg, &context->sc_regs[i]); - regs->regs[i] = (int) reg; - } __get_user(reg, &context->sc_mdhi); regs->hi = (int) reg; __get_user(reg, &context->sc_mdlo); @@ -156,11 +151,15 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext *context) restore_gp_reg(31); #undef restore_gp_reg - /* - * FP depends on what FPU in what mode we have. Best done in - * Assembler ... - */ - restore_fp_context(context); + /* FP depends on what FPU in what mode we have. */ + __get_user(owned_fp, &context->sc_ownedfp); +#if 0 + if (owned_fp) { + restore_fp_context(context); + last_task_used_math = current; + } +#endif +restore_fp_context(context); } /* @@ -191,8 +190,16 @@ asmlinkage int sys_sigreturn(struct pt_regs regs) (regs.regs[29] & (SZREG - 1))) goto badframe; +#if 1 + if (__get_user(blocked.sig[0], &context->sc_sigset[0]) || + __get_user(blocked.sig[1], &context->sc_sigset[1]) || + __get_user(blocked.sig[2], &context->sc_sigset[2]) || + __get_user(blocked.sig[3], &context->sc_sigset[3])) + goto badframe; +#else if (__copy_from_user(&blocked, &context->sc_sigset, sizeof(blocked))) goto badframe; +#endif sigdelsetmask(&blocked, ~_BLOCKABLE); spin_lock_irq(¤t->sigmask_lock); @@ -251,6 +258,8 @@ setup_trampoline(unsigned int *code) static void inline setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc, sigset_t *set) { + int owned_fp; + __put_user(regs->cp0_epc, &sc->sc_pc); __put_user(regs->cp0_status, &sc->sc_status); /* Status register */ @@ -266,13 +275,29 @@ setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc, sigset_t *set) save_gp_reg(31); #undef save_gp_reg - save_fp_context(sc); /* cpu dependant */ __put_user(regs->hi, &sc->sc_mdhi); __put_user(regs->lo, &sc->sc_mdlo); __put_user(regs->cp0_cause, &sc->sc_cause); - __put_user((regs->cp0_status & ST0_CU1) != 0, &sc->sc_ownedfp); - __copy_to_user(sc->sc_sigset, set, sizeof(*set)); + owned_fp = (current == last_task_used_math); + __put_user(owned_fp, &sc->sc_ownedfp); + +#if 0 + if (current->used_math) { /* fp is active. */ + set_cp0_status(ST0_CU1, ST0_CU1); + save_fp_context(sc); /* cpu dependant */ + last_task_used_math = NULL; + regs->cp0_status &= ~ST0_CU1; + current->used_math = 0; + } +#endif +set_cp0_status(ST0_CU1, ST0_CU1); +save_fp_context(sc); /* cpu dependant */ + + __put_user(set->sig[0], &sc->sc_sigset[0]); + __put_user(set->sig[1], &sc->sc_sigset[1]); + __put_user(set->sig[2], &sc->sc_sigset[2]); + __put_user(set->sig[3], &sc->sc_sigset[3]); } static void inline diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 629a07836..b554cad39 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -8,11 +8,12 @@ * Copyright 1994, 1995, 1996, 1997 by Ralf Baechle * Modified for R3000 by Paul M. Antoine, 1995, 1996 * - * $Id: traps.c,v 1.12 1998/03/26 07:39:11 ralf Exp $ + * $Id: traps.c,v 1.9 1998/03/27 04:47:56 ralf Exp $ */ #include <linux/config.h> #include <linux/init.h> #include <linux/mm.h> +#include <linux/sched.h> #include <linux/smp.h> #include <linux/smp_lock.h> @@ -229,6 +230,9 @@ int unregister_fpe(void (*handler)(struct pt_regs *regs, unsigned int fcr31)) } #endif +/* + * XXX Delayed fp exceptions when doing a lazy ctx switch XXX + */ void do_fpe(struct pt_regs *regs, unsigned long fcr31) { #ifdef CONFIG_MIPS_FPE_MODULE @@ -257,6 +261,7 @@ void do_fpe(struct pt_regs *regs, unsigned long fcr31) printk("Unimplemented exception at 0x%08lx in %s.\n", regs->cp0_epc, current->comm); } + if (compute_return_epc(regs)) goto out; force_sig(SIGFPE, current); @@ -354,11 +359,24 @@ void do_cpu(struct pt_regs *regs) unsigned int cpid; cpid = (regs->cp0_cause >> CAUSEB_CE) & 3; - if (cpid == 1) { - regs->cp0_status |= ST0_CU1; + if (cpid != 1) + goto bad_cid; + + regs->cp0_status |= ST0_CU1; + if (last_task_used_math == current) goto out; + + if (current->used_math) { /* Using the FPU again. */ + r4xx0_lazy_fpu_switch(last_task_used_math); + } else { /* First time FPU user. */ + + r4xx0_init_fpu(); + current->used_math = 1; } + last_task_used_math = current; + return; +bad_cid: lock_kernel(); force_sig(SIGILL, current); unlock_kernel(); @@ -369,8 +387,9 @@ void do_vcei(struct pt_regs *regs) { lock_kernel(); /* - * Only possible on R4[04]00[SM]C. No handler because I don't have - * such a cpu. Theory says this exception doesn't happen. + * Theory says this exception doesn't happen. + * + * Murphy is right. It does happen ... */ panic("Caught VCEI exception - should not happen"); unlock_kernel(); @@ -380,10 +399,11 @@ void do_vced(struct pt_regs *regs) { lock_kernel(); /* - * Only possible on R4[04]00[SM]C. No handler because I don't have - * such a cpu. Theory says this exception doesn't happen. + * Theory says this exception doesn't happen. + * + * Murphy is right. It does happen ... */ - panic("Caught VCE exception - should not happen"); + panic("Caught VCED exception - should not happen"); unlock_kernel(); } @@ -527,8 +547,14 @@ __initfunc(void trap_init(void)) case CPU_R4400MC: case CPU_R4000SC: case CPU_R4400SC: - /* XXX The following won't work because we _cannot_ - * XXX perform any load/store before the VCE handler. + /* + * The following won't work because we _cannot_ perform any + * load/store before the VCE handler. We deal with this + * by checking for for vced / vcei exceptions before doing + * the generic exception handling thing. This costs us + * several instructions, therefore there should be a special + * handler for those CPUs which have these exceptions. + * */ set_except_vector(14, handle_vcei); set_except_vector(31, handle_vced); diff --git a/arch/mips/ld.script.big b/arch/mips/ld.script.big index 88da74972..7181d0886 100644 --- a/arch/mips/ld.script.big +++ b/arch/mips/ld.script.big @@ -37,6 +37,15 @@ SECTIONS } =0 _etext = .; PROVIDE (etext = .); + + /* Startup code */ + . = ALIGN(4096); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(4096); /* Align double page for init_task_union */ + __init_end = .; + .fini : { *(.fini) } =0 .reginfo : { *(.reginfo) } /* Adjust the address for the data segment. We want to adjust up to @@ -74,6 +83,7 @@ SECTIONS .sdata : { *(.sdata) } _edata = .; PROVIDE (edata = .); + __bss_start = .; _fbss = .; .bss : diff --git a/arch/mips/ld.script.little b/arch/mips/ld.script.little index 26464d9f7..7e638d739 100644 --- a/arch/mips/ld.script.little +++ b/arch/mips/ld.script.little @@ -37,6 +37,15 @@ SECTIONS } =0 _etext = .; PROVIDE (etext = .); + + /* Startup code */ + . = ALIGN(4096); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(4096); /* Align double page for init_task_union */ + __init_end = .; + .fini : { *(.fini) } =0 .reginfo : { *(.reginfo) } /* Adjust the address for the data segment. We want to adjust up to @@ -74,6 +83,7 @@ SECTIONS .sdata : { *(.sdata) } _edata = .; PROVIDE (edata = .); + __bss_start = .; _fbss = .; .bss : diff --git a/arch/mips/mm/andes.c b/arch/mips/mm/andes.c index 529c12465..05150aa83 100644 --- a/arch/mips/mm/andes.c +++ b/arch/mips/mm/andes.c @@ -3,13 +3,12 @@ * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: andes.c,v 1.3 1998/03/21 08:03:53 ralf Exp $ + * $Id: andes.c,v 1.3 1998/03/22 23:27:14 ralf Exp $ */ - +#include <linux/init.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/mm.h> - #include <asm/page.h> #include <asm/pgtable.h> #include <asm/system.h> @@ -89,10 +88,10 @@ static void andes_add_wired_entry(unsigned long entrylo0, unsigned long entrylo1 static void andes_user_mode(struct pt_regs *regs) { - return regs->cp0_status & ST0_KSU == KSU_USER; + return (regs->cp0_status & ST0_KSU) == KSU_USER; } -void ld_mmu_andes(void) +__initfunc(void ld_mmu_andes(void)) { flush_cache_all = andes_flush_cache_all; flush_cache_mm = andes_flush_cache_mm; diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 3e309e438..dd2fcbad2 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -5,9 +5,10 @@ * * Copyright (C) 1994, 1995, 1996 by Ralf Baechle * - * $Id: init.c,v 1.4 1998/03/21 08:01:45 ralf Exp $ + * $Id: init.c,v 1.4 1998/03/22 23:27:15 ralf Exp $ */ #include <linux/config.h> +#include <linux/init.h> #include <linux/signal.h> #include <linux/sched.h> #include <linux/head.h> @@ -155,13 +156,13 @@ void show_mem(void) extern unsigned long free_area_init(unsigned long, unsigned long); -unsigned long paging_init(unsigned long start_mem, unsigned long end_mem) +__initfunc(unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)) { pgd_init((unsigned long)swapper_pg_dir); return free_area_init(start_mem, end_mem); } -void mem_init(unsigned long start_mem, unsigned long end_mem) +__initfunc(void mem_init(unsigned long start_mem, unsigned long end_mem)) { int codepages = 0; int datapages = 0; @@ -178,7 +179,7 @@ void mem_init(unsigned long start_mem, unsigned long end_mem) high_memory = (void *)end_mem; /* clear the zero-page */ - clear_page(empty_zero_page); + clear_page((unsigned long)empty_zero_page); /* mark usable pages in the mem_map[] */ start_mem = PAGE_ALIGN(start_mem); @@ -225,9 +226,20 @@ void mem_init(unsigned long start_mem, unsigned long end_mem) return; } +extern char __init_begin, __init_end; + void free_initmem(void) { - /* To be written */ + unsigned long addr; + + addr = (unsigned long)(&__init_begin); + for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { + mem_map[MAP_NR(addr)].flags &= ~(1 << PG_reserved); + atomic_set(&mem_map[MAP_NR(addr)].count, 1); + free_page(addr); + } + printk("Freeing unused kernel memory: %dk freed\n", + (&__init_end - &__init_begin) >> 10); } void si_meminfo(struct sysinfo *val) diff --git a/arch/mips/mm/loadmmu.c b/arch/mips/mm/loadmmu.c index 9f4624ba6..f8730ad26 100644 --- a/arch/mips/mm/loadmmu.c +++ b/arch/mips/mm/loadmmu.c @@ -3,9 +3,9 @@ * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: loadmmu.c,v 1.5 1998/03/03 16:57:25 ralf Exp $ + * $Id: loadmmu.c,v 1.6 1998/03/22 23:27:15 ralf Exp $ */ - +#include <linux/init.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/mm.h> @@ -61,7 +61,7 @@ extern void ld_mmu_r6000(void); extern void ld_mmu_tfp(void); extern void ld_mmu_andes(void); -void loadmmu(void) +__initfunc(void loadmmu(void)) { switch(mips_cputype) { case CPU_R2000: diff --git a/arch/mips/mm/r2300.c b/arch/mips/mm/r2300.c index 822cb1a1a..925c5222b 100644 --- a/arch/mips/mm/r2300.c +++ b/arch/mips/mm/r2300.c @@ -3,9 +3,9 @@ * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: r2300.c,v 1.3 1997/07/29 22:54:51 tsbogend Exp $ + * $Id: r2300.c,v 1.4 1998/03/22 23:27:15 ralf Exp $ */ - +#include <linux/init.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/mm.h> @@ -258,7 +258,7 @@ static int r2300_user_mode(struct pt_regs *regs) return !(regs->cp0_status & 0x4); } -void ld_mmu_r2300(void) +__initfunc(void ld_mmu_r2300(void)) { clear_page = r2300_clear_page; copy_page = r2300_copy_page; diff --git a/arch/mips/mm/r4xx0.c b/arch/mips/mm/r4xx0.c index 2cd1c9236..0bfa42c3a 100644 --- a/arch/mips/mm/r4xx0.c +++ b/arch/mips/mm/r4xx0.c @@ -3,7 +3,7 @@ * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: r4xx0.c,v 1.13 1998/03/18 17:18:13 ralf Exp $ + * $Id: r4xx0.c,v 1.14 1998/03/22 23:27:16 ralf Exp $ * * To do: * @@ -11,10 +11,10 @@ * - many of the bug workarounds are not efficient at all, but at * least they are functional ... */ +#include <linux/init.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/mm.h> -#include <linux/autoconf.h> #include <asm/bcache.h> #include <asm/io.h> @@ -65,9 +65,19 @@ struct bcache_ops *bcops = &no_sc_ops; #define dcache_waybit (dcache_size >> 1) /* - * Zero an entire page. We have three flavours of the routine available. - * One for CPU with 16byte, with 32byte cachelines plus a special version - * with nops which handles the buggy R4600 v1.x. + * Zero an entire page. Basically a simple unrolled loop should do the + * job but we want more performance by saving memory bus bandwidth. We + * have five flavours of the routine available for: + * + * - 16byte cachelines and no second level cache + * - 32byte cachelines second level cache + * - a version which handles the buggy R4600 v1.x + * - a version which handles the buggy R4600 v2.0 + * - Finally a last version without fancy cache games for the SC and MC + * versions of R4000 and R4400. Cache instructions are quite expensive + * and I guess using them for both the primary and the second level cache + * wouldn't be worth the effort. + * This needs to be verified by benchmarking. */ static void r4k_clear_page_d16(unsigned long page) @@ -231,6 +241,58 @@ static void r4k_clear_page_r4600_v2(unsigned long page) restore_flags(flags); } +static void r4k_clear_page(unsigned long page) +{ + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + ".set\tmips3\n\t" + "daddiu\t$1,%0,%2\n" + "1:\tsd\t$0,(%0)\n\t" + "sd\t$0,8(%0)\n\t" + "sd\t$0,16(%0)\n\t" + "sd\t$0,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "sd\t$0,-32(%0)\n\t" + "sd\t$0,-24(%0)\n\t" + "sd\t$0,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sd\t$0,-8(%0)\n\t" + ".set\tmips0\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (page) + :"0" (page), + "I" (PAGE_SIZE) + :"$1","memory"); +} + +static void r4k_clear_page(unsigned long page) +{ + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + ".set\tmips3\n\t" + "daddiu\t$1,%0,%2\n" + "1:\tsd\t$0,(%0)\n\t" + "sd\t$0,8(%0)\n\t" + "sd\t$0,16(%0)\n\t" + "sd\t$0,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "sd\t$0,-32(%0)\n\t" + "sd\t$0,-24(%0)\n\t" + "sd\t$0,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sd\t$0,-8(%0)\n\t" + ".set\tmips0\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (page) + :"0" (page), + "I" (PAGE_SIZE) + :"$1","memory"); +} + /* * This is still inefficient. We only can do better if we know the @@ -489,6 +551,114 @@ static void r4k_copy_page_r4600_v2(unsigned long to, unsigned long from) restore_flags(flags); } +static void r4k_copy_page(unsigned long to, unsigned long from) +{ + unsigned long dummy1, dummy2; + unsigned long reg1, reg2, reg3, reg4; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + ".set\tmips3\n\t" + "daddiu\t$1,%0,%8\n" + "1:\tlw\t%2,(%1)\n\t" + "lw\t%3,4(%1)\n\t" + "lw\t%4,8(%1)\n\t" + "lw\t%5,12(%1)\n\t" + "sw\t%2,(%0)\n\t" + "sw\t%3,4(%0)\n\t" + "sw\t%4,8(%0)\n\t" + "sw\t%5,12(%0)\n\t" + "lw\t%2,16(%1)\n\t" + "lw\t%3,20(%1)\n\t" + "lw\t%4,24(%1)\n\t" + "lw\t%5,28(%1)\n\t" + "sw\t%2,16(%0)\n\t" + "sw\t%3,20(%0)\n\t" + "sw\t%4,24(%0)\n\t" + "sw\t%5,28(%0)\n\t" + "daddiu\t%0,64\n\t" + "daddiu\t%1,64\n\t" + "lw\t%2,-32(%1)\n\t" + "lw\t%3,-28(%1)\n\t" + "lw\t%4,-24(%1)\n\t" + "lw\t%5,-20(%1)\n\t" + "sw\t%2,-32(%0)\n\t" + "sw\t%3,-28(%0)\n\t" + "sw\t%4,-24(%0)\n\t" + "sw\t%5,-20(%0)\n\t" + "lw\t%2,-16(%1)\n\t" + "lw\t%3,-12(%1)\n\t" + "lw\t%4,-8(%1)\n\t" + "lw\t%5,-4(%1)\n\t" + "sw\t%2,-16(%0)\n\t" + "sw\t%3,-12(%0)\n\t" + "sw\t%4,-8(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sw\t%5,-4(%0)\n\t" + ".set\tmips0\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (dummy1), "=r" (dummy2), + "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4) + :"0" (to), "1" (from), + "I" (PAGE_SIZE)); +} + +static void r4k_copy_page(unsigned long to, unsigned long from) +{ + unsigned long dummy1, dummy2; + unsigned long reg1, reg2, reg3, reg4; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + ".set\tmips3\n\t" + "daddiu\t$1,%0,%8\n" + "1:\tlw\t%2,(%1)\n\t" + "lw\t%3,4(%1)\n\t" + "lw\t%4,8(%1)\n\t" + "lw\t%5,12(%1)\n\t" + "sw\t%2,(%0)\n\t" + "sw\t%3,4(%0)\n\t" + "sw\t%4,8(%0)\n\t" + "sw\t%5,12(%0)\n\t" + "lw\t%2,16(%1)\n\t" + "lw\t%3,20(%1)\n\t" + "lw\t%4,24(%1)\n\t" + "lw\t%5,28(%1)\n\t" + "sw\t%2,16(%0)\n\t" + "sw\t%3,20(%0)\n\t" + "sw\t%4,24(%0)\n\t" + "sw\t%5,28(%0)\n\t" + "daddiu\t%0,64\n\t" + "daddiu\t%1,64\n\t" + "lw\t%2,-32(%1)\n\t" + "lw\t%3,-28(%1)\n\t" + "lw\t%4,-24(%1)\n\t" + "lw\t%5,-20(%1)\n\t" + "sw\t%2,-32(%0)\n\t" + "sw\t%3,-28(%0)\n\t" + "sw\t%4,-24(%0)\n\t" + "sw\t%5,-20(%0)\n\t" + "lw\t%2,-16(%1)\n\t" + "lw\t%3,-12(%1)\n\t" + "lw\t%4,-8(%1)\n\t" + "lw\t%5,-4(%1)\n\t" + "sw\t%2,-16(%0)\n\t" + "sw\t%3,-12(%0)\n\t" + "sw\t%4,-8(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sw\t%5,-4(%0)\n\t" + ".set\tmips0\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (dummy1), "=r" (dummy2), + "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4) + :"0" (to), "1" (from), + "I" (PAGE_SIZE)); +} + /* * If you think for one second that this stuff coming up is a lot * of bulky code eating too many kernel cache lines. Think _again_. @@ -1951,9 +2121,9 @@ r4k_dma_cache_wback_inv_sc(unsigned long addr, unsigned long size) a = addr & ~(sc_lsize - 1); end = (addr + size) & ~(sc_lsize - 1); while (1) { - flush_scache_line(addr); /* Hit_Writeback_Inv_SD */ - if (addr == end) break; - addr += sc_lsize; + flush_scache_line(a); /* Hit_Writeback_Inv_SD */ + if (a == end) break; + a += sc_lsize; } } @@ -2006,9 +2176,9 @@ r4k_dma_cache_inv_sc(unsigned long addr, unsigned long size) a = addr & ~(sc_lsize - 1); end = (addr + size) & ~(sc_lsize - 1); while (1) { - flush_scache_line(addr); /* Hit_Writeback_Inv_SD */ - if (addr == end) break; - addr += sc_lsize; + flush_scache_line(a); /* Hit_Writeback_Inv_SD */ + if (a == end) break; + a += sc_lsize; } } @@ -2373,7 +2543,7 @@ static void r4k_add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, } /* Detect and size the various r4k caches. */ -static void probe_icache(unsigned long config) +__initfunc(static void probe_icache(unsigned long config)) { icache_size = 1 << (12 + ((config >> 6) & 7)); ic_lsize = 16 << ((config >> 4) & 1); @@ -2382,7 +2552,7 @@ static void probe_icache(unsigned long config) icache_size >> 10, ic_lsize); } -static void probe_dcache(unsigned long config) +__initfunc(static void probe_dcache(unsigned long config)) { dcache_size = 1 << (12 + ((config >> 6) & 7)); dc_lsize = 16 << ((config >> 4) & 1); @@ -2397,7 +2567,7 @@ static void probe_dcache(unsigned long config) * the cache sizing loop that executes in KSEG1 space or else * you will crash and burn badly. You have been warned. */ -static int probe_scache(unsigned long config) +__initfunc(static int probe_scache(unsigned long config)) { extern unsigned long stext; unsigned long flags, addr, begin, end, pow2; @@ -2481,7 +2651,7 @@ static int probe_scache(unsigned long config) return 1; } -static void setup_noscache_funcs(void) +__initfunc(static void setup_noscache_funcs(void)) { unsigned int prid; @@ -2524,8 +2694,6 @@ static void setup_scache_funcs(void) case 16: switch(dc_lsize) { case 16: - clear_page = r4k_clear_page_d16; - copy_page = r4k_copy_page_d16; flush_cache_all = r4k_flush_cache_all_s16d16i16; flush_cache_mm = r4k_flush_cache_mm_s16d16i16; flush_cache_range = r4k_flush_cache_range_s16d16i16; @@ -2533,8 +2701,6 @@ static void setup_scache_funcs(void) flush_page_to_ram = r4k_flush_page_to_ram_s16d16i16; break; case 32: - clear_page = r4k_clear_page_d32; - copy_page = r4k_copy_page_d32; flush_cache_all = r4k_flush_cache_all_s16d32i32; flush_cache_mm = r4k_flush_cache_mm_s16d32i32; flush_cache_range = r4k_flush_cache_range_s16d32i32; @@ -2546,8 +2712,6 @@ static void setup_scache_funcs(void) case 32: switch(dc_lsize) { case 16: - clear_page = r4k_clear_page_d16; - copy_page = r4k_copy_page_d16; flush_cache_all = r4k_flush_cache_all_s32d16i16; flush_cache_mm = r4k_flush_cache_mm_s32d16i16; flush_cache_range = r4k_flush_cache_range_s32d16i16; @@ -2555,8 +2719,6 @@ static void setup_scache_funcs(void) flush_page_to_ram = r4k_flush_page_to_ram_s32d16i16; break; case 32: - clear_page = r4k_clear_page_d32; - copy_page = r4k_copy_page_d32; flush_cache_all = r4k_flush_cache_all_s32d32i32; flush_cache_mm = r4k_flush_cache_mm_s32d32i32; flush_cache_range = r4k_flush_cache_range_s32d32i32; @@ -2567,8 +2729,6 @@ static void setup_scache_funcs(void) case 64: switch(dc_lsize) { case 16: - clear_page = r4k_clear_page_d16; - copy_page = r4k_copy_page_d16; flush_cache_all = r4k_flush_cache_all_s64d16i16; flush_cache_mm = r4k_flush_cache_mm_s64d16i16; flush_cache_range = r4k_flush_cache_range_s64d16i16; @@ -2576,8 +2736,6 @@ static void setup_scache_funcs(void) flush_page_to_ram = r4k_flush_page_to_ram_s64d16i16; break; case 32: - clear_page = r4k_clear_page_d32; - copy_page = r4k_copy_page_d32; flush_cache_all = r4k_flush_cache_all_s64d32i32; flush_cache_mm = r4k_flush_cache_mm_s64d32i32; flush_cache_range = r4k_flush_cache_range_s64d32i32; @@ -2588,8 +2746,6 @@ static void setup_scache_funcs(void) case 128: switch(dc_lsize) { case 16: - clear_page = r4k_clear_page_d16; - copy_page = r4k_copy_page_d16; flush_cache_all = r4k_flush_cache_all_s128d16i16; flush_cache_mm = r4k_flush_cache_mm_s128d16i16; flush_cache_range = r4k_flush_cache_range_s128d16i16; @@ -2597,8 +2753,6 @@ static void setup_scache_funcs(void) flush_page_to_ram = r4k_flush_page_to_ram_s128d16i16; break; case 32: - clear_page = r4k_clear_page_d32; - copy_page = r4k_copy_page_d32; flush_cache_all = r4k_flush_cache_all_s128d32i32; flush_cache_mm = r4k_flush_cache_mm_s128d32i32; flush_cache_range = r4k_flush_cache_range_s128d32i32; @@ -2608,6 +2762,8 @@ static void setup_scache_funcs(void) }; break; } + clear_page = r4k_clear_page; + copy_page = r4k_copy_page; dma_cache_wback_inv = r4k_dma_cache_wback_inv_sc; dma_cache_inv = r4k_dma_cache_inv_sc; } @@ -2637,7 +2793,7 @@ static int r4k_user_mode(struct pt_regs *regs) } -void ld_mmu_r4xx0(void) +__initfunc(void ld_mmu_r4xx0(void)) { unsigned long config = read_32bit_cp0_register(CP0_CONFIG); diff --git a/arch/mips/mm/r6000.c b/arch/mips/mm/r6000.c index d656c897c..748fa3293 100644 --- a/arch/mips/mm/r6000.c +++ b/arch/mips/mm/r6000.c @@ -1,9 +1,9 @@ -/* $Id: r6000.c,v 1.2 1997/07/29 22:54:52 tsbogend Exp $ +/* $Id: r6000.c,v 1.4 1998/03/27 08:53:42 ralf Exp $ * r6000.c: MMU and cache routines for the R6000 processors. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) */ - +#include <linux/init.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/mm.h> @@ -167,7 +167,7 @@ static int r6000_user_mode(struct pt_regs *regs) return !(regs->cp0_status & 0x4); } -void ld_mmu_r6000(void) +__initfunc(void ld_mmu_r6000(void)) { flush_cache_all = r6000_flush_cache_all; flush_cache_mm = r6000_flush_cache_mm; diff --git a/arch/mips/mm/tfp.c b/arch/mips/mm/tfp.c index 931661f82..d1701c03a 100644 --- a/arch/mips/mm/tfp.c +++ b/arch/mips/mm/tfp.c @@ -1,9 +1,9 @@ -/* $Id: tfp.c,v 1.2 1997/07/29 22:54:53 tsbogend Exp $ +/* $Id: tfp.c,v 1.4 1998/03/27 08:53:42 ralf Exp $ * tfp.c: MMU and cache routines specific to the r8000 (TFP). * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) */ - +#include <linux/init.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/mm.h> @@ -90,7 +90,7 @@ static int tfp_user_mode(struct pt_regs *regs) return regs->cp0_status & ST0_KSU == KSU_USER; } -void ld_mmu_tfp(void) +__initfunc(void ld_mmu_tfp(void)) { flush_cache_all = tfp_flush_cache_all; flush_cache_mm = tfp_flush_cache_mm; diff --git a/arch/mips/sgi/kernel/indy_hpc.c b/arch/mips/sgi/kernel/indy_hpc.c index 92d0ba669..eb00fe55c 100644 --- a/arch/mips/sgi/kernel/indy_hpc.c +++ b/arch/mips/sgi/kernel/indy_hpc.c @@ -1,8 +1,11 @@ -/* $Id: indy_hpc.c,v 1.4 1996/06/29 07:06:50 dm Exp $ +/* * indy_hpc.c: Routines for generic manipulation of the HPC controllers. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * + * $Id: indy_hpc.c,v 1.2 1998/03/27 08:53:43 ralf Exp $ */ +#include <linux/init.h> #include <asm/addrspace.h> #include <asm/ptrace.h> @@ -38,7 +41,7 @@ void sgihpc_write2_modify(int set, int clear) hpc3mregs->write2 = write2; } -void sgihpc_init(void) +__initfunc(void sgihpc_init(void)) { unsigned long sid, crev, brev; diff --git a/arch/mips/sgi/kernel/indy_int.c b/arch/mips/sgi/kernel/indy_int.c index 0726ee179..950744328 100644 --- a/arch/mips/sgi/kernel/indy_int.c +++ b/arch/mips/sgi/kernel/indy_int.c @@ -4,10 +4,10 @@ * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: indy_int.c,v 1.5 1997/12/01 17:57:38 ralf Exp $ + * $Id: indy_int.c,v 1.6 1998/03/17 22:07:41 ralf Exp $ */ #include <linux/config.h> - +#include <linux/init.h> #include <linux/errno.h> #include <linux/kernel_stat.h> #include <linux/signal.h> @@ -417,7 +417,7 @@ void free_irq(unsigned int irq, void *dev_id) printk("Trying to free free IRQ%d\n",irq); } -void init_IRQ(void) +__initfunc(void init_IRQ(void)) { irq_setup(); } @@ -495,7 +495,7 @@ int probe_irq_off (unsigned long irqs) return 0; } -void sgint_init(void) +__initfunc(void sgint_init(void)) { int i; #ifdef CONFIG_REMOTE_DEBUG diff --git a/arch/mips/sgi/kernel/indy_mc.c b/arch/mips/sgi/kernel/indy_mc.c index 449bb5b41..c34cc48f2 100644 --- a/arch/mips/sgi/kernel/indy_mc.c +++ b/arch/mips/sgi/kernel/indy_mc.c @@ -1,8 +1,11 @@ -/* $Id: indy_mc.c,v 1.5 1996/06/29 07:06:51 dm Exp $ +/* * indy_mc.c: Routines for manipulating the INDY memory controller. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * + * $Id: indy_mc.c,v 1.2 1998/03/27 08:53:44 ralf Exp $ */ +#include <linux/init.h> #include <asm/addrspace.h> #include <asm/ptrace.h> @@ -43,7 +46,7 @@ static inline char *mconfig_string(unsigned long val) }; } -void sgimc_init(void) +__initfunc(void sgimc_init(void)) { unsigned long tmpreg; diff --git a/arch/mips/sgi/kernel/indy_sc.c b/arch/mips/sgi/kernel/indy_sc.c index 3cee74968..b7466339a 100644 --- a/arch/mips/sgi/kernel/indy_sc.c +++ b/arch/mips/sgi/kernel/indy_sc.c @@ -4,10 +4,10 @@ * Copyright (C) 1997 Ralf Baechle (ralf@gnu.org), * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com). * - * $Id: indy_sc.c,v 1.5 1998/03/26 07:33:13 ralf Exp $ + * $Id: indy_sc.c,v 1.2 1998/03/27 04:47:57 ralf Exp $ */ #include <linux/config.h> - +#include <linux/init.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/mm.h> @@ -161,7 +161,7 @@ static void indy_sc_disable(void) " : "=r" (tmp1), "=r" (tmp2), "=r" (tmp3)); } -static inline int indy_sc_probe(void) +__initfunc(static inline int indy_sc_probe(void)) { volatile unsigned int *cpu_control; unsigned short cmd = 0xc220; @@ -257,7 +257,7 @@ struct bcache_ops indy_sc_ops = { indy_sc_wback_invalidate }; -void indy_sc_init(void) +__initfunc(void indy_sc_init(void)) { if (indy_sc_probe()) { indy_sc_enable(); diff --git a/arch/mips/sgi/kernel/indy_timer.c b/arch/mips/sgi/kernel/indy_timer.c index 7d9e041f3..a1270e7f3 100644 --- a/arch/mips/sgi/kernel/indy_timer.c +++ b/arch/mips/sgi/kernel/indy_timer.c @@ -3,10 +3,10 @@ * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: indy_timer.c,v 1.6 1998/03/17 22:07:41 ralf Exp $ + * $Id: indy_timer.c,v 1.7 1998/03/22 23:27:17 ralf Exp $ */ - #include <linux/errno.h> +#include <linux/init.h> #include <linux/sched.h> #include <linux/kernel.h> #include <linux/param.h> @@ -195,7 +195,7 @@ static inline unsigned long mktime(unsigned int year, unsigned int mon, )*60 + sec; /* finally seconds */ } -unsigned long get_indy_time(void) +__initfunc(static unsigned long get_indy_time(void)) { struct indy_clock *clock = INDY_CLOCK_REGS; unsigned int year, mon, day, hour, min, sec; @@ -240,7 +240,7 @@ unsigned long get_indy_time(void) #define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5) -void indy_timer_init(void) +__initfunc(void indy_timer_init(void)) { struct sgi_ioc_timers *p; volatile unsigned char *tcwp, *tc2p; @@ -307,4 +307,3 @@ void do_settimeofday(struct timeval *tv) time_esterror = MAXPHASE; sti(); } - diff --git a/arch/mips/sgi/kernel/setup.c b/arch/mips/sgi/kernel/setup.c index c8c8afc89..6b2c1846e 100644 --- a/arch/mips/sgi/kernel/setup.c +++ b/arch/mips/sgi/kernel/setup.c @@ -3,8 +3,9 @@ * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: setup.c,v 1.6 1997/12/01 17:57:38 ralf Exp $ + * $Id: setup.c,v 1.7 1998/03/04 08:47:27 ralf Exp $ */ +#include <linux/init.h> #include <linux/kernel.h> #include <linux/sched.h> @@ -50,7 +51,7 @@ static unsigned char sgi_read_status(void) return sgi_kh->command; } -static void sgi_keyboard_setup(void) +__initfunc(static void sgi_keyboard_setup(void)) { kbd_read_input = sgi_read_input; kbd_write_output = sgi_write_output; @@ -58,12 +59,12 @@ static void sgi_keyboard_setup(void) kbd_read_status = sgi_read_status; } -static void sgi_irq_setup(void) +__initfunc(static void sgi_irq_setup(void)) { sgint_init(); } -void sgi_setup(void) +__initfunc(void sgi_setup(void)) { char *ctype; diff --git a/arch/mips/sgi/kernel/system.c b/arch/mips/sgi/kernel/system.c index affb009f2..f27d2ce05 100644 --- a/arch/mips/sgi/kernel/system.c +++ b/arch/mips/sgi/kernel/system.c @@ -3,8 +3,9 @@ * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: system.c,v 1.3 1997/09/13 02:19:18 ralf Exp $ + * $Id: system.c,v 1.4 1997/12/01 17:57:39 ralf Exp $ */ +#include <linux/init.h> #include <linux/kernel.h> #include <linux/types.h> #include <linux/string.h> @@ -56,7 +57,7 @@ static struct smatch sgi_cputable[] = { #define NUM_CPUS 9 /* for now */ -static enum sgi_mach string_to_mach(char *s) +__initfunc(static enum sgi_mach string_to_mach(char *s)) { int i; @@ -71,7 +72,7 @@ static enum sgi_mach string_to_mach(char *s) return (enum sgi_mach) 0; } -static int string_to_cpu(char *s) +__initfunc(static int string_to_cpu(char *s)) { int i; @@ -90,7 +91,7 @@ static int string_to_cpu(char *s) * We' call this early before loadmmu(). If we do the other way around * the firmware will crash and burn. */ -void sgi_sysinit(void) +__initfunc(void sgi_sysinit(void)) { pcomponent *p, *toplev, *cpup = 0; int cputype = -1; diff --git a/arch/mips/sgi/kernel/time.c b/arch/mips/sgi/kernel/time.c index 1f5137c27..7dc5a4d53 100644 --- a/arch/mips/sgi/kernel/time.c +++ b/arch/mips/sgi/kernel/time.c @@ -1,13 +1,14 @@ -/* $Id: time.c,v 1.1 1996/06/08 12:07:08 dm Exp $ +/* $Id: time.c,v 1.2 1998/03/27 08:53:45 ralf Exp $ * time.c: Generic SGI time_init() code, this will dispatch to the * appropriate per-architecture time/counter init code. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) */ +#include <linux/init.h> extern void indy_timer_init(void); -void time_init(void) +__initfunc(void time_init(void)) { /* XXX assume INDY for now XXX */ indy_timer_init(); diff --git a/arch/mips/sgi/prom/cmdline.c b/arch/mips/sgi/prom/cmdline.c index 35b6b48ac..43f1c315c 100644 --- a/arch/mips/sgi/prom/cmdline.c +++ b/arch/mips/sgi/prom/cmdline.c @@ -1,9 +1,11 @@ -/* $Id: cmdline.c,v 1.1.1.1 1997/06/01 03:16:40 ralf Exp $ +/* * cmdline.c: Kernel command line creation using ARCS argc/argv. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * + * $Id: cmdline.c,v 1.3 1998/03/27 08:53:46 ralf Exp $ */ - +#include <linux/init.h> #include <linux/kernel.h> #include <linux/string.h> @@ -14,7 +16,7 @@ extern char arcs_cmdline[CL_SIZE]; -char *prom_getcmdline(void) +__initfunc(char *prom_getcmdline(void)) { return &(arcs_cmdline[0]); } @@ -29,7 +31,7 @@ static char *ignored[] = { }; #define NENTS(foo) ((sizeof((foo)) / (sizeof((foo[0]))))) -void prom_init_cmdline(void) +__initfunc(void prom_init_cmdline(void)) { char *cp; int actr, i; diff --git a/arch/mips/sgi/prom/console.c b/arch/mips/sgi/prom/console.c index 3f4d69f45..bfbba24e4 100644 --- a/arch/mips/sgi/prom/console.c +++ b/arch/mips/sgi/prom/console.c @@ -1,12 +1,14 @@ -/* $Id: console.c,v 1.1 1996/06/04 00:57:05 dm Exp $ +/* * console.c: SGI arcs console code. * * Copyright (C) 1996 David S. Miller (dm@sgi.com) + * + * $Id: console.c,v 1.2 1998/03/27 08:53:46 ralf Exp $ */ - +#include <linux/init.h> #include <asm/sgialib.h> -void prom_putchar(char c) +__initfunc(void prom_putchar(char c)) { long cnt; char it = c; @@ -14,7 +16,7 @@ void prom_putchar(char c) romvec->write(1, &it, 1, &cnt); } -char prom_getchar(void) +__initfunc(char prom_getchar(void)) { long cnt; char c; diff --git a/arch/mips/sgi/prom/env.c b/arch/mips/sgi/prom/env.c index 5aff47efd..c972c8400 100644 --- a/arch/mips/sgi/prom/env.c +++ b/arch/mips/sgi/prom/env.c @@ -1,20 +1,22 @@ -/* $Id: env.c,v 1.2 1996/06/08 04:48:41 dm Exp $ +/* * env.c: ARCS environment variable routines. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * + * $Id: env.c,v 1.2 1998/03/27 08:53:46 ralf Exp $ */ - +#include <linux/init.h> #include <linux/kernel.h> #include <linux/string.h> #include <asm/sgialib.h> -char *prom_getenv(char *name) +__initfunc(char *prom_getenv(char *name)) { return romvec->get_evar(name); } -long prom_setenv(char *name, char *value) +__initfunc(long prom_setenv(char *name, char *value)) { return romvec->set_evar(name, value); } diff --git a/arch/mips/sgi/prom/file.c b/arch/mips/sgi/prom/file.c index b62d33dda..b8911d595 100644 --- a/arch/mips/sgi/prom/file.c +++ b/arch/mips/sgi/prom/file.c @@ -1,58 +1,59 @@ -/* $Id: file.c,v 1.1 1996/06/08 04:47:22 dm Exp $ +/* * file.c: ARCS firmware interface to files. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * + * $Id: file.c,v 1.2 1998/03/27 08:53:47 ralf Exp $ */ - +#include <linux/init.h> #include <asm/sgialib.h> -long prom_getvdirent(unsigned long fd, struct linux_vdirent *ent, unsigned long num, - unsigned long *cnt) +__initfunc(long prom_getvdirent(unsigned long fd, struct linux_vdirent *ent, unsigned long num, unsigned long *cnt)) { return romvec->get_vdirent(fd, ent, num, cnt); } -long prom_open(char *name, enum linux_omode md, unsigned long *fd) +__initfunc(long prom_open(char *name, enum linux_omode md, unsigned long *fd)) { return romvec->open(name, md, fd); } -long prom_close(unsigned long fd) +__initfunc(long prom_close(unsigned long fd)) { return romvec->close(fd); } -long prom_read(unsigned long fd, void *buf, unsigned long num, unsigned long *cnt) +__initfunc(long prom_read(unsigned long fd, void *buf, unsigned long num, unsigned long *cnt)) { return romvec->read(fd, buf, num, cnt); } -long prom_getrstatus(unsigned long fd) +__initfunc(long prom_getrstatus(unsigned long fd)) { return romvec->get_rstatus(fd); } -long prom_write(unsigned long fd, void *buf, unsigned long num, unsigned long *cnt) +__initfunc(long prom_write(unsigned long fd, void *buf, unsigned long num, unsigned long *cnt)) { return romvec->write(fd, buf, num, cnt); } -long prom_seek(unsigned long fd, struct linux_bigint *off, enum linux_seekmode sm) +__initfunc(long prom_seek(unsigned long fd, struct linux_bigint *off, enum linux_seekmode sm)) { return romvec->seek(fd, off, sm); } -long prom_mount(char *name, enum linux_mountops op) +__initfunc(long prom_mount(char *name, enum linux_mountops op)) { return romvec->mount(name, op); } -long prom_getfinfo(unsigned long fd, struct linux_finfo *buf) +__initfunc(long prom_getfinfo(unsigned long fd, struct linux_finfo *buf)) { return romvec->get_finfo(fd, buf); } -long prom_setfinfo(unsigned long fd, unsigned long flags, unsigned long msk) +__initfunc(long prom_setfinfo(unsigned long fd, unsigned long flags, unsigned long msk)) { return romvec->set_finfo(fd, flags, msk); } diff --git a/arch/mips/sgi/prom/init.c b/arch/mips/sgi/prom/init.c index 6b6167efd..c18d5deb2 100644 --- a/arch/mips/sgi/prom/init.c +++ b/arch/mips/sgi/prom/init.c @@ -1,9 +1,11 @@ -/* $Id: init.c,v 1.6 1996/06/10 16:38:33 dm Exp $ +/* * init.c: PROM library initialisation code. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * + * $Id: init.c,v 1.2 1998/03/27 08:53:47 ralf Exp $ */ - +#include <linux/init.h> #include <linux/kernel.h> #include <asm/sgialib.h> @@ -19,7 +21,7 @@ unsigned short prom_vers, prom_rev; extern void prom_testtree(void); -int prom_init(int argc, char **argv, char **envp) +__initfunc(int prom_init(int argc, char **argv, char **envp)) { struct linux_promblock *pb; diff --git a/arch/mips/sgi/prom/memory.c b/arch/mips/sgi/prom/memory.c index cb392a805..b6a212f87 100644 --- a/arch/mips/sgi/prom/memory.c +++ b/arch/mips/sgi/prom/memory.c @@ -1,10 +1,12 @@ -/* $Id: memory.c,v 1.5 1996/06/10 16:38:33 dm Exp $ +/* * memory.c: PROM library functions for acquiring/using memory descriptors * given to us from the ARCS firmware. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * + * $Id: memory.c,v 1.2 1998/03/27 08:53:47 ralf Exp $ */ - +#include <linux/init.h> #include <linux/kernel.h> #include <linux/types.h> #include <linux/sched.h> @@ -18,7 +20,7 @@ /* #define DEBUG */ -struct linux_mdesc *prom_getmdesc(struct linux_mdesc *curr) +__initfunc(struct linux_mdesc *prom_getmdesc(struct linux_mdesc *curr)) { return romvec->get_mdesc(curr); } @@ -38,12 +40,12 @@ static char *mtypes[8] = { static struct prom_pmemblock prom_pblocks[PROM_MAX_PMEMBLOCKS]; -struct prom_pmemblock *prom_getpblock_array(void) +__initfunc(struct prom_pmemblock *prom_getpblock_array(void)) { return &prom_pblocks[0]; } -static void prom_setup_memupper(void) +__initfunc(static void prom_setup_memupper(void)) { struct prom_pmemblock *p, *highest; @@ -60,7 +62,7 @@ static void prom_setup_memupper(void) #endif } -void prom_meminit(void) +__initfunc(void prom_meminit(void)) { struct linux_mdesc *p; int totram; @@ -104,7 +106,7 @@ void prom_meminit(void) } /* Called from mem_init() to fixup the mem_map page settings. */ -void prom_fixup_mem_map(unsigned long start, unsigned long end) +__initfunc(void prom_fixup_mem_map(unsigned long start, unsigned long end)) { struct prom_pmemblock *p; int i, nents; diff --git a/arch/mips/sgi/prom/misc.c b/arch/mips/sgi/prom/misc.c index b6ccd60c1..8d7c300c7 100644 --- a/arch/mips/sgi/prom/misc.c +++ b/arch/mips/sgi/prom/misc.c @@ -2,8 +2,11 @@ * misc.c: Miscellaneous ARCS PROM routines. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * + * $Id: misc.c,v 1.5 1998/03/27 08:53:47 ralf Exp $ */ #include <linux/config.h> +#include <linux/init.h> #include <linux/kernel.h> #include <asm/bcache.h> @@ -82,7 +85,7 @@ struct linux_sysid *prom_getsysid(void) return romvec->get_sysid(); } -void prom_cacheflush(void) +__initfunc(void prom_cacheflush(void)) { romvec->cache_flush(); } diff --git a/arch/mips/sgi/prom/printf.c b/arch/mips/sgi/prom/printf.c index 02e7e4734..dbc0c8dc1 100644 --- a/arch/mips/sgi/prom/printf.c +++ b/arch/mips/sgi/prom/printf.c @@ -1,18 +1,19 @@ -/* $Id: printf.c,v 1.1 1996/06/04 00:57:06 dm Exp $ +/* * printf.c: Putting things on the screen using SGI arcs * PROM facilities. * * Copyright (C) 1996 David S. Miller (dm@sgi.com) + * + * $Id: printf.c,v 1.2 1998/03/27 08:53:48 ralf Exp $ */ - +#include <linux/init.h> #include <linux/kernel.h> #include <asm/sgialib.h> static char ppbuf[1024]; -void -prom_printf(char *fmt, ...) +__initfunc(void prom_printf(char *fmt, ...)) { va_list args; char ch, *bptr; diff --git a/arch/mips/sgi/prom/salone.c b/arch/mips/sgi/prom/salone.c index 4f120af3a..f363aedeb 100644 --- a/arch/mips/sgi/prom/salone.c +++ b/arch/mips/sgi/prom/salone.c @@ -1,24 +1,25 @@ -/* $Id: salone.c,v 1.1 1996/06/08 04:47:22 dm Exp $ +/* * salone.c: Routines to load into memory and execute stand-along * program images using ARCS PROM firmware. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * + * $Id: salone.c,v 1.2 1998/03/27 08:53:48 ralf Exp $ */ - +#include <linux/init.h> #include <asm/sgialib.h> -long prom_load(char *name, unsigned long end, unsigned long *pc, unsigned long *eaddr) +__initfunc(long prom_load(char *name, unsigned long end, unsigned long *pc, unsigned long *eaddr)) { return romvec->load(name, end, pc, eaddr); } -long prom_invoke(unsigned long pc, unsigned long sp, long argc, - char **argv, char **envp) +__initfunc(long prom_invoke(unsigned long pc, unsigned long sp, long argc, char **argv, char **envp)) { return romvec->invoke(pc, sp, argc, argv, envp); } -long prom_exec(char *name, long argc, char **argv, char **envp) +__initfunc(long prom_exec(char *name, long argc, char **argv, char **envp)) { return romvec->exec(name, argc, argv, envp); } diff --git a/arch/mips/sgi/prom/tags.c b/arch/mips/sgi/prom/tags.c index d408822d0..1de56376d 100644 --- a/arch/mips/sgi/prom/tags.c +++ b/arch/mips/sgi/prom/tags.c @@ -1,10 +1,12 @@ -/* $Id: tags.c,v 1.5 1996/06/24 07:12:22 dm Exp $ +/* * tags.c: Initialize the arch tags the way the MIPS kernel setup * expects. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * + * $Id: tags.c,v 1.2 1998/03/27 08:53:48 ralf Exp $ */ - +#include <linux/init.h> #include <linux/kernel.h> #include <linux/string.h> @@ -43,7 +45,7 @@ tag_def taglist_sgi_indy[] = { /* XXX COLOSTOMY BAG!!!! XXX */ }; -void prom_setup_archtags(void) +__initfunc(void prom_setup_archtags(void)) { tag_def *tdp = &taglist_sgi_indy[0]; tag *tp; diff --git a/arch/mips/sgi/prom/time.c b/arch/mips/sgi/prom/time.c index 9a836b810..616e253bf 100644 --- a/arch/mips/sgi/prom/time.c +++ b/arch/mips/sgi/prom/time.c @@ -1,17 +1,19 @@ -/* $Id: time.c,v 1.1 1996/06/08 04:47:23 dm Exp $ +/* * time.c: Extracting time information from ARCS prom. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * + * $Id: time.c,v 1.2 1998/03/27 08:53:49 ralf Exp $ */ - +#include <linux/init.h> #include <asm/sgialib.h> -struct linux_tinfo *prom_gettinfo(void) +__initfunc(struct linux_tinfo *prom_gettinfo(void)) { return romvec->get_tinfo(); } -unsigned long prom_getrtime(void) +__initfunc(unsigned long prom_getrtime(void)) { return romvec->get_rtime(); } diff --git a/arch/mips/sgi/prom/tree.c b/arch/mips/sgi/prom/tree.c index 1cefd4964..414e1dacd 100644 --- a/arch/mips/sgi/prom/tree.c +++ b/arch/mips/sgi/prom/tree.c @@ -1,48 +1,50 @@ -/* $Id: tree.c,v 1.4 1996/06/08 04:48:41 dm Exp $ +/* * tree.c: PROM component device tree code. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * + * $Id: tree.c,v 1.2 1998/03/27 08:53:49 ralf Exp $ */ - +#include <linux/init.h> #include <asm/sgialib.h> #define DEBUG_PROM_TREE -pcomponent *prom_getsibling(pcomponent *this) +__initfunc(pcomponent *prom_getsibling(pcomponent *this)) { if(this == PROM_NULL_COMPONENT) return PROM_NULL_COMPONENT; return romvec->next_component(this); } -pcomponent *prom_getchild(pcomponent *this) +__initfunc(pcomponent *prom_getchild(pcomponent *this)) { return romvec->child_component(this); } -pcomponent *prom_getparent(pcomponent *child) +__initfunc(pcomponent *prom_getparent(pcomponent *child)) { if(child == PROM_NULL_COMPONENT) return PROM_NULL_COMPONENT; return romvec->parent_component(child); } -long prom_getcdata(void *buffer, pcomponent *this) +__initfunc(long prom_getcdata(void *buffer, pcomponent *this)) { return romvec->component_data(buffer, this); } -pcomponent *prom_childadd(pcomponent *this, pcomponent *tmp, void *data) +__initfunc(pcomponent *prom_childadd(pcomponent *this, pcomponent *tmp, void *data)) { return romvec->child_add(this, tmp, data); } -long prom_delcomponent(pcomponent *this) +__initfunc(long prom_delcomponent(pcomponent *this)) { return romvec->comp_del(this); } -pcomponent *prom_componentbypath(char *path) +__initfunc(pcomponent *prom_componentbypath(char *path)) { return romvec->component_by_path(path); } @@ -72,7 +74,7 @@ static char *iflags[] = { "input", "output" }; -static void dump_component(pcomponent *p) +__initfunc(static void dump_component(pcomponent *p)) { prom_printf("[%p]:class<%s>type<%s>flags<%s>ver<%d>rev<%d>", p, classes[p->class], types[p->type], @@ -81,7 +83,7 @@ static void dump_component(pcomponent *p) p->key, p->amask, (int)p->cdsize, (int)p->ilen, p->iname); } -static void traverse(pcomponent *p, int op) +__initfunc(static void traverse(pcomponent *p, int op)) { dump_component(p); if(prom_getchild(p)) @@ -90,7 +92,7 @@ static void traverse(pcomponent *p, int op) traverse(prom_getsibling(p), 1); } -void prom_testtree(void) +__initfunc(void prom_testtree(void)) { pcomponent *p; diff --git a/arch/mips/sni/hw-access.c b/arch/mips/sni/hw-access.c index 5bc31e103..744518971 100644 --- a/arch/mips/sni/hw-access.c +++ b/arch/mips/sni/hw-access.c @@ -5,11 +5,12 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1996, 1997 by Ralf Baechle + * Copyright (C) 1996, 1997, 1998 by Ralf Baechle * - * $Id: hw-access.c,v 1.3 1997/07/29 17:46:46 ralf Exp $ + * $Id: hw-access.c,v 1.3 1997/12/01 17:57:39 ralf Exp $ */ #include <linux/delay.h> +#include <linux/init.h> #include <linux/kbdcntrlr.h> #include <linux/kernel.h> #include <linux/linkage.h> @@ -182,7 +183,7 @@ static unsigned char sni_read_status(void) return inb(KBD_STATUS_REG); } -void sni_rm200_keyboard_setup(void) +__initfunc(void sni_rm200_keyboard_setup(void)) { kbd_read_input = sni_read_input; kbd_write_output = sni_write_output; diff --git a/arch/mips/sni/io.c b/arch/mips/sni/io.c index f62fdc2d7..8a97b80a8 100644 --- a/arch/mips/sni/io.c +++ b/arch/mips/sni/io.c @@ -4,6 +4,8 @@ * for more details. * * Low level I/O functions for SNI. + * + * $Id: io.c,v 1.2 1998/03/27 08:53:50 ralf Exp $ */ #include <linux/string.h> #include <asm/mipsconfig.h> diff --git a/arch/mips/sni/pci.c b/arch/mips/sni/pci.c index 8c2d773cd..e2255b127 100644 --- a/arch/mips/sni/pci.c +++ b/arch/mips/sni/pci.c @@ -5,11 +5,10 @@ * * SNI specific PCI support for RM200/RM300. * - * $Id: pci.c,v 1.3 1998/01/14 05:01:51 ralf Exp $ + * $Id: pci.c,v 1.3 1998/03/04 08:47:29 ralf Exp $ */ #include <linux/config.h> #include <linux/bios32.h> -#include <linux/init.h> #include <linux/pci.h> #include <linux/types.h> #include <asm/byteorder.h> diff --git a/arch/mips/tools/offset.c b/arch/mips/tools/offset.c index 9474472c9..3ccd434d3 100644 --- a/arch/mips/tools/offset.c +++ b/arch/mips/tools/offset.c @@ -4,7 +4,7 @@ * Copyright (C) 1996 David S. Miller * Made portable by Ralf Baechle * - * $Id: offset.c,v 1.7 1998/03/26 07:28:02 ralf Exp $ + * $Id: offset.c,v 1.6 1998/03/27 04:47:58 ralf Exp $ */ #include <linux/types.h> @@ -104,7 +104,6 @@ void output_thread_defines(void) offset("#define THREAD_BVADDR ", struct task_struct, tss.cp0_badvaddr); offset("#define THREAD_ECODE ", struct task_struct, tss.error_code); offset("#define THREAD_TRAPNO ", struct task_struct, tss.trap_no); - offset("#define THREAD_KSP ", struct task_struct, tss.ksp); offset("#define THREAD_PGDIR ", struct task_struct, tss.pg_dir); offset("#define THREAD_MFLAGS ", struct task_struct, tss.mflags); offset("#define THREAD_CURDS ", struct task_struct, tss.current_ds); |