diff options
author | Harald Koerfgen <hkoerfg@web.de> | 1999-07-26 19:42:38 +0000 |
---|---|---|
committer | Harald Koerfgen <hkoerfg@web.de> | 1999-07-26 19:42:38 +0000 |
commit | 14ab59aa8aba8687dc957c2186e115ac0b8ab542 (patch) | |
tree | c2eb55db21b6b46ddd983e2d40196fa61f19b64c | |
parent | 552f7f2f262b8ea12edc36f9a260b068bd10f423 (diff) |
The remaining R3000 changes. From now on the CVS will be R3000 aware. R3000 Indigo anyone? :-)
-rw-r--r-- | CREDITS | 6 | ||||
-rw-r--r-- | Documentation/Configure.help | 27 | ||||
-rw-r--r-- | arch/mips/kernel/entry.S | 32 | ||||
-rw-r--r-- | arch/mips/kernel/head.S | 29 | ||||
-rw-r--r-- | arch/mips/kernel/process.c | 10 | ||||
-rw-r--r-- | arch/mips/kernel/ptrace.c | 7 | ||||
-rw-r--r-- | arch/mips/kernel/scall_o32.S | 24 | ||||
-rw-r--r-- | arch/mips/kernel/traps.c | 153 | ||||
-rw-r--r-- | arch/mips/mm/r2300.c | 13 | ||||
-rw-r--r-- | drivers/net/declance.c | 6 | ||||
-rw-r--r-- | drivers/scsi/NCR53C9x.c | 22 | ||||
-rw-r--r-- | drivers/tc/zs.c | 11 | ||||
-rw-r--r-- | include/asm-mips/atomic.h | 30 | ||||
-rw-r--r-- | include/asm-mips/bitops.h | 4 | ||||
-rw-r--r-- | include/asm-mips/current.h | 4 | ||||
-rw-r--r-- | include/asm-mips/fp.h | 10 | ||||
-rw-r--r-- | include/asm-mips/mipsregs.h | 10 | ||||
-rw-r--r-- | include/asm-mips/pgtable.h | 166 | ||||
-rw-r--r-- | include/asm-mips/ptrace.h | 5 | ||||
-rw-r--r-- | include/asm-mips/semaphore-helper.h | 62 | ||||
-rw-r--r-- | include/asm-mips/semaphore.h | 16 | ||||
-rw-r--r-- | include/asm-mips/softirq.h | 11 | ||||
-rw-r--r-- | include/asm-mips/stackframe.h | 55 | ||||
-rw-r--r-- | include/asm-mips/system.h | 39 |
24 files changed, 557 insertions, 195 deletions
@@ -1116,6 +1116,12 @@ N: Andreas Koensgen E: ajk@iehk.rwth-aachen.de D: 6pack driver for AX.25 +N: Harald Koerfgen +E: harald@unix-ag.org +D: DECstation port +S: D-50931 Koeln +S: Germany + N: Willy Konynenberg E: willy@xos.nl W: http://www.xos.nl/ diff --git a/Documentation/Configure.help b/Documentation/Configure.help index 4bcfad3cd..43f57df7c 100644 --- a/Documentation/Configure.help +++ b/Documentation/Configure.help @@ -1233,7 +1233,18 @@ CONFIG_BAGET_MIPS Support for DECstations CONFIG_DECSTATION This enables support for DEC's MIPS based workstations. For details - see the Linux/MIPS FAQ on http://www.linux.sgi.com. + see the Linux/MIPS FAQ on http://www.linux.sgi.com or the + DECstation porting pages on http://decstation.unix-ag.org. + + If you have one of the following DECstation Models you definitely + want to choose R4xx0 for the CPU Type: + + DECstation 5000/50 + DECstation 5000/150 + DECstation 5000/260 + DECsystem 5900/260 + + otherwise choose R3000. IDE card support CONFIG_BLK_DEV_IDE_CARDS @@ -1281,16 +1292,16 @@ CONFIG_JAZZ_ESP CPU type CONFIG_CPU_R3000 - Give the type of your machine's MIPS CPU. For this question, it - suffices to give a unique prefix of the option you want to choose. - In case of doubt select the R3000 CPU. The kernel will then run on - other MIPS machines but with slightly reduced performance. + Please make shure to pick the right CPU type. Linux/MIPS is not + designed to be generic, i.e. Kernels compiled for R3000 CPUs will + *not* work on R4000 Machines and vice versa. + However, since most the supported Machines have an R4000 (or similar) + CPU R4xx0 might be a safe bet. + If the resulting Kernel does not work try to recompile with R3000. Compile the kernel into the ECOFF object format CONFIG_ECOFF_KERNEL - Some machines require a kernel in the ECOFF format. You will have to - say Y here for example if you want to use a Mips Magnum 3000 or a - DECstation. + Oops. How di I get here? Generate little endian code CONFIG_CPU_LITTLE_ENDIAN diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S index 534cba7cf..a740bac27 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.13 1998/10/14 23:40:43 ralf Exp $ + * $Id: entry.S,v 1.14 1999/04/12 19:13:21 harald Exp $ */ /* @@ -31,23 +31,21 @@ #include <asm/regdef.h> #include <asm/fpregdef.h> #include <asm/unistd.h> +#include <asm/isadep.h> /* * Heia ... The %lo, %hi and %HI stuff is too strong for the ELF assembler * and the ABI to cope with ... */ .text - .set noreorder - .set mips3 .align 4 + .set push + .set reorder EXPORT(handle_bottom_half) jal do_bottom_half - nop b 9f - nop reschedule: jal schedule - nop EXPORT(ret_from_sys_call) EXPORT(ret_from_irq) @@ -55,22 +53,20 @@ EXPORT(ret_from_irq) lw t1,bh_active # unused delay slot and t0,t1 bnez t0,handle_bottom_half -9: lw t0,PT_STATUS(sp) # returning to kernel mode? - andi t1, t0, 0x10 +9: lw t0,PT_STATUS(sp) # returning to kernel mode? + lw t2, TASK_NEED_RESCHED($28) + andi t1, t0, KU_USER beqz t1, return # -> yes - lw t1, TASK_NEED_RESCHED($28) - bnez t1, reschedule + bnez t2, reschedule lw v0, TASK_SIGPENDING($28) move a0, zero beqz v0, return - nop - jal do_signal move a1, sp + jal do_signal EXPORT(return) .set noat - RESTORE_ALL - eret + RESTORE_ALL_AND_RET .set at /* @@ -84,7 +80,9 @@ LEAF(spurious_interrupt) * couldn't find a cause for it. */ lui t1,%hi(spurious_count) + .set reorder lw t0,%lo(spurious_count)(t1) + .set noreorder addiu t0,1 j ret_from_irq sw t0,%lo(spurious_count)(t1) @@ -107,7 +105,9 @@ LEAF(spurious_interrupt) ctc1 a2,fcr31; \ STI #define __BUILD_clear_ade(exception) \ + .set reorder; \ MFC0 t0,CP0_BADVADDR; \ + .set noreorder; \ REG_S t0,PT_BVADDR(sp); \ KMODE #define __BUILD_silent(exception) @@ -122,9 +122,9 @@ LEAF(spurious_interrupt) #define __BUILD_count(exception) \ .set reorder; \ lw t0,exception_count_##exception; \ + .set noreorder; \ addiu t0, 1; \ sw t0,exception_count_##exception; \ - .set noreorder; \ .data; \ EXPORT(exception_count_##exception); \ .word 0; \ @@ -156,6 +156,8 @@ EXPORT(exception_count_##exception); \ BUILD_HANDLER(watch,watch,sti,verbose) /* #23 */ BUILD_HANDLER(reserved,reserved,sti,verbose) /* others */ + .set pop + /* * Table of syscalls */ diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S index 1eb0ca5dc..72d42a2da 100644 --- a/arch/mips/kernel/head.S +++ b/arch/mips/kernel/head.S @@ -1,4 +1,4 @@ -/* $Id: head.S,v 1.10 1998/10/14 23:40:44 ralf Exp $ +/* $Id: head.S,v 1.11 1998/10/18 13:27:12 tsbogend Exp $ * * arch/mips/kernel/head.S * @@ -11,7 +11,7 @@ * Copyright (C) 1995, 1996, 1997, 1998 Ralf Baechle * Copyright (C) 1996 Paul M. Antoine * Modified for DECStation and hence R3000 support by Paul M. Antoine - * Further modifications by David S. Miller + * Further modifications by David S. Miller and Harald Koerfgen * * Head.S contains the MIPS exception handler and startup code. */ @@ -258,6 +258,7 @@ /* TLB refill, EXL == 0, R[23]00 version */ LEAF(except_vec0_r2300) + .set noat .set mips1 mfc0 k0, CP0_BADVADDR _GET_CURRENT(k1) # get current task ptr @@ -267,18 +268,13 @@ addu k1, k1, k0 mfc0 k0, CP0_CONTEXT lw k1, (k1) - srl k0, k0, 1 and k0, k0, 0xffc addu k1, k1, k0 lw k0, (k1) - srl k0, k0, 12 + nop mtc0 k0, CP0_ENTRYLO0 mfc0 k1, CP0_EPC tlbwr - nop - nop - nop - nop jr k1 rfe END(except_vec0_r2300) @@ -371,6 +367,7 @@ handle_vcei: /* General exception vector. */ NESTED(except_vec3_generic, 0, sp) .set noat + .set mips0 mfc0 k1, CP0_CAUSE la k0, exception_handlers andi k1, k1, 0x7c @@ -408,6 +405,14 @@ NESTED(kernel_entry, 16, sp) probe_done: + /* + * Stack for kernel and init, current variable + */ + la $28, init_task_union + addiu t0, $28, KERNEL_STACK_SIZE-32 + sw t0, kernelsp + subu sp, t0, 4*SZREG + /* The firmware/bootloader passes argc/argp/envp * to us as arguments. But clear bss first because * the romvec and other important info is stored there @@ -441,14 +446,6 @@ probe_done: jal loadmmu nop - /* - * Stack for kernel and init, current variable - */ - la $28, init_task_union - addiu t0, $28, KERNEL_STACK_SIZE-32 - sw t0, kernelsp - subu sp, t0, 4*SZREG - /* Disable coprocessors */ mfc0 t0, CP0_STATUS li t1, ~(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX) diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index a4f64b5fb..04e6dc191 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.11 1999/01/03 17:50:51 ralf Exp $ +/* $Id: process.c,v 1.12 1999/06/17 13:25:46 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -28,6 +28,7 @@ #include <asm/uaccess.h> #include <asm/io.h> #include <asm/elf.h> +#include <asm/isadep.h> struct task_struct *last_task_used_math = NULL; @@ -39,7 +40,7 @@ asmlinkage void ret_from_sys_call(void); void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) { /* New thread looses kernel privileges. */ - regs->cp0_status = (regs->cp0_status & ~(ST0_CU0|ST0_KSU)) | KSU_USER; + regs->cp0_status = (regs->cp0_status & ~(ST0_CU0|KU_MASK)) | KU_USER; regs->cp0_epc = pc; regs->regs[29] = sp; current->tss.current_ds = USER_DS; @@ -74,12 +75,13 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, { struct pt_regs * childregs; long childksp; + extern void (*save_fp)(struct sigcontext *); 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); + save_fp(p); } /* set up new TSS. */ childregs = (struct pt_regs *) childksp - 1; @@ -111,7 +113,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_CU3|ST0_CU2|ST0_CU1|KU_MASK); 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 476f331ef..77ea1a58c 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c @@ -1,4 +1,4 @@ -/* $Id: ptrace.c,v 1.12 1999/06/13 16:30:32 ralf Exp $ +/* $Id: ptrace.c,v 1.13 1999/06/17 13:25:46 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -242,6 +242,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) struct task_struct *child; unsigned int flags; int res; + extern void (*save_fp)(struct sigcontext *); lock_kernel(); #if 0 @@ -351,7 +352,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) if (last_task_used_math == child) { enable_cp1(); - r4xx0_save_fp(child); + save_fp(child); disable_cp1(); last_task_used_math = NULL; } @@ -413,7 +414,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) if (child->used_math) { if (last_task_used_math == child) { enable_cp1(); - r4xx0_save_fp(child); + save_fp(child); disable_cp1(); last_task_used_math = NULL; } diff --git a/arch/mips/kernel/scall_o32.S b/arch/mips/kernel/scall_o32.S index b31a8b18e..aa949f7ee 100644 --- a/arch/mips/kernel/scall_o32.S +++ b/arch/mips/kernel/scall_o32.S @@ -12,6 +12,7 @@ #include <asm/mipsregs.h> #include <asm/regdef.h> #include <asm/stackframe.h> +#include <asm/isadep.h> #include <asm/unistd.h> /* This duplicates the definition from <linux/sched.h> */ @@ -48,6 +49,7 @@ NESTED(handle_sys, PT_SIZE, sp) bgez t0, stackargs stack_done: + sw a3, PT_R26(sp) # save for syscall restart lw t0, TASK_FLAGS($28) # syscall tracing enabled? andi t0, PF_TRACESYS bnez t0, trace_a_syscall @@ -70,7 +72,7 @@ EXPORT(o32_ret_from_sys_call) bnez t0,o32_handle_bottom_half 9: lw t0,PT_STATUS(sp) # returning to kernel mode? - andi t1, t0, 0x10 + andi t1, t0, KU_USER lw t2, TASK_NEED_RESCHED($28) beqz t1, o32_return # -> yes bnez t2, o32_reschedule @@ -83,10 +85,7 @@ EXPORT(o32_ret_from_sys_call) o32_return: RESTORE_SOME - RESTORE_SP - .set mips3 - eret - .set mips0 + RESTORE_SP_AND_RET o32_handle_bottom_half: jal do_bottom_half @@ -140,15 +139,28 @@ stackargs: lw t0, PT_R29(sp) # get old user stack pointer la t1, 3f # copy 1 to 2 arguments - sll t3, t3, 3 + sll t3, t3, 4 subu t1, t3 jr t1 /* Ok, copy the args from the luser stack to the kernel stack */ + /* + * I know Ralf doesn't like nops but this avoids code + * duplication for R3000 targets (and this is the + * only place where ".set reorder" doesn't help). + * Harald. + */ + .set push + .set noreorder 1: lw t1, 20(t0) # argument #6 from usp + nop sw t1, 20(sp) + nop 2: lw t1, 16(t0) # argument #5 from usp + nop sw t1, 16(sp) + nop + .set pop 3: j stack_done # go back diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 757fbafc2..3cca8acb1 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -1,4 +1,4 @@ -/* $Id: traps.c,v 1.20 1999/06/13 16:30:34 ralf Exp $ +/* $Id: traps.c,v 1.21 1999/06/23 22:15:57 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -60,6 +60,15 @@ extern asmlinkage void handle_fpe(void); extern asmlinkage void handle_watch(void); extern asmlinkage void handle_reserved(void); +extern asmlinkage void r4xx0_lazy_fpu_switch(struct task_struct *); +extern asmlinkage void r4xx0_init_fpu(void); +extern asmlinkage void r4xx0_save_fp(struct sigcontext *); +extern asmlinkage void r2300_lazy_fpu_switch(struct task_struct *); +extern asmlinkage void r2300_init_fpu(void); +extern asmlinkage void r2300_save_fp(struct sigcontext *); + +extern asmlinkage void simfp(unsigned int); + static char *cpu_names[] = CPU_NAMES; char watch_available = 0; @@ -69,6 +78,10 @@ char vce_available = 0; void (*ibe_board_handler)(struct pt_regs *regs); void (*dbe_board_handler)(struct pt_regs *regs); +static void (*lazy_fpu_switch)(struct task_struct *); +static void (*init_fpu)(void); +void (*save_fp)(struct sigcontext *); + int kstack_depth_to_print = 24; /* @@ -77,6 +90,23 @@ int kstack_depth_to_print = 24; */ #define MODULE_RANGE (8*1024*1024) +#if (_MIPS_ISA == _MIPS_ISA_MIPS1) +/* + * This stuff is needed for the userland ll-sc emulation for R2300 + */ +void simulate_ll(struct pt_regs *regs, unsigned int opcode); +void simulate_sc(struct pt_regs *regs, unsigned int opcode); + +#define OPCODE 0xfc000000 +#define BASE 0x03e00000 +#define RT 0x001f0000 +#define OFFSET 0x0000ffff +#define LL 0xc0000000 +#define SC 0xd0000000 + +#define DEBUG_LLSC +#endif + /* * This routine abuses get_user()/put_user() to reference pointers * with at least a bit of error checking ... @@ -201,8 +231,10 @@ static void default_be_board_handler(struct pt_regs *regs) /* * Assume it would be too dangerous to continue ... */ - force_sig(SIGBUS, current); +/* XXX */ +printk("Got Bus Error at %08x\n", (unsigned int)regs->cp0_epc); show_regs(regs); while(1); + force_sig(SIGBUS, current); } void do_ibe(struct pt_regs *regs) @@ -345,6 +377,110 @@ void do_tr(struct pt_regs *regs) force_sig(SIGTRAP, current); } +#if (_MIPS_ISA == _MIPS_ISA_MIPS1) + +/* + * userland emulation for R2300 CPUs + * needed for the multithreading part of glibc + */ +void do_ri(struct pt_regs *regs) +{ + unsigned int opcode; + + lock_kernel(); + if (!get_insn_opcode(regs, &opcode)) { + if ((opcode & OPCODE) == LL) + simulate_ll(regs, opcode); + if ((opcode & OPCODE) == SC) + simulate_sc(regs, opcode); + } else { + printk("[%s:%ld] Illegal instruction at %08lx ra=%08lx\n", + current->comm, current->pid, regs->cp0_epc, regs->regs[31]); + } + unlock_kernel(); + if (compute_return_epc(regs)) + return; + force_sig(SIGILL, current); +} + +/* + * the ll_bit will be cleared by r2300_switch.S + */ +unsigned long ll_bit, *lladdr; + +void simulate_ll(struct pt_regs *regp, unsigned int opcode) +{ + unsigned long *addr, *vaddr; + long offset; + + /* + * analyse the ll instruction that just caused a ri exception + * and put the referenced address to addr. + */ + /* sign extend offset */ + offset = opcode & OFFSET; + if (offset & 0x00008000) + offset = -(offset & 0x00007fff); + else + offset = (offset & 0x00007fff); + + vaddr = (unsigned long *)((long)(regp->regs[(opcode & BASE) >> 21]) + offset); + +#ifdef DEBUG_LLSC + printk("ll: vaddr = 0x%08x, reg = %d\n", (unsigned int)vaddr, (opcode & RT) >> 16); +#endif + + /* + * TODO: compute physical address from vaddr + */ + panic("ll: emulation not yet finished!"); + + lladdr = addr; + ll_bit = 1; + regp->regs[(opcode & RT) >> 16] = *addr; +} + +void simulate_sc(struct pt_regs *regp, unsigned int opcode) +{ + unsigned long *addr, *vaddr, reg; + long offset; + + /* + * analyse the sc instruction that just caused a ri exception + * and put the referenced address to addr. + */ + /* sign extend offset */ + offset = opcode & OFFSET; + if (offset & 0x00008000) + offset = -(offset & 0x00007fff); + else + offset = (offset & 0x00007fff); + + vaddr = (unsigned long *)((long)(regp->regs[(opcode & BASE) >> 21]) + offset); + reg = (opcode & RT) >> 16; + +#ifdef DEBUG_LLSC + printk("sc: vaddr = 0x%08x, reg = %d\n", (unsigned int)vaddr, (unsigned int)reg); +#endif + + /* + * TODO: compute physical address from vaddr + */ + panic("sc: emulation not yet finished!"); + + lladdr = addr; + + if (ll_bit == 0) { + regp->regs[reg] = 0; + return; + } + + *addr = regp->regs[reg]; + regp->regs[reg] = 1; +} + +#else /* MIPS 2 or higher */ + void do_ri(struct pt_regs *regs) { lock_kernel(); @@ -356,6 +492,8 @@ void do_ri(struct pt_regs *regs) force_sig(SIGILL, current); } +#endif + void do_cpu(struct pt_regs *regs) { unsigned int cpid; @@ -369,10 +507,10 @@ void do_cpu(struct pt_regs *regs) return; if (current->used_math) { /* Using the FPU again. */ - r4xx0_lazy_fpu_switch(last_task_used_math); + lazy_fpu_switch(last_task_used_math); } else { /* First time FPU user. */ - r4xx0_init_fpu(); + init_fpu(); current->used_math = 1; } last_task_used_math = current; @@ -548,6 +686,9 @@ __initfunc(void trap_init(void)) save_fp_context = r4k_save_fp_context; restore_fp_context = r4k_restore_fp_context; + lazy_fpu_switch = r4xx0_lazy_fpu_switch; + init_fpu = r4xx0_init_fpu; + save_fp = r4xx0_save_fp; resume = r4xx0_resume; set_except_vector(1, r4k_handle_mod); set_except_vector(2, r4k_handle_tlbl); @@ -592,8 +733,12 @@ __initfunc(void trap_init(void)) case CPU_R3000: case CPU_R3000A: memcpy((void *)KSEG0, &except_vec0_r2300, 0x80); + memcpy((void *)(KSEG0 + 0x80), &except_vec3_generic, 0x80); save_fp_context = r2300_save_fp_context; restore_fp_context = r2300_restore_fp_context; + lazy_fpu_switch = r2300_lazy_fpu_switch; + init_fpu = r2300_init_fpu; + save_fp = r2300_save_fp; resume = r2300_resume; set_except_vector(1, r2300_handle_mod); set_except_vector(2, r2300_handle_tlbl); diff --git a/arch/mips/mm/r2300.c b/arch/mips/mm/r2300.c index 3c2cec663..6e4127e7e 100644 --- a/arch/mips/mm/r2300.c +++ b/arch/mips/mm/r2300.c @@ -7,7 +7,7 @@ * Copyright (C) 1998 Harald Koerfgen * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov * - * $Id: r2300.c,v 1.5 1998/04/05 11:23:55 ralf Exp $ + * $Id: r2300.c,v 1.8 1999/04/11 17:13:56 harald Exp $ */ #include <linux/init.h> #include <linux/kernel.h> @@ -19,13 +19,9 @@ #include <asm/mmu_context.h> #include <asm/system.h> #include <asm/sgialib.h> -#include <asm/mipsregs.h> +#include <asm/isadep.h> #include <asm/io.h> -/* - * Temporarily disabled - * #include <asm/wbflush.h> - */ /* * According to the paper written by D. Miller about Linux cache & TLB @@ -374,10 +370,7 @@ static void r3k_dma_cache_wback_inv(unsigned long start, unsigned long size) register unsigned long i, flags; register volatile unsigned char *p = (volatile unsigned char*) start; -/* - * Temporarily disabled wbflush(); - */ /* * Invalidate dcache @@ -680,7 +673,7 @@ printk("r2300_add_wired_entry"); static int r2300_user_mode(struct pt_regs *regs) { - return !(regs->cp0_status & ST0_KUP); + return !(regs->cp0_status & KU_USER); } __initfunc(void ld_mmu_r2300(void)) diff --git a/drivers/net/declance.c b/drivers/net/declance.c index b0183061c..b5c5b4f42 100644 --- a/drivers/net/declance.c +++ b/drivers/net/declance.c @@ -60,6 +60,7 @@ static char *lancestr = "LANCE"; #include <asm/dec/machtype.h> #include <asm/dec/tc.h> #include <asm/dec/kn01.h> +#include <asm/wbflush.h> #include <asm/addrspace.h> #include <linux/config.h> @@ -301,6 +302,7 @@ int dec_lance_debug = 2; static inline void writereg(volatile unsigned short *regptr, short value) { *regptr = value; + wbflush(); } /* Load the CSR registers */ @@ -380,6 +382,7 @@ void cp_to_buf(void *to, const void *from, __kernel_size_t len) } } + wbflush(); } void cp_from_buf(void *to, unsigned char *from, int len) @@ -515,6 +518,7 @@ static void lance_init_ring(struct device *dev) if (i < 3 && ZERO) printk("%d: 0x%8.8x(0x%8.8x)\n", i, leptr, (int) lp->rx_buf_ptr_cpu[i]); } + wbflush(); } static int init_restart_lance(struct lance_private *lp) @@ -752,6 +756,7 @@ static void lance_interrupt(const int irq, void *dev_id, struct pt_regs *regs) * re-enable LANCE DMA */ *(unsigned long *) (system_base + IOCTL + SSR) |= (1 << 16); + wbflush(); } writereg(&ll->rdp, LE_C0_STOP); @@ -1071,6 +1076,7 @@ __initfunc(static int dec_lance_init(struct device *dev, const int type)) lp->dma_ptr_reg = (unsigned long *) (system_base + IOCTL + LANCE_DMA_P); *(lp->dma_ptr_reg) = PHYSADDR(dev->mem_start) << 3; *(unsigned long *) (system_base + IOCTL + SSR) |= (1 << 16); + wbflush(); break; case PMAD_LANCE: diff --git a/drivers/scsi/NCR53C9x.c b/drivers/scsi/NCR53C9x.c index c997cba65..875889706 100644 --- a/drivers/scsi/NCR53C9x.c +++ b/drivers/scsi/NCR53C9x.c @@ -9,6 +9,9 @@ * * Set up to use GETREG/SETREG (preprocessor macros in NCR53c9x.h) by * Tymm Twillman (tymm@coe.missouri.edu) + * + * Support for IOASIC DECstations by + * Harald Koerfgen (harald@unix-ag.org) */ /* TODO: @@ -52,6 +55,13 @@ #undef SYMBIOS_HACK #endif +#ifdef CONFIG_DECSTATION +/* IOASIC DECstations only! */ +#include <asm/wbflush.h> +#else +#define wbflush() +#endif + #include <asm/system.h> #include <asm/ptrace.h> #include <asm/pgtable.h> @@ -302,6 +312,7 @@ extern inline void esp_cmd(struct NCR_ESP *esp, struct ESP_regs *eregs, esp->espcmdent = (esp->espcmdent + 1) & 31; #endif SETREG(eregs->esp_cmnd, cmd); + wbflush(); } /* How we use the various Linux SCSI data structures for operation. @@ -442,6 +453,7 @@ static inline void esp_reset_esp(struct NCR_ESP *esp, struct ESP_regs *eregs) SETREG(eregs->esp_timeo, esp->neg_defp); esp->max_period = (esp->max_period + 3)>>2; esp->min_period = (esp->min_period + 3)>>2; + wbflush(); SETREG(eregs->esp_cfg1, esp->config1); switch(esp->erev) { @@ -492,6 +504,7 @@ static inline void esp_reset_esp(struct NCR_ESP *esp, struct ESP_regs *eregs) panic("esp: what could it be... I wonder..."); break; }; + wbflush(); /* Eat any bitrot in the chip */ trash = GETREG(eregs->esp_intrpt); @@ -515,6 +528,7 @@ inline void esp_bootup_reset(struct NCR_ESP *esp, struct ESP_regs *eregs) esp_cmd(esp, eregs, ESP_CMD_RS); udelay(400); SETREG(eregs->esp_cfg1, esp->config1); + wbflush(); /* Eat any bitrot in the chip and we are done... */ trash = GETREG(eregs->esp_intrpt); @@ -655,6 +669,7 @@ void esp_initialize(struct NCR_ESP *esp) esp->config1 = (ESP_CONFIG1_PENABLE | (esp->scsi_id & 7)); esp->config2 = (ESP_CONFIG2_SCSI2ENAB | ESP_CONFIG2_REGPARITY); SETREG(eregs->esp_cfg2, esp->config2); + wbflush(); #ifndef SYMBIOS_HACK if((GETREG(eregs->esp_cfg2) & ~(ESP_CONFIG2_MAGIC)) != (ESP_CONFIG2_SCSI2ENAB | ESP_CONFIG2_REGPARITY)) { @@ -667,6 +682,7 @@ void esp_initialize(struct NCR_ESP *esp) SETREG(eregs->esp_cfg3, 0); esp->config3[0] = 5; SETREG(eregs->esp_cfg3, esp->config3[0]); + wbflush(); #ifndef SYMBIOS_HACK if(GETREG(eregs->esp_cfg3) != 5) { printk("NCR53C90A(esp100a) detected\n"); @@ -695,6 +711,7 @@ void esp_initialize(struct NCR_ESP *esp) esp->config2 = 0; SETREG(eregs->esp_cfg2, esp->config2); } + wbflush(); } #endif } @@ -1676,6 +1693,7 @@ static inline void esp_setcount(struct ESP_regs *eregs, int cnt, int hme) SETREG(eregs->fas_rlo, 0); SETREG(eregs->fas_rhi, 0); } + wbflush(); } static inline int esp_getcount(struct ESP_regs *eregs) @@ -1831,6 +1849,7 @@ static inline void esp_connect(struct NCR_ESP *esp, struct ESP_regs *eregs, SETREG(eregs->esp_busid, (sp->target & 0xf) | (ESP_BUSID_RESELID | ESP_BUSID_CTR32BIT)); esp->current_SC = sp; + wbflush(); } /* This will place the current working command back into the issue queue @@ -2951,6 +2970,7 @@ static inline int check_multibyte_msg(struct NCR_ESP *esp, } SETREG(eregs->esp_soff, SDptr->sync_min_period); SETREG(eregs->esp_stp, SDptr->sync_max_offset); + wbflush(); ESPSDTR(("soff=%2x stp=%2x cfg3=%2x\n", SDptr->sync_max_offset, @@ -2975,6 +2995,7 @@ static inline int check_multibyte_msg(struct NCR_ESP *esp, esp->config3[SCptr->target] &= ~bit; SETREG(eregs->esp_cfg3, esp->config3[SCptr->target]); + wbflush(); } } @@ -3025,6 +3046,7 @@ static inline int check_multibyte_msg(struct NCR_ESP *esp, esp->config3[SCptr->target] &= ~(ESP_CONFIG3_EWIDE); } SETREG(eregs->esp_cfg3, esp->config3[SCptr->target]); + wbflush(); /* Regardless, next try for sync transfers. */ build_sync_nego_msg(esp, esp->sync_defp, 15); diff --git a/drivers/tc/zs.c b/drivers/tc/zs.c index 84111ee1a..667387bc8 100644 --- a/drivers/tc/zs.c +++ b/drivers/tc/zs.c @@ -42,6 +42,7 @@ #include <asm/segment.h> #include <asm/bitops.h> #include <asm/uaccess.h> +#include <asm/wbflush.h> #include <asm/dec/interrupts.h> #include <asm/dec/machtype.h> #include <asm/dec/tc.h> @@ -195,7 +196,7 @@ static inline unsigned char read_zsreg(struct dec_zschannel *channel, if (reg != 0) { *channel->control = reg & 0xf; - RECOVERY_DELAY; + wbflush(); RECOVERY_DELAY; } retval = *channel->control; RECOVERY_DELAY; @@ -207,10 +208,10 @@ static inline void write_zsreg(struct dec_zschannel *channel, { if (reg != 0) { *channel->control = reg & 0xf; - RECOVERY_DELAY; + wbflush(); RECOVERY_DELAY; } *channel->control = value; - RECOVERY_DELAY; + wbflush(); RECOVERY_DELAY; return; } @@ -227,7 +228,7 @@ static inline void write_zsdata(struct dec_zschannel *channel, unsigned char value) { *channel->data = value; - RECOVERY_DELAY; + wbflush(); RECOVERY_DELAY; return; } @@ -1829,7 +1830,7 @@ zs_console_putchar(struct dec_serial *info, char ch) while (!(*(info->zs_channel->control) & Tx_BUF_EMP) && --loops) RECOVERY_DELAY; *(info->zs_channel->data) = ch; - RECOVERY_DELAY; + wbflush(); RECOVERY_DELAY; restore_flags(flags); } diff --git a/include/asm-mips/atomic.h b/include/asm-mips/atomic.h index 5cebea94d..58e095a53 100644 --- a/include/asm-mips/atomic.h +++ b/include/asm-mips/atomic.h @@ -11,7 +11,7 @@ * * Copyright (C) 1996, 1997 by Ralf Baechle * - * $Id: atomic.h,v 1.3 1997/12/15 10:38:29 ralf Exp $ + * $Id: atomic.h,v 1.5 1998/03/04 09:51:21 ralf Exp $ */ #ifndef __ASM_MIPS_ATOMIC_H #define __ASM_MIPS_ATOMIC_H @@ -44,7 +44,7 @@ extern __inline__ void atomic_add(int i, volatile atomic_t * v) save_flags(flags); cli(); - *v += i; + v->counter += i; restore_flags(flags); } @@ -54,7 +54,7 @@ extern __inline__ void atomic_sub(int i, volatile atomic_t * v) save_flags(flags); cli(); - *v -= i; + v->counter -= i; restore_flags(flags); } @@ -64,9 +64,9 @@ extern __inline__ int atomic_add_return(int i, atomic_t * v) save_flags(flags); cli(); - temp = *v; + temp = v->counter; temp += i; - *v = temp; + v->counter = temp; restore_flags(flags); return temp; @@ -78,13 +78,29 @@ extern __inline__ int atomic_sub_return(int i, atomic_t * v) save_flags(flags); cli(); - temp = *v; + temp = v->counter; temp -= i; - *v = temp; + v->counter = temp; restore_flags(flags); return temp; } + +extern __inline__ void atomic_clear_mask(unsigned long mask, unsigned long * v) +{ + unsigned long temp; + int flags; + + save_flags(flags); + cli(); + temp = *v; + temp &= ~mask; + *v = temp; + restore_flags(flags); + + return; +} + #endif #if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) || \ diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h index d1b1d7152..55e9940ec 100644 --- a/include/asm-mips/bitops.h +++ b/include/asm-mips/bitops.h @@ -11,7 +11,7 @@ #define __ASM_MIPS_BITOPS_H #include <linux/types.h> -#include <linux/byteorder/swab.h> /* sigh ... */ +#include <asm/byteorder.h> /* sigh ... */ #ifdef __KERNEL__ @@ -144,6 +144,8 @@ extern __inline__ int test_and_change_bit(int nr, void *addr) #else /* MIPS I */ +#include <asm/mipsregs.h> + extern __inline__ void set_bit(int nr, void * addr) { int mask; diff --git a/include/asm-mips/current.h b/include/asm-mips/current.h index bcaf22b5c..0311d92e1 100644 --- a/include/asm-mips/current.h +++ b/include/asm-mips/current.h @@ -1,4 +1,4 @@ -/* $Id: current.h,v 1.4 1998/07/20 17:52:19 ralf Exp $ +/* $Id: current.h,v 1.4 1998/08/25 09:21:55 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -24,7 +24,7 @@ register struct task_struct *current asm("$28"); #define _GET_CURRENT(reg) \ lui reg, %hi(kernelsp); \ .set push; \ - .set noreorder; \ + .set reorder; \ lw reg, %lo(kernelsp)(reg); \ .set pop; \ ori reg, 8191; \ diff --git a/include/asm-mips/fp.h b/include/asm-mips/fp.h index 463478147..30c17dc83 100644 --- a/include/asm-mips/fp.h +++ b/include/asm-mips/fp.h @@ -1,4 +1,4 @@ -/* $Id: fp.h,v 1.1 1998/07/16 17:01:54 ralf Exp $ +/* $Id: fp.h,v 1.1 1998/07/16 19:10:04 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -12,19 +12,23 @@ */ #define enable_cp1() \ __asm__ __volatile__( \ + ".set\tpush\n\t" \ ".set\tnoat\n\t" \ + ".set\treorder\n\t" \ "mfc0\t$1,$12\n\t" \ "or\t$1,%0\n\t" \ "mtc0\t$1,$12\n\t" \ - ".set\tat" \ + ".set\tpop" \ : : "r" (ST0_CU1)); #define disable_cp1() \ __asm__ __volatile__( \ + ".set\tpush\n\t" \ ".set\tnoat\n\t" \ + ".set\treorder\n\t" \ "mfc0\t$1,$12\n\t" \ "or\t$1,%0\n\t" \ "xor\t$1,%0\n\t" \ "mtc0\t$1,$12\n\t" \ - ".set\tat" \ + ".set\tpop" \ : : "r" (ST0_CU1)); diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h index ab1b4228c..72a657573 100644 --- a/include/asm-mips/mipsregs.h +++ b/include/asm-mips/mipsregs.h @@ -1,4 +1,4 @@ -/* $Id: mipsregs.h,v 1.4 1998/08/25 09:21:57 ralf Exp $ +/* $Id: mipsregs.h,v 1.5 1999/04/11 17:13:57 harald Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -103,7 +103,10 @@ #define read_32bit_cp0_register(source) \ ({ int __res; \ __asm__ __volatile__( \ - "mfc0\t%0,"STR(source) \ + ".set\tpush\n\t" \ + ".set\treorder\n\t" \ + "mfc0\t%0,"STR(source)"\n\t" \ + ".set\tpop" \ : "=r" (__res)); \ __res;}) @@ -121,7 +124,8 @@ #define write_32bit_cp0_register(register,value) \ __asm__ __volatile__( \ - "mtc0\t%0,"STR(register) \ + "mtc0\t%0,"STR(register)"\n\t" \ + "nop" \ : : "r" (value)); #define write_64bit_cp0_register(register,value) \ diff --git a/include/asm-mips/pgtable.h b/include/asm-mips/pgtable.h index 2a85a1617..d74a241c9 100644 --- a/include/asm-mips/pgtable.h +++ b/include/asm-mips/pgtable.h @@ -1,4 +1,4 @@ -/* $Id: pgtable.h,v 1.19 1999/06/13 16:35:53 ralf Exp $ +/* $Id: pgtable.h,v 1.20 1999/07/22 01:58:28 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -110,6 +110,20 @@ extern void (*add_wired_entry)(unsigned long entrylo0, unsigned long entrylo1, #define _PAGE_WRITE (1<<2) /* implemented in software */ #define _PAGE_ACCESSED (1<<3) /* implemented in software */ #define _PAGE_MODIFIED (1<<4) /* implemented in software */ + +#if (_MIPS_ISA == _MIPS_ISA_MIPS1) + +#define _PAGE_GLOBAL (1<<8) +#define _PAGE_VALID (1<<9) +#define _PAGE_SILENT_READ (1<<9) /* synonym */ +#define _PAGE_DIRTY (1<<10) /* The MIPS dirty bit */ +#define _PAGE_SILENT_WRITE (1<<10) +#define _CACHE_UNCACHED (1<<11) /* R4[0246]00 */ +#define _CACHE_MASK (1<<11) +#define _CACHE_CACHABLE_NONCOHERENT 0 + +#else + #define _PAGE_R4KBUG (1<<5) /* workaround for r4k bug */ #define _PAGE_GLOBAL (1<<6) #define _PAGE_VALID (1<<7) @@ -126,6 +140,8 @@ extern void (*add_wired_entry)(unsigned long entrylo0, unsigned long entrylo1, #define _CACHE_CACHABLE_ACCELERATED (7<<9) /* R10000 only */ #define _CACHE_MASK (7<<9) +#endif + #define __READABLE (_PAGE_READ | _PAGE_SILENT_READ | _PAGE_ACCESSED) #define __WRITEABLE (_PAGE_WRITE | _PAGE_SILENT_WRITE | _PAGE_MODIFIED) @@ -356,7 +372,7 @@ extern inline pte_t mk_pte(unsigned long page, pgprot_t pgprot) extern inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot) { - return __pte(physpage | pgprot_val(pgprot)); + return __pte(((physpage & PAGE_MASK) - PAGE_OFFSET) | pgprot_val(pgprot)); } extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) @@ -595,33 +611,37 @@ extern void (*update_mmu_cache)(struct vm_area_struct *vma, extern inline void tlb_probe(void) { __asm__ __volatile__( - ".set noreorder\n\t" + ".set push\n\t" + ".set reorder\n\t" "tlbp\n\t" - ".set reorder"); + ".set pop"); } extern inline void tlb_read(void) { __asm__ __volatile__( - ".set noreorder\n\t" + ".set push\n\t" + ".set reorder\n\t" "tlbr\n\t" - ".set reorder"); + ".set pop"); } extern inline void tlb_write_indexed(void) { __asm__ __volatile__( - ".set noreorder\n\t" + ".set push\n\t" + ".set reorder\n\t" "tlbwi\n\t" - ".set reorder"); + ".set pop"); } extern inline void tlb_write_random(void) { __asm__ __volatile__( - ".set noreorder\n\t" + ".set push\n\t" + ".set reorder\n\t" "tlbwr\n\t" - ".set reorder"); + ".set pop"); } /* Dealing with various CP0 mmu/cache related registers. */ @@ -632,11 +652,10 @@ extern inline unsigned long get_pagemask(void) unsigned long val; __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" + ".set push\n\t" + ".set reorder\n\t" "mfc0 %0, $5\n\t" - ".set mips0\n\t" - ".set reorder" + ".set pop" : "=r" (val)); return val; } @@ -644,11 +663,10 @@ extern inline unsigned long get_pagemask(void) extern inline void set_pagemask(unsigned long val) { __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" + ".set push\n\t" + ".set reorder\n\t" "mtc0 %0, $5\n\t" - ".set mips0\n\t" - ".set reorder" + ".set pop" : : "r" (val)); } @@ -658,11 +676,10 @@ extern inline unsigned long get_entrylo0(void) unsigned long val; __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" + ".set push\n\t" + ".set reorder\n\t" "mfc0 %0, $2\n\t" - ".set mips0\n\t" - ".set reorder" + ".set pop" : "=r" (val)); return val; } @@ -670,11 +687,10 @@ extern inline unsigned long get_entrylo0(void) extern inline void set_entrylo0(unsigned long val) { __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" + ".set push\n\t" + ".set reorder\n\t" "mtc0 %0, $2\n\t" - ".set mips0\n\t" - ".set reorder" + ".set pop" : : "r" (val)); } @@ -683,11 +699,10 @@ extern inline unsigned long get_entrylo1(void) unsigned long val; __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" + ".set push\n\t" + ".set reorder\n\t" "mfc0 %0, $3\n\t" - ".set mips0\n\t" - ".set reorder" : "=r" (val)); + ".set pop" : "=r" (val)); return val; } @@ -695,11 +710,10 @@ extern inline unsigned long get_entrylo1(void) extern inline void set_entrylo1(unsigned long val) { __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" + ".set push\n\t" + ".set reorder\n\t" "mtc0 %0, $3\n\t" - ".set mips0\n\t" - ".set reorder" + ".set pop" : : "r" (val)); } @@ -709,11 +723,10 @@ extern inline unsigned long get_entryhi(void) unsigned long val; __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" + ".set push\n\t" + ".set reorder\n\t" "mfc0 %0, $10\n\t" - ".set mips0\n\t" - ".set reorder" + ".set pop" : "=r" (val)); return val; @@ -722,11 +735,10 @@ extern inline unsigned long get_entryhi(void) extern inline void set_entryhi(unsigned long val) { __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" + ".set push\n\t" + ".set reorder\n\t" "mtc0 %0, $10\n\t" - ".set mips0\n\t" - ".set reorder" + ".set pop" : : "r" (val)); } @@ -736,11 +748,10 @@ extern inline unsigned long get_index(void) unsigned long val; __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" + ".set push\n\t" + ".set reorder\n\t" "mfc0 %0, $0\n\t" - ".set mips0\n\t" - ".set reorder" + ".set pop" : "=r" (val)); return val; } @@ -748,11 +759,10 @@ extern inline unsigned long get_index(void) extern inline void set_index(unsigned long val) { __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "mtc0 %0, $0\n\t" - ".set mips0\n\t" + ".set push\n\t" ".set reorder\n\t" + "mtc0 %0, $0\n\t" + ".set pop" : : "r" (val)); } @@ -762,11 +772,10 @@ extern inline unsigned long get_wired(void) unsigned long val; __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "mfc0 %0, $6\n\t" - ".set mips0\n\t" + ".set push\n\t" ".set reorder\n\t" + "mfc0 %0, $6\n\t" + ".set pop" : "=r" (val)); return val; } @@ -774,11 +783,10 @@ extern inline unsigned long get_wired(void) extern inline void set_wired(unsigned long val) { __asm__ __volatile__( - "\n\t.set noreorder\n\t" - ".set mips3\n\t" + ".set push\n\t" + ".set reorder\n\t" "mtc0 %0, $6\n\t" - ".set mips0\n\t" - ".set reorder" + ".set pop" : : "r" (val)); } @@ -788,11 +796,10 @@ extern inline unsigned long get_taglo(void) unsigned long val; __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" + ".set push\n\t" + ".set reorder\n\t" "mfc0 %0, $28\n\t" - ".set mips0\n\t" - ".set reorder" + ".set pop" : "=r" (val)); return val; } @@ -800,11 +807,10 @@ extern inline unsigned long get_taglo(void) extern inline void set_taglo(unsigned long val) { __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" + ".set push\n\t" + ".set reorder\n\t" "mtc0 %0, $28\n\t" - ".set mips0\n\t" - ".set reorder" + ".set pop" : : "r" (val)); } @@ -813,11 +819,10 @@ extern inline unsigned long get_taghi(void) unsigned long val; __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" + ".set push\n\t" + ".set reorder\n\t" "mfc0 %0, $29\n\t" - ".set mips0\n\t" - ".set reorder" + ".set pop" : "=r" (val)); return val; } @@ -825,11 +830,10 @@ extern inline unsigned long get_taghi(void) extern inline void set_taghi(unsigned long val) { __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" + ".set push\n\t" + ".set reorder\n\t" "mtc0 %0, $29\n\t" - ".set mips0\n\t" - ".set reorder" + ".set pop" : : "r" (val)); } @@ -839,11 +843,10 @@ extern inline unsigned long get_context(void) unsigned long val; __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" + ".set push\n\t" + ".set reorder\n\t" "mfc0 %0, $4\n\t" - ".set mips0\n\t" - ".set reorder" + ".set pop" : "=r" (val)); return val; @@ -852,11 +855,10 @@ extern inline unsigned long get_context(void) extern inline void set_context(unsigned long val) { __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" + ".set push\n\t" + ".set reorder\n\t" "mtc0 %0, $4\n\t" - ".set mips0\n\t" - ".set reorder" + ".set pop" : : "r" (val)); } diff --git a/include/asm-mips/ptrace.h b/include/asm-mips/ptrace.h index 4a52e9440..e7db7a022 100644 --- a/include/asm-mips/ptrace.h +++ b/include/asm-mips/ptrace.h @@ -1,4 +1,4 @@ -/* $Id: ptrace.h,v 1.3 1998/07/10 01:14:55 ralf Exp $ +/* $Id: ptrace.h,v 1.4 1999/01/04 16:09:25 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -12,6 +12,7 @@ #ifndef __ASM_MIPS_PTRACE_H #define __ASM_MIPS_PTRACE_H +#include <asm/isadep.h> #include <linux/types.h> /* 0 - 31 are integer registers, 32 - 63 are fp registers. */ @@ -59,7 +60,7 @@ struct pt_regs { /* * Does the process account for user or for system time? */ -#define user_mode(regs) ((regs)->cp0_status & 0x10) +#define user_mode(regs) ((regs)->cp0_status & KU_USER) #define instruction_pointer(regs) ((regs)->cp0_epc) diff --git a/include/asm-mips/semaphore-helper.h b/include/asm-mips/semaphore-helper.h index 95210135f..f80be5b9d 100644 --- a/include/asm-mips/semaphore-helper.h +++ b/include/asm-mips/semaphore-helper.h @@ -17,6 +17,66 @@ static inline void wake_one_more(struct semaphore * sem) atomic_inc(&sem->waking); } +#if (_MIPS_ISA == _MIPS_ISA_MIPS1) + +/* + * It doesn't make sense, IMHO, to endlessly turn interrupts off and on again. + * Do it once and that's it. ll/sc *has* it's advantages. HK + */ +#define read(a) ((a)->counter) +#define inc(a) (((a)->counter)++) +#define dec(a) (((a)->counter)--) + +static inline int waking_non_zero(struct semaphore *sem) +{ + unsigned long flags; + int ret = 0; + + save_and_cli(flags); + if (read(&sem->waking) > 0) { + dec(&sem->waking); + ret = 1; + } + restore_flags(flags); + return ret; +} + +static inline int waking_non_zero_interruptible(struct semaphore *sem, + struct task_struct *tsk) +{ + int ret = 0; + unsigned long flags; + + save_and_cli(flags); + if (read(&sem->waking) > 0) { + dec(&sem->waking); + ret = 1; + } else if (signal_pending(tsk)) { + inc(&sem->count); + ret = -EINTR; + } + restore_flags(flags); + return ret; +} + +static inline int waking_non_zero_trylock(struct semaphore *sem) +{ + int ret = 1; + unsigned long flags; + + save_and_cli(flags); + if (read(&sem->waking) <= 0) + inc(&sem->count); + else { + dec(&sem->waking); + ret = 0; + } + restore_flags(flags); + return ret; +} + +#else + static inline int waking_non_zero(struct semaphore *sem) { @@ -150,4 +210,6 @@ static inline int waking_non_zero_trylock(struct semaphore *sem) return ret; } +#endif + #endif /* __ASM_MIPS_SEMAPHORE_HELPER_H */ diff --git a/include/asm-mips/semaphore.h b/include/asm-mips/semaphore.h index 1f713fe49..c6486fe5b 100644 --- a/include/asm-mips/semaphore.h +++ b/include/asm-mips/semaphore.h @@ -1,4 +1,4 @@ -/* $Id: semaphore.h,v 1.6 1999/06/17 13:30:38 ralf Exp $ +/* $Id: semaphore.h,v 1.7 1999/06/22 22:12:59 tsbogend Exp $ * * SMP- and interrupt-safe semaphores.. * @@ -92,6 +92,18 @@ extern inline int down_interruptible(struct semaphore * sem) return ret; } +#if (_MIPS_ISA == _MIPS_ISA_MIPS1) + +extern inline int down_trylock(struct semaphore * sem) +{ + int ret = 0; + if (atomic_dec_return(&sem->count) < 0) + ret = __down_trylock(sem); + return ret; +} + +#else + /* * down_trylock returns 0 on success, 1 if we failed to get the lock. * @@ -162,6 +174,8 @@ extern inline int down_trylock(struct semaphore * sem) return ret; } +#endif + /* * Note! This is subtle. We jump to wake people up only if * the semaphore was negative (== somebody was waiting on it). diff --git a/include/asm-mips/softirq.h b/include/asm-mips/softirq.h index 7a6e4ff5c..1e5f4a754 100644 --- a/include/asm-mips/softirq.h +++ b/include/asm-mips/softirq.h @@ -1,4 +1,4 @@ -/* $Id: softirq.h,v 1.5 1999/02/15 02:22:12 ralf Exp $ +/* $Id: softirq.h,v 1.6 1999/06/17 13:30:38 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -28,6 +28,12 @@ extern unsigned int local_bh_count[NR_CPUS]; #define get_active_bhs() (bh_mask & bh_active) +#if (_MIPS_ISA == _MIPS_ISA_MIPS1) + +#define clear_active_bhs(x) atomic_clear_mask((x),&bh_active) + +#else + static inline void clear_active_bhs(unsigned long x) { unsigned long temp; @@ -41,8 +47,11 @@ static inline void clear_active_bhs(unsigned long x) "=m" (bh_active) :"Ir" (~x), "m" (bh_active)); + } +#endif + extern inline void init_bh(int nr, void (*routine)(void)) { bh_base[nr] = routine; diff --git a/include/asm-mips/stackframe.h b/include/asm-mips/stackframe.h index 4b3a74043..68c8eabb6 100644 --- a/include/asm-mips/stackframe.h +++ b/include/asm-mips/stackframe.h @@ -3,7 +3,7 @@ * * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Paul M. Antoine. * - * $Id: stackframe.h,v 1.7 1998/05/04 09:13:01 ralf Exp $ + * $Id: stackframe.h,v 1.8 1999/05/01 10:08:19 harald Exp $ */ #ifndef __ASM_MIPS_STACKFRAME_H #define __ASM_MIPS_STACKFRAME_H @@ -102,9 +102,6 @@ #define RESTORE_AT \ lw $1, PT_R1(sp); \ -#define RESTORE_SP \ - lw sp, PT_R29(sp) - #define RESTORE_TEMP \ lw $24, PT_LO(sp); \ lw $8, PT_R8(sp); \ @@ -131,6 +128,44 @@ lw $23, PT_R23(sp); \ lw $30, PT_R30(sp) +#if (_MIPS_ISA == _MIPS_ISA_MIPS1) + +#define RESTORE_SOME \ + .set push; \ + .set reorder; \ + mfc0 t0, CP0_STATUS; \ + .set pop; \ + ori t0, 0x1f; \ + xori t0, 0x1f; \ + mtc0 t0, CP0_STATUS; \ + li v1, 0xff00; \ + and t0, v1; \ + lw v0, PT_STATUS(sp); \ + nor v1, $0, v1; \ + and v0, v1; \ + or v0, t0; \ + mtc0 v0, CP0_STATUS; \ + lw $31, PT_R31(sp); \ + lw $28, PT_R28(sp); \ + lw $25, PT_R25(sp); \ + lw $7, PT_R7(sp); \ + lw $6, PT_R6(sp); \ + lw $5, PT_R5(sp); \ + lw $4, PT_R4(sp); \ + lw $3, PT_R3(sp); \ + lw $2, PT_R2(sp) + +#define RESTORE_SP_AND_RET \ + .set push; \ + .set noreorder; \ + lw k0, PT_EPC(sp); \ + lw sp, PT_R29(sp); \ + jr k0; \ + rfe; \ + .set pop + +#else + #define RESTORE_SOME \ .set push; \ .set reorder; \ @@ -158,12 +193,20 @@ lw $3, PT_R3(sp); \ lw $2, PT_R2(sp) -#define RESTORE_ALL \ +#define RESTORE_SP_AND_RET \ + lw sp, PT_R29(sp); \ + .set mips3; \ + eret; \ + .set mips0 + +#endif + +#define RESTORE_ALL_AND_RET \ RESTORE_SOME; \ RESTORE_AT; \ RESTORE_TEMP; \ RESTORE_STATIC; \ - RESTORE_SP + RESTORE_SP_AND_RET /* * Move to kernel mode and disable interrupts. diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h index ab62be3d4..a397989a0 100644 --- a/include/asm-mips/system.h +++ b/include/asm-mips/system.h @@ -1,4 +1,4 @@ -/* $Id: system.h,v 1.11 1999/06/17 13:30:39 ralf Exp $ +/* $Id: system.h,v 1.8 1999/02/15 02:22:13 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -17,14 +17,14 @@ extern __inline__ void __sti(void) { __asm__ __volatile__( - ".set\tnoreorder\n\t" + ".set\tpush\n\t" + ".set\treorder\n\t" ".set\tnoat\n\t" "mfc0\t$1,$12\n\t" "ori\t$1,0x1f\n\t" "xori\t$1,0x1e\n\t" "mtc0\t$1,$12\n\t" - ".set\tat\n\t" - ".set\treorder" + ".set\tpop\n\t" : /* no outputs */ : /* no inputs */ : "$1", "memory"); @@ -41,17 +41,18 @@ extern __inline__ void __cli(void) { __asm__ __volatile__( - ".set\tnoreorder\n\t" + ".set\tpush\n\t" + ".set\treorder\n\t" ".set\tnoat\n\t" "mfc0\t$1,$12\n\t" "ori\t$1,1\n\t" "xori\t$1,1\n\t" + ".set\tnoreorder\n\t" "mtc0\t$1,$12\n\t" "nop\n\t" "nop\n\t" "nop\n\t" - ".set\tat\n\t" - ".set\treorder" + ".set\tpop\n\t" : /* no outputs */ : /* no inputs */ : "$1", "memory"); @@ -59,26 +60,28 @@ __cli(void) #define __save_flags(x) \ __asm__ __volatile__( \ - ".set\tnoreorder\n\t" \ + ".set\tpush\n\t" \ + ".set\treorder\n\t" \ "mfc0\t%0,$12\n\t" \ - ".set\treorder" \ + ".set\tpop\n\t" \ : "=r" (x) \ : /* no inputs */ \ : "memory") #define __save_and_cli(x) \ __asm__ __volatile__( \ - ".set\tnoreorder\n\t" \ + ".set\tpush\n\t" \ + ".set\treorder\n\t" \ ".set\tnoat\n\t" \ "mfc0\t%0,$12\n\t" \ "ori\t$1,%0,1\n\t" \ "xori\t$1,1\n\t" \ + ".set\tnoreorder\n\t" \ "mtc0\t$1,$12\n\t" \ "nop\n\t" \ "nop\n\t" \ "nop\n\t" \ - ".set\tat\n\t" \ - ".set\treorder" \ + ".set\tpop\n\t" \ : "=r" (x) \ : /* no inputs */ \ : "$1", "memory") @@ -87,19 +90,21 @@ extern void __inline__ __restore_flags(int flags) { __asm__ __volatile__( - ".set\tnoreorder\n\t" + ".set\tpush\n\t" + ".set\treorder\n\t" "mfc0\t$8,$12\n\t" "li\t$9,0xff00\n\t" "and\t$8,$9\n\t" "nor\t$9,$0,$9\n\t" "and\t%0,$9\n\t" "or\t%0,$8\n\t" + ".set\tnoreorder\n\t" "mtc0\t%0,$12\n\t" "nop\n\t" "nop\n\t" "nop\n\t" - ".set\treorder" - : /* no output */ + ".set\tpop\n\t" + : : "r" (flags) : "$8", "$9", "memory"); } @@ -171,6 +176,8 @@ extern __inline__ unsigned long xchg_u32(volatile int * m, unsigned long val) : "=r" (val), "=r" (m), "=r" (dummy) : "1" (m), "2" (val) : "memory"); + + return val; #else unsigned long flags, retval; @@ -179,9 +186,9 @@ extern __inline__ unsigned long xchg_u32(volatile int * m, unsigned long val) retval = *m; *m = val; restore_flags(flags); + return retval; #endif /* Processor-dependent optimization */ - return val; } /* |