summaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r--arch/mips/kernel/Makefile1
-rw-r--r--arch/mips/kernel/branch.c9
-rw-r--r--arch/mips/kernel/entry.S77
-rw-r--r--arch/mips/kernel/fpe.c2
-rw-r--r--arch/mips/kernel/gdb-low.S2
-rw-r--r--arch/mips/kernel/head.S70
-rw-r--r--arch/mips/kernel/irixelf.c9
-rw-r--r--arch/mips/kernel/irixsig.c2
-rw-r--r--arch/mips/kernel/irq.c81
-rw-r--r--arch/mips/kernel/mips_ksyms.c14
-rw-r--r--arch/mips/kernel/pci.c44
-rw-r--r--arch/mips/kernel/proc.c28
-rw-r--r--arch/mips/kernel/process.c4
-rw-r--r--arch/mips/kernel/r2300_fpu.S8
-rw-r--r--arch/mips/kernel/r4k_fpu.S153
-rw-r--r--arch/mips/kernel/r4k_misc.S2
-rw-r--r--arch/mips/kernel/r6000_fpu.S22
-rw-r--r--arch/mips/kernel/setup.c8
-rw-r--r--arch/mips/kernel/signal.c4
-rw-r--r--arch/mips/kernel/syscall.c12
-rw-r--r--arch/mips/kernel/syscalls.h6
-rw-r--r--arch/mips/kernel/sysmips.c2
-rw-r--r--arch/mips/kernel/time.c9
-rw-r--r--arch/mips/kernel/traps.c60
-rw-r--r--arch/mips/kernel/unaligned.c21
25 files changed, 318 insertions, 332 deletions
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 69cd54975..2b398d00b 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -16,7 +16,6 @@ O_OBJS := branch.o process.o signal.o entry.o traps.o ptrace.o vm86.o \
ioport.o pci.o reset.o setup.o syscall.o sysmips.o ipc.o \
r4k_switch.o r4k_misc.o r4k_scall.o r4k_fpu.o r2300_switch.o \
r2300_misc.o r2300_scall.o r2300_fpu.o r6000_fpu.o unaligned.o
-
OX_OBJS := mips_ksyms.o
ifdef CONFIG_MIPS_FPE_MODULE
diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c
index b9d138a32..4ca20214d 100644
--- a/arch/mips/kernel/branch.c
+++ b/arch/mips/kernel/branch.c
@@ -16,8 +16,7 @@
#include <asm/uaccess.h>
/*
- * Compute the return address and do emulate branch and instruction
- * simulation, if required.
+ * Compute the return address and do emulate branch simulation, if required.
*/
int __compute_return_epc(struct pt_regs *regs)
{
@@ -162,14 +161,12 @@ int __compute_return_epc(struct pt_regs *regs)
/*
* And now the FPA/cp1 branch instructions.
- *
- * FIXME: This will silently fail for MIPS IV cop1 branches with
- * the cc field != 0.
*/
case cop1_op:
asm ("cfc1\t%0,$31":"=r" (fcr31));
bit = (insn.i_format.rt >> 2);
- bit += bit ? 24 : 23;
+ bit += (bit != 0);
+ bit += 23;
switch (insn.i_format.rt) {
case 0: /* bc1f */
case 2: /* bc1fl */
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S
index c955b964e..2e286da80 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.2 1997/08/11 04:21:31 ralf Exp $
+ * $Id: entry.S,v 1.4 1997/09/20 19:20:13 root Exp $
*/
/*
@@ -50,6 +50,7 @@ reschedule: jal schedule
nop
EXPORT(ret_from_sys_call)
+EXPORT(ret_from_irq)
lw t0,bh_mask
lw t1,bh_active # unused delay slot
and t0,t1
@@ -75,64 +76,15 @@ EXPORT(ret_from_sys_call)
jal do_signal
move a1,sp
- .set noat
-EXPORT(return)
+EXPORT(return) .set noat
RESTORE_ALL
eret
.set at
/*
- * Beware: interrupt, fast_interrupt and bad_interrupt have unusual
- * calling conventions to speedup the mess.
- *
- * a0 - interrupt number
- * s2 - destroyed
- * return values:
- * v0 - return routine
+ * Common spurious interrupt handler.
*/
.text
- .set at
- .align 5
-NESTED(interrupt, PT_SIZE, sp)
- move s2,ra
- mfc0 t0,CP0_STATUS # enable IRQs
- ori t0,0x1f
- xori t0,0x1e
- mtc0 t0,CP0_STATUS
-
- jal do_IRQ
- move a1,sp
-
- mfc0 t0,CP0_STATUS # disable IRQs
- ori t0,1
- xori t0,1
- mtc0 t0,CP0_STATUS
- .set reorder
- la v0,ret_from_sys_call
- jr s2
- .set noreorder
- END(interrupt)
-
- .align 5
-NESTED(fast_interrupt, PT_SIZE, sp)
- move s2,ra
- jal do_fast_IRQ
- nop
-
- .set reorder
- la v0,return
- jr s2
- .set noreorder
- END(fast_interrupt)
-
- /*
- * Don't return & unblock the pic
- */
-LEAF(bad_interrupt)
- j return
- END(bad_interrupt)
-
- .text
.align 5
LEAF(spurious_interrupt)
/*
@@ -141,10 +93,8 @@ LEAF(spurious_interrupt)
*/
lui t1,%hi(spurious_count)
lw t0,%lo(spurious_count)(t1)
- la v0,return
addiu t0,1
-
- jr ra
+ j ret_from_irq
sw t0,%lo(spurious_count)(t1)
END(spurious_interrupt)
@@ -164,7 +114,7 @@ LEAF(spurious_interrupt)
REG_S t0,PT_BVADDR(sp);
#define __BUILD_silent(exception)
-#define fmt "Got %s at %016Lx.\n"
+#define fmt "Got %s at %08lx.\n"
#define __BUILD_verbose(exception) \
la a1,8f; \
@@ -215,21 +165,6 @@ EXPORT(exception_count_##exception); \
BUILD_HANDLER(reserved,reserved,none,verbose) /* others */
/*
- * Exception handler table with 32 entries.
- * This might be extended to handle software exceptions
- */
- .bss
- .align PTRLOG
-EXPORT(exception_handlers)
- .fill 32,PTRSIZE,0
-
-/*
- * Interrupt handler table with 32 entries.
- */
-EXPORT(IRQ_vectors)
- .fill 32,PTRSIZE,0
-
-/*
* Table of syscalls
*/
.data
diff --git a/arch/mips/kernel/fpe.c b/arch/mips/kernel/fpe.c
index 46ff43bb4..ee47f016f 100644
--- a/arch/mips/kernel/fpe.c
+++ b/arch/mips/kernel/fpe.c
@@ -6,7 +6,7 @@
*
* Copyright (C) 1997 Ralf Baechle
*
- * $Id:$
+ * $Id: fpe.c,v 1.1 1997/08/11 04:17:18 ralf Exp $
*/
#include <linux/kernel.h>
#include <linux/module.h>
diff --git a/arch/mips/kernel/gdb-low.S b/arch/mips/kernel/gdb-low.S
index bd7ef94fb..a379c5c5b 100644
--- a/arch/mips/kernel/gdb-low.S
+++ b/arch/mips/kernel/gdb-low.S
@@ -4,6 +4,8 @@
* gdb-low.S contains the low-level trap handler for the GDB stub.
*
* Copyright (C) 1995 Andreas Busse
+ *
+ * $Id:$
*/
#include <linux/sys.h>
diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S
index 3251c89d9..d6e82febf 100644
--- a/arch/mips/kernel/head.S
+++ b/arch/mips/kernel/head.S
@@ -7,6 +7,8 @@
* Further modifications by David S. Miller
*
* Head.S contains the MIPS exception handler and startup code.
+ *
+ * $Id: head.S,v 1.10 1997/11/13 12:55:29 ralf Exp $
*/
#include <linux/config.h>
#include <linux/tasks.h>
@@ -27,8 +29,10 @@
/*
* Reserved space for exception handlers.
* Necessary for machines which link their kernels at KSEG0.
+ * FIXME: We could overwrite some of the useless handlers
+ * with those actually being used.
*/
- .fill 512
+ .fill 520
/*
* This is space for the interrupt handlers.
* After trap_init() they are located at virtual address KSEG0.
@@ -93,6 +97,34 @@
eret
END(except_vec0_r4600)
+ /* TLB refill, EXL == 0, R4xx0, non-R4600 version */
+ .set noreorder
+ .set noat
+ LEAF(except_vec0_nevada)
+ .set mips3
+ mfc0 k0, CP0_BADVADDR # Get faulting address
+ _GET_CURRENT(k1) # get current task ptr
+ srl k0, k0, 22 # get pgd only bits
+ lw k1, THREAD_PGDIR(k1) # get task pg_dir
+ sll k0, k0, 2
+ addu k1, k1, k0 # add in pgd offset
+ lw k1, (k1)
+ mfc0 k0, CP0_CONTEXT # get context reg
+ srl k0, k0, 1 # get pte offset
+ and k0, k0, 0xff8
+ addu k1, k1, k0 # add in offset
+ lw k0, 0(k1) # get even pte
+ lw k1, 4(k1) # get odd pte
+ srl k0, k0, 6 # convert to entrylo0
+ mtc0 k0, CP0_ENTRYLO0 # load it
+ srl k1, k1, 6 # convert to entrylo1
+ mtc0 k1, CP0_ENTRYLO1 # load it
+ tlbwr # write random tlb entry
+ nop
+ nop
+ eret # return from trap
+ END(except_vec0_nevada)
+
/* TLB refill, EXL == 0, R4[40]00/R5000 badvaddr hwbug version */
LEAF(except_vec0_r45k_bvahwbug)
.set mips3
@@ -109,6 +141,7 @@
addu k1, k1, k0
lw k0, 0(k1)
lw k1, 4(k1)
+ nop /* XXX */
tlbp
srl k0, k0, 6
mtc0 k0, CP0_ENTRYLO0
@@ -139,6 +172,7 @@
addu k1, k1, k0
lw k0, 0(k1)
lw k1, 4(k1)
+ nop /* XXX */
tlbp
srl k0, k0, 6
mtc0 k0, CP0_ENTRYLO0
@@ -199,6 +233,7 @@
addu k1, k1, k0
lw k0, 0(k1)
lw k1, 4(k1)
+ nop /* XXX */
tlbp
srl k0, k0, 6
mtc0 zero, CP0_ENTRYLO0
@@ -309,6 +344,17 @@
END(except_vec3_generic)
.set at
+ /*
+ * Special interrupt vector for embedded MIPS. This is a
+ * dedicated interrupt vector which reduces interrupt processing
+ * overhead. The jump instruction will be inserted here at
+ * initialization time. This handler may only be 8 bytes in size!
+ */
+ NESTED(except_vec4, 0, sp)
+1: j 1b /* Dummy, will be replaced */
+ nop
+ END(except_vec4)
+
/*
* Kernel entry point
*/
@@ -357,13 +403,10 @@ probe_done:
#ifndef CONFIG_SGI
/* Clear BSS first so that there are no surprises... */
la t0, _edata
- la t1, (_end - 4)
- sw zero, (t0)
-1:
- addiu t0, 4
+ la t1, _end
+1: addiu t0, 1
bne t0, t1, 1b
- sw zero, (t0)
- nop
+ sb zero, -1(t0)
#endif
/*
* Determine the mmu/cache attached to this machine,
@@ -400,8 +443,9 @@ probe_done:
/*
* Stack for kernel and init
*/
-9: la sp, init_task_union+(KERNEL_STACK_SIZE-4*SZREG)
- sw sp, kernelsp
+9: la t0, init_task_union+KERNEL_STACK_SIZE-32
+ sw t0, kernelsp
+ subu sp, t0, 4*SZREG
/* Disable coprocessors */
mfc0 t0, CP0_STATUS
@@ -604,6 +648,14 @@ LEAF(wire_mappings_r3000)
b probe_done
sw t2, (t3)
1:
+ li t2, PRID_IMP_NEVADA
+ bne t1, t2, 1f
+ nop
+
+ li t2, CPU_NEVADA
+ b probe_done
+ sw t2, (t3)
+1:
li t2, CPU_UNKNOWN
sw t2, (t3)
diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c
index 26ae60b9e..a7c7bb7df 100644
--- a/arch/mips/kernel/irixelf.c
+++ b/arch/mips/kernel/irixelf.c
@@ -6,7 +6,6 @@
*
* Based upon work which is:
* Copyright 1993, 1994: Eric Youngdale (ericy@cais.com).
- *
*/
#include <linux/module.h>
@@ -228,6 +227,7 @@ unsigned long * create_irix_tables(char * p, int argc, int envc,
return sp;
}
+
/* This is much more generalized than the library routine read function,
* so we keep this separate. Technically the library read function
* is only provided so that we can read a.out libraries that have
@@ -679,7 +679,7 @@ static inline int do_load_irix_binary(struct linux_binprm * bprm,
start_code = 0xffffffff;
end_code = 0;
end_data = 0;
-
+
retval = look_for_irix_interpreter(&elf_interpreter,
&interpreter_dentry,
&interp_elf_ex, elf_phdata, bprm,
@@ -754,7 +754,6 @@ static inline int do_load_irix_binary(struct linux_binprm * bprm,
}
}
-
set_fs(old_fs);
kfree(elf_phdata);
@@ -861,7 +860,7 @@ static inline int do_load_irix_library(int fd)
/* Seek to the beginning of the file. */
if (file->f_op->llseek) {
- if ((error = file->f_op->llseek(inode, file, 0, 0)) != 0)
+ if ((error = file->f_op->llseek(file, 0, 0)) != 0)
return -ENOEXEC;
} else
file->f_pos = 0;
@@ -1028,7 +1027,7 @@ static int dump_write(struct file *file, const void *addr, int nr)
static int dump_seek(struct file *file, off_t off)
{
if (file->f_op->llseek) {
- if (file->f_op->llseek(file->f_dentry->d_inode, file, off, 0) != off)
+ if (file->f_op->llseek(file, off, 0) != off)
return 0;
} else
file->f_pos = off;
diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c
index a40178f36..c84a391a7 100644
--- a/arch/mips/kernel/irixsig.c
+++ b/arch/mips/kernel/irixsig.c
@@ -1,4 +1,4 @@
-/* $Id: irixsig.c,v 1.3 1997/07/29 03:04:27 ralf Exp $
+/* $Id: irixsig.c,v 1.4 1997/08/05 09:43:10 ralf Exp $
* irixsig.c: WHEEE, IRIX signals! YOW, am I compatable or what?!?!
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
index 81ac4846d..2f29b0ca5 100644
--- a/arch/mips/kernel/irq.c
+++ b/arch/mips/kernel/irq.c
@@ -4,7 +4,7 @@
* Copyright (C) 1992 Linus Torvalds
* Copyright (C) 1994, 1995, 1996, 1997 Ralf Baechle
*
- * $Id: irq.c,v 1.4 1997/09/12 01:30:22 ralf Exp $
+ * $Id: irq.c,v 1.7 1997/09/26 11:51:33 ralf Exp $
*/
#include <linux/errno.h>
#include <linux/init.h>
@@ -86,8 +86,6 @@ void enable_irq(unsigned int irq_nr)
* fast ones, then the bad ones.
*/
extern void interrupt(void);
-extern void fast_interrupt(void);
-extern void bad_interrupt(void);
static struct irqaction *irq_action[32] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -130,48 +128,45 @@ atomic_t __mips_bh_counter;
*/
asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
{
- struct irqaction * action = *(irq + irq_action);
- int do_random, cpu = smp_processor_id();
+ struct irqaction *action;
+ int do_random, cpu;
+ cpu = smp_processor_id();
irq_enter(cpu, irq);
kstat.interrupts[irq]++;
- /* slow interrupts run with interrupts enabled */
- sti();
- action = *(irq + irq_action);
- do_random = 0;
- while (action) {
- do_random |= action->flags;
- action->handler(irq, action->dev_id, regs);
- action = action->next;
- }
- if (do_random & SA_SAMPLE_RANDOM)
- add_interrupt_randomness(irq);
- irq_exit(cpu, irq);
-}
+ /*
+ * mask and ack quickly, we don't want the irq controller
+ * thinking we're snobs just because some other CPU has
+ * disabled global interrupts (we have already done the
+ * INT_ACK cycles, it's too late to try to pretend to the
+ * controller that we aren't taking the interrupt).
+ *
+ * Commented out because we've already done this in the
+ * machinespecific part of the handler. It's reasonable to
+ * do this here in a highlevel language though because that way
+ * we could get rid of a good part of duplicated code ...
+ */
+ /* mask_and_ack_irq(irq); */
-/*
- * do_fast_IRQ handles IRQ's that don't need the fancy interrupt return
- * stuff - the handler is also running with interrupts disabled unless
- * it explicitly enables them later.
- */
-asmlinkage void do_fast_IRQ(int irq)
-{
- struct irqaction * action;
- int do_random, cpu = smp_processor_id();
-
- irq_enter(cpu, irq);
- kstat.interrupts[irq]++;
action = *(irq + irq_action);
- do_random = 0;
- while (action) {
- do_random |= action->flags;
- action->handler(irq, action->dev_id, NULL);
- action = action->next;
+ if (action) {
+ if (!(action->flags & SA_INTERRUPT))
+ __sti();
+ action = *(irq + irq_action);
+ do_random = 0;
+ do {
+ do_random |= action->flags;
+ action->handler(irq, action->dev_id, regs);
+ action = action->next;
+ } while (action);
+ if (do_random & SA_SAMPLE_RANDOM)
+ add_interrupt_randomness(irq);
+ __cli();
}
- if (do_random & SA_SAMPLE_RANDOM)
- add_interrupt_randomness(irq);
irq_exit(cpu, irq);
+
+ /* unmasking and bottom half handling is done magically for us. */
}
/*
@@ -211,10 +206,6 @@ int setup_x86_irq(int irq, struct irqaction * new)
*p = new;
if (!shared) {
- if (new->flags & SA_INTERRUPT)
- set_int_vector(irq,fast_interrupt);
- else
- set_int_vector(irq,interrupt);
unmask_irq(irq);
}
restore_flags(flags);
@@ -269,10 +260,8 @@ void free_irq(unsigned int irq, void *dev_id)
/* Found it - now free it */
save_and_cli(flags);
*p = action->next;
- if (!irq[irq_action]) {
+ if (!irq[irq_action])
mask_irq(irq);
- set_int_vector(irq, bad_interrupt);
- }
restore_flags(flags);
kfree(action);
return;
@@ -321,9 +310,5 @@ int probe_irq_off (unsigned long irqs)
__initfunc(void init_IRQ(void))
{
- int i;
-
- for (i = 0; i < 32 ; i++)
- set_int_vector(i, bad_interrupt);
irq_setup();
}
diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c
index 83712649c..3e8fc275d 100644
--- a/arch/mips/kernel/mips_ksyms.c
+++ b/arch/mips/kernel/mips_ksyms.c
@@ -7,7 +7,7 @@
*
* Copyright (C) 1996, 1997 by Ralf Baechle
*
- * $Id: mips_ksyms.c,v 1.2 1997/07/29 03:58:54 ralf Exp $
+ * $Id: mips_ksyms.c,v 1.4 1997/08/11 04:17:18 ralf Exp $
*/
#include <linux/config.h>
#include <linux/module.h>
@@ -62,11 +62,21 @@ EXPORT_SYMBOL(csum_partial_copy);
*/
EXPORT_SYMBOL(flush_page_to_ram);
EXPORT_SYMBOL(fd_cacheflush);
+EXPORT_SYMBOL(flush_cache_all);
/*
* Base address of ports for Intel style I/O.
*/
-EXPORT_SYMBOL(port_base);
+EXPORT_SYMBOL(mips_io_port_base);
+
+/*
+ * Architecture specific stuff.
+ */
+#ifdef CONFIG_MIPS_JAZZ
+EXPORT_SYMBOL(vdma_alloc);
+EXPORT_SYMBOL(vdma_free);
+EXPORT_SYMBOL(vdma_log2phys);
+#endif
#ifdef CONFIG_SGI
EXPORT_SYMBOL(hpc3c0);
diff --git a/arch/mips/kernel/pci.c b/arch/mips/kernel/pci.c
index 25ea56fdd..6f7374fd2 100644
--- a/arch/mips/kernel/pci.c
+++ b/arch/mips/kernel/pci.c
@@ -13,7 +13,9 @@
#include <linux/types.h>
#include <asm/pci.h>
-#ifndef CONFIG_PCI
+#ifdef CONFIG_PCI
+
+struct pci_ops *pci_ops;
/*
* BIOS32 replacement.
@@ -24,15 +26,13 @@ __initfunc(unsigned long pcibios_init(unsigned long memory_start,
return memory_start;
}
-#else /* defined(CONFIG_PCI) */
-
/*
* Following the generic parts of the MIPS BIOS32 code.
*/
int pcibios_present (void)
{
- return _pcibios_init != NULL;
+ return pci_ops != NULL;
}
/*
@@ -87,68 +87,46 @@ int pcibios_find_class (unsigned int class_code, unsigned short index,
* each PCI chipset configuration. We just run the hook to the machine
* specific implementation.
*/
-unsigned long (*_pcibios_init)(unsigned long memory_start, unsigned long memory_end);
-__initfunc(unsigned long pcibios_init(unsigned long memory_start,
- unsigned long memory_end))
-{
- return _pcibios_init ? _pcibios_init(memory_start, memory_end)
- : memory_start;
-}
-
-unsigned long (*_pcibios_fixup) (unsigned long memory_start,
- unsigned long memory_end);
unsigned long pcibios_fixup (unsigned long memory_start,
unsigned long memory_end)
{
- return _pcibios_fixup(memory_start, memory_end);
+ return pci_ops->pcibios_fixup(memory_start, memory_end);
}
-int (*_pcibios_read_config_byte) (unsigned char bus, unsigned char dev_fn,
- unsigned char where, unsigned char *val);
int pcibios_read_config_byte (unsigned char bus, unsigned char dev_fn,
unsigned char where, unsigned char *val)
{
- return _pcibios_read_config_byte(bus, dev_fn, where, val);
+ return pci_ops->pcibios_read_config_byte(bus, dev_fn, where, val);
}
-int (*_pcibios_read_config_word) (unsigned char bus, unsigned char dev_fn,
- unsigned char where, unsigned short *val);
int pcibios_read_config_word (unsigned char bus, unsigned char dev_fn,
unsigned char where, unsigned short *val)
{
- return _pcibios_read_config_word(bus, dev_fn, where, val);
+ return pci_ops->pcibios_read_config_word(bus, dev_fn, where, val);
}
-int (*_pcibios_read_config_dword) (unsigned char bus, unsigned char dev_fn,
- unsigned char where, unsigned int *val);
int pcibios_read_config_dword (unsigned char bus, unsigned char dev_fn,
unsigned char where, unsigned int *val)
{
- return _pcibios_read_config_dword(bus, dev_fn, where, val);
+ return pci_ops->pcibios_read_config_dword(bus, dev_fn, where, val);
}
-int (*_pcibios_write_config_byte) (unsigned char bus, unsigned char dev_fn,
- unsigned char where, unsigned char val);
int pcibios_write_config_byte (unsigned char bus, unsigned char dev_fn,
unsigned char where, unsigned char val)
{
- return _pcibios_write_config_byte(bus, dev_fn, where, val);
+ return pci_ops->pcibios_write_config_byte(bus, dev_fn, where, val);
}
-int (*_pcibios_write_config_word) (unsigned char bus, unsigned char dev_fn,
- unsigned char where, unsigned short val);
int pcibios_write_config_word (unsigned char bus, unsigned char dev_fn,
unsigned char where, unsigned short val)
{
- return _pcibios_write_config_word(bus, dev_fn, where, val);
+ return pci_ops->pcibios_write_config_word(bus, dev_fn, where, val);
}
-int (*_pcibios_write_config_dword) (unsigned char bus, unsigned char dev_fn,
- unsigned char where, unsigned int val);
int pcibios_write_config_dword (unsigned char bus, unsigned char dev_fn,
unsigned char where, unsigned int val)
{
- return _pcibios_write_config_dword(bus, dev_fn, where, val);
+ return pci_ops->pcibios_write_config_dword(bus, dev_fn, where, val);
}
#endif /* defined(CONFIG_PCI) */
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c
index 0e2803dd3..2c454c019 100644
--- a/arch/mips/kernel/proc.c
+++ b/arch/mips/kernel/proc.c
@@ -5,11 +5,12 @@
*/
#include <linux/delay.h>
#include <linux/kernel.h>
+#include <linux/sched.h>
#include <asm/bootinfo.h>
#include <asm/mipsregs.h>
+#include <asm/processor.h>
+#include <asm/watch.h>
-unsigned long dflushes = 0;
-unsigned long iflushes = 0;
unsigned long unaligned_instructions;
/*
@@ -27,8 +28,15 @@ int get_cpuinfo(char *buffer)
const char *mach_dec_names[] = GROUP_DEC_NAMES;
const char *mach_arc_names[] = GROUP_ARC_NAMES;
const char *mach_sni_rm_names[] = GROUP_SNI_RM_NAMES;
- const char **mach_group_to_name[] = { mach_unknown_names, mach_jazz_names,
- mach_dec_names, mach_arc_names, mach_sni_rm_names};
+ const char *mach_acn_names[] = GROUP_ACN_NAMES;
+ const char *mach_sgi_names[] = GROUP_SGI_NAMES;
+ const char **mach_group_to_name[] = { mach_unknown_names,
+ mach_jazz_names,
+ mach_dec_names,
+ mach_arc_names,
+ mach_sni_rm_names,
+ mach_acn_names,
+ mach_sgi_names };
unsigned int version = read_32bit_cp0_register(CP0_PRID);
int len;
@@ -51,12 +59,16 @@ int get_cpuinfo(char *buffer)
#if defined (__MIPSEL__)
len += sprintf(buffer + len, "byteorder\t\t: little endian\n");
#endif
- len += sprintf(buffer + len, "D-cache flushes\t\t: %lu\n",
- dflushes);
- len += sprintf(buffer + len, "I-cache flushes\t\t: %lu\n",
- iflushes);
len += sprintf(buffer + len, "unaligned accesses\t: %lu\n",
unaligned_instructions);
+ len += sprintf(buffer + len, "wait instruction\t: %s\n",
+ wait_available ? "yes" : "no");
+ len += sprintf(buffer + len, "microsecond timers\t: %s\n",
+ cyclecounter_available ? "yes" : "no");
+ len += sprintf(buffer + len, "extra interrupt vector\t: %s\n",
+ dedicated_iv_available ? "yes" : "no");
+ len += sprintf(buffer + len, "hardware watchpoint\t: %s\n",
+ watch_available ? "yes" : "no");
return len;
}
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 3ffb9b258..6d28d6e98 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -70,10 +70,10 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
struct pt_regs * childregs;
long childksp;
- childksp = (unsigned long)p + KERNEL_STACK_SIZE - 8;
+ childksp = (unsigned long)p + KERNEL_STACK_SIZE - 32;
/* set up new TSS. */
- childregs = ((struct pt_regs *) ((unsigned long)p + KERNEL_STACK_SIZE)) - 1;
+ childregs = (struct pt_regs *) childksp - 1;
*childregs = *regs;
childregs->regs[7] = 0; /* Clear error flag */
if(current->personality == PER_LINUX) {
diff --git a/arch/mips/kernel/r2300_fpu.S b/arch/mips/kernel/r2300_fpu.S
index fc4e04617..6c699c74d 100644
--- a/arch/mips/kernel/r2300_fpu.S
+++ b/arch/mips/kernel/r2300_fpu.S
@@ -10,7 +10,7 @@
* Multi-arch abstraction and asm macros for easier reading:
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
*
- * $Id: r2300_fpu.S,v 1.2 1997/06/25 14:44:51 ralf Exp $
+ * $Id: r2300_fpu.S,v 1.3 1997/12/01 16:54:20 ralf Exp $
*/
#include <asm/asm.h>
#include <asm/fpregdef.h>
@@ -30,7 +30,7 @@
nop
cfc1 t0,fcr31
- /* Store the 16 odd double precision registers */
+ /* Store the 32 single precision registers */
swc1 $f0,(SC_FPREGS+0)(a0)
swc1 $f1,(SC_FPREGS+8)(a0)
swc1 $f2,(SC_FPREGS+16)(a0)
@@ -76,7 +76,8 @@
.set macro
END(r2300_save_fp_context)
-/* Restore fpu state:
+/*
+ * Restore fpu state:
* - fp gp registers
* - cp1 status/control register
*
@@ -91,7 +92,6 @@
bgez t0,1f
nop
- bgez t0,1f
lw t0,SC_FPC_CSR(a0)
/* Restore the 16 odd double precision registers only
* when enabled in the cp0 status register.
diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S
index c5c519f4e..72638d462 100644
--- a/arch/mips/kernel/r4k_fpu.S
+++ b/arch/mips/kernel/r4k_fpu.S
@@ -10,7 +10,7 @@
* Multi-arch abstraction and asm macros for easier reading:
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
*
- * $Id: r4k_fpu.S,v 1.2 1997/06/25 14:44:52 ralf Exp $
+ * $Id: r4k_fpu.S,v 1.3 1997/12/01 16:56:06 ralf Exp $
*/
#include <asm/asm.h>
#include <asm/fpregdef.h>
@@ -21,7 +21,7 @@
.set noreorder
.set mips3
/* Save floating point context */
- LEAF(r4k_save_fp_context)
+LEAF(r4k_save_fp_context)
mfc0 t1,CP0_STATUS
sll t2,t1,2
bgez t2,2f
@@ -31,41 +31,41 @@
bgez t2,1f
nop
/* Store the 16 odd double precision registers */
- swc1 $f1,(SC_FPREGS+8)(a0)
- swc1 $f3,(SC_FPREGS+24)(a0)
- swc1 $f5,(SC_FPREGS+40)(a0)
- swc1 $f7,(SC_FPREGS+56)(a0)
- swc1 $f9,(SC_FPREGS+72)(a0)
- swc1 $f11,(SC_FPREGS+88)(a0)
- swc1 $f13,(SC_FPREGS+104)(a0)
- swc1 $f15,(SC_FPREGS+120)(a0)
- swc1 $f17,(SC_FPREGS+136)(a0)
- swc1 $f19,(SC_FPREGS+152)(a0)
- swc1 $f21,(SC_FPREGS+168)(a0)
- swc1 $f23,(SC_FPREGS+184)(a0)
- swc1 $f25,(SC_FPREGS+200)(a0)
- swc1 $f27,(SC_FPREGS+216)(a0)
- swc1 $f29,(SC_FPREGS+232)(a0)
- swc1 $f31,(SC_FPREGS+248)(a0)
+ sdc1 $f1,(SC_FPREGS+8)(a0)
+ sdc1 $f3,(SC_FPREGS+24)(a0)
+ sdc1 $f5,(SC_FPREGS+40)(a0)
+ sdc1 $f7,(SC_FPREGS+56)(a0)
+ sdc1 $f9,(SC_FPREGS+72)(a0)
+ sdc1 $f11,(SC_FPREGS+88)(a0)
+ sdc1 $f13,(SC_FPREGS+104)(a0)
+ sdc1 $f15,(SC_FPREGS+120)(a0)
+ sdc1 $f17,(SC_FPREGS+136)(a0)
+ sdc1 $f19,(SC_FPREGS+152)(a0)
+ sdc1 $f21,(SC_FPREGS+168)(a0)
+ sdc1 $f23,(SC_FPREGS+184)(a0)
+ sdc1 $f25,(SC_FPREGS+200)(a0)
+ sdc1 $f27,(SC_FPREGS+216)(a0)
+ sdc1 $f29,(SC_FPREGS+232)(a0)
+ sdc1 $f31,(SC_FPREGS+248)(a0)
/* Store the 16 even double precision registers */
1:
- swc1 $f0,(SC_FPREGS+0)(a0)
- swc1 $f2,(SC_FPREGS+16)(a0)
- swc1 $f4,(SC_FPREGS+32)(a0)
- swc1 $f6,(SC_FPREGS+48)(a0)
- swc1 $f8,(SC_FPREGS+64)(a0)
- swc1 $f10,(SC_FPREGS+80)(a0)
- swc1 $f12,(SC_FPREGS+96)(a0)
- swc1 $f14,(SC_FPREGS+112)(a0)
- swc1 $f16,(SC_FPREGS+128)(a0)
- swc1 $f18,(SC_FPREGS+144)(a0)
- swc1 $f20,(SC_FPREGS+160)(a0)
- swc1 $f22,(SC_FPREGS+176)(a0)
- swc1 $f24,(SC_FPREGS+192)(a0)
- swc1 $f26,(SC_FPREGS+208)(a0)
- swc1 $f28,(SC_FPREGS+224)(a0)
- swc1 $f30,(SC_FPREGS+240)(a0)
+ sdc1 $f0,(SC_FPREGS+0)(a0)
+ sdc1 $f2,(SC_FPREGS+16)(a0)
+ sdc1 $f4,(SC_FPREGS+32)(a0)
+ sdc1 $f6,(SC_FPREGS+48)(a0)
+ sdc1 $f8,(SC_FPREGS+64)(a0)
+ sdc1 $f10,(SC_FPREGS+80)(a0)
+ sdc1 $f12,(SC_FPREGS+96)(a0)
+ sdc1 $f14,(SC_FPREGS+112)(a0)
+ sdc1 $f16,(SC_FPREGS+128)(a0)
+ sdc1 $f18,(SC_FPREGS+144)(a0)
+ sdc1 $f20,(SC_FPREGS+160)(a0)
+ sdc1 $f22,(SC_FPREGS+176)(a0)
+ sdc1 $f24,(SC_FPREGS+192)(a0)
+ sdc1 $f26,(SC_FPREGS+208)(a0)
+ sdc1 $f28,(SC_FPREGS+224)(a0)
+ sdc1 $f30,(SC_FPREGS+240)(a0)
sw t1,SC_FPC_CSR(a0)
cfc1 t0,$0 # implementation/version
@@ -80,7 +80,8 @@
.set macro
END(r4k_save_fp_context)
-/* Restore fpu state:
+/*
+ * Restore fpu state:
* - fp gp registers
* - cp1 status/control register
*
@@ -88,7 +89,7 @@
* frame on the current content of c0_status, not on the content of the
* stack frame which might have been changed by the user.
*/
- LEAF(r4k_restore_fp_context)
+LEAF(r4k_restore_fp_context)
mfc0 t1,CP0_STATUS
sll t0,t1,2
bgez t0,2f
@@ -99,52 +100,46 @@
/* Restore the 16 odd double precision registers only
* when enabled in the cp0 status register.
*/
- lwc1 $f1,(SC_FPREGS+8)(a0)
- lwc1 $f3,(SC_FPREGS+24)(a0)
- lwc1 $f5,(SC_FPREGS+40)(a0)
- lwc1 $f7,(SC_FPREGS+56)(a0)
- lwc1 $f9,(SC_FPREGS+72)(a0)
- lwc1 $f11,(SC_FPREGS+88)(a0)
- lwc1 $f13,(SC_FPREGS+104)(a0)
- lwc1 $f15,(SC_FPREGS+120)(a0)
- lwc1 $f17,(SC_FPREGS+136)(a0)
- lwc1 $f19,(SC_FPREGS+152)(a0)
- lwc1 $f21,(SC_FPREGS+168)(a0)
- lwc1 $f23,(SC_FPREGS+184)(a0)
- lwc1 $f25,(SC_FPREGS+200)(a0)
- lwc1 $f27,(SC_FPREGS+216)(a0)
- lwc1 $f29,(SC_FPREGS+232)(a0)
- lwc1 $f31,(SC_FPREGS+248)(a0)
+ ldc1 $f1,(SC_FPREGS+8)(a0)
+ ldc1 $f3,(SC_FPREGS+24)(a0)
+ ldc1 $f5,(SC_FPREGS+40)(a0)
+ ldc1 $f7,(SC_FPREGS+56)(a0)
+ ldc1 $f9,(SC_FPREGS+72)(a0)
+ ldc1 $f11,(SC_FPREGS+88)(a0)
+ ldc1 $f13,(SC_FPREGS+104)(a0)
+ ldc1 $f15,(SC_FPREGS+120)(a0)
+ ldc1 $f17,(SC_FPREGS+136)(a0)
+ ldc1 $f19,(SC_FPREGS+152)(a0)
+ ldc1 $f21,(SC_FPREGS+168)(a0)
+ ldc1 $f23,(SC_FPREGS+184)(a0)
+ ldc1 $f25,(SC_FPREGS+200)(a0)
+ ldc1 $f27,(SC_FPREGS+216)(a0)
+ ldc1 $f29,(SC_FPREGS+232)(a0)
+ ldc1 $f31,(SC_FPREGS+248)(a0)
- /* Restore the 16 even double precision registers
+ /*
+ * Restore the 16 even double precision registers
* when cp1 was enabled in the cp0 status register.
*/
-1:
- lwc1 $f0,(SC_FPREGS+0)(a0)
- lwc1 $f2,(SC_FPREGS+16)(a0)
- lwc1 $f4,(SC_FPREGS+32)(a0)
- lwc1 $f6,(SC_FPREGS+48)(a0)
- lwc1 $f8,(SC_FPREGS+64)(a0)
- lwc1 $f10,(SC_FPREGS+80)(a0)
- lwc1 $f12,(SC_FPREGS+96)(a0)
- lwc1 $f14,(SC_FPREGS+112)(a0)
- lwc1 $f16,(SC_FPREGS+128)(a0)
- lwc1 $f18,(SC_FPREGS+144)(a0)
- lwc1 $f20,(SC_FPREGS+160)(a0)
- lwc1 $f22,(SC_FPREGS+176)(a0)
- lwc1 $f24,(SC_FPREGS+192)(a0)
- lwc1 $f26,(SC_FPREGS+208)(a0)
- lwc1 $f28,(SC_FPREGS+224)(a0)
- lwc1 $f30,(SC_FPREGS+240)(a0)
- ctc1 t0,fcr31
-
+1: ldc1 $f0,(SC_FPREGS+0)(a0)
+ ldc1 $f2,(SC_FPREGS+16)(a0)
+ ldc1 $f4,(SC_FPREGS+32)(a0)
+ ldc1 $f6,(SC_FPREGS+48)(a0)
+ ldc1 $f8,(SC_FPREGS+64)(a0)
+ ldc1 $f10,(SC_FPREGS+80)(a0)
+ ldc1 $f12,(SC_FPREGS+96)(a0)
+ ldc1 $f14,(SC_FPREGS+112)(a0)
+ ldc1 $f16,(SC_FPREGS+128)(a0)
+ ldc1 $f18,(SC_FPREGS+144)(a0)
+ ldc1 $f20,(SC_FPREGS+160)(a0)
+ ldc1 $f22,(SC_FPREGS+176)(a0)
+ ldc1 $f24,(SC_FPREGS+192)(a0)
+ ldc1 $f26,(SC_FPREGS+208)(a0)
+ ldc1 $f28,(SC_FPREGS+224)(a0)
+ ldc1 $f30,(SC_FPREGS+240)(a0)
jr ra
- .set nomacro
- nop
- .set macro
-2:
- jr ra
- .set nomacro
+ ctc1 t0,fcr31
+
+2: jr ra
nop
- .set macro
END(r4k_restore_fp_context)
diff --git a/arch/mips/kernel/r4k_misc.S b/arch/mips/kernel/r4k_misc.S
index 090b3109f..2e0223260 100644
--- a/arch/mips/kernel/r4k_misc.S
+++ b/arch/mips/kernel/r4k_misc.S
@@ -6,7 +6,7 @@
* Multi-cpu abstraction and reworking:
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
*
- * $Id: r4k_misc.S,v 1.2 1997/06/09 06:20:52 ralf Exp $
+ * $Id: r4k_misc.S,v 1.3 1997/09/07 04:51:07 ralf Exp $
*/
#include <asm/asm.h>
#include <asm/current.h>
diff --git a/arch/mips/kernel/r6000_fpu.S b/arch/mips/kernel/r6000_fpu.S
index 66d4fa848..db471fa96 100644
--- a/arch/mips/kernel/r6000_fpu.S
+++ b/arch/mips/kernel/r6000_fpu.S
@@ -10,7 +10,7 @@
* Multi-arch abstraction and asm macros for easier reading:
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
*
- * $Id: r6000_fpu.S,v 1.2 1997/06/25 14:44:52 ralf Exp $
+ * $Id: r6000_fpu.S,v 1.3 1997/12/01 16:56:56 ralf Exp $
*/
#include <asm/asm.h>
#include <asm/fpregdef.h>
@@ -44,18 +44,10 @@
sdc1 $f26,(SC_FPREGS+208)(a0)
sdc1 $f28,(SC_FPREGS+224)(a0)
sdc1 $f30,(SC_FPREGS+240)(a0)
- sw t0,SC_FPC_CSR(a0)
- cfc1 t0,$0 # implementation/version
-
- jr ra
- .set nomacro
- sw t0,SC_FPC_EIR(a0)
- .set macro
-1:
jr ra
- .set nomacro
+ sw t0,SC_FPC_CSR(a0)
+1: jr ra
nop
- .set macro
END(r6000_save_fp_context)
/* Restore fpu state:
@@ -89,14 +81,8 @@
ldc1 $f26,(SC_FPREGS+208)(a0)
ldc1 $f28,(SC_FPREGS+224)(a0)
ldc1 $f30,(SC_FPREGS+240)(a0)
-
jr ra
- .set nomacro
ctc1 t0,fcr31
- .set macro
-1:
- jr ra
- .set nomacro
+1: jr ra
nop
- .set macro
END(r6000_restore_fp_context)
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 3ebf269f5..a1932d117 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -5,7 +5,7 @@
* Copyright (C) 1995, 1996 Ralf Baechle
* Copyright (C) 1996 Stoned Elipot
*
- * $Id:$
+ * $Id: setup.c,v 1.4 1997/09/07 04:55:42 ralf Exp $
*/
#include <linux/config.h>
#include <linux/errno.h>
@@ -122,6 +122,12 @@ static char command_line[CL_SIZE] = { 0, };
void (*irq_setup)(void);
/*
+ * mips_io_port_base is the begin of the address space to which x86 style
+ * I/O ports are mapped.
+ */
+unsigned long mips_io_port_base;
+
+/*
* isa_slot_offset is the address where E(ISA) busaddress 0 is is mapped
* for the processor.
*/
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index 4ff1a98b4..481a34147 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -4,7 +4,7 @@
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright (C) 1994, 1995, 1996 Ralf Baechle
*
- * $Id: signal.c,v 1.5 1997/09/12 01:30:24 ralf Exp $
+ * $Id: signal.c,v 1.8 1997/12/01 16:26:34 ralf Exp $
*/
#include <linux/config.h>
#include <linux/sched.h>
@@ -174,7 +174,7 @@ static void setup_frame(struct sigaction * sa, struct pt_regs *regs,
* Set up the return code ...
*
* .set noreorder
- * addiu sp,24
+ * addiu sp,0x20
* li v0,__NR_sigreturn
* syscall
* .set reorder
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index 0a190e3ab..ffcf176e4 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -10,6 +10,8 @@
* TODO: Implement the compatibility syscalls.
* Don't waste that much memory for empty entries in the syscall
* table.
+ *
+ * $Id: syscall.c,v 1.4 1997/09/18 07:57:30 root Exp $
*/
#undef CONF_PRINT_SYSCALLS
#undef CONF_DEBUG_IRIX
@@ -84,15 +86,17 @@ asmlinkage int sys_idle(void)
current->counter = -100;
for (;;) {
/*
- * R4[236]00 have wait, R4[04]00 don't.
+ * R4[36]00 have wait, R4[04]00 don't.
* FIXME: We should save power by reducing the clock where
- * possible. Should help alot for battery powered
- * R4200/4300i systems.
+ * possible. Thiss will cut down the power consuption
+ * of R4200 systems to about 1/16th of normal, the
+ * same for logic clocked with the processor generated
+ * clocks.
*/
if (wait_available && !need_resched)
__asm__(".set\tmips3\n\t"
"wait\n\t"
- ".set\tmips0\n\t");
+ ".set\tmips0");
run_task_queue(&tq_scheduler);
schedule();
}
diff --git a/arch/mips/kernel/syscalls.h b/arch/mips/kernel/syscalls.h
index 3232af01c..159931b4b 100644
--- a/arch/mips/kernel/syscalls.h
+++ b/arch/mips/kernel/syscalls.h
@@ -5,9 +5,9 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 1995, 1996, 1997 by Ralf Baechle
+ * Copyright (C) 1995, 1996 by Ralf Baechle
*
- * $Id: syscalls.h,v 1.6 1997/08/06 19:15:08 miguel Exp $
+ * $Id: syscalls.h,v 1.5 1997/09/11 01:57:38 ralf Exp $
*/
/*
@@ -210,5 +210,3 @@ SYS(sys_poll, 3)
SYS(sys_nfsservctl, 3)
SYS(sys_setresgid, 3) /* 4190 */
SYS(sys_getresgid, 3)
-SYS(sys_setresgid, 3) /* 4190 */
-SYS(sys_getresgid, 3)
diff --git a/arch/mips/kernel/sysmips.c b/arch/mips/kernel/sysmips.c
index e73598345..62f8687c0 100644
--- a/arch/mips/kernel/sysmips.c
+++ b/arch/mips/kernel/sysmips.c
@@ -7,7 +7,7 @@
*
* Copyright (C) 1995, 1996, 1997 by Ralf Baechle
*
- * $Id: sysmips.c,v 1.2 1997/07/01 08:59:08 ralf Exp $
+ * $Id: sysmips.c,v 1.3 1997/07/18 06:26:02 ralf Exp $
*/
#include <linux/errno.h>
#include <linux/linkage.h>
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
index 886b9b35e..f2cbabd86 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -6,7 +6,7 @@
* This file contains the time handling details for PC-style clocks as
* found in some MIPS systems.
*
- * $Id: time.c,v 1.2 1997/07/01 08:59:08 ralf Exp $
+ * $Id: time.c,v 1.5 1997/11/12 12:12:12 ralf Exp $
*/
#include <linux/errno.h>
#include <linux/init.h>
@@ -39,7 +39,6 @@ extern volatile unsigned long lost_ticks;
/* Cycle counter value at the previous timer interrupt.. */
static unsigned int timerhi = 0, timerlo = 0;
-static char cyclecounter_available = 1;
/*
* On MIPS only R4000 and better have a cycle counter.
@@ -397,7 +396,7 @@ static inline unsigned long mktime(unsigned int year, unsigned int mon,
)*60 + sec; /* finally seconds */
}
-static char cyclecounter_available;
+char cyclecounter_available;
static inline void init_cycle_counter(void)
{
@@ -437,7 +436,9 @@ static inline void init_cycle_counter(void)
}
}
-static struct irqaction irq0 = { timer_interrupt, 0, 0, "timer", NULL, NULL};
+struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0,
+ "timer", NULL, NULL};
+
void (*board_time_init)(struct irqaction *irq);
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 99ebc3aeb..fc0dd091c 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -8,7 +8,7 @@
* Copyright 1994, 1995, 1996, 1997 by Ralf Baechle
* Modified for R3000 by Paul M. Antoine, 1995, 1996
*
- * $Id: traps.c,v 1.3 1997/09/17 07:22:12 ralf Exp $
+ * $Id: traps.c,v 1.7 1997/12/01 16:33:28 ralf Exp $
*/
#include <linux/config.h>
#include <linux/init.h>
@@ -72,7 +72,8 @@ extern asmlinkage void handle_reserved(void);
static char *cpu_names[] = CPU_NAMES;
-unsigned int watch_available = 0;
+char watch_available = 0;
+char dedicated_iv_available = 0;
void (*ibe_board_handler)(struct pt_regs *regs);
void (*dbe_board_handler)(struct pt_regs *regs);
@@ -175,7 +176,7 @@ void die_if_kernel(const char * str, struct pt_regs * regs, long err)
return;
#endif
#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4)
- if (!(regs->cp0_status & 0x18))
+ if (regs->cp0_status & ST0_KSU == KSU_USER)
return;
#endif
console_verbose();
@@ -189,8 +190,6 @@ static void default_be_board_handler(struct pt_regs *regs)
/*
* Assume it would be too dangerous to continue ...
*/
- printk ("BE HANDLER\n");
- show_regs (regs);
force_sig(SIGBUS, current);
}
@@ -427,6 +426,40 @@ static inline void watch_init(unsigned long cputype)
}
}
+/*
+ * Some MIPS CPUs have a dedicated interrupt vector which reduces the
+ * interrupt processing overhead. Use it where available.
+ * FIXME: more CPUs than just the Nevada have this feature.
+ */
+static inline void setup_dedicated_int(void)
+{
+ extern void except_vec4(void);
+ switch(mips_cputype) {
+ case CPU_NEVADA:
+ memcpy((void *)(KSEG0 + 0x200), except_vec4, 8);
+ set_cp0_cause(CAUSEF_IV, CAUSEF_IV);
+ dedicated_iv_available = 1;
+ }
+}
+
+unsigned long exception_handlers[32];
+
+/*
+ * As a side effect of the way this is implemented we're limited
+ * to interrupt handlers in the address range from
+ * KSEG0 <= x < KSEG0 + 256mb on the Nevada. Oh well ...
+ */
+void set_except_vector(int n, void *addr)
+{
+ unsigned handler = (unsigned long) addr;
+ exception_handlers[n] = handler;
+ if (n == 0 && dedicated_iv_available) {
+ *(volatile u32 *)(KSEG0+0x200) = 0x08000000 |
+ (0x03ffffff & (handler >> 2));
+ flush_icache_range(KSEG0+0x200, KSEG0 + 0x204);
+ }
+}
+
typedef asmlinkage int (*syscall_t)(void *a0,...);
asmlinkage int (*do_syscalls)(struct pt_regs *regs, syscall_t fun, int narg);
extern asmlinkage int r4k_do_syscalls(struct pt_regs *regs,
@@ -449,7 +482,8 @@ extern asmlinkage void r2300_resume(void *tsk);
__initfunc(void trap_init(void))
{
- extern char except_vec0_r4000, except_vec0_r4600, except_vec0_r2300;
+ extern char except_vec0_nevada, except_vec0_r4000;
+ extern char except_vec0_r4600, except_vec0_r2300;
extern char except_vec1_generic, except_vec2_generic;
extern char except_vec3_generic, except_vec3_r4000;
unsigned long i;
@@ -471,9 +505,11 @@ __initfunc(void trap_init(void))
set_except_vector(i, handle_reserved);
/*
- * Only some CPUs have the watch exception.
+ * Only some CPUs have the watch exceptions or a dedicated
+ * interrupt vector.
*/
watch_init(mips_cputype);
+ setup_dedicated_int();
/*
* Handling the following exceptions depends mostly of the cpu type
@@ -509,10 +545,12 @@ __initfunc(void trap_init(void))
case CPU_R4600:
case CPU_R5000:
case CPU_NEVADA:
- if(mips_cputype != CPU_R4600)
- memcpy((void *)KSEG0, &except_vec0_r4000, 0x80);
- else
+ if(mips_cputype == CPU_NEVADA) {
+ memcpy((void *)KSEG0, &except_vec0_nevada, 0x80);
+ } else if (mips_cputype == CPU_R4600)
memcpy((void *)KSEG0, &except_vec0_r4600, 0x80);
+ else
+ memcpy((void *)KSEG0, &except_vec0_r4000, 0x80);
/*
* The idea is that this special r4000 general exception
@@ -611,5 +649,5 @@ __initfunc(void trap_init(void))
default:
panic("Unknown CPU type");
}
- flush_cache_all();
+ flush_icache_range(KSEG0, KSEG0 + 0x200);
}
diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c
index 696244b6c..ea81ba7db 100644
--- a/arch/mips/kernel/unaligned.c
+++ b/arch/mips/kernel/unaligned.c
@@ -407,11 +407,11 @@ do_ade(struct pt_regs *regs)
{
register_t pc = regs->cp0_epc;
register_t badvaddr __attribute__ ((unused)) = regs->cp0_badvaddr;
- char *adels;
+ char adels;
lock_kernel();
adels = (((regs->cp0_cause & CAUSEF_EXCCODE) >>
- CAUSEB_EXCCODE) == 4) ? "adel" : "ades";
+ CAUSEB_EXCCODE) == 4) ? 'l' : 's';
#ifdef CONF_NO_UNALIGNED_KERNEL_ACCESS
/*
@@ -420,13 +420,8 @@ do_ade(struct pt_regs *regs)
*/
if (kernel_address(badvaddr) && !user_mode(regs)) {
show_regs(regs);
-#ifdef __mips64
- panic("Caught %s exception in kernel mode accessing %016Lx.",
- adels, badvaddr);
-#else
- panic("Caught %s exception in kernel mode accessing %08lx.",
- adels, badvaddr);
-#endif
+ panic("Caught adel%c exception in kernel mode accessing %08lx.",
+ adels, badvaddr);
}
#endif /* CONF_NO_UNALIGNED_KERNEL_ACCESS */
@@ -435,15 +430,9 @@ do_ade(struct pt_regs *regs)
register_t logpc = pc;
if (regs->cp0_cause & CAUSEF_BD)
logpc += 4;
-#ifdef __mips64
- printk(KERN_DEBUG
- "Caught %s in '%s' at 0x%016Lx accessing 0x%016Lx.\n",
- adels, current->comm, logpc, regs->cp0_badvaddr);
-#else
printk(KERN_DEBUG
- "Caught %s in '%s' at 0x%08lx accessing 0x%08lx.\n",
+ "Caught adel%c in '%s' at 0x%08lx accessing 0x%08lx.\n",
adels, current->comm, logpc, regs->cp0_badvaddr);
-#endif
}
#endif /* CONF_LOG_UNALIGNED_ACCESSES */