summaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/lib/Makefile6
-rw-r--r--arch/mips/lib/floppy-std.c3
-rw-r--r--arch/mips/lib/ide-std.c2
-rw-r--r--arch/mips/lib/kbd-no.c63
-rw-r--r--arch/mips/lib/kbd-std.c81
-rw-r--r--arch/mips/mm/andes.c7
-rw-r--r--arch/mips/mm/fault.c39
-rw-r--r--arch/mips/mm/init.c123
-rw-r--r--arch/mips/mm/r2300.c7
-rw-r--r--arch/mips/mm/r4xx0.c3
-rw-r--r--arch/mips/mm/r6000.c5
-rw-r--r--arch/mips/mm/tfp.c5
-rw-r--r--arch/mips/sgi/kernel/indy_int.c18
-rw-r--r--arch/mips/sgi/kernel/indy_sc.c3
-rw-r--r--arch/mips/sgi/kernel/indy_timer.c6
-rw-r--r--arch/mips/sgi/kernel/setup.c64
-rw-r--r--arch/mips/sni/Makefile5
-rw-r--r--arch/mips/sni/hw-access.c70
-rw-r--r--arch/mips/sni/int-handler.S214
-rw-r--r--arch/mips/sni/io.c106
-rw-r--r--arch/mips/sni/pci.c41
-rw-r--r--arch/mips/sni/pcimt_scache.c33
-rw-r--r--arch/mips/sni/setup.c22
23 files changed, 478 insertions, 448 deletions
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
index f5a79996c..5d21e075b 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.7 1998/06/30 00:21:54 ralf Exp $
+# $Id: Makefile,v 1.8 1998/10/18 13:21:50 tsbogend Exp $
#
# Makefile for MIPS-specific library files..
#
@@ -10,7 +10,7 @@
L_TARGET = lib.a
L_OBJS = csum_partial.o csum_partial_copy.o dump_tlb.o floppy-std.o \
- floppy-no.o ide-std.o ide-no.o rtc-std.o rtc-no.o memset.o memcpy.o \
- strlen_user.o strncpy_user.o watch.o
+ floppy-no.o ide-std.o ide-no.o kbd-std.o kbd-no.o rtc-std.o \
+ rtc-no.o memset.o memcpy.o strlen_user.o strncpy_user.o watch.o
include $(TOPDIR)/Rules.make
diff --git a/arch/mips/lib/floppy-std.c b/arch/mips/lib/floppy-std.c
index 04b32f40a..3d1c95feb 100644
--- a/arch/mips/lib/floppy-std.c
+++ b/arch/mips/lib/floppy-std.c
@@ -1,4 +1,4 @@
-/* $Id: floppy-std.c,v 1.2 1998/05/28 03:17:57 ralf Exp $
+/* $Id: floppy-std.c,v 1.3 1998/10/28 12:38: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
@@ -12,7 +12,6 @@
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/sched.h>
-#include <linux/kbdcntrlr.h>
#include <linux/kernel.h>
#include <linux/linkage.h>
#include <linux/types.h>
diff --git a/arch/mips/lib/ide-std.c b/arch/mips/lib/ide-std.c
index e6bf4dc5f..97c2c0c33 100644
--- a/arch/mips/lib/ide-std.c
+++ b/arch/mips/lib/ide-std.c
@@ -9,6 +9,8 @@
*
* Copyright (C) 1998 by Ralf Baechle
*/
+#include <linux/sched.h>
+#include <linux/ioport.h>
#include <linux/hdreg.h>
#include <asm/ptrace.h>
#include <asm/ide.h>
diff --git a/arch/mips/lib/kbd-no.c b/arch/mips/lib/kbd-no.c
new file mode 100644
index 000000000..c94e8c000
--- /dev/null
+++ b/arch/mips/lib/kbd-no.c
@@ -0,0 +1,63 @@
+/* $Id: kbd-no.c,v 1.1 1998/10/28 12:38:14 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
+ * for more details.
+ *
+ * Stub keyboard and psaux routines to keep Linux from crashing on machines
+ * without a keyboard.
+ *
+ * Copyright (C) 1998 by Ralf Baechle
+ */
+#include <linux/sched.h>
+#include <asm/keyboard.h>
+
+static void no_kbd_request_region(void)
+{
+ /* No I/O ports are being used on the Indy. */
+}
+
+static int no_kbd_request_irq(void (*handler)(int, void *, struct pt_regs *))
+{
+ return -ENODEV;
+}
+
+static int no_aux_request_irq(void (*handler)(int, void *, struct pt_regs *))
+{
+ return -ENODEV;
+}
+
+static void no_aux_free_irq(void)
+{
+}
+
+static unsigned char no_kbd_read_input(void)
+{
+ return 0;
+}
+
+static void no_kbd_write_output(unsigned char val)
+{
+}
+
+static void no_kbd_write_command(unsigned char val)
+{
+}
+
+static unsigned char no_kbd_read_status(void)
+{
+ return 0;
+}
+
+struct kbd_ops no_kbd_ops = {
+ no_kbd_request_region,
+ no_kbd_request_irq,
+
+ no_aux_request_irq,
+ no_aux_free_irq,
+
+ no_kbd_read_input,
+ no_kbd_write_output,
+ no_kbd_write_command,
+ no_kbd_read_status
+};
diff --git a/arch/mips/lib/kbd-std.c b/arch/mips/lib/kbd-std.c
new file mode 100644
index 000000000..9ccb49fbd
--- /dev/null
+++ b/arch/mips/lib/kbd-std.c
@@ -0,0 +1,81 @@
+/* $Id: kbd-std.c,v 1.1 1998/10/28 12:38:14 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
+ * for more details.
+ *
+ * Routines for standard PC style keyboards accessible via I/O ports.
+ *
+ * Copyright (C) 1998 by Ralf Baechle
+ */
+#include <linux/pc_keyb.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <asm/keyboard.h>
+#include <asm/io.h>
+
+#define KEYBOARD_IRQ 1
+#define AUX_IRQ 12
+
+static void std_kbd_request_region(void)
+{
+ request_region(0x60, 16, "keyboard");
+}
+
+static int std_kbd_request_irq(void (*handler)(int, void *, struct pt_regs *))
+{
+ return request_irq(KEYBOARD_IRQ, handler, 0, "keyboard", NULL);
+}
+
+static int std_aux_request_irq(void (*handler)(int, void *, struct pt_regs *))
+{
+ return request_irq(AUX_IRQ, handler, 0, "PS/2 Mouse", NULL);
+}
+
+static void std_aux_free_irq(void)
+{
+ free_irq(AUX_IRQ, NULL);
+}
+
+static unsigned char std_kbd_read_input(void)
+{
+ return inb(KBD_DATA_REG);
+}
+
+static void std_kbd_write_output(unsigned char val)
+{
+ int status;
+
+ do {
+ status = inb(KBD_CNTL_REG);
+ } while (status & KBD_STAT_IBF);
+ outb(val, KBD_DATA_REG);
+}
+
+static void std_kbd_write_command(unsigned char val)
+{
+ int status;
+
+ do {
+ status = inb(KBD_CNTL_REG);
+ } while (status & KBD_STAT_IBF);
+ outb(val, KBD_CNTL_REG);
+}
+
+static unsigned char std_kbd_read_status(void)
+{
+ return inb(KBD_STATUS_REG);
+}
+
+struct kbd_ops std_kbd_ops = {
+ std_kbd_request_region,
+ std_kbd_request_irq,
+
+ std_aux_request_irq,
+ std_aux_free_irq,
+
+ std_kbd_read_input,
+ std_kbd_write_output,
+ std_kbd_write_command,
+ std_kbd_read_status
+};
diff --git a/arch/mips/mm/andes.c b/arch/mips/mm/andes.c
index b29dcb274..c0653eb64 100644
--- a/arch/mips/mm/andes.c
+++ b/arch/mips/mm/andes.c
@@ -1,9 +1,8 @@
-/*
+/* $Id: andes.c,v 1.5 1998/05/04 09:12:55 ralf Exp $
+ *
* andes.c: MMU and cache operations for the R10000 (ANDES).
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
- * $Id: andes.c,v 1.4 1998/04/05 11:23:54 ralf Exp $
*/
#include <linux/init.h>
#include <linux/kernel.h>
@@ -13,6 +12,7 @@
#include <asm/pgtable.h>
#include <asm/system.h>
#include <asm/sgialib.h>
+#include <asm/mmu_context.h>
extern unsigned long mips_tlb_entries;
@@ -104,6 +104,7 @@ __initfunc(void ld_mmu_andes(void))
flush_tlb_mm = andes_flush_tlb_mm;
flush_tlb_range = andes_flush_tlb_range;
flush_tlb_page = andes_flush_tlb_page;
+ andes_asid_setup();
add_wired_entry = andes_add_wired_entry;
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index d1ec6cb4c..18bfbf80e 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -1,8 +1,10 @@
-/* $Id: fault.c,v 1.10 1998/09/16 22:50:44 ralf Exp $
+/* $Id: fault.c,v 1.8 1998/09/19 19:16:18 ralf Exp $
*
- * arch/mips/mm/fault.c
+ * 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
+ * for more details.
*
- * Copyright (C) 1995, 1996, 1997 by Ralf Baechle
+ * Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle
*/
#include <linux/signal.h>
#include <linux/sched.h>
@@ -16,6 +18,7 @@
#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
+#include <linux/version.h>
#include <asm/hardirq.h>
#include <asm/pgtable.h>
@@ -24,9 +27,11 @@
#include <asm/system.h>
#include <asm/uaccess.h>
+#define development_version (LINUX_VERSION_CODE & 0x100)
+
extern void die(char *, struct pt_regs *, unsigned long write);
-unsigned long asid_cache = ASID_FIRST_VERSION;
+unsigned long asid_cache;
/*
* Macro for exception fixup code to access integer registers.
@@ -46,9 +51,12 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
struct mm_struct *mm = tsk->mm;
unsigned long fixup;
- if (in_interrupt())
- die("page fault from irq handler", regs, writeaccess);
- lock_kernel();
+ /*
+ * If we're in an interrupt or have no user
+ * context, we must not take the fault..
+ */
+ if (in_interrupt() || mm == &init_mm)
+ goto no_context;
#if 0
printk("[%s:%d:%08lx:%ld:%08lx]\n", current->comm, current->pid,
address, writeaccess, regs->cp0_epc);
@@ -77,8 +85,7 @@ good_area:
}
handle_mm_fault(tsk, vma, address, writeaccess);
up(&mm->mmap_sem);
-
- goto out;
+ return;
/*
* Something tried to access memory that isn't in our memory map..
@@ -100,20 +107,22 @@ bad_area:
(unsigned long) regs->regs[31]);
#endif
force_sig(SIGSEGV, tsk);
- goto out;
+ return;
}
- /* Did we have an exception handler installed? */
+no_context:
+ /* Are we prepared to handle this kernel fault? */
fixup = search_exception_table(regs->cp0_epc);
if (fixup) {
long new_epc;
tsk->tss.cp0_baduaddr = address;
new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc);
- printk(KERN_DEBUG "%s: Exception at [<%lx>] (%lx)\n",
- tsk->comm, regs->cp0_epc, new_epc);
+ if (development_version)
+ printk(KERN_DEBUG "%s: Exception at [<%lx>] (%lx)\n",
+ tsk->comm, regs->cp0_epc, new_epc);
regs->cp0_epc = new_epc;
- goto out;
+ return;
}
/*
@@ -125,6 +134,4 @@ bad_area:
address, regs->cp0_epc, regs->regs[31]);
die("Oops", regs, writeaccess);
do_exit(SIGKILL);
-out:
- unlock_kernel();
}
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 8bdbffaf8..f7fa99a37 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -1,4 +1,4 @@
-/* $Id: init.c,v 1.8 1998/09/04 21:21:34 ralf Exp $
+/* $Id: init.c,v 1.9 1998/09/19 19:16:18 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
@@ -33,13 +33,8 @@
#ifdef CONFIG_SGI
#include <asm/sgialib.h>
#endif
+#include <asm/mmu_context.h>
-/*
- * Define this to effectivly disable the userpage colouring shit.
- */
-#define CONF_GIVE_A_SHIT_ABOUT_COLOURS
-
-extern void deskstation_tyne_dma_init(void);
extern void show_net_buffers(void);
void __bad_pte_kernel(pmd_t *pmd)
@@ -58,7 +53,7 @@ pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset)
{
pte_t *page;
- page = (pte_t *) __get_free_page(GFP_KERNEL);
+ page = (pte_t *) __get_free_page(GFP_USER);
if (pmd_none(*pmd)) {
if (page) {
clear_page((unsigned long)page);
@@ -243,83 +238,6 @@ pte_t __bad_page(void)
return pte_mkdirty(mk_pte(page, PAGE_SHARED));
}
-#ifdef __SMP__
-spinlock_t user_page_lock = SPIN_LOCK_UNLOCKED;
-#endif
-struct upcache user_page_cache[8] __attribute__((aligned(32)));
-static unsigned long user_page_order;
-unsigned long user_page_colours;
-
-unsigned long get_user_page_slow(int which)
-{
- unsigned long chunk;
- struct upcache *up = &user_page_cache[0];
- struct page *p, *res;
- int i;
-
- do {
- chunk = __get_free_pages(GFP_KERNEL, user_page_order);
- } while(chunk==0);
-
- p = mem_map + MAP_NR(chunk);
- res = p + which;
- spin_lock(&user_page_lock);
- for (i=user_page_colours; i>=0; i--,p++,up++,chunk+=PAGE_SIZE) {
- atomic_set(&p->count, 1);
- p->age = PAGE_INITIAL_AGE;
-
- if (p != res) {
- if(up->count < USER_PAGE_WATER) {
- p->next = up->list;
- up->list = p;
- up->count++;
- } else
- free_pages(chunk, 0);
- }
- }
- spin_unlock(&user_page_lock);
-
- return page_address(res);
-}
-
-static inline void user_page_setup(void)
-{
- unsigned long assoc = 0;
- unsigned long dcache_log, icache_log, cache_log;
- unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
-
- switch(mips_cputype) {
- case CPU_R4000SC:
- case CPU_R4000MC:
- case CPU_R4400SC:
- case CPU_R4400MC:
- cache_log = 3; /* => 32k, sucks */
- break;
-
- case CPU_R4600: /* two way set associative caches? */
- case CPU_R4700:
- case CPU_R5000:
- case CPU_NEVADA:
- assoc = 1;
- /* fall through */
- default:
- /* use bigger cache */
- icache_log = (config >> 9) & 7;
- dcache_log = (config >> 6) & 7;
- if (dcache_log > icache_log)
- cache_log = dcache_log;
- else
- cache_log = icache_log;
- }
-
-#ifdef CONF_GIVE_A_SHIT_ABOUT_COLOURS
- cache_log = assoc = 0;
-#endif
-
- user_page_order = cache_log - assoc;
- user_page_colours = (1 << (cache_log - assoc)) - 1;
-}
-
void show_mem(void)
{
int i, free = 0, total = 0, reserved = 0;
@@ -423,9 +341,6 @@ __initfunc(void mem_init(unsigned long start_mem, unsigned long end_mem))
max_mapnr << (PAGE_SHIFT-10),
codepages << (PAGE_SHIFT-10),
datapages << (PAGE_SHIFT-10));
-
- /* Initialize allocator for colour matched mapped pages. */
- user_page_setup();
}
extern char __init_begin, __init_end;
@@ -465,3 +380,35 @@ void si_meminfo(struct sysinfo *val)
val->sharedram <<= PAGE_SHIFT;
return;
}
+
+/* Fixup an immediate instruction */
+__initfunc(static void __i_insn_fixup(unsigned int **start, unsigned int **stop,
+ unsigned int i_const))
+{
+ unsigned int **p, *ip;
+
+ for (p = start;p < stop; p++) {
+ ip = *p;
+ *ip = (*ip & 0xffff0000) | i_const;
+ }
+}
+
+#define i_insn_fixup(section, const) \
+do { \
+ extern unsigned int *__start_ ## section; \
+ extern unsigned int *__stop_ ## section; \
+ __i_insn_fixup(&__start_ ## section, &__stop_ ## section, const); \
+} while(0)
+
+/* Caller is assumed to flush the caches before the first context switch. */
+__initfunc(void __asid_setup(unsigned int inc, unsigned int mask,
+ unsigned int version_mask,
+ unsigned int first_version))
+{
+ i_insn_fixup(__asid_inc, inc);
+ i_insn_fixup(__asid_mask, mask);
+ i_insn_fixup(__asid_version_mask, version_mask);
+ i_insn_fixup(__asid_first_version, first_version);
+
+ asid_cache = first_version;
+}
diff --git a/arch/mips/mm/r2300.c b/arch/mips/mm/r2300.c
index 03a0c63e9..8f8e7ddfa 100644
--- a/arch/mips/mm/r2300.c
+++ b/arch/mips/mm/r2300.c
@@ -1,9 +1,8 @@
-/*
+/* $Id: r2300.c,v 1.6 1998/08/25 09:14:46 ralf Exp $
+ *
* r2300.c: R2000 and R3000 specific mmu/cache code.
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
- * $Id: r2300.c,v 1.5 1998/04/05 11:23:55 ralf Exp $
*/
#include <linux/init.h>
#include <linux/kernel.h>
@@ -14,6 +13,7 @@
#include <asm/pgtable.h>
#include <asm/system.h>
#include <asm/sgialib.h>
+#include <asm/mmu_context.h>
extern unsigned long mips_tlb_entries;
@@ -274,6 +274,7 @@ __initfunc(void ld_mmu_r2300(void))
flush_tlb_mm = r2300_flush_tlb_mm;
flush_tlb_range = r2300_flush_tlb_range;
flush_tlb_page = r2300_flush_tlb_page;
+ r3000_asid_setup();
load_pgd = r2300_load_pgd;
pgd_init = r2300_pgd_init;
diff --git a/arch/mips/mm/r4xx0.c b/arch/mips/mm/r4xx0.c
index 31b636296..1b2ac3674 100644
--- a/arch/mips/mm/r4xx0.c
+++ b/arch/mips/mm/r4xx0.c
@@ -1,4 +1,4 @@
-/* $Id: r4xx0.c,v 1.19 1998/08/25 09:14:46 ralf Exp $
+/* $Id: r4xx0.c,v 1.20 1998/10/14 23:40:45 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
@@ -2791,6 +2791,7 @@ __initfunc(void ld_mmu_r4xx0(void))
flush_tlb_mm = r4k_flush_tlb_mm;
flush_tlb_range = r4k_flush_tlb_range;
flush_tlb_page = r4k_flush_tlb_page;
+ r4xx0_asid_setup();
load_pgd = r4k_load_pgd;
pgd_init = r4k_pgd_init;
diff --git a/arch/mips/mm/r6000.c b/arch/mips/mm/r6000.c
index 047cb7b2f..b8b442728 100644
--- a/arch/mips/mm/r6000.c
+++ b/arch/mips/mm/r6000.c
@@ -1,4 +1,5 @@
-/* $Id: r6000.c,v 1.4 1998/04/05 11:23:56 ralf Exp $
+/* $Id: r6000.c,v 1.5 1998/08/25 09:14:47 ralf Exp $
+ *
* r6000.c: MMU and cache routines for the R6000 processors.
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
@@ -13,6 +14,7 @@
#include <asm/pgtable.h>
#include <asm/system.h>
#include <asm/sgialib.h>
+#include <asm/mmu_context.h>
__asm__(".set mips3"); /* because we know... */
@@ -180,6 +182,7 @@ __initfunc(void ld_mmu_r6000(void))
flush_tlb_mm = r6000_flush_tlb_mm;
flush_tlb_range = r6000_flush_tlb_range;
flush_tlb_page = r6000_flush_tlb_page;
+ r6000_asid_setup();
load_pgd = r6000_load_pgd;
pgd_init = r6000_pgd_init;
diff --git a/arch/mips/mm/tfp.c b/arch/mips/mm/tfp.c
index dab618b3e..0d8ab7c86 100644
--- a/arch/mips/mm/tfp.c
+++ b/arch/mips/mm/tfp.c
@@ -1,4 +1,5 @@
-/*
+/* $Id: tfp.c,v 1.6 1998/10/16 19:22:44 ralf Exp $
+ *
* tfp.c: MMU and cache routines specific to the r8000 (TFP).
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
@@ -13,6 +14,7 @@
#include <asm/pgtable.h>
#include <asm/system.h>
#include <asm/sgialib.h>
+#include <asm/mmu_context.h>
extern unsigned long mips_tlb_entries;
@@ -104,6 +106,7 @@ __initfunc(void ld_mmu_tfp(void))
flush_tlb_mm = tfp_flush_tlb_mm;
flush_tlb_range = tfp_flush_tlb_range;
flush_tlb_page = tfp_flush_tlb_page;
+ tfp_asid_setup();
add_wired_entry = tfp_add_wired_entry;
diff --git a/arch/mips/sgi/kernel/indy_int.c b/arch/mips/sgi/kernel/indy_int.c
index fcc7e7092..f1f2bbc9f 100644
--- a/arch/mips/sgi/kernel/indy_int.c
+++ b/arch/mips/sgi/kernel/indy_int.c
@@ -1,4 +1,4 @@
-/* $Id: indy_int.c,v 1.9 1998/06/30 00:21:57 ralf Exp $
+/* $Id: indy_int.c,v 1.10 1998/08/25 09:14:49 ralf Exp $
*
* indy_int.c: Routines for generic manipulation of the INT[23] ASIC
* found on INDY workstations..
@@ -274,7 +274,7 @@ asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
int do_random, cpu;
cpu = smp_processor_id();
- irq_enter(cpu, irq);
+ hardirq_enter(cpu);
kstat.irqs[0][irq]++;
printk("Got irq %d, press a key.", irq);
@@ -310,7 +310,7 @@ asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
add_interrupt_randomness(irq);
__cli();
}
- irq_exit(cpu, irq);
+ hardirq_exit(cpu);
/* unmasking and bottom half handling is done magically for us. */
}
@@ -448,10 +448,10 @@ void indy_local0_irqdispatch(struct pt_regs *regs)
action = local_irq_action[irq];
}
- irq_enter(cpu, irq);
+ hardirq_enter(cpu);
kstat.irqs[0][irq + 16]++;
action->handler(irq, action->dev_id, regs);
- irq_exit(cpu, irq);
+ hardirq_exit(cpu);
}
void indy_local1_irqdispatch(struct pt_regs *regs)
@@ -472,10 +472,10 @@ void indy_local1_irqdispatch(struct pt_regs *regs)
irq = lc1msk_to_irqnr[mask];
action = local_irq_action[irq];
}
- irq_enter(cpu, irq);
+ hardirq_enter(cpu);
kstat.irqs[0][irq + 24]++;
action->handler(irq, action->dev_id, regs);
- irq_exit(cpu, irq);
+ hardirq_exit(cpu);
}
void indy_buserror_irq(struct pt_regs *regs)
@@ -483,13 +483,13 @@ void indy_buserror_irq(struct pt_regs *regs)
int cpu = smp_processor_id();
int irq = 6;
- irq_enter(cpu, irq);
+ hardirq_enter(cpu);
kstat.irqs[0][irq]++;
printk("Got a bus error IRQ, shouldn't happen yet\n");
show_regs(regs);
printk("Spinning...\n");
while(1);
- irq_exit(cpu, irq);
+ hardirq_exit(cpu);
}
/* Misc. crap just to keep the kernel linking... */
diff --git a/arch/mips/sgi/kernel/indy_sc.c b/arch/mips/sgi/kernel/indy_sc.c
index ddac55816..9e78a2963 100644
--- a/arch/mips/sgi/kernel/indy_sc.c
+++ b/arch/mips/sgi/kernel/indy_sc.c
@@ -1,11 +1,10 @@
-/* $Id: indy_sc.c,v 1.9 1998/08/17 12:14:55 ralf Exp $
+/* $Id: indy_sc.c,v 1.5 1998/08/25 09:14:49 ralf Exp $
*
* indy_sc.c: Indy cache managment functions.
*
* Copyright (C) 1997 Ralf Baechle (ralf@gnu.org),
* derived from r4xx0.c by David S. Miller (dm@engr.sgi.com).
*/
-#include <linux/config.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
diff --git a/arch/mips/sgi/kernel/indy_timer.c b/arch/mips/sgi/kernel/indy_timer.c
index e71441085..0920b9d2c 100644
--- a/arch/mips/sgi/kernel/indy_timer.c
+++ b/arch/mips/sgi/kernel/indy_timer.c
@@ -1,4 +1,4 @@
-/* $Id: indy_timer.c,v 1.9 1998/06/25 20:15:02 ralf Exp $
+/* $Id: indy_timer.c,v 1.10 1998/08/25 09:14:49 ralf Exp $
*
* indy_timer.c: Setting up the clock on the INDY 8254 controller.
*
@@ -261,12 +261,12 @@ void indy_8254timer_irq(void)
int cpu = smp_processor_id();
int irq = 4;
- irq_enter(cpu, irq);
+ hardirq_enter(cpu);
kstat.irqs[0][irq]++;
printk("indy_8254timer_irq: Whoops, should not have gotten this IRQ\n");
prom_getchar();
prom_imode();
- irq_exit(cpu, irq);
+ hardirq_exit(cpu);
}
void do_gettimeofday(struct timeval *tv)
diff --git a/arch/mips/sgi/kernel/setup.c b/arch/mips/sgi/kernel/setup.c
index 99cd9946f..dd1a67bfd 100644
--- a/arch/mips/sgi/kernel/setup.c
+++ b/arch/mips/sgi/kernel/setup.c
@@ -1,10 +1,11 @@
-/* $Id: setup.c,v 1.15 1998/09/26 12:25:03 tsbogend Exp $
+/* $Id: setup.c,v 1.16 1998/10/02 22:06:11 tsbogend Exp $
*
* setup.c: SGI specific setup, including init of the feature struct.
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
* Copyright (C) 1997, 1998 Ralf Baechle (ralf@gnu.org)
*/
+#include <linux/config.h>
#include <linux/init.h>
#include <linux/kbd_ll.h>
#include <linux/kernel.h>
@@ -13,6 +14,7 @@
#include <linux/console.h>
#include <linux/sched.h>
#include <linux/mc146818rtc.h>
+#include <linux/pc_keyb.h>
#include <asm/addrspace.h>
#include <asm/bcache.h>
@@ -28,10 +30,38 @@
extern struct rtc_ops indy_rtc_ops;
void indy_reboot_setup(void);
-static volatile struct hpc_keyb *sgi_kh = (struct hpc_keyb *) (KSEG1 + 0x1fbd9800 + 64);
+#define sgi_kh ((struct hpc_keyb *) (KSEG1 + 0x1fbd9800 + 64))
#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */
+static void sgi_request_region(void)
+{
+ /* No I/O ports are being used on the Indy. */
+}
+
+static int sgi_request_irq(void (*handler)(int, void *, struct pt_regs *))
+{
+ /* Dirty hack, this get's called as a callback from the keyboard
+ driver. We piggyback the initialization of the front panel
+ button handling on it even though they're technically not
+ related with the keyboard driver in any way. Doing it from
+ indy_setup wouldn't work since kmalloc isn't initialized yet. */
+ indy_reboot_setup();
+
+ return request_irq(SGI_KEYBOARD_IRQ, handler, 0, "keyboard", NULL);
+}
+
+static int sgi_aux_request_irq(void (*handler)(int, void *, struct pt_regs *))
+{
+ /* Nothing to do, interrupt is shared with the keyboard hw */
+ return 0;
+}
+
+static void sgi_aux_free_irq(void)
+{
+ /* Nothing to do, interrupt is shared with the keyboard hw */
+}
+
static unsigned char sgi_read_input(void)
{
return sgi_kh->data;
@@ -62,23 +92,18 @@ static unsigned char sgi_read_status(void)
return sgi_kh->command;
}
-__initfunc(static void sgi_keyboard_setup(void))
-{
- kbd_read_input = sgi_read_input;
- kbd_write_output = sgi_write_output;
- kbd_write_command = sgi_write_command;
- kbd_read_status = sgi_read_status;
+struct kbd_ops sgi_kbd_ops = {
+ sgi_request_region,
+ sgi_request_irq,
- request_irq(SGI_KEYBOARD_IRQ, keyboard_interrupt,
- 0, "keyboard", NULL);
+ sgi_aux_request_irq,
+ sgi_aux_free_irq,
- /* Dirty hack, this get's called as a callback from the keyboard
- driver. We piggyback the initialization of the front panel
- button handling on it even though they're technically not
- related with the keyboard driver in any way. Doing it from
- indy_setup wouldn't work since kmalloc isn't initialized yet. */
- indy_reboot_setup();
-}
+ sgi_read_input,
+ sgi_write_output,
+ sgi_write_command,
+ sgi_read_status
+};
__initfunc(static void sgi_irq_setup(void))
{
@@ -92,7 +117,6 @@ __initfunc(void sgi_setup(void))
#endif
irq_setup = sgi_irq_setup;
- keyboard_setup = sgi_keyboard_setup;
/* Init the INDY HPC I/O controller. Need to call this before
* fucking with the memory controller because it needs to know the
@@ -124,4 +148,8 @@ __initfunc(void sgi_setup(void))
conswitchp = &newport_con;
#endif
rtc_ops = &indy_rtc_ops;
+ kbd_ops = &sgi_kbd_ops;
+#ifdef CONFIG_PSMOUSE
+ aux_device_present = 0xaa;
+#endif
}
diff --git a/arch/mips/sni/Makefile b/arch/mips/sni/Makefile
index 84622b55f..f3bb81704 100644
--- a/arch/mips/sni/Makefile
+++ b/arch/mips/sni/Makefile
@@ -1,3 +1,4 @@
+# $Id: Makefile,v 1.3 1998/10/28 12:38:16 ralf Exp $
#
# Makefile for the SNI specific part of the kernel
#
@@ -5,8 +6,6 @@
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
-# $Id: Makefile,v 1.2 1997/12/20 13:27:14 ralf Exp $
-#
.S.s:
$(CPP) $(CFLAGS) $< -o $*.s
@@ -15,7 +14,7 @@
all: sni.o
O_TARGET := sni.o
-O_OBJS := hw-access.o int-handler.o io.o pci.o pcimt_scache.o reset.o setup.o
+O_OBJS := int-handler.o io.o pci.o pcimt_scache.o reset.o setup.o
int-handler.o: int-handler.S
diff --git a/arch/mips/sni/hw-access.c b/arch/mips/sni/hw-access.c
deleted file mode 100644
index c2c121318..000000000
--- a/arch/mips/sni/hw-access.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/* $Id: hw-access.c,v 1.6 1998/06/30 00:21:59 ralf Exp $
- *
- * Low-level hardware access stuff for SNI RM200 PCI
- *
- * 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
- * for more details.
- *
- * Copyright (C) 1996, 1997, 1998 by Ralf Baechle
- */
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/kbd_ll.h>
-#include <linux/kbdcntrlr.h>
-#include <linux/kernel.h>
-#include <linux/linkage.h>
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <asm/bootinfo.h>
-#include <asm/cachectl.h>
-#include <asm/dma.h>
-#include <asm/keyboard.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/mc146818rtc.h>
-#include <asm/pgtable.h>
-#include <asm/sni.h>
-
-#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */
-
-static unsigned char sni_read_input(void)
-{
- return inb(KBD_DATA_REG);
-}
-
-static void sni_write_output(unsigned char val)
-{
- int status;
-
- do {
- status = inb(KBD_CNTL_REG);
- } while (status & KBD_STAT_IBF);
- outb(val, KBD_DATA_REG);
-}
-
-static void sni_write_command(unsigned char val)
-{
- int status;
-
- do {
- status = inb(KBD_CNTL_REG);
- } while (status & KBD_STAT_IBF);
- outb(val, KBD_CNTL_REG);
-}
-
-static unsigned char sni_read_status(void)
-{
- return inb(KBD_STATUS_REG);
-}
-
-__initfunc(void sni_rm200_keyboard_setup(void))
-{
- kbd_read_input = sni_read_input;
- kbd_write_output = sni_write_output;
- kbd_write_command = sni_write_command;
- kbd_read_status = sni_read_status;
- request_irq(PCIMT_KEYBOARD_IRQ, keyboard_interrupt,
- 0, "keyboard", NULL);
- request_region(0x60, 16, "keyboard");
-}
diff --git a/arch/mips/sni/int-handler.S b/arch/mips/sni/int-handler.S
index 3c920954d..fbda9cb26 100644
--- a/arch/mips/sni/int-handler.S
+++ b/arch/mips/sni/int-handler.S
@@ -1,17 +1,22 @@
-/* $Id: int-handler.S,v 1.2 1997/12/01 17:57:40 ralf Exp $
+/* $Id: int-handler.S,v 1.3 1998/05/07 23:44:01 ralf Exp $
*
* SNI RM200 PCI specific interrupt handler code.
*
* Copyright (C) 1994 - 1997 by Ralf Baechle
*/
#include <asm/asm.h>
-#include <linux/config.h>
#include <asm/mipsconfig.h>
#include <asm/mipsregs.h>
#include <asm/regdef.h>
#include <asm/sni.h>
#include <asm/stackframe.h>
+/* The PCI ASIC has the nasty property that it may delay writes if it is busy.
+ As a consequence from writes that have not graduated when we exit from the
+ interrupt handler we might catch a spurious interrupt. To avoid this we
+ force the PCI ASIC to graduate all writes by executing a read from the
+ PCI bus. */
+
.set noreorder
.set noat
.align 5
@@ -20,34 +25,38 @@
CLI
.set at
- lb t0,led_cache
- addiu t0,1
- sb t0,led_cache
- sb t0,PCIMT_CSLED
+ /* Blinken light ... */
+ lb t0, led_cache
+ addiu t0, 1
+ sb t0, led_cache
+ sb t0, PCIMT_CSLED # write only register
.data
led_cache: .byte 0
.text
- mfc0 t0,CP0_STATUS
- mfc0 t1,CP0_CAUSE
- and t0,t1
-
- andi t1,t0,0x0800 # hardware interrupt 1
- bnez t1,hwint1
- andi t1,t0,0x4000 # hardware interrupt 4
- bnez t1,eth_int
-
- andi t1,t0,0x1000 # hardware interrupt 2
- bnez t1,hwint2
- andi t1,t0,0x2000 # hardware interrupt 3
- bnez t1,hwint3
- andi t1,t0,0x8000 # hardware interrupt 5
- bnez t1,hwint5
- andi t1,t0,0x0400 # hardware interrupt 0
- bnez t1,hwint0
+ mfc0 t0, CP0_STATUS
+ mfc0 t1, CP0_CAUSE
+ and t0, t1
+
+ /* The following interrupt dispatch tests for hwint 1 /
+ EISA bridge first such that the timer interrupt get the
+ highest priority. */
+ andi t1, t0, 0x0800 # hardware interrupt 1
+ bnez t1, hwint1
+ andi t1, t0, 0x4000 # hardware interrupt 4
+ bnez t1, hwint4
+
+ andi t1, t0, 0x1000 # hardware interrupt 2
+ bnez t1, hwint2
+ andi t1, t0, 0x2000 # hardware interrupt 3
+ bnez t1, hwint3
+ andi t1, t0, 0x8000 # hardware interrupt 5
+ bnez t1, hwint5
+ andi t1, t0, 0x0400 # hardware interrupt 0
+ bnez t1, hwint0
nop
- j spurious_interrupt # Nothing up ...
+ j return # spurious interrupt
nop
##############################################################################
@@ -57,146 +66,61 @@ swint1: PANIC("swint1")
/* ------------------------------------------------------------------------ */
-hwint1: lbu t0,PCIMT_CSITPEND
-
- andi t1,t0,0x20
- bnez t1,eisa_int
-
-#ifdef CONFIG_SCSI_NCR53C8XX
- andi t1,t0,0x40
- beqz t1,scsi_int
-#endif
- nop
-
- j spurious_interrupt
- nop
-
- /* ------------------------------------------------------------------------ */
-
-hwint0: lbu t0,PCIMT_CSITPEND
-
- andi t1,t0,0x01
- beqz t1,int2
+/* hwint1 deals with EISA and SCSI interrupts. */
+hwint1: lbu s0, PCIMT_CSITPEND
-go_spurious: j spurious_interrupt # we got fooled
+ andi t1, s0, 0x20
+ beqz t1, 1f
+ andi s1, s0, 0x40
+ lbu a0, PCIMT_INT_ACKNOWLEDGE # IACK cycle
+ xori t0, a0, 0xff
+ beqz t0, 1f # spurious interrupt?
nop
+ jal i8259_do_irq # call real handler
+ move a1, sp
-eisa_int: lui s0,%hi(SNI_PORT_BASE)
- li a0,0x0f
- sb a0,%lo(SNI_PORT_BASE+0x20)(s0) # poll command
- lb a0,%lo(SNI_PORT_BASE+0x20)(s0) # read result
- bgtz a0,poll_second
- andi a0,7
- beq a0,2,poll_second # cascade?
- li s1,1
- /*
- * Acknowledge first pic
- */
- lb t2,%lo(SNI_PORT_BASE+0x21)(s0)
- lui s4,%hi(cache_21)
- lb t0,%lo(cache_21)(s4)
- sllv s1,s1,a0
- or t0,s1
- sb t0,%lo(cache_21)(s4)
- sb t0,%lo(SNI_PORT_BASE+0x21)(s0)
- li t2,0x20
- sb t2,%lo(SNI_PORT_BASE+0x20)(s0)
- /*
- * Now call the real handler
- */
+1: bnez s1, 1f
+ li a0, PCIMT_IRQ_SCSI
jal do_IRQ
- move a1,sp
- /*
- * Unblock first pic
- */
- lbu t1,%lo(SNI_PORT_BASE+0x21)(s0)
- lb t1,%lo(cache_21)(s4)
- nor s1,zero,s1
- and t1,s1
- sb t1,%lo(cache_21)(s4)
- j ret_from_irq
- sb t1,%lo(SNI_PORT_BASE+0x21)(s0)
+ move a1, sp
- /*
- * Cascade interrupt from second PIC
- */
- .align 5
-poll_second: li a0,0x0f
- sb a0,%lo(SNI_PORT_BASE+0xa0)(s0) # poll command
- lb a0,%lo(SNI_PORT_BASE+0xa0)(s0) # read result
- bgtz a0,go_spurious
- andi a0,7
- /*
- * Acknowledge second pic
- */
- lbu t2,%lo(SNI_PORT_BASE+0xa1)(s0)
- lui s4,%hi(cache_A1)
- lb t3,%lo(cache_A1)(s4)
- sllv s1,s1,a0
- or t3,s1
- sb t3,%lo(cache_A1)(s4)
- sb t3,%lo(SNI_PORT_BASE+0xa1)(s0)
- li t3,0x20
- sb t3,%lo(SNI_PORT_BASE+0xa0)(s0)
- sb t3,%lo(SNI_PORT_BASE+0x20)(s0)
- /*
- * Now call the real handler
- */
- addiu a0,8
- jal do_IRQ
- move a1,sp
- /*
- * Unblock second pic
- */
- lb t1,%lo(SNI_PORT_BASE+0xa1)(s0)
- lb t1,%lo(cache_A1)(s4)
- subu t0,1
- nor s1,zero,s1
- and t1,t1,s1
- sb t1,%lo(cache_A1)(s4)
+1: lui t0, %hi(PCIMT_CSITPEND)
j ret_from_irq
- sb t1,%lo(SNI_PORT_BASE+0xa1)(s0)
-
-/*
- * ... check if we were interrupted by the Lance ...
- */
-eth_int: mfc0 s0,CP0_STATUS
- ori t0,s0,0x4000
- xori t0,0x4000
- mtc0 t0,CP0_STATUS
+ lbu zero, %lo(PCIMT_CSITPEND)(t0)
- li a0,PCIMT_IRQ_ETHERNET
- jal do_IRQ
- move a1,sp
+ /* ------------------------------------------------------------------------ */
- mtc0 s0,CP0_STATUS
+/* hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug
+ button interrupts. */
+hwint0: PANIC("Received int0 but no handler yet ...\n")
+1: j 1b
+ nop
- j ret_from_irq
+go_spurious: j spurious_interrupt # we got fooled
nop
-#ifdef CONFIG_SCSI_NCR53C8XX
+/* hwint4 is used for only the onboard PCnet 32. */
+hwint4: mfc0 s0, CP0_STATUS
+ ori t0, s0, 0x4000
+ xori t0, 0x4000
+ mtc0 t0, CP0_STATUS
-/*
- * ... check if we were interrupted by the NCR ...
- */
-scsi_int: li a0,PCIMT_IRQ_SCSI
+ li a0, PCIMT_IRQ_ETHERNET
jal do_IRQ
- move a1,sp
- j ret_from_irq
- nop
-
-#endif /* CONFIG_SCSI_NCR53C8XX */
+ move a1, sp
-pci_int: PANIC("Received PCI interrupt but no handler yet ...\n")
-1: j 1b
- nop
+ mtc0 s0, CP0_STATUS
-int2: PANIC("Received int2 but no handler yet ...\n")
-1: j 1b
+ j ret_from_irq
nop
+/* This interrupt was used for the com1 console on the first prototypes. */
hwint2: PANIC("hwint2 and no handler yet")
+
+/* hwint3 should deal with the PCI A - D interrupts. */
hwint3: PANIC("hwint3 and no handler yet")
+
+/* hwint5 is the r4k count / compare interrupt */
hwint5: PANIC("hwint5 and no handler yet")
END(sni_rm200_pci_handle_int)
diff --git a/arch/mips/sni/io.c b/arch/mips/sni/io.c
index 8a97b80a8..a59df4565 100644
--- a/arch/mips/sni/io.c
+++ b/arch/mips/sni/io.c
@@ -1,11 +1,10 @@
-/*
+/* $Id: io.c,v 1.2 1998/04/05 11:24:06 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
* for more details.
*
* Low level I/O functions for SNI.
- *
- * $Id: io.c,v 1.2 1998/03/27 08:53:50 ralf Exp $
*/
#include <linux/string.h>
#include <asm/mipsconfig.h>
@@ -14,46 +13,42 @@
#include <asm/spinlock.h>
#include <asm/sni.h>
-unsigned char sni_map_isa_cache;
-
-#define unused __attribute__((unused))
-
-/*
- * The PCIMT_CSMAPISA is shared by all processors; we need locking.
- *
- * XXX It's legal to use all the I/O memory access functions in interrupt
- * code, so we need to use the _irq locking stuff which may result in
- * significant IRQ latencies.
- */
-static spinlock_t csmapisa_lock unused = SPIN_LOCK_UNLOCKED;
-
/*
* Urgs... We only can see a 16mb window of the 4gb EISA address space
* at PCIMT_EISA_BASE. Maladia segmentitis ...
*
- * XXX Check out if accessing PCIMT_CSMAPISA really is slow.
- * For now assume so.
+ * To avoid locking and all the related headacke we implement this such
+ * that accessing the bus address space nests, so we're treating this
+ * correctly even for interrupts. This is going to suck seriously for
+ * the SMP members of the RM family.
+ *
+ * Making things worse the PCIMT_CSMAPISA register resides on the X bus with
+ * it's unbeatable 1.4 mb/s transfer rate.
*/
-static inline void update_isa_cache(unsigned long address)
+
+static inline void eisa_map(unsigned long address)
{
unsigned char upper;
upper = address >> 24;
- if (sni_map_isa_cache != upper) {
- sni_map_isa_cache = upper;
- *(volatile unsigned char *)PCIMT_CSMAPISA = ~upper;
- }
+ *(volatile unsigned char *)PCIMT_CSMAPISA = ~upper;
}
+#define save_eisa_map() \
+ (*(volatile unsigned char *)PCIMT_CSMAPISA)
+#define restore_eisa_map(val) \
+ do { (*(volatile unsigned char *)PCIMT_CSMAPISA) = val; } while(0)
+
static unsigned char sni_readb(unsigned long addr)
{
unsigned char res;
+ unsigned int save_map;
- spin_lock_irq(&csmapisa_lock);
- update_isa_cache(addr);
+ save_map = save_eisa_map();
+ eisa_map(addr);
addr &= 0xffffff;
res = *(volatile unsigned char *) (PCIMT_EISA_BASE + addr);
- spin_unlock_irq(&csmapisa_lock);
+ restore_eisa_map(save_map);
return res;
}
@@ -61,12 +56,13 @@ static unsigned char sni_readb(unsigned long addr)
static unsigned short sni_readw(unsigned long addr)
{
unsigned short res;
+ unsigned int save_map;
- spin_lock_irq(&csmapisa_lock);
- update_isa_cache(addr);
+ save_map = save_eisa_map();
+ eisa_map(addr);
addr &= 0xffffff;
res = *(volatile unsigned char *) (PCIMT_EISA_BASE + addr);
- spin_unlock_irq(&csmapisa_lock);
+ restore_eisa_map(save_map);
return res;
}
@@ -74,101 +70,111 @@ static unsigned short sni_readw(unsigned long addr)
static unsigned int sni_readl(unsigned long addr)
{
unsigned int res;
+ unsigned int save_map;
- spin_lock_irq(&csmapisa_lock);
- update_isa_cache(addr);
+ save_map = save_eisa_map();
+ eisa_map(addr);
addr &= 0xffffff;
res = *(volatile unsigned char *) (PCIMT_EISA_BASE + addr);
- spin_unlock_irq(&csmapisa_lock);
+ restore_eisa_map(save_map);
return res;
}
static void sni_writeb(unsigned char val, unsigned long addr)
{
- spin_lock_irq(&csmapisa_lock);
- update_isa_cache(addr);
+ unsigned int save_map;
+
+ save_map = save_eisa_map();
+ eisa_map(addr);
addr &= 0xffffff;
*(volatile unsigned char *) (PCIMT_EISA_BASE + addr) = val;
- spin_unlock_irq(&csmapisa_lock);
+ restore_eisa_map(save_map);
}
static void sni_writew(unsigned short val, unsigned long addr)
{
- spin_lock_irq(&csmapisa_lock);
- update_isa_cache(addr);
+ unsigned int save_map;
+
+ save_map = save_eisa_map();
+ eisa_map(addr);
addr &= 0xffffff;
*(volatile unsigned char *) (PCIMT_EISA_BASE + addr) = val;
- spin_unlock_irq(&csmapisa_lock);
+ restore_eisa_map(save_map);
}
static void sni_writel(unsigned int val, unsigned long addr)
{
- spin_lock_irq(&csmapisa_lock);
- update_isa_cache(addr);
+ unsigned int save_map;
+
+ save_map = save_eisa_map();
+ eisa_map(addr);
addr &= 0xffffff;
*(volatile unsigned char *) (PCIMT_EISA_BASE + addr) = val;
- spin_unlock_irq(&csmapisa_lock);
+ restore_eisa_map(save_map);
}
static void sni_memset_io(unsigned long addr, int val, unsigned long len)
{
unsigned long waddr;
+ unsigned int save_map;
+ save_map = save_eisa_map();
waddr = PCIMT_EISA_BASE | (addr & 0xffffff);
- spin_lock_irq(&csmapisa_lock);
while(len) {
unsigned long fraglen;
fraglen = (~addr + 1) & 0xffffff;
fraglen = (fraglen < len) ? fraglen : len;
- update_isa_cache(addr);
+ eisa_map(addr);
memset((char *)waddr, val, fraglen);
addr += fraglen;
waddr = waddr + fraglen - 0x1000000;
len -= fraglen;
}
- spin_unlock_irq(&csmapisa_lock);
+ restore_eisa_map(save_map);
}
static void sni_memcpy_fromio(unsigned long to, unsigned long from, unsigned long len)
{
unsigned long waddr;
+ unsigned int save_map;
+ save_map = save_eisa_map();
waddr = PCIMT_EISA_BASE | (from & 0xffffff);
- spin_lock_irq(&csmapisa_lock);
while(len) {
unsigned long fraglen;
fraglen = (~from + 1) & 0xffffff;
fraglen = (fraglen < len) ? fraglen : len;
- update_isa_cache(from);
+ eisa_map(from);
memcpy((void *)to, (void *)waddr, fraglen);
to += fraglen;
from += fraglen;
waddr = waddr + fraglen - 0x1000000;
len -= fraglen;
}
- spin_unlock_irq(&csmapisa_lock);
+ restore_eisa_map(save_map);
}
static void sni_memcpy_toio(unsigned long to, unsigned long from, unsigned long len)
{
unsigned long waddr;
+ unsigned int save_map;
+ save_map = save_eisa_map();
waddr = PCIMT_EISA_BASE | (to & 0xffffff);
- spin_lock_irq(&csmapisa_lock);
while(len) {
unsigned long fraglen;
fraglen = (~to + 1) & 0xffffff;
fraglen = (fraglen < len) ? fraglen : len;
- update_isa_cache(to);
+ eisa_map(to);
memcpy((char *)to + PCIMT_EISA_BASE, (void *)from, fraglen);
to += fraglen;
from += fraglen;
waddr = waddr + fraglen - 0x1000000;
len -= fraglen;
}
- spin_unlock_irq(&csmapisa_lock);
+ restore_eisa_map(save_map);
}
diff --git a/arch/mips/sni/pci.c b/arch/mips/sni/pci.c
index fe538d277..0da6b8004 100644
--- a/arch/mips/sni/pci.c
+++ b/arch/mips/sni/pci.c
@@ -1,4 +1,4 @@
-/* $Id: pci.c,v 1.5 1998/05/07 02:57:22 ralf Exp $
+/* $Id: pci.c,v 1.6 1998/05/07 23:44:02 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
@@ -9,6 +9,7 @@
* Copyright (C) 1997, 1998 Ralf Baechle
*/
#include <linux/config.h>
+#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/types.h>
#include <asm/byteorder.h>
@@ -28,13 +29,37 @@ do { \
static void sni_rm200_pcibios_fixup (void)
{
- /*
- * TODO: Fix PCI_INTERRUPT_LINE register for onboard cards.
- * Take care of RM300 revision D boards for where the network
- * slot became an ordinary PCI slot.
- */
- pcibios_write_config_byte(0, PCI_DEVFN(1, 0), PCI_INTERRUPT_LINE,
- PCIMT_IRQ_SCSI);
+ struct pci_dev *dev;
+
+ for (dev=pci_devices; dev; dev=dev->next) {
+ /*
+ * TODO: Take care of RM300 revision D boards for where the
+ * network slot became an ordinary PCI slot.
+ */
+ if (dev->devfn == PCI_DEVFN(1, 0)) {
+ /* Evil hack ... */
+ set_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NO_WA);
+ dev->irq = PCIMT_IRQ_SCSI;
+ continue;
+ }
+ if (dev->devfn == PCI_DEVFN(2, 0)) {
+ dev->irq = PCIMT_IRQ_ETHERNET;
+ continue;
+ }
+
+ switch(dev->irq) {
+ case 1 ... 4:
+ dev->irq += PCIMT_IRQ_INTA - 1;
+ break;
+ case 0:
+ break;
+ default:
+ printk("PCI device on bus %d, dev %d, function %d "
+ "impossible interrupt configured.\n",
+ dev->bus->number, PCI_SLOT(dev->devfn),
+ PCI_SLOT(dev->devfn));
+ }
+ }
}
/*
diff --git a/arch/mips/sni/pcimt_scache.c b/arch/mips/sni/pcimt_scache.c
index feec16967..55c96b939 100644
--- a/arch/mips/sni/pcimt_scache.c
+++ b/arch/mips/sni/pcimt_scache.c
@@ -1,35 +1,38 @@
-/*
+/* $Id: pcimt_scache.c,v 1.3 1998/08/25 09:14:51 ralf Exp $
+ *
* arch/mips/sni/pcimt_scache.c
*
* 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
* for more details.
*
- * Copyright (c) 1997 by Ralf Baechle
- *
- * $Id: pcimt_scache.c,v 1.2 1998/05/28 03:18:02 ralf Exp $
+ * Copyright (c) 1997, 1998 by Ralf Baechle
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <asm/bcache.h>
#include <asm/sni.h>
+#define cacheconf (*(volatile unsigned int *)PCIMT_CACHECONF)
+#define invspace (*(volatile unsigned int *)PCIMT_INVSPACE)
+
__initfunc(void sni_pcimt_sc_init(void))
{
- unsigned int cacheconf, sc_size;
+ unsigned int scsiz, sc_size;
- cacheconf = *(volatile unsigned int *)PCIMT_CACHECONF;
- if ((cacheconf & 7) == 0) {
- printk("No second level cache detected\n");
- printk("WARNING: not activating second level cache, "
- "tell ralf@gnu.org\n");
+ scsiz = cacheconf & 7;
+ if (scsiz == 0) {
+ printk("Second level cache is deactived.\n");
return;
}
- if ((cacheconf & 7) >= 6) {
- printk("Invalid second level cache size detected\n");
+ if (scsiz >= 6) {
+ printk("Invalid second level cache size configured, "
+ "deactivating second level cache.\n");
+ cacheconf = 0;
return;
}
-
- sc_size = 128 << (cacheconf & 7);
- printk("%dkb second level cache detected.\n", sc_size);
+
+ sc_size = 128 << scsiz;
+ printk("%dkb second level cache detected, deactivating.\n", sc_size);
+ cacheconf = 0;
}
diff --git a/arch/mips/sni/setup.c b/arch/mips/sni/setup.c
index 2f3499707..0652c171b 100644
--- a/arch/mips/sni/setup.c
+++ b/arch/mips/sni/setup.c
@@ -1,4 +1,4 @@
-/* $Id: setup.c,v 1.13 1998/08/17 13:57:45 ralf Exp $
+/* $Id: setup.c,v 1.9 1998/08/25 09:14:51 ralf Exp $
*
* Setup pointers to hardware-dependent routines.
*
@@ -17,6 +17,11 @@
#include <linux/interrupt.h>
#include <linux/timex.h>
#include <linux/pci.h>
+#include <linux/mc146818rtc.h>
+#include <linux/console.h>
+#include <linux/fb.h>
+#include <linux/pc_keyb.h>
+
#include <asm/bcache.h>
#include <asm/bootinfo.h>
#include <asm/keyboard.h>
@@ -39,7 +44,6 @@ static void no_action(int cpl, void *dev_id, struct pt_regs *regs) { }
static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL};
extern asmlinkage void sni_rm200_pci_handle_int(void);
-extern void sni_rm200_keyboard_setup(void);
extern void sni_machine_restart(char *command);
extern void sni_machine_halt(void);
@@ -47,19 +51,20 @@ extern void sni_machine_power_off(void);
extern struct ide_ops std_ide_ops;
extern struct rtc_ops std_rtc_ops;
+extern struct kbd_ops std_kbd_ops;
__initfunc(static void sni_irq_setup(void))
{
set_except_vector(0, sni_rm200_pci_handle_int);
request_region(0x20,0x20, "pic1");
request_region(0xa0,0x20, "pic2");
- setup_x86_irq(2, &irq2);
+ i8259_setup_irq(2, &irq2);
/*
* IRQ0 seems to be the irq for PC style stuff.
* I don't know how to handle the debug button interrupt, so
* don't use this button yet or bad things happen ...
*/
- set_cp0_status(ST0_IM, IE_IRQ1 | IE_IRQ4);
+ set_cp0_status(ST0_IM, IE_IRQ1 | IE_IRQ3 | IE_IRQ4);
}
void (*board_time_init)(struct irqaction *irq);
@@ -70,7 +75,7 @@ __initfunc(static void sni_rm200_pci_time_init(struct irqaction *irq))
outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */
outb_p(LATCH & 0xff , 0x40); /* LSB */
outb(LATCH >> 8 , 0x40); /* MSB */
- setup_x86_irq(0, irq);
+ i8259_setup_irq(0, irq);
}
unsigned char aux_device_present;
@@ -132,7 +137,6 @@ __initfunc(void sni_rm200_pci_setup(void))
irq_setup = sni_irq_setup;
mips_io_port_base = SNI_PORT_BASE;
- keyboard_setup = sni_rm200_keyboard_setup;
/*
* Setup (E)ISA I/O memory access stuff
@@ -165,6 +169,10 @@ __initfunc(void sni_rm200_pci_setup(void))
#ifdef CONFIG_BLK_DEV_IDE
ide_ops = &std_ide_ops;
#endif
-
+ conswitchp = &vga_con;
rtc_ops = &std_rtc_ops;
+ kbd_ops = &std_kbd_ops;
+#ifdef CONFIG_PSMOUSE
+ aux_device_present = 0xaa;
+#endif
}