diff options
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/lib/Makefile | 6 | ||||
-rw-r--r-- | arch/mips/lib/floppy-std.c | 3 | ||||
-rw-r--r-- | arch/mips/lib/ide-std.c | 2 | ||||
-rw-r--r-- | arch/mips/lib/kbd-no.c | 63 | ||||
-rw-r--r-- | arch/mips/lib/kbd-std.c | 81 | ||||
-rw-r--r-- | arch/mips/mm/andes.c | 7 | ||||
-rw-r--r-- | arch/mips/mm/fault.c | 39 | ||||
-rw-r--r-- | arch/mips/mm/init.c | 123 | ||||
-rw-r--r-- | arch/mips/mm/r2300.c | 7 | ||||
-rw-r--r-- | arch/mips/mm/r4xx0.c | 3 | ||||
-rw-r--r-- | arch/mips/mm/r6000.c | 5 | ||||
-rw-r--r-- | arch/mips/mm/tfp.c | 5 | ||||
-rw-r--r-- | arch/mips/sgi/kernel/indy_int.c | 18 | ||||
-rw-r--r-- | arch/mips/sgi/kernel/indy_sc.c | 3 | ||||
-rw-r--r-- | arch/mips/sgi/kernel/indy_timer.c | 6 | ||||
-rw-r--r-- | arch/mips/sgi/kernel/setup.c | 64 | ||||
-rw-r--r-- | arch/mips/sni/Makefile | 5 | ||||
-rw-r--r-- | arch/mips/sni/hw-access.c | 70 | ||||
-rw-r--r-- | arch/mips/sni/int-handler.S | 214 | ||||
-rw-r--r-- | arch/mips/sni/io.c | 106 | ||||
-rw-r--r-- | arch/mips/sni/pci.c | 41 | ||||
-rw-r--r-- | arch/mips/sni/pcimt_scache.c | 33 | ||||
-rw-r--r-- | arch/mips/sni/setup.c | 22 |
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 } |