summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CREDITS6
-rw-r--r--Documentation/Configure.help27
-rw-r--r--arch/mips/kernel/entry.S32
-rw-r--r--arch/mips/kernel/head.S29
-rw-r--r--arch/mips/kernel/process.c10
-rw-r--r--arch/mips/kernel/ptrace.c7
-rw-r--r--arch/mips/kernel/scall_o32.S24
-rw-r--r--arch/mips/kernel/traps.c153
-rw-r--r--arch/mips/mm/r2300.c13
-rw-r--r--drivers/net/declance.c6
-rw-r--r--drivers/scsi/NCR53C9x.c22
-rw-r--r--drivers/tc/zs.c11
-rw-r--r--include/asm-mips/atomic.h30
-rw-r--r--include/asm-mips/bitops.h4
-rw-r--r--include/asm-mips/current.h4
-rw-r--r--include/asm-mips/fp.h10
-rw-r--r--include/asm-mips/mipsregs.h10
-rw-r--r--include/asm-mips/pgtable.h166
-rw-r--r--include/asm-mips/ptrace.h5
-rw-r--r--include/asm-mips/semaphore-helper.h62
-rw-r--r--include/asm-mips/semaphore.h16
-rw-r--r--include/asm-mips/softirq.h11
-rw-r--r--include/asm-mips/stackframe.h55
-rw-r--r--include/asm-mips/system.h39
24 files changed, 557 insertions, 195 deletions
diff --git a/CREDITS b/CREDITS
index 745fa36c6..3ebba7bf2 100644
--- a/CREDITS
+++ b/CREDITS
@@ -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;
}
/*