From: Ralf Baechle Update the generic MIPS code. Highlights are oprofile for MIPS, initially for the PMC-Sierra RM9000. We're also taking a significantly more aggressive approach to the TLB exception handlers which now are runtime generated and provide an upto 20% speedup on certain micro benchmarks. Signed-off-by: Andrew Morton --- /dev/null | 885 --------------------------- 25-akpm/arch/mips/Makefile | 24 25-akpm/arch/mips/kernel/Makefile | 8 25-akpm/arch/mips/kernel/irq-rm9000.c | 149 ++++ 25-akpm/arch/mips/kernel/irq.c | 2 25-akpm/arch/mips/kernel/linux32.c | 2 25-akpm/arch/mips/kernel/mips_ksyms.c | 7 25-akpm/arch/mips/kernel/module.c | 2 25-akpm/arch/mips/kernel/process.c | 43 + 25-akpm/arch/mips/kernel/scall32-o32.S | 209 ++---- 25-akpm/arch/mips/kernel/scall64-64.S | 10 25-akpm/arch/mips/kernel/scall64-o32.S | 67 -- 25-akpm/arch/mips/kernel/semaphore.c | 3 25-akpm/arch/mips/kernel/setup.c | 23 25-akpm/arch/mips/kernel/signal-common.h | 136 ++++ 25-akpm/arch/mips/kernel/signal.c | 149 ---- 25-akpm/arch/mips/kernel/signal32.c | 20 25-akpm/arch/mips/kernel/signal_n32.c | 51 - 25-akpm/arch/mips/kernel/smp.c | 4 25-akpm/arch/mips/kernel/syscall.c | 18 25-akpm/arch/mips/kernel/time.c | 3 25-akpm/arch/mips/kernel/traps.c | 34 - 25-akpm/arch/mips/kernel/vmlinux.lds.S | 1 25-akpm/arch/mips/lib-64/dump_tlb.c | 8 25-akpm/arch/mips/math-emu/cp1emu.c | 2 25-akpm/arch/mips/math-emu/dp_add.c | 2 25-akpm/arch/mips/math-emu/dp_cmp.c | 2 25-akpm/arch/mips/math-emu/dp_div.c | 2 25-akpm/arch/mips/math-emu/dp_fint.c | 2 25-akpm/arch/mips/math-emu/dp_flong.c | 2 25-akpm/arch/mips/math-emu/dp_frexp.c | 2 25-akpm/arch/mips/math-emu/dp_fsp.c | 2 25-akpm/arch/mips/math-emu/dp_logb.c | 2 25-akpm/arch/mips/math-emu/dp_modf.c | 2 25-akpm/arch/mips/math-emu/dp_mul.c | 2 25-akpm/arch/mips/math-emu/dp_scalb.c | 2 25-akpm/arch/mips/math-emu/dp_simple.c | 2 25-akpm/arch/mips/math-emu/dp_sqrt.c | 2 25-akpm/arch/mips/math-emu/dp_sub.c | 2 25-akpm/arch/mips/math-emu/dp_tint.c | 2 25-akpm/arch/mips/math-emu/dp_tlong.c | 2 25-akpm/arch/mips/math-emu/ieee754.c | 2 25-akpm/arch/mips/math-emu/ieee754.h | 2 25-akpm/arch/mips/math-emu/ieee754d.c | 2 25-akpm/arch/mips/math-emu/ieee754dp.c | 2 25-akpm/arch/mips/math-emu/ieee754dp.h | 2 25-akpm/arch/mips/math-emu/ieee754int.h | 2 25-akpm/arch/mips/math-emu/ieee754m.c | 2 25-akpm/arch/mips/math-emu/ieee754sp.c | 2 25-akpm/arch/mips/math-emu/ieee754sp.h | 2 25-akpm/arch/mips/math-emu/ieee754xcpt.c | 2 25-akpm/arch/mips/math-emu/sp_add.c | 2 25-akpm/arch/mips/math-emu/sp_cmp.c | 2 25-akpm/arch/mips/math-emu/sp_div.c | 2 25-akpm/arch/mips/math-emu/sp_fdp.c | 2 25-akpm/arch/mips/math-emu/sp_fint.c | 2 25-akpm/arch/mips/math-emu/sp_flong.c | 2 25-akpm/arch/mips/math-emu/sp_frexp.c | 2 25-akpm/arch/mips/math-emu/sp_logb.c | 2 25-akpm/arch/mips/math-emu/sp_modf.c | 2 25-akpm/arch/mips/math-emu/sp_mul.c | 2 25-akpm/arch/mips/math-emu/sp_scalb.c | 2 25-akpm/arch/mips/math-emu/sp_simple.c | 2 25-akpm/arch/mips/math-emu/sp_sqrt.c | 2 25-akpm/arch/mips/math-emu/sp_sub.c | 2 25-akpm/arch/mips/math-emu/sp_tint.c | 2 25-akpm/arch/mips/math-emu/sp_tlong.c | 2 25-akpm/arch/mips/mm/Makefile | 39 - 25-akpm/arch/mips/mm/c-r4k.c | 78 +- 25-akpm/arch/mips/mm/c-sb1.c | 2 25-akpm/arch/mips/mm/cache.c | 13 25-akpm/arch/mips/mm/cerr-sb1.c | 22 25-akpm/arch/mips/mm/cex-sb1.S | 1 25-akpm/arch/mips/mm/dma-ip32.c | 382 +++++++++++ 25-akpm/arch/mips/mm/init.c | 3 25-akpm/arch/mips/mm/pg-r4k.c | 17 25-akpm/arch/mips/mm/pg-sb1.c | 257 ++++--- 25-akpm/arch/mips/mm/pgtable-32.c | 4 25-akpm/arch/mips/mm/pgtable-64.c | 1 25-akpm/arch/mips/mm/pgtable.c | 1 25-akpm/arch/mips/mm/sc-rm7k.c | 6 25-akpm/arch/mips/mm/tlb-andes.c | 1 25-akpm/arch/mips/mm/tlb-sb1.c | 3 25-akpm/arch/mips/mm/tlbex-fault.S | 28 25-akpm/arch/mips/mm/tlbex.c | 764 +++++++++++++++++++++-- 25-akpm/arch/mips/oprofile/Kconfig | 23 25-akpm/arch/mips/oprofile/Makefile | 15 25-akpm/arch/mips/oprofile/common.c | 106 +++ 25-akpm/arch/mips/oprofile/op_impl.h | 37 + 25-akpm/arch/mips/oprofile/op_model_rm9000.c | 137 ++++ 25-akpm/arch/mips/pci/pci.c | 6 25-akpm/include/asm-mips/addrspace.h | 1 25-akpm/include/asm-mips/bitops.h | 14 25-akpm/include/asm-mips/bootinfo.h | 1 25-akpm/include/asm-mips/break.h | 2 25-akpm/include/asm-mips/cpu-features.h | 23 25-akpm/include/asm-mips/cpu-info.h | 1 25-akpm/include/asm-mips/debug.h | 4 25-akpm/include/asm-mips/elf.h | 24 25-akpm/include/asm-mips/gt64120.h | 227 +++++- 25-akpm/include/asm-mips/hardirq.h | 3 25-akpm/include/asm-mips/hazards.h | 85 +- 25-akpm/include/asm-mips/io.h | 530 +++++++--------- 25-akpm/include/asm-mips/irq_cpu.h | 1 25-akpm/include/asm-mips/m48t37.h | 35 + 25-akpm/include/asm-mips/mach-generic/ide.h | 82 +- 25-akpm/include/asm-mips/mipsregs.h | 101 ++- 25-akpm/include/asm-mips/mmu_context.h | 28 25-akpm/include/asm-mips/pgtable-32.h | 2 25-akpm/include/asm-mips/pmon.h | 39 - 25-akpm/include/asm-mips/prefetch.h | 44 + 25-akpm/include/asm-mips/processor.h | 5 25-akpm/include/asm-mips/r4kcache.h | 15 25-akpm/include/asm-mips/reg.h | 129 +++ 25-akpm/include/asm-mips/sigcontext.h | 5 25-akpm/include/asm-mips/spinlock.h | 1 25-akpm/include/asm-mips/stackframe.h | 20 25-akpm/include/asm-mips/string.h | 4 25-akpm/include/asm-mips/uaccess.h | 27 25-akpm/include/asm-mips/unistd.h | 3 arch/mips/lib/csum_partial_copy.c | 0 121 files changed, 3275 insertions(+), 2071 deletions(-) diff -puN arch/mips/kernel/irq.c~mips-generic-mips-updates arch/mips/kernel/irq.c --- 25/arch/mips/kernel/irq.c~mips-generic-mips-updates 2005-01-29 11:25:48.562486688 -0800 +++ 25-akpm/arch/mips/kernel/irq.c 2005-01-29 11:25:48.725461912 -0800 @@ -125,7 +125,7 @@ void __init init_IRQ(void) irq_desc[i].action = NULL; irq_desc[i].depth = 1; irq_desc[i].handler = &no_irq_type; - irq_desc[i].lock = SPIN_LOCK_UNLOCKED; + spin_lock_init(&irq_desc[i].lock); } arch_init_irq(); diff -puN /dev/null arch/mips/kernel/irq-rm9000.c --- /dev/null 2003-09-15 06:40:47.000000000 -0700 +++ 25-akpm/arch/mips/kernel/irq-rm9000.c 2005-01-29 11:25:48.726461760 -0800 @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2003 Ralf Baechle + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * Handler for RM9000 extended interrupts. These are a non-standard + * feature so we handle them separately from standard interrupts. + */ +#include +#include +#include +#include + +#include +#include +#include + +static int irq_base; + +static inline void unmask_rm9k_irq(unsigned int irq) +{ + set_c0_intcontrol(0x1000 << (irq - irq_base)); +} + +static inline void mask_rm9k_irq(unsigned int irq) +{ + clear_c0_intcontrol(0x1000 << (irq - irq_base)); +} + +static inline void rm9k_cpu_irq_enable(unsigned int irq) +{ + unsigned long flags; + + local_irq_save(flags); + unmask_rm9k_irq(irq); + local_irq_restore(flags); +} + +static void rm9k_cpu_irq_disable(unsigned int irq) +{ + unsigned long flags; + + local_irq_save(flags); + mask_rm9k_irq(irq); + local_irq_restore(flags); +} + +static unsigned int rm9k_cpu_irq_startup(unsigned int irq) +{ + rm9k_cpu_irq_enable(irq); + + return 0; +} + +#define rm9k_cpu_irq_shutdown rm9k_cpu_irq_disable + +/* + * Performance counter interrupts are global on all processors. + */ +static void local_rm9k_perfcounter_irq_startup(void *args) +{ + unsigned int irq = (unsigned int) args; + + rm9k_cpu_irq_enable(irq); +} + +static unsigned int rm9k_perfcounter_irq_startup(unsigned int irq) +{ + on_each_cpu(local_rm9k_perfcounter_irq_startup, (void *) irq, 0, 1); + + return 0; +} + +static void local_rm9k_perfcounter_irq_shutdown(void *args) +{ + unsigned int irq = (unsigned int) args; + unsigned long flags; + + local_irq_save(flags); + mask_rm9k_irq(irq); + local_irq_restore(flags); +} + +static void rm9k_perfcounter_irq_shutdown(unsigned int irq) +{ + on_each_cpu(local_rm9k_perfcounter_irq_shutdown, (void *) irq, 0, 1); +} + + +/* + * While we ack the interrupt interrupts are disabled and thus we don't need + * to deal with concurrency issues. Same for rm9k_cpu_irq_end. + */ +static void rm9k_cpu_irq_ack(unsigned int irq) +{ + mask_rm9k_irq(irq); +} + +static void rm9k_cpu_irq_end(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + unmask_rm9k_irq(irq); +} + +static hw_irq_controller rm9k_irq_controller = { + "RM9000", + rm9k_cpu_irq_startup, + rm9k_cpu_irq_shutdown, + rm9k_cpu_irq_enable, + rm9k_cpu_irq_disable, + rm9k_cpu_irq_ack, + rm9k_cpu_irq_end, +}; + +static hw_irq_controller rm9k_perfcounter_irq = { + "RM9000", + rm9k_perfcounter_irq_startup, + rm9k_perfcounter_irq_shutdown, + rm9k_cpu_irq_enable, + rm9k_cpu_irq_disable, + rm9k_cpu_irq_ack, + rm9k_cpu_irq_end, +}; + +unsigned int rm9000_perfcount_irq; + +EXPORT_SYMBOL(rm9000_perfcount_irq); + +void __init rm9k_cpu_irq_init(int base) +{ + int i; + + clear_c0_intcontrol(0x0000f000); /* Mask all */ + + for (i = base; i < base + 4; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = NULL; + irq_desc[i].depth = 1; + irq_desc[i].handler = &rm9k_irq_controller; + } + + rm9000_perfcount_irq = base + 1; + irq_desc[rm9000_perfcount_irq].handler = &rm9k_perfcounter_irq; + + irq_base = base; +} diff -puN arch/mips/kernel/linux32.c~mips-generic-mips-updates arch/mips/kernel/linux32.c --- 25/arch/mips/kernel/linux32.c~mips-generic-mips-updates 2005-01-29 11:25:48.564486384 -0800 +++ 25-akpm/arch/mips/kernel/linux32.c 2005-01-29 11:25:48.727461608 -0800 @@ -99,7 +99,7 @@ int cp_compat_stat(struct kstat *stat, s } asmlinkage unsigned long -sys32_mmap2(unsigned long addr, size_t len, unsigned long prot, +sys32_mmap2(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff) { struct file * file = NULL; diff -puN arch/mips/kernel/Makefile~mips-generic-mips-updates arch/mips/kernel/Makefile --- 25/arch/mips/kernel/Makefile~mips-generic-mips-updates 2005-01-29 11:25:48.565486232 -0800 +++ 25-akpm/arch/mips/kernel/Makefile 2005-01-29 11:25:48.728461456 -0800 @@ -8,6 +8,9 @@ obj-y += cpu-probe.o branch.o entry.o g ptrace.o reset.o semaphore.o setup.o signal.o syscall.o \ time.o traps.o unaligned.o +binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \ + irix5sys.o sysirix.o + ifdef CONFIG_MODULES obj-y += mips_ksyms.o module.o obj-$(CONFIG_MIPS32) += module-elf32.o @@ -35,15 +38,16 @@ obj-$(CONFIG_CPU_R6000) += r6000_fpu.o obj-$(CONFIG_SMP) += smp.o +obj-$(CONFIG_NO_ISA) += dma-no-isa.o obj-$(CONFIG_I8259) += i8259.o obj-$(CONFIG_IRQ_CPU) += irq_cpu.o obj-$(CONFIG_IRQ_CPU_RM7K) += irq-rm7000.o +obj-$(CONFIG_IRQ_CPU_RM9K) += irq-rm9000.o obj-$(CONFIG_IRQ_MV64340) += irq-mv6434x.o obj-$(CONFIG_MIPS32) += scall32-o32.o obj-$(CONFIG_MIPS64) += scall64-64.o -obj-$(CONFIG_BINFMT_IRIX) += irixelf.o irixioctl.o irixsig.o sysirix.o \ - irixinv.o +obj-$(CONFIG_BINFMT_IRIX) += binfmt_irix.o obj-$(CONFIG_MIPS32_COMPAT) += ioctl32.o linux32.o signal32.o obj-$(CONFIG_MIPS32_N32) += binfmt_elfn32.o scall64-n32.o signal_n32.o obj-$(CONFIG_MIPS32_O32) += binfmt_elfo32.o scall64-o32.o ptrace32.o diff -puN arch/mips/kernel/mips_ksyms.c~mips-generic-mips-updates arch/mips/kernel/mips_ksyms.c --- 25/arch/mips/kernel/mips_ksyms.c~mips-generic-mips-updates 2005-01-29 11:25:48.566486080 -0800 +++ 25-akpm/arch/mips/kernel/mips_ksyms.c 2005-01-29 11:25:48.728461456 -0800 @@ -5,9 +5,11 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1996, 97, 98, 99, 2000, 01, 03 by Ralf Baechle + * Copyright (C) 1996, 97, 98, 99, 2000, 01, 03, 04, 05 by Ralf Baechle * Copyright (C) 1999, 2000, 01 Silicon Graphics, Inc. */ +#include +#include #include #include #include @@ -60,3 +62,6 @@ EXPORT_SYMBOL(__strnlen_user_asm); EXPORT_SYMBOL(csum_partial); EXPORT_SYMBOL(invalid_pte_table); +#ifdef CONFIG_GENERIC_IRQ_PROBE +EXPORT_SYMBOL(probe_irq_mask); +#endif diff -puN arch/mips/kernel/module.c~mips-generic-mips-updates arch/mips/kernel/module.c --- 25/arch/mips/kernel/module.c~mips-generic-mips-updates 2005-01-29 11:25:48.568485776 -0800 +++ 25-akpm/arch/mips/kernel/module.c 2005-01-29 11:25:48.728461456 -0800 @@ -2,7 +2,7 @@ #include static LIST_HEAD(dbe_list); -static spinlock_t dbe_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(dbe_lock); /* Given an address, look for it in the module exception tables. */ const struct exception_table_entry *search_module_dbetables(unsigned long addr) diff -puN arch/mips/kernel/process.c~mips-generic-mips-updates arch/mips/kernel/process.c --- 25/arch/mips/kernel/process.c~mips-generic-mips-updates 2005-01-29 11:25:48.570485472 -0800 +++ 25-akpm/arch/mips/kernel/process.c 2005-01-29 11:25:48.729461304 -0800 @@ -113,19 +113,15 @@ int copy_thread(int nr, unsigned long cl *childregs = *regs; childregs->regs[7] = 0; /* Clear error flag */ -#ifdef CONFIG_BINFMT_IRIX +#if defined(CONFIG_BINFMT_IRIX) if (current->personality != PER_LINUX) { /* Under IRIX things are a little different. */ - childregs->regs[2] = 0; childregs->regs[3] = 1; - regs->regs[2] = p->pid; regs->regs[3] = 0; - } else -#endif - { - childregs->regs[2] = 0; /* Child gets zero as return value */ - regs->regs[2] = p->pid; } +#endif + childregs->regs[2] = 0; /* Child gets zero as return value */ + regs->regs[2] = p->pid; if (childregs->cp0_status & ST0_CU0) { childregs->regs[28] = (unsigned long) ti; @@ -153,6 +149,36 @@ int copy_thread(int nr, unsigned long cl int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r) { memcpy(r, ¤t->thread.fpu, sizeof(current->thread.fpu)); + + return 1; +} + +void dump_regs(elf_greg_t *gp, struct pt_regs *regs) +{ + int i; + + for (i = 0; i < EF_R0; i++) + gp[i] = 0; + gp[EF_R0] = 0; + for (i = 1; i <= 31; i++) + gp[EF_R0 + i] = regs->regs[i]; + gp[EF_R26] = 0; + gp[EF_R27] = 0; + gp[EF_LO] = regs->lo; + gp[EF_HI] = regs->hi; + gp[EF_CP0_EPC] = regs->cp0_epc; + gp[EF_CP0_BADVADDR] = regs->cp0_badvaddr; + gp[EF_CP0_STATUS] = regs->cp0_status; + gp[EF_CP0_CAUSE] = regs->cp0_cause; +#ifdef EF_UNUSED0 + gp[EF_UNUSED0] = 0; +#endif +} + +int dump_task_fpu (struct task_struct *t, elf_fpregset_t *fpr) +{ + memcpy(fpr, &t->thread.fpu, sizeof(current->thread.fpu)); + return 1; } @@ -263,7 +289,6 @@ arch_initcall(frame_info_init); */ unsigned long thread_saved_pc(struct task_struct *tsk) { - extern void ret_from_fork(void); struct thread_struct *t = &tsk->thread; /* New born processes are a special case */ diff -L arch/mips/kernel/reg.c -puN arch/mips/kernel/reg.c~mips-generic-mips-updates /dev/null --- 25/arch/mips/kernel/reg.c +++ /dev/null 2003-09-15 06:40:47.000000000 -0700 @@ -1,69 +0,0 @@ -/* - * offset.c: Calculate pt_regs and task_struct indices. - * - * Copyright (C) 1996 David S. Miller - * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 Ralf Baechle - */ -#include -#include -#include -#include - -#include -#include - -#define text(t) __asm__("\n@@@" t) -#define _offset(type, member) ((unsigned long) &(((type *)NULL)->member)) -#define index(string, ptr, member) \ - __asm__("\n@@@" string "%0" : : "i" (_offset(ptr, member)/sizeof(long))) -#define size(string, size) \ - __asm__("\n@@@" string "%0" : : "i" (sizeof(size))) -#define linefeed text("") - -void output_ptreg_defines(void) -{ - text("/* MIPS pt_regs indices. */"); - index("#define EF_R0 ", struct pt_regs, regs[0]); - index("#define EF_R1 ", struct pt_regs, regs[1]); - index("#define EF_R2 ", struct pt_regs, regs[2]); - index("#define EF_R3 ", struct pt_regs, regs[3]); - index("#define EF_R4 ", struct pt_regs, regs[4]); - index("#define EF_R5 ", struct pt_regs, regs[5]); - index("#define EF_R6 ", struct pt_regs, regs[6]); - index("#define EF_R7 ", struct pt_regs, regs[7]); - index("#define EF_R8 ", struct pt_regs, regs[8]); - index("#define EF_R9 ", struct pt_regs, regs[9]); - index("#define EF_R10 ", struct pt_regs, regs[10]); - index("#define EF_R11 ", struct pt_regs, regs[11]); - index("#define EF_R12 ", struct pt_regs, regs[12]); - index("#define EF_R13 ", struct pt_regs, regs[13]); - index("#define EF_R14 ", struct pt_regs, regs[14]); - index("#define EF_R15 ", struct pt_regs, regs[15]); - index("#define EF_R16 ", struct pt_regs, regs[16]); - index("#define EF_R17 ", struct pt_regs, regs[17]); - index("#define EF_R18 ", struct pt_regs, regs[18]); - index("#define EF_R19 ", struct pt_regs, regs[19]); - index("#define EF_R20 ", struct pt_regs, regs[20]); - index("#define EF_R21 ", struct pt_regs, regs[21]); - index("#define EF_R22 ", struct pt_regs, regs[22]); - index("#define EF_R23 ", struct pt_regs, regs[23]); - index("#define EF_R24 ", struct pt_regs, regs[24]); - index("#define EF_R25 ", struct pt_regs, regs[25]); - index("#define EF_R26 ", struct pt_regs, regs[26]); - index("#define EF_R27 ", struct pt_regs, regs[27]); - index("#define EF_R28 ", struct pt_regs, regs[28]); - index("#define EF_R29 ", struct pt_regs, regs[29]); - index("#define EF_R30 ", struct pt_regs, regs[30]); - index("#define EF_R31 ", struct pt_regs, regs[31]); - linefeed; - index("#define EF_LO ", struct pt_regs, lo); - index("#define EF_HI ", struct pt_regs, hi); - linefeed; - index("#define EF_EPC ", struct pt_regs, cp0_epc); - index("#define EF_BVADDR ", struct pt_regs, cp0_badvaddr); - index("#define EF_STATUS ", struct pt_regs, cp0_status); - index("#define EF_CAUSE ", struct pt_regs, cp0_cause); - linefeed; - size("#define EF_SIZE ", struct pt_regs); - linefeed; -} diff -puN arch/mips/kernel/scall32-o32.S~mips-generic-mips-updates arch/mips/kernel/scall32-o32.S --- 25/arch/mips/kernel/scall32-o32.S~mips-generic-mips-updates 2005-01-29 11:25:48.573485016 -0800 +++ 25-akpm/arch/mips/kernel/scall32-o32.S 2005-01-29 11:25:48.732460848 -0800 @@ -5,6 +5,7 @@ * * Copyright (C) 1995, 96, 97, 98, 99, 2000, 01, 02 by Ralf Baechle * Copyright (C) 2001 MIPS Technologies, Inc. + * Copyright (C) 2004 Thiemo Seufer */ #include #include @@ -32,26 +33,30 @@ NESTED(handle_sys, PT_SIZE, sp) lw t1, PT_EPC(sp) # skip syscall on return +#if defined(CONFIG_BINFMT_IRIX) sltiu t0, v0, MAX_SYSCALL_NO + 1 # check syscall number +#else + subu v0, v0, __NR_O32_Linux # check syscall number + sltiu t0, v0, __NR_O32_Linux_syscalls + 1 +#endif addiu t1, 4 # skip to next instruction sw t1, PT_EPC(sp) beqz t0, illegal_syscall - /* XXX Put both in one cacheline, should save a bit. */ - sll t0, v0, 2 - lw t2, sys_call_table(t0) # syscall routine - lbu t3, sys_narg_table(v0) # number of arguments - beqz t2, illegal_syscall; + sll t0, v0, 3 + la t1, sys_call_table + addu t1, t0 + lw t2, (t1) # syscall routine + lw t3, 4(t1) # >= 0 if we need stack arguments + beqz t2, illegal_syscall - subu t0, t3, 5 # 5 or more arguments? sw a3, PT_R26(sp) # save a3 for syscall restarting - bgez t0, stackargs + bgez t3, stackargs stack_done: - sw a3, PT_R26(sp) # save for syscall restart - LONG_L t0, TI_FLAGS($28) # syscall tracing enabled? + lw t0, TI_FLAGS($28) # syscall tracing enabled? li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT - and t0, t1, t0 + and t0, t1 bnez t0, syscall_trace_entry # -> yes jalr t2 # Do The Real Thing (TM) @@ -70,9 +75,9 @@ o32_syscall_exit: local_irq_disable # make sure need_resched and # signals dont change between # sampling and return - LONG_L a2, TI_FLAGS($28) # current->work + lw a2, TI_FLAGS($28) # current->work li t0, _TIF_ALLWORK_MASK - and t0, a2, t0 + and t0, a2 bnez t0, o32_syscall_exit_work j restore_partial @@ -116,49 +121,48 @@ syscall_trace_entry: */ stackargs: lw t0, PT_R29(sp) # get old user stack pointer - subu t3, 4 - sll t1, t3, 2 # stack valid? - addu t1, t0 # end address - or t0, t1 - bltz t0, bad_stack # -> sp is bad - - lw t0, PT_R29(sp) # get old user stack pointer - PTR_LA t1, 4f # copy 1 to 3 arguments - sll t3, t3, 4 - subu t1, t3 - jr t1 - - /* Ok, copy the args from the luser stack to the kernel stack */ /* - * I know Ralf doesn't like nops but this avoids code - * duplication for R3000 targets (and this is the - * only place where ".set reorder" doesn't help). - * Harald. + * We intentionally keep the kernel stack a little below the top of + * userspace so we don't have to do a slower byte accurate check here. + */ + lw t5, TI_ADDR_LIMIT($28) + addu t4, t0, 32 + and t5, t4 + bltz t5, bad_stack # -> sp is bad + + /* Ok, copy the args from the luser stack to the kernel stack. + * t3 is the precomputed number of instruction bytes needed to + * load or store arguments 6-8. */ + + la t1, 5f # load up to 3 arguments + subu t1, t3 +1: lw t5, 16(t0) # argument #5 from usp .set push .set noreorder .set nomacro -1: lw t1, 24(t0) # argument #7 from usp - nop - sw t1, 24(sp) - nop -2: lw t1, 20(t0) # argument #5 from usp - nop - sw t1, 20(sp) - nop -3: lw t1, 16(t0) # argument #5 from usp - nop - sw t1, 16(sp) - nop -4: .set pop + jr t1 + addiu t1, 6f - 5f - j stack_done # go back +2: lw t8, 28(t0) # argument #8 from usp +3: lw t7, 24(t0) # argument #7 from usp +4: lw t6, 20(t0) # argument #6 from usp +5: jr t1 + sw t5, 16(sp) # argument #5 to ksp + + sw t8, 28(sp) # argument #8 to ksp + sw t7, 24(sp) # argument #7 to ksp + sw t6, 20(sp) # argument #6 to ksp +6: j stack_done # go back + nop + .set pop .section __ex_table,"a" PTR 1b,bad_stack PTR 2b,bad_stack PTR 3b,bad_stack + PTR 4b,bad_stack .previous /* @@ -177,7 +181,7 @@ bad_stack: * The system call does not exist in this kernel */ illegal_syscall: - li v0, ENOSYS # error + li v0, -ENOSYS # error sw v0, PT_R2(sp) li t0, 1 # set error flag sw t0, PT_R7(sp) @@ -238,12 +242,12 @@ illegal_syscall: sw v0, PT_R2(sp) # result /* Success, so skip usual error handling garbage. */ - LONG_L a2, TI_FLAGS($28) # syscall tracing enabled? + lw a2, TI_FLAGS($28) # syscall tracing enabled? li t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT and t0, a2, t0 bnez t0, 1f - b o32_syscall_exit + j o32_syscall_exit 1: SAVE_STATIC move a0, sp @@ -269,69 +273,49 @@ bad_alignment: END(sys_sysmips) LEAF(sys_syscall) - lw t0, PT_R29(sp) # user sp - - sltu v0, a0, __NR_O32_Linux + __NR_O32_Linux_syscalls + 1 - beqz v0, enosys - - sll v0, a0, 2 - la v1, sys_syscall - lw t2, sys_call_table(v0) # function pointer - lbu t4, sys_narg_table(a0) # number of arguments - - li v0, -EINVAL - beq t2, v1, out # do not recurse +#if defined(CONFIG_BINFMT_IRIX) + sltiu v0, a0, MAX_SYSCALL_NO + 1 # check syscall number +#else + subu t0, a0, __NR_O32_Linux # check syscall number + sltiu v0, t0, __NR_O32_Linux_syscalls + 1 +#endif + sll t1, t0, 3 + beqz v0, einval - beqz t2, enosys # null function pointer? + lw t2, sys_call_table(t1) # syscall routine - andi v0, t0, 0x3 # unaligned stack pointer? - bnez v0, sigsegv +#if defined(CONFIG_BINFMT_IRIX) + li v1, 4000 # nr of sys_syscall +#else + li v1, 4000 - __NR_O32_Linux # index of sys_syscall +#endif + beq t0, v1, einval # do not recurse - addu v0, t0, 16 # v0 = usp + 16 - addu t1, v0, 12 # 3 32-bit arguments - lw v1, TI_ADDR_LIMIT($28) - or v0, v0, t1 - and v1, v1, v0 - bltz v1, efault + /* Some syscalls like execve get their arguments from struct pt_regs + and claim zero arguments in the syscall table. Thus we have to + assume the worst case and shuffle around all potential arguments. + If you want performance, don't use indirect syscalls. */ move a0, a1 # shift argument registers move a1, a2 move a2, a3 - -1: lw a3, 16(t0) -2: lw t3, 20(t0) -3: lw t4, 24(t0) - - .section __ex_table, "a" - .word 1b, efault - .word 2b, efault - .word 3b, efault - .previous - - sw t3, 16(sp) # put into new stackframe - sw t4, 20(sp) - - bnez t4, 1f # zero arguments? - addu a0, sp, 32 # then pass sp in a0 -1: - - sw t3, 16(sp) - sw v1, 20(sp) + lw a3, 16(sp) + lw t4, 20(sp) + lw t5, 24(sp) + lw t6, 28(sp) + sw t4, 16(sp) + sw t5, 20(sp) + sw t6, 24(sp) + sw a0, PT_R4(sp) # .. and push back a0 - a3, some + sw a1, PT_R5(sp) # syscalls expect them there + sw a2, PT_R6(sp) + sw a3, PT_R7(sp) + sw a3, PT_R26(sp) # update a3 for syscall restarting jr t2 /* Unreached */ -enosys: li v0, -ENOSYS - b out - -sigsegv: - li a0, _SIGSEGV - move a1, $28 - jal force_sig - /* Fall through */ - -efault: li v0, -EFAULT - -out: jr ra +einval: li v0, -EINVAL + jr ra END(sys_syscall) .macro fifty ptr, nargs, from=1, to=50 @@ -349,12 +333,14 @@ out: jr ra .endm .macro syscalltable +#if defined(CONFIG_BINFMT_IRIX) mille sys_ni_syscall 0 /* 0 - 999 SVR4 flavour */ - #include "irix5sys.h" /* 1000 - 1999 32-bit IRIX */ + mille sys_ni_syscall 0 /* 1000 - 1999 32-bit IRIX */ mille sys_ni_syscall 0 /* 2000 - 2999 BSD43 flavour */ mille sys_ni_syscall 0 /* 3000 - 3999 POSIX flavour */ +#endif - sys sys_syscall 0 /* 4000 */ + sys sys_syscall 8 /* 4000 */ sys sys_exit 1 sys sys_fork 0 sys sys_read 3 @@ -405,7 +391,7 @@ out: jr ra sys sys_ni_syscall 0 /* was signal(2) */ sys sys_geteuid 0 sys sys_getegid 0 /* 4050 */ - sys sys_acct 0 + sys sys_acct 1 sys sys_umount 2 sys sys_ni_syscall 0 sys sys_ioctl 3 @@ -485,7 +471,7 @@ out: jr ra sys sys_init_module 5 sys sys_delete_module 1 sys sys_ni_syscall 0 /* 4130 was get_kernel_syms */ - sys sys_quotactl 0 + sys sys_quotactl 4 sys sys_getpgid 1 sys sys_fchdir 1 sys sys_bdflush 2 @@ -506,7 +492,7 @@ out: jr ra sys sys_sysmips 4 sys sys_ni_syscall 0 /* 4150 */ sys sys_getsid 1 - sys sys_fdatasync 0 + sys sys_fdatasync 1 sys sys_sysctl 1 sys sys_mlock 2 sys sys_munlock 2 /* 4155 */ @@ -640,19 +626,16 @@ out: jr ra .endm + /* We pre-compute the number of _instruction_ bytes needed to + load or store the arguments 6-8. Negative values are ignored. */ + .macro sys function, nargs PTR \function + LONG (\nargs << 2) - (5 << 2) .endm .align 3 -sys_call_table: + .type sys_call_table,@object +EXPORT(sys_call_table) syscalltable .size sys_call_table, . - sys_call_table - - .macro sys function, nargs - .byte \nargs - .endm - -sys_narg_table: - syscalltable - .size sys_narg_table, . - sys_narg_table diff -puN arch/mips/kernel/scall64-64.S~mips-generic-mips-updates arch/mips/kernel/scall64-64.S --- 25/arch/mips/kernel/scall64-64.S~mips-generic-mips-updates 2005-01-29 11:25:48.574484864 -0800 +++ 25-akpm/arch/mips/kernel/scall64-64.S 2005-01-29 11:25:48.733460696 -0800 @@ -53,8 +53,10 @@ NESTED(handle_sys64, PT_SIZE, sp) sd a3, PT_R26(sp) # save a3 for syscall restarting - LONG_L t0, TI_FLAGS($28) - bltz t0, syscall_trace_entry # syscall tracing enabled? + li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT + LONG_L t0, TI_FLAGS($28) # syscall tracing enabled? + and t0, t1, t0 + bnez t0, syscall_trace_entry jalr t2 # Do The Real Thing (TM) @@ -112,7 +114,7 @@ syscall_trace_entry: illegal_syscall: /* This also isn't a 64-bit syscall, throw an error. */ - li v0, ENOSYS # error + li v0, -ENOSYS # error sd v0, PT_R2(sp) li t0, 1 # set error flag sd t0, PT_R7(sp) @@ -173,8 +175,8 @@ illegal_syscall: sd v0, PT_R2(sp) # result /* Success, so skip usual error handling garbage. */ - LONG_L a2, TI_FLAGS($28) # syscall tracing enabled? li t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT + LONG_L a2, TI_FLAGS($28) # syscall tracing enabled? and t0, a2, t0 bnez t0, 1f diff -puN arch/mips/kernel/scall64-o32.S~mips-generic-mips-updates arch/mips/kernel/scall64-o32.S --- 25/arch/mips/kernel/scall64-o32.S~mips-generic-mips-updates 2005-01-29 11:25:48.576484560 -0800 +++ 25-akpm/arch/mips/kernel/scall64-o32.S 2005-01-29 11:25:48.734460544 -0800 @@ -6,6 +6,7 @@ * Copyright (C) 1995 - 2000, 2001 by Ralf Baechle * Copyright (C) 1999, 2000 Silicon Graphics, Inc. * Copyright (C) 2001 MIPS Technologies, Inc. + * Copyright (C) 2004 Thiemo Seufer * * Hairy, the userspace application uses a different argument passing * convention than the kernel, so we have to translate things from o32 @@ -43,6 +44,8 @@ NESTED(handle_sys, PT_SIZE, sp) RESTORE_ALL #endif + /* We don't want to stumble over broken sign extensions from + userland. O32 does never use the upper half. */ sll a0, a0, 0 sll a1, a1, 0 sll a2, a2, 0 @@ -68,11 +71,13 @@ NESTED(handle_sys, PT_SIZE, sp) 1: lw a4, 16(t0) # argument #5 from usp 2: lw a5, 20(t0) # argument #6 from usp 3: lw a6, 24(t0) # argument #7 from usp +4: lw a7, 28(t0) # argument #8 from usp (for indirect syscalls) .section __ex_table,"a" PTR 1b, bad_stack PTR 2b, bad_stack PTR 3b, bad_stack + PTR 4b, bad_stack .previous li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT @@ -91,7 +96,7 @@ NESTED(handle_sys, PT_SIZE, sp) sd v0, PT_R0(sp) # flag for syscall restarting 1: sd v0, PT_R2(sp) # result -FEXPORT(o32_syscall_exit) +o32_syscall_exit: local_irq_disable # make need_resched and # signals dont change between # sampling and return @@ -109,12 +114,12 @@ o32_syscall_exit_work: trace_a_syscall: SAVE_STATIC - sd a4, PT_R8(sp) + sd a4, PT_R8(sp) # Save argument registers sd a5, PT_R9(sp) sd a6, PT_R10(sp) - sd a7, PT_R11(sp) + sd a7, PT_R11(sp) # For indirect syscalls - move s0, t2 + move s0, t2 # Save syscall pointer move a0, sp li a1, 0 jal do_syscall_trace @@ -125,7 +130,8 @@ trace_a_syscall: ld a3, PT_R7(sp) ld a4, PT_R8(sp) ld a5, PT_R9(sp) - ld a6, PT_R10(sp) # For indirect syscalls + ld a6, PT_R10(sp) + ld a7, PT_R11(sp) # For indirect syscalls jalr s0 li t0, -EMAXERRNO - 1 # error? @@ -162,40 +168,17 @@ not_o32_scall: #else j handle_sys64 #endif - -illegal_syscall: - /* This also isn't a 64-bit syscall, throw an error. */ - li v0, ENOSYS # error - sd v0, PT_R2(sp) - li t0, 1 # set error flag - sd t0, PT_R7(sp) - j o32_syscall_exit END(handle_sys) LEAF(sys32_syscall) - ld t0, PT_R29(sp) # user sp - sltu v0, a0, __NR_O32_Linux + __NR_O32_Linux_syscalls + 1 - beqz v0, enosys + beqz v0, einval dsll v0, a0, 3 - dla v1, sys32_syscall ld t2, (sys_call_table - (__NR_O32_Linux * 8))(v0) - li v0, -EINVAL - beq t2, v1, out # do not recurse - - beqz t2, enosys # null function pointer? - - andi v0, t0, 0x3 # unaligned stack pointer? - bnez v0, sigsegv - - daddiu v0, t0, 16 # v0 = usp + 16 - daddu t1, v0, 12 # 3 32-bit arguments - ld v1, TI_ADDR_LIMIT($28) - or v0, v0, t1 - and v1, v1, v0 - bnez v1, efault + li v1, 4000 # indirect syscall number + beq a0, v1, einval # do not recurse move a0, a1 # shift argument registers move a1, a2 @@ -203,25 +186,21 @@ LEAF(sys32_syscall) move a3, a4 move a4, a5 move a5, a6 + move a6, a7 + sd a0, PT_R4(sp) # ... and push back a0 - a3, some + sd a1, PT_R5(sp) # syscalls expect them there + sd a2, PT_R6(sp) + sd a3, PT_R7(sp) + sd a3, PT_R26(sp) # update a3 for syscall restarting jr t2 /* Unreached */ -enosys: li v0, -ENOSYS - b out - -sigsegv: - li a0, _SIGSEGV - move a1, $28 - jal force_sig - /* Fall through */ - -efault: li v0, -EFAULT - -out: jr ra +einval: li v0, -EINVAL + jr ra END(sys32_syscall) .align 3 - .type sys_call_table,@object; + .type sys_call_table,@object sys_call_table: PTR sys32_syscall /* 4000 */ PTR sys_exit diff -puN arch/mips/kernel/semaphore.c~mips-generic-mips-updates arch/mips/kernel/semaphore.c --- 25/arch/mips/kernel/semaphore.c~mips-generic-mips-updates 2005-01-29 11:25:48.577484408 -0800 +++ 25-akpm/arch/mips/kernel/semaphore.c 2005-01-29 11:25:48.735460392 -0800 @@ -15,7 +15,6 @@ * indicate that some process(es) are waiting for the semaphore. */ -#include #include #include #include @@ -64,7 +63,7 @@ static inline int __sem_update_count(str : "=&r" (old_count), "=&r" (tmp), "=m" (sem->count) : "r" (incr), "m" (sem->count)); } else { - static spinlock_t semaphore_lock = SPIN_LOCK_UNLOCKED; + static DEFINE_SPINLOCK(semaphore_lock); unsigned long flags; spin_lock_irqsave(&semaphore_lock, flags); diff -puN arch/mips/kernel/setup.c~mips-generic-mips-updates arch/mips/kernel/setup.c --- 25/arch/mips/kernel/setup.c~mips-generic-mips-updates 2005-01-29 11:25:48.578484256 -0800 +++ 25-akpm/arch/mips/kernel/setup.c 2005-01-29 11:25:48.736460240 -0800 @@ -281,12 +281,12 @@ static inline void bootmem_init(void) initrd_reserve_bootmem = 1; } else { unsigned long tmp; - unsigned long *initrd_header; + u32 *initrd_header; - tmp = ((reserved_end + PAGE_SIZE-1) & PAGE_MASK) - 8; + tmp = ((reserved_end + PAGE_SIZE-1) & PAGE_MASK) - sizeof(u32) * 2; if (tmp < reserved_end) tmp += PAGE_SIZE; - initrd_header = (unsigned long *)tmp; + initrd_header = (u32 *)tmp; if (initrd_header[0] == 0x494E5244) { initrd_start = (unsigned long)&initrd_header[2]; initrd_end = initrd_start + initrd_header[1]; @@ -425,8 +425,10 @@ static inline void bootmem_init(void) if (CPHYSADDR(initrd_end) > PFN_PHYS(max_low_pfn)) { printk("initrd extends beyond end of memory " "(0x%0*Lx > 0x%0*Lx)\ndisabling initrd\n", - sizeof(long) * 2, CPHYSADDR(initrd_end), - sizeof(long) * 2, PFN_PHYS(max_low_pfn)); + sizeof(long) * 2, + (unsigned long long)CPHYSADDR(initrd_end), + sizeof(long) * 2, + (unsigned long long)PFN_PHYS(max_low_pfn)); initrd_start = initrd_end = 0; initrd_reserve_bootmem = 0; } @@ -441,10 +443,21 @@ static inline void resource_init(void) { int i; +#if defined(CONFIG_MIPS64) && !defined(CONFIG_BUILD_ELF64) + /* + * The 64bit code in 32bit object format trick can't represent + * 64bit wide relocations for linker script symbols. + */ + code_resource.start = CPHYSADDR(&_text); + code_resource.end = CPHYSADDR(&_etext) - 1; + data_resource.start = CPHYSADDR(&_etext); + data_resource.end = CPHYSADDR(&_edata) - 1; +#else code_resource.start = virt_to_phys(&_text); code_resource.end = virt_to_phys(&_etext) - 1; data_resource.start = virt_to_phys(&_etext); data_resource.end = virt_to_phys(&_edata) - 1; +#endif /* * Request address space for all standard RAM. diff -puN arch/mips/kernel/signal32.c~mips-generic-mips-updates arch/mips/kernel/signal32.c --- 25/arch/mips/kernel/signal32.c~mips-generic-mips-updates 2005-01-29 11:25:48.580483952 -0800 +++ 25-akpm/arch/mips/kernel/signal32.c 2005-01-29 11:25:48.737460088 -0800 @@ -37,7 +37,7 @@ typedef union sigval32 { s32 sival_ptr; } sigval_t32; -typedef struct compat_siginfo{ +typedef struct compat_siginfo { int si_signo; int si_code; int si_errno; @@ -106,7 +106,7 @@ typedef struct compat_siginfo{ #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) -extern asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs *regs); +extern int do_signal32(sigset_t *oldset, struct pt_regs *regs); /* 32-bit compatibility types */ @@ -192,6 +192,7 @@ static inline int get_sigset(sigset_t *k /* * Atomically swap in the new signal mask, and wait for a signal. */ + save_static_function(sys32_sigsuspend); __attribute_used__ noinline static int _sys32_sigsuspend(nabi_no_regargs struct pt_regs regs) @@ -333,8 +334,7 @@ asmlinkage int sys32_sigaltstack(nabi_no return ret; } -static asmlinkage int restore_sigcontext32(struct pt_regs *regs, - struct sigcontext32 *sc) +static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 *sc) { int err = 0; __u32 used_math; @@ -391,7 +391,7 @@ struct sigframe { struct rt_sigframe32 { u32 rs_ass[4]; /* argument save space for o32 */ u32 rs_code[2]; /* signal trampoline */ - struct compat_siginfo_t rs_info; + compat_siginfo_t rs_info; struct ucontext32 rs_uc; }; @@ -442,7 +442,9 @@ int copy_siginfo_to_user32(compat_siginf return err; } -asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs) +save_static_function(sys32_sigreturn); +__attribute_used__ noinline static void +_sys32_sigreturn(nabi_no_regargs struct pt_regs regs) { struct sigframe *frame; sigset_t blocked; @@ -478,7 +480,9 @@ badframe: force_sig(SIGSEGV, current); } -asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) +save_static_function(sys32_rt_sigreturn); +__attribute_used__ noinline static void +_sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) { struct rt_sigframe32 *frame; sigset_t set; @@ -761,7 +765,7 @@ static inline void handle_signal(unsigne } } -asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs *regs) +int do_signal32(sigset_t *oldset, struct pt_regs *regs) { struct k_sigaction ka; siginfo_t info; diff -puN arch/mips/kernel/signal.c~mips-generic-mips-updates arch/mips/kernel/signal.c --- 25/arch/mips/kernel/signal.c~mips-generic-mips-updates 2005-01-29 11:25:48.581483800 -0800 +++ 25-akpm/arch/mips/kernel/signal.c 2005-01-29 11:25:48.739459784 -0800 @@ -28,12 +28,15 @@ #include #include #include +#include + +#include "signal-common.h" #define DEBUG_SIG 0 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) -extern asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs); +static int do_signal(sigset_t *oldset, struct pt_regs *regs); /* * Atomically swap in the new signal mask, and wait for a signal. @@ -151,53 +154,6 @@ asmlinkage int sys_sigaltstack(nabi_no_r return do_sigaltstack(uss, uoss, usp); } -asmlinkage int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) -{ - int err = 0; - unsigned int used_math; - - /* Always make any pending restarted system calls return -EINTR */ - current_thread_info()->restart_block.fn = do_no_restart_syscall; - - err |= __get_user(regs->cp0_epc, &sc->sc_pc); - err |= __get_user(regs->hi, &sc->sc_mdhi); - err |= __get_user(regs->lo, &sc->sc_mdlo); - -#define restore_gp_reg(i) do { \ - err |= __get_user(regs->regs[i], &sc->sc_regs[i]); \ -} while(0) - restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3); - restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6); - restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9); - restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12); - restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15); - restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18); - restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21); - restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24); - restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27); - restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30); - restore_gp_reg(31); -#undef restore_gp_reg - - err |= __get_user(used_math, &sc->sc_used_math); - conditional_used_math(used_math); - - preempt_disable(); - - if (used_math()) { - /* restore fpu context if we have used it before */ - own_fpu(); - err |= restore_fp_context(sc); - } else { - /* signal handler may have used FPU. Give it up. */ - lose_fpu(); - } - - preempt_enable(); - - return err; -} - #if PLAT_TRAMPOLINE_STUFF_LINE #define __tramp __attribute__((aligned(PLAT_TRAMPOLINE_STUFF_LINE))) #else @@ -221,7 +177,9 @@ struct rt_sigframe { }; #ifdef CONFIG_TRAD_SIGNALS -asmlinkage void sys_sigreturn(struct pt_regs regs) +save_static_function(sys_sigreturn); +__attribute_used__ noinline static void +_sys_sigreturn(nabi_no_regargs struct pt_regs regs) { struct sigframe *frame; sigset_t blocked; @@ -258,7 +216,9 @@ badframe: } #endif -asmlinkage void sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs) +save_static_function(sys_rt_sigreturn); +__attribute_used__ noinline static void +_sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs) { struct rt_sigframe *frame; sigset_t set; @@ -299,85 +259,6 @@ badframe: force_sig(SIGSEGV, current); } -inline int setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc) -{ - int err = 0; - - err |= __put_user(regs->cp0_epc, &sc->sc_pc); - err |= __put_user(regs->cp0_status, &sc->sc_status); - -#define save_gp_reg(i) do { \ - err |= __put_user(regs->regs[i], &sc->sc_regs[i]); \ -} while(0) - __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2); - save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6); - save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10); - save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14); - save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18); - save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22); - save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26); - save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30); - save_gp_reg(31); -#undef save_gp_reg - - err |= __put_user(regs->hi, &sc->sc_mdhi); - err |= __put_user(regs->lo, &sc->sc_mdlo); - err |= __put_user(regs->cp0_cause, &sc->sc_cause); - err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr); - - err |= __put_user(!!used_math(), &sc->sc_used_math); - - if (!used_math()) - goto out; - - /* - * Save FPU state to signal context. Signal handler will "inherit" - * current FPU state. - */ - preempt_disable(); - - if (!is_fpu_owner()) { - own_fpu(); - restore_fp(current); - } - err |= save_fp_context(sc); - - preempt_enable(); - -out: - return err; -} - -/* - * Determine which stack to use.. - */ -static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, - size_t frame_size) -{ - unsigned long sp, almask; - - /* Default to using normal stack */ - sp = regs->regs[29]; - - /* - * FPU emulator may have it's own trampoline active just - * above the user stack, 16-bytes before the next lowest - * 16 byte boundary. Try to avoid trashing it. - */ - sp -= 32; - - /* This is the X/Open sanctioned signal stack switching. */ - if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0)) - sp = current->sas_ss_sp + current->sas_ss_size; - - if (PLAT_TRAMPOLINE_STUFF_LINE) - almask = ~(PLAT_TRAMPOLINE_STUFF_LINE - 1); - else - almask = ALMASK; - - return (void *)((sp - frame_size) & ~(PLAT_TRAMPOLINE_STUFF_LINE - 1)); -} - #ifdef CONFIG_TRAD_SIGNALS static void inline setup_frame(struct k_sigaction * ka, struct pt_regs *regs, int signr, sigset_t *set) @@ -396,8 +277,7 @@ static void inline setup_frame(struct k_ * syscall */ if (PLAT_TRAMPOLINE_STUFF_LINE) - __builtin_memset(frame->sf_code, '0', - PLAT_TRAMPOLINE_STUFF_LINE); + __clear_user(frame->sf_code, PLAT_TRAMPOLINE_STUFF_LINE); err |= __put_user(0x24020000 + __NR_sigreturn, frame->sf_code + 0); err |= __put_user(0x0000000c , frame->sf_code + 1); flush_cache_sigtramp((unsigned long) frame->sf_code); @@ -453,8 +333,7 @@ static void inline setup_rt_frame(struct * syscall */ if (PLAT_TRAMPOLINE_STUFF_LINE) - __builtin_memset(frame->rs_code, '0', - PLAT_TRAMPOLINE_STUFF_LINE); + __clear_user(frame->rs_code, PLAT_TRAMPOLINE_STUFF_LINE); err |= __put_user(0x24020000 + __NR_rt_sigreturn, frame->rs_code + 0); err |= __put_user(0x0000000c , frame->rs_code + 1); flush_cache_sigtramp((unsigned long) frame->rs_code); @@ -558,7 +437,7 @@ static inline void handle_signal(unsigne extern int do_signal32(sigset_t *oldset, struct pt_regs *regs); extern int do_irix_signal(sigset_t *oldset, struct pt_regs *regs); -asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs) +static int do_signal(sigset_t *oldset, struct pt_regs *regs) { struct k_sigaction ka; siginfo_t info; @@ -612,8 +491,6 @@ no_signal: return 0; } -extern int do_irix_signal(sigset_t *oldset, struct pt_regs *regs); - /* * notification of userspace execution resumption * - triggered by current->work.notify_resume diff -puN /dev/null arch/mips/kernel/signal-common.h --- /dev/null 2003-09-15 06:40:47.000000000 -0700 +++ 25-akpm/arch/mips/kernel/signal-common.h 2005-01-29 11:25:48.740459632 -0800 @@ -0,0 +1,136 @@ +/* + * 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) 1991, 1992 Linus Torvalds + * Copyright (C) 1994 - 2000 Ralf Baechle + * Copyright (C) 1999, 2000 Silicon Graphics, Inc. + */ + +static inline int +setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc) +{ + int err = 0; + + err |= __put_user(regs->cp0_epc, &sc->sc_pc); + err |= __put_user(regs->cp0_status, &sc->sc_status); + +#define save_gp_reg(i) do { \ + err |= __put_user(regs->regs[i], &sc->sc_regs[i]); \ +} while(0) + __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2); + save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6); + save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10); + save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14); + save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18); + save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22); + save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26); + save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30); + save_gp_reg(31); +#undef save_gp_reg + + err |= __put_user(regs->hi, &sc->sc_mdhi); + err |= __put_user(regs->lo, &sc->sc_mdlo); + err |= __put_user(regs->cp0_cause, &sc->sc_cause); + err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr); + + err |= __put_user(!!used_math(), &sc->sc_used_math); + + if (!used_math()) + goto out; + + /* + * Save FPU state to signal context. Signal handler will "inherit" + * current FPU state. + */ + preempt_disable(); + + if (!is_fpu_owner()) { + own_fpu(); + restore_fp(current); + } + err |= save_fp_context(sc); + + preempt_enable(); + +out: + return err; +} + +static inline int +restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) +{ + int err = 0; + + /* Always make any pending restarted system calls return -EINTR */ + current_thread_info()->restart_block.fn = do_no_restart_syscall; + + err |= __get_user(regs->cp0_epc, &sc->sc_pc); + err |= __get_user(regs->hi, &sc->sc_mdhi); + err |= __get_user(regs->lo, &sc->sc_mdlo); + +#define restore_gp_reg(i) do { \ + err |= __get_user(regs->regs[i], &sc->sc_regs[i]); \ +} while(0) + restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3); + restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6); + restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9); + restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12); + restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15); + restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18); + restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21); + restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24); + restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27); + restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30); + restore_gp_reg(31); +#undef restore_gp_reg + + err |= __get_user(!!used_math(), &sc->sc_used_math); + conditional_used_math(used_math); + + preempt_disable(); + + if (used_math()) { + /* restore fpu context if we have used it before */ + own_fpu(); + err |= restore_fp_context(sc); + } else { + /* signal handler may have used FPU. Give it up. */ + lose_fpu(); + } + + preempt_enable(); + + return err; +} + +/* + * Determine which stack to use.. + */ +static inline void * +get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) +{ + unsigned long sp, almask; + + /* Default to using normal stack */ + sp = regs->regs[29]; + + /* + * FPU emulator may have it's own trampoline active just + * above the user stack, 16-bytes before the next lowest + * 16 byte boundary. Try to avoid trashing it. + */ + sp -= 32; + + /* This is the X/Open sanctioned signal stack switching. */ + if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0)) + sp = current->sas_ss_sp + current->sas_ss_size; + + if (PLAT_TRAMPOLINE_STUFF_LINE) + almask = ~(PLAT_TRAMPOLINE_STUFF_LINE - 1); + else + almask = ALMASK; + + return (void *)((sp - frame_size) & almask); +} diff -puN arch/mips/kernel/signal_n32.c~mips-generic-mips-updates arch/mips/kernel/signal_n32.c --- 25/arch/mips/kernel/signal_n32.c~mips-generic-mips-updates 2005-01-29 11:25:48.583483496 -0800 +++ 25-akpm/arch/mips/kernel/signal_n32.c 2005-01-29 11:25:48.741459480 -0800 @@ -35,9 +35,12 @@ #include #include #include +#include + +#include "signal-common.h" /* - * Including would give use the 64-bit syscall numbers ... */ #define __NR_N32_rt_sigreturn 6211 #define __NR_N32_restart_syscall 6214 @@ -59,17 +62,22 @@ struct ucontextn32 { sigset_t uc_sigmask; /* mask last for extensibility */ }; +#if PLAT_TRAMPOLINE_STUFF_LINE +#define __tramp __attribute__((aligned(PLAT_TRAMPOLINE_STUFF_LINE))) +#else +#define __tramp +#endif + struct rt_sigframe_n32 { u32 rs_ass[4]; /* argument save space for o32 */ - u32 rs_code[2]; /* signal trampoline */ - struct siginfo rs_info; + u32 rs_code[2] __tramp; /* signal trampoline */ + struct siginfo rs_info __tramp; struct ucontextn32 rs_uc; }; -extern asmlinkage int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc); -extern int inline setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc); - -asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) +save_static_function(sysn32_rt_sigreturn); +__attribute_used__ noinline static void +_sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) { struct rt_sigframe_n32 *frame; sigset_t set; @@ -118,31 +126,6 @@ badframe: force_sig(SIGSEGV, current); } -/* - * Determine which stack to use.. - */ -static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, - size_t frame_size) -{ - unsigned long sp; - - /* Default to using normal stack */ - sp = regs->regs[29]; - - /* - * FPU emulator may have it's own trampoline active just - * above the user stack, 16-bytes before the next lowest - * 16 byte boundary. Try to avoid trashing it. - */ - sp -= 32; - - /* This is the X/Open sanctioned signal stack switching. */ - if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0)) - sp = current->sas_ss_sp + current->sas_ss_size; - - return (void *)((sp - frame_size) & ALMASK); -} - void setup_rt_frame_n32(struct k_sigaction * ka, struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info) { @@ -160,8 +143,10 @@ void setup_rt_frame_n32(struct k_sigacti * li v0, __NR_rt_sigreturn * syscall */ + if (PLAT_TRAMPOLINE_STUFF_LINE) + __clear_user(frame->rs_code, PLAT_TRAMPOLINE_STUFF_LINE); err |= __put_user(0x24020000 + __NR_N32_rt_sigreturn, frame->rs_code + 0); - err |= __put_user(0x0000000c , frame->rs_code + 1); + err |= __put_user(0x0000000c , frame->rs_code + 1); flush_cache_sigtramp((unsigned long) frame->rs_code); /* Create siginfo. */ diff -puN arch/mips/kernel/smp.c~mips-generic-mips-updates arch/mips/kernel/smp.c --- 25/arch/mips/kernel/smp.c~mips-generic-mips-updates 2005-01-29 11:25:48.584483344 -0800 +++ 25-akpm/arch/mips/kernel/smp.c 2005-01-29 11:25:48.741459480 -0800 @@ -18,7 +18,6 @@ * Copyright (C) 2000, 2001 Silicon Graphics, Inc. * Copyright (C) 2000, 2001, 2003 Broadcom Corporation */ -#include #include #include #include @@ -94,6 +93,7 @@ static void smp_tune_scheduling (void) } extern void __init calibrate_delay(void); +extern ATTRIB_NORET void cpu_idle(void); /* * First C code run on the secondary CPUs after being started up by @@ -123,7 +123,7 @@ asmlinkage void start_secondary(void) cpu_idle(); } -spinlock_t smp_call_lock = SPIN_LOCK_UNLOCKED; +DEFINE_SPINLOCK(smp_call_lock); struct call_data_struct *call_data; diff -puN arch/mips/kernel/syscall.c~mips-generic-mips-updates arch/mips/kernel/syscall.c --- 25/arch/mips/kernel/syscall.c~mips-generic-mips-updates 2005-01-29 11:25:48.586483040 -0800 +++ 25-akpm/arch/mips/kernel/syscall.c 2005-01-29 11:25:48.742459328 -0800 @@ -3,10 +3,11 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1995, 1996, 1997, 2000, 2001 by Ralf Baechle + * Copyright (C) 1995, 1996, 1997, 2000, 2001, 05 by Ralf Baechle * Copyright (C) 1999, 2000 Silicon Graphics, Inc. * Copyright (C) 2001 MIPS Technologies, Inc. */ +#include #include #include #include @@ -66,11 +67,7 @@ unsigned long arch_get_unmapped_area(str int do_color_align; unsigned long task_size; -#ifdef CONFIG_MIPS32 - task_size = TASK_SIZE; -#else - task_size = (current->thread.mflags & MF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE; -#endif + task_size = STACK_TOP; if (flags & MAP_FIXED) { /* @@ -116,7 +113,7 @@ unsigned long arch_get_unmapped_area(str } /* common code for old and new mmaps */ -static inline long +static inline unsigned long do_mmap2(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff) { @@ -140,8 +137,9 @@ out: return error; } -asmlinkage unsigned long old_mmap(unsigned long addr, size_t len, int prot, - int flags, int fd, off_t offset) +asmlinkage unsigned long +old_mmap(unsigned long addr, unsigned long len, int prot, + int flags, int fd, off_t offset) { unsigned long result; @@ -155,7 +153,7 @@ out: return result; } -asmlinkage long +asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff) { diff -puN arch/mips/kernel/time.c~mips-generic-mips-updates arch/mips/kernel/time.c --- 25/arch/mips/kernel/time.c~mips-generic-mips-updates 2005-01-29 11:25:48.587482888 -0800 +++ 25-akpm/arch/mips/kernel/time.c 2005-01-29 11:25:48.743459176 -0800 @@ -11,7 +11,6 @@ * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. */ -#include #include #include #include @@ -53,7 +52,7 @@ EXPORT_SYMBOL(jiffies_64); */ extern volatile unsigned long wall_jiffies; -spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED; +DEFINE_SPINLOCK(rtc_lock); /* * By default we provide the null RTC ops diff -puN arch/mips/kernel/traps.c~mips-generic-mips-updates arch/mips/kernel/traps.c --- 25/arch/mips/kernel/traps.c~mips-generic-mips-updates 2005-01-29 11:25:48.589482584 -0800 +++ 25-akpm/arch/mips/kernel/traps.c 2005-01-29 11:25:48.744459024 -0800 @@ -38,12 +38,9 @@ #include #include -extern asmlinkage void handle_mod(void); +extern asmlinkage void handle_tlbm(void); extern asmlinkage void handle_tlbl(void); extern asmlinkage void handle_tlbs(void); -extern asmlinkage void __xtlb_mod(void); -extern asmlinkage void __xtlb_tlbl(void); -extern asmlinkage void __xtlb_tlbs(void); extern asmlinkage void handle_adel(void); extern asmlinkage void handle_ades(void); extern asmlinkage void handle_ibe(void); @@ -82,7 +79,12 @@ void show_stack(struct task_struct *task long stackdata; int i; - sp = sp ? sp : (unsigned long *) &sp; + if (!sp) { + if (task && task != current) + sp = (unsigned long *) task->thread.reg29; + else + sp = (unsigned long *) &sp; + } printk("Stack :"); i = 0; @@ -110,8 +112,12 @@ void show_trace(struct task_struct *task const int field = 2 * sizeof(unsigned long); unsigned long addr; - if (!stack) - stack = (unsigned long*)&stack; + if (!stack) { + if (task && task != current) + stack = (unsigned long *) task->thread.reg29; + else + stack = (unsigned long *) &stack; + } printk("Call Trace:"); #ifdef CONFIG_KALLSYMS @@ -244,7 +250,7 @@ void show_registers(struct pt_regs *regs printk("\n"); } -static spinlock_t die_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(die_lock); NORET_TYPE void __die(const char * str, struct pt_regs * regs, const char * file, const char * func, unsigned long line) @@ -1001,16 +1007,10 @@ void __init trap_init(void) if (board_be_init) board_be_init(); -#ifdef CONFIG_MIPS32 - set_except_vector(1, handle_mod); + set_except_vector(1, handle_tlbm); set_except_vector(2, handle_tlbl); set_except_vector(3, handle_tlbs); -#endif -#ifdef CONFIG_MIPS64 - set_except_vector(1, __xtlb_mod); - set_except_vector(2, __xtlb_tlbl); - set_except_vector(3, __xtlb_tlbs); -#endif + set_except_vector(4, handle_adel); set_except_vector(5, handle_ades); @@ -1047,7 +1047,7 @@ void __init trap_init(void) * unaligned ldc1/sdc1 exception. The handlers have not been * written yet. Well, anyway there is no R6000 machine on the * current list of targets for Linux/MIPS. - * (Duh, crap, there is someone with a tripple R6k machine) + * (Duh, crap, there is someone with a triple R6k machine) */ //set_except_vector(14, handle_mc); //set_except_vector(15, handle_ndc); diff -puN arch/mips/kernel/vmlinux.lds.S~mips-generic-mips-updates arch/mips/kernel/vmlinux.lds.S --- 25/arch/mips/kernel/vmlinux.lds.S~mips-generic-mips-updates 2005-01-29 11:25:48.590482432 -0800 +++ 25-akpm/arch/mips/kernel/vmlinux.lds.S 2005-01-29 11:25:48.745458872 -0800 @@ -156,6 +156,7 @@ SECTIONS *(.options) *(.pdr) *(.reginfo) + *(.mdebug*) } /* This is the MIPS specific mdebug section. */ diff -puN arch/mips/lib-64/dump_tlb.c~mips-generic-mips-updates arch/mips/lib-64/dump_tlb.c --- 25/arch/mips/lib-64/dump_tlb.c~mips-generic-mips-updates 2005-01-29 11:25:48.591482280 -0800 +++ 25-akpm/arch/mips/lib-64/dump_tlb.c 2005-01-29 11:25:48.745458872 -0800 @@ -148,16 +148,16 @@ void dump_list_process(struct task_struc printk("tasks->mm.pgd == %08lx\n", (unsigned long) t->mm->pgd); page_dir = pgd_offset(t->mm, 0); - printk("page_dir == %08lx\n", (unsigned long) page_dir); + printk("page_dir == %016lx\n", (unsigned long) page_dir); pgd = pgd_offset(t->mm, addr); - printk("pgd == %08lx, ", (unsigned long) pgd); + printk("pgd == %016lx\n", (unsigned long) pgd); pmd = pmd_offset(pgd, addr); - printk("pmd == %08lx, ", (unsigned long) pmd); + printk("pmd == %016lx\n", (unsigned long) pmd); pte = pte_offset(pmd, addr); - printk("pte == %08lx, ", (unsigned long) pte); + printk("pte == %016lx\n", (unsigned long) pte); page = *pte; printk("page == %08lx\n", pte_val(page)); diff -puN arch/mips/lib/csum_partial_copy.c~mips-generic-mips-updates arch/mips/lib/csum_partial_copy.c diff -puN arch/mips/Makefile~mips-generic-mips-updates arch/mips/Makefile --- 25/arch/mips/Makefile~mips-generic-mips-updates 2005-01-29 11:25:48.594481824 -0800 +++ 25-akpm/arch/mips/Makefile 2005-01-29 11:25:48.746458720 -0800 @@ -673,6 +673,8 @@ libs-$(CONFIG_MIPS64) += arch/mips/lib-6 core-y += arch/mips/kernel/ arch/mips/mm/ arch/mips/math-emu/ +drivers-$(CONFIG_OPROFILE) += arch/mips/oprofile/ + ifdef CONFIG_LASAT rom.bin rom.sw: vmlinux $(call descend,arch/mips/lasat/image,$@) @@ -744,36 +746,16 @@ define filechk_gen-asm-offset.h echo "#endif /* _ASM_OFFSET_H */" ) endef -define filechk_gen-asm-reg.h - (set -e; \ - echo "#ifndef _ASM_REG_H"; \ - echo "#define _ASM_REG_H"; \ - echo "/*"; \ - echo " * DO NOT MODIFY."; \ - echo " *"; \ - echo " * This file was generated by arch/$(ARCH)/Makefile"; \ - echo " *"; \ - echo " */"; \ - echo ""; \ - sed -ne "/^@@@/s///p"; \ - echo "#endif /* _ASM_REG_H */" ) -endef - -prepare: include/asm-$(ARCH)/offset.h \ - include/asm-$(ARCH)/reg.h +prepare: include/asm-$(ARCH)/offset.h arch/$(ARCH)/kernel/offset.s: include/asm include/linux/version.h \ include/config/MARKER include/asm-$(ARCH)/offset.h: arch/$(ARCH)/kernel/offset.s $(call filechk,gen-asm-offset.h) -include/asm-$(ARCH)/reg.h: arch/$(ARCH)/kernel/reg.s - $(call filechk,gen-asm-reg.h) CLEAN_FILES += include/asm-$(ARCH)/offset.h.tmp \ include/asm-$(ARCH)/offset.h \ - include/asm-$(ARCH)/reg.h.tmp \ - include/asm-$(ARCH)/reg.h \ vmlinux.32 \ vmlinux.64 \ vmlinux.ecoff diff -puN arch/mips/math-emu/cp1emu.c~mips-generic-mips-updates arch/mips/math-emu/cp1emu.c --- 25/arch/mips/math-emu/cp1emu.c~mips-generic-mips-updates 2005-01-29 11:25:48.596481520 -0800 +++ 25-akpm/arch/mips/math-emu/cp1emu.c 2005-01-29 11:25:48.747458568 -0800 @@ -2,7 +2,7 @@ * cp1emu.c: a MIPS coprocessor 1 (fpu) instruction emulator * * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com diff -puN arch/mips/math-emu/dp_add.c~mips-generic-mips-updates arch/mips/math-emu/dp_add.c --- 25/arch/mips/math-emu/dp_add.c~mips-generic-mips-updates 2005-01-29 11:25:48.597481368 -0800 +++ 25-akpm/arch/mips/math-emu/dp_add.c 2005-01-29 11:25:48.748458416 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/dp_cmp.c~mips-generic-mips-updates arch/mips/math-emu/dp_cmp.c --- 25/arch/mips/math-emu/dp_cmp.c~mips-generic-mips-updates 2005-01-29 11:25:48.598481216 -0800 +++ 25-akpm/arch/mips/math-emu/dp_cmp.c 2005-01-29 11:25:48.748458416 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/dp_div.c~mips-generic-mips-updates arch/mips/math-emu/dp_div.c --- 25/arch/mips/math-emu/dp_div.c~mips-generic-mips-updates 2005-01-29 11:25:48.599481064 -0800 +++ 25-akpm/arch/mips/math-emu/dp_div.c 2005-01-29 11:25:48.748458416 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/dp_fint.c~mips-generic-mips-updates arch/mips/math-emu/dp_fint.c --- 25/arch/mips/math-emu/dp_fint.c~mips-generic-mips-updates 2005-01-29 11:25:48.601480760 -0800 +++ 25-akpm/arch/mips/math-emu/dp_fint.c 2005-01-29 11:25:48.749458264 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/dp_flong.c~mips-generic-mips-updates arch/mips/math-emu/dp_flong.c --- 25/arch/mips/math-emu/dp_flong.c~mips-generic-mips-updates 2005-01-29 11:25:48.602480608 -0800 +++ 25-akpm/arch/mips/math-emu/dp_flong.c 2005-01-29 11:25:48.749458264 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/dp_frexp.c~mips-generic-mips-updates arch/mips/math-emu/dp_frexp.c --- 25/arch/mips/math-emu/dp_frexp.c~mips-generic-mips-updates 2005-01-29 11:25:48.603480456 -0800 +++ 25-akpm/arch/mips/math-emu/dp_frexp.c 2005-01-29 11:25:48.749458264 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/dp_fsp.c~mips-generic-mips-updates arch/mips/math-emu/dp_fsp.c --- 25/arch/mips/math-emu/dp_fsp.c~mips-generic-mips-updates 2005-01-29 11:25:48.605480152 -0800 +++ 25-akpm/arch/mips/math-emu/dp_fsp.c 2005-01-29 11:25:48.750458112 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/dp_logb.c~mips-generic-mips-updates arch/mips/math-emu/dp_logb.c --- 25/arch/mips/math-emu/dp_logb.c~mips-generic-mips-updates 2005-01-29 11:25:48.606480000 -0800 +++ 25-akpm/arch/mips/math-emu/dp_logb.c 2005-01-29 11:25:48.750458112 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/dp_modf.c~mips-generic-mips-updates arch/mips/math-emu/dp_modf.c --- 25/arch/mips/math-emu/dp_modf.c~mips-generic-mips-updates 2005-01-29 11:25:48.607479848 -0800 +++ 25-akpm/arch/mips/math-emu/dp_modf.c 2005-01-29 11:25:48.750458112 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/dp_mul.c~mips-generic-mips-updates arch/mips/math-emu/dp_mul.c --- 25/arch/mips/math-emu/dp_mul.c~mips-generic-mips-updates 2005-01-29 11:25:48.608479696 -0800 +++ 25-akpm/arch/mips/math-emu/dp_mul.c 2005-01-29 11:25:48.751457960 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/dp_scalb.c~mips-generic-mips-updates arch/mips/math-emu/dp_scalb.c --- 25/arch/mips/math-emu/dp_scalb.c~mips-generic-mips-updates 2005-01-29 11:25:48.610479392 -0800 +++ 25-akpm/arch/mips/math-emu/dp_scalb.c 2005-01-29 11:25:48.751457960 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/dp_simple.c~mips-generic-mips-updates arch/mips/math-emu/dp_simple.c --- 25/arch/mips/math-emu/dp_simple.c~mips-generic-mips-updates 2005-01-29 11:25:48.611479240 -0800 +++ 25-akpm/arch/mips/math-emu/dp_simple.c 2005-01-29 11:25:48.751457960 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/dp_sqrt.c~mips-generic-mips-updates arch/mips/math-emu/dp_sqrt.c --- 25/arch/mips/math-emu/dp_sqrt.c~mips-generic-mips-updates 2005-01-29 11:25:48.612479088 -0800 +++ 25-akpm/arch/mips/math-emu/dp_sqrt.c 2005-01-29 11:25:48.752457808 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/dp_sub.c~mips-generic-mips-updates arch/mips/math-emu/dp_sub.c --- 25/arch/mips/math-emu/dp_sub.c~mips-generic-mips-updates 2005-01-29 11:25:48.614478784 -0800 +++ 25-akpm/arch/mips/math-emu/dp_sub.c 2005-01-29 11:25:48.752457808 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/dp_tint.c~mips-generic-mips-updates arch/mips/math-emu/dp_tint.c --- 25/arch/mips/math-emu/dp_tint.c~mips-generic-mips-updates 2005-01-29 11:25:48.615478632 -0800 +++ 25-akpm/arch/mips/math-emu/dp_tint.c 2005-01-29 11:25:48.753457656 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/dp_tlong.c~mips-generic-mips-updates arch/mips/math-emu/dp_tlong.c --- 25/arch/mips/math-emu/dp_tlong.c~mips-generic-mips-updates 2005-01-29 11:25:48.616478480 -0800 +++ 25-akpm/arch/mips/math-emu/dp_tlong.c 2005-01-29 11:25:48.753457656 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/ieee754.c~mips-generic-mips-updates arch/mips/math-emu/ieee754.c --- 25/arch/mips/math-emu/ieee754.c~mips-generic-mips-updates 2005-01-29 11:25:48.618478176 -0800 +++ 25-akpm/arch/mips/math-emu/ieee754.c 2005-01-29 11:25:48.753457656 -0800 @@ -8,7 +8,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/ieee754d.c~mips-generic-mips-updates arch/mips/math-emu/ieee754d.c --- 25/arch/mips/math-emu/ieee754d.c~mips-generic-mips-updates 2005-01-29 11:25:48.619478024 -0800 +++ 25-akpm/arch/mips/math-emu/ieee754d.c 2005-01-29 11:25:48.754457504 -0800 @@ -3,7 +3,7 @@ * * MIPS floating point support * - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * This program is free software; you can distribute it and/or modify it diff -puN arch/mips/math-emu/ieee754dp.c~mips-generic-mips-updates arch/mips/math-emu/ieee754dp.c --- 25/arch/mips/math-emu/ieee754dp.c~mips-generic-mips-updates 2005-01-29 11:25:48.620477872 -0800 +++ 25-akpm/arch/mips/math-emu/ieee754dp.c 2005-01-29 11:25:48.754457504 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/ieee754dp.h~mips-generic-mips-updates arch/mips/math-emu/ieee754dp.h --- 25/arch/mips/math-emu/ieee754dp.h~mips-generic-mips-updates 2005-01-29 11:25:48.622477568 -0800 +++ 25-akpm/arch/mips/math-emu/ieee754dp.h 2005-01-29 11:25:48.754457504 -0800 @@ -4,7 +4,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/ieee754.h~mips-generic-mips-updates arch/mips/math-emu/ieee754.h --- 25/arch/mips/math-emu/ieee754.h~mips-generic-mips-updates 2005-01-29 11:25:48.623477416 -0800 +++ 25-akpm/arch/mips/math-emu/ieee754.h 2005-01-29 11:25:48.755457352 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/ieee754int.h~mips-generic-mips-updates arch/mips/math-emu/ieee754int.h --- 25/arch/mips/math-emu/ieee754int.h~mips-generic-mips-updates 2005-01-29 11:25:48.625477112 -0800 +++ 25-akpm/arch/mips/math-emu/ieee754int.h 2005-01-29 11:25:48.755457352 -0800 @@ -4,7 +4,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/ieee754m.c~mips-generic-mips-updates arch/mips/math-emu/ieee754m.c --- 25/arch/mips/math-emu/ieee754m.c~mips-generic-mips-updates 2005-01-29 11:25:48.626476960 -0800 +++ 25-akpm/arch/mips/math-emu/ieee754m.c 2005-01-29 11:25:48.756457200 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/ieee754sp.c~mips-generic-mips-updates arch/mips/math-emu/ieee754sp.c --- 25/arch/mips/math-emu/ieee754sp.c~mips-generic-mips-updates 2005-01-29 11:25:48.627476808 -0800 +++ 25-akpm/arch/mips/math-emu/ieee754sp.c 2005-01-29 11:25:48.756457200 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/ieee754sp.h~mips-generic-mips-updates arch/mips/math-emu/ieee754sp.h --- 25/arch/mips/math-emu/ieee754sp.h~mips-generic-mips-updates 2005-01-29 11:25:48.629476504 -0800 +++ 25-akpm/arch/mips/math-emu/ieee754sp.h 2005-01-29 11:25:48.757457048 -0800 @@ -4,7 +4,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/ieee754xcpt.c~mips-generic-mips-updates arch/mips/math-emu/ieee754xcpt.c --- 25/arch/mips/math-emu/ieee754xcpt.c~mips-generic-mips-updates 2005-01-29 11:25:48.630476352 -0800 +++ 25-akpm/arch/mips/math-emu/ieee754xcpt.c 2005-01-29 11:25:48.757457048 -0800 @@ -1,6 +1,6 @@ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/sp_add.c~mips-generic-mips-updates arch/mips/math-emu/sp_add.c --- 25/arch/mips/math-emu/sp_add.c~mips-generic-mips-updates 2005-01-29 11:25:48.631476200 -0800 +++ 25-akpm/arch/mips/math-emu/sp_add.c 2005-01-29 11:25:48.757457048 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/sp_cmp.c~mips-generic-mips-updates arch/mips/math-emu/sp_cmp.c --- 25/arch/mips/math-emu/sp_cmp.c~mips-generic-mips-updates 2005-01-29 11:25:48.633475896 -0800 +++ 25-akpm/arch/mips/math-emu/sp_cmp.c 2005-01-29 11:25:48.758456896 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/sp_div.c~mips-generic-mips-updates arch/mips/math-emu/sp_div.c --- 25/arch/mips/math-emu/sp_div.c~mips-generic-mips-updates 2005-01-29 11:25:48.634475744 -0800 +++ 25-akpm/arch/mips/math-emu/sp_div.c 2005-01-29 11:25:48.758456896 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/sp_fdp.c~mips-generic-mips-updates arch/mips/math-emu/sp_fdp.c --- 25/arch/mips/math-emu/sp_fdp.c~mips-generic-mips-updates 2005-01-29 11:25:48.635475592 -0800 +++ 25-akpm/arch/mips/math-emu/sp_fdp.c 2005-01-29 11:25:48.759456744 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/sp_fint.c~mips-generic-mips-updates arch/mips/math-emu/sp_fint.c --- 25/arch/mips/math-emu/sp_fint.c~mips-generic-mips-updates 2005-01-29 11:25:48.637475288 -0800 +++ 25-akpm/arch/mips/math-emu/sp_fint.c 2005-01-29 11:25:48.759456744 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/sp_flong.c~mips-generic-mips-updates arch/mips/math-emu/sp_flong.c --- 25/arch/mips/math-emu/sp_flong.c~mips-generic-mips-updates 2005-01-29 11:25:48.638475136 -0800 +++ 25-akpm/arch/mips/math-emu/sp_flong.c 2005-01-29 11:25:48.759456744 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/sp_frexp.c~mips-generic-mips-updates arch/mips/math-emu/sp_frexp.c --- 25/arch/mips/math-emu/sp_frexp.c~mips-generic-mips-updates 2005-01-29 11:25:48.639474984 -0800 +++ 25-akpm/arch/mips/math-emu/sp_frexp.c 2005-01-29 11:25:48.760456592 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/sp_logb.c~mips-generic-mips-updates arch/mips/math-emu/sp_logb.c --- 25/arch/mips/math-emu/sp_logb.c~mips-generic-mips-updates 2005-01-29 11:25:48.640474832 -0800 +++ 25-akpm/arch/mips/math-emu/sp_logb.c 2005-01-29 11:25:48.760456592 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/sp_modf.c~mips-generic-mips-updates arch/mips/math-emu/sp_modf.c --- 25/arch/mips/math-emu/sp_modf.c~mips-generic-mips-updates 2005-01-29 11:25:48.642474528 -0800 +++ 25-akpm/arch/mips/math-emu/sp_modf.c 2005-01-29 11:25:48.760456592 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/sp_mul.c~mips-generic-mips-updates arch/mips/math-emu/sp_mul.c --- 25/arch/mips/math-emu/sp_mul.c~mips-generic-mips-updates 2005-01-29 11:25:48.643474376 -0800 +++ 25-akpm/arch/mips/math-emu/sp_mul.c 2005-01-29 11:25:48.761456440 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/sp_scalb.c~mips-generic-mips-updates arch/mips/math-emu/sp_scalb.c --- 25/arch/mips/math-emu/sp_scalb.c~mips-generic-mips-updates 2005-01-29 11:25:48.644474224 -0800 +++ 25-akpm/arch/mips/math-emu/sp_scalb.c 2005-01-29 11:25:48.761456440 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/sp_simple.c~mips-generic-mips-updates arch/mips/math-emu/sp_simple.c --- 25/arch/mips/math-emu/sp_simple.c~mips-generic-mips-updates 2005-01-29 11:25:48.646473920 -0800 +++ 25-akpm/arch/mips/math-emu/sp_simple.c 2005-01-29 11:25:48.761456440 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/sp_sqrt.c~mips-generic-mips-updates arch/mips/math-emu/sp_sqrt.c --- 25/arch/mips/math-emu/sp_sqrt.c~mips-generic-mips-updates 2005-01-29 11:25:48.647473768 -0800 +++ 25-akpm/arch/mips/math-emu/sp_sqrt.c 2005-01-29 11:25:48.762456288 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/sp_sub.c~mips-generic-mips-updates arch/mips/math-emu/sp_sub.c --- 25/arch/mips/math-emu/sp_sub.c~mips-generic-mips-updates 2005-01-29 11:25:48.648473616 -0800 +++ 25-akpm/arch/mips/math-emu/sp_sub.c 2005-01-29 11:25:48.762456288 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/sp_tint.c~mips-generic-mips-updates arch/mips/math-emu/sp_tint.c --- 25/arch/mips/math-emu/sp_tint.c~mips-generic-mips-updates 2005-01-29 11:25:48.649473464 -0800 +++ 25-akpm/arch/mips/math-emu/sp_tint.c 2005-01-29 11:25:48.763456136 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/math-emu/sp_tlong.c~mips-generic-mips-updates arch/mips/math-emu/sp_tlong.c --- 25/arch/mips/math-emu/sp_tlong.c~mips-generic-mips-updates 2005-01-29 11:25:48.651473160 -0800 +++ 25-akpm/arch/mips/math-emu/sp_tlong.c 2005-01-29 11:25:48.763456136 -0800 @@ -3,7 +3,7 @@ */ /* * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. + * Copyright (C) 1994-2000 Algorithmics Ltd. * http://www.algor.co.uk * * ######################################################################## diff -puN arch/mips/mm/cache.c~mips-generic-mips-updates arch/mips/mm/cache.c --- 25/arch/mips/mm/cache.c~mips-generic-mips-updates 2005-01-29 11:25:48.652473008 -0800 +++ 25-akpm/arch/mips/mm/cache.c 2005-01-29 11:25:48.763456136 -0800 @@ -45,10 +45,17 @@ EXPORT_SYMBOL(_dma_cache_inv); #endif /* CONFIG_DMA_NONCOHERENT */ -asmlinkage int sys_cacheflush(void *addr, int bytes, int cache) +/* + * We could optimize the case where the cache argument is not BCACHE but + * that seems very atypical use ... + */ +asmlinkage int sys_cacheflush(unsigned long addr, unsigned long int bytes, + unsigned int cache) { - /* This should flush more selectivly ... */ - __flush_cache_all(); + if (verify_area(VERIFY_WRITE, (void *) addr, bytes)) + return -EFAULT; + + flush_icache_range(addr, addr + bytes); return 0; } diff -puN arch/mips/mm/cerr-sb1.c~mips-generic-mips-updates arch/mips/mm/cerr-sb1.c --- 25/arch/mips/mm/cerr-sb1.c~mips-generic-mips-updates 2005-01-29 11:25:48.653472856 -0800 +++ 25-akpm/arch/mips/mm/cerr-sb1.c 2005-01-29 11:25:48.764455984 -0800 @@ -251,14 +251,14 @@ static const uint8_t parity[256] = { /* Masks to select bits for Hamming parity, mask_72_64[i] for bit[i] */ static const uint64_t mask_72_64[8] = { - 0x0738C808099264FFL, - 0x38C808099264FF07L, - 0xC808099264FF0738L, - 0x08099264FF0738C8L, - 0x099264FF0738C808L, - 0x9264FF0738C80809L, - 0x64FF0738C8080992L, - 0xFF0738C808099264L + 0x0738C808099264FFULL, + 0x38C808099264FF07ULL, + 0xC808099264FF0738ULL, + 0x08099264FF0738C8ULL, + 0x099264FF0738C808ULL, + 0x9264FF0738C80809ULL, + 0x64FF0738C8080992ULL, + 0xFF0738C808099264ULL }; /* Calculate the parity on a range of bits */ @@ -330,9 +330,9 @@ static uint32_t extract_ic(unsigned shor ((lru >> 4) & 0x3), ((lru >> 6) & 0x3)); } - va = (taglo & 0xC0000FFFFFFFE000) | addr; + va = (taglo & 0xC0000FFFFFFFE000ULL) | addr; if ((taglo & (1 << 31)) && (((taglo >> 62) & 0x3) == 3)) - va |= 0x3FFFF00000000000; + va |= 0x3FFFF00000000000ULL; valid = ((taghi >> 29) & 1); if (valid) { tlo_tmp = taglo & 0xfff3ff; @@ -473,7 +473,7 @@ static uint32_t extract_dc(unsigned shor : "r" ((way << 13) | addr)); taglo = ((unsigned long long)taglohi << 32) | taglolo; - pa = (taglo & 0xFFFFFFE000) | addr; + pa = (taglo & 0xFFFFFFE000ULL) | addr; if (way == 0) { lru = (taghi >> 14) & 0xff; prom_printf("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n", diff -puN arch/mips/mm/cex-sb1.S~mips-generic-mips-updates arch/mips/mm/cex-sb1.S --- 25/arch/mips/mm/cex-sb1.S~mips-generic-mips-updates 2005-01-29 11:25:48.655472552 -0800 +++ 25-akpm/arch/mips/mm/cex-sb1.S 2005-01-29 11:25:48.765455832 -0800 @@ -15,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include #include #include diff -puN arch/mips/mm/c-r4k.c~mips-generic-mips-updates arch/mips/mm/c-r4k.c --- 25/arch/mips/mm/c-r4k.c~mips-generic-mips-updates 2005-01-29 11:25:48.656472400 -0800 +++ 25-akpm/arch/mips/mm/c-r4k.c 2005-01-29 11:25:48.766455680 -0800 @@ -238,6 +238,22 @@ static inline void r4k_blast_scache_page r4k_blast_scache_page = blast_scache128_page; } +static void (* r4k_blast_scache_page_indexed)(unsigned long addr); + +static inline void r4k_blast_scache_page_indexed_setup(void) +{ + unsigned long sc_lsize = cpu_scache_line_size(); + + if (sc_lsize == 16) + r4k_blast_scache_page_indexed = blast_scache16_page_indexed; + else if (sc_lsize == 32) + r4k_blast_scache_page_indexed = blast_scache32_page_indexed; + else if (sc_lsize == 64) + r4k_blast_scache_page_indexed = blast_scache64_page_indexed; + else if (sc_lsize == 128) + r4k_blast_scache_page_indexed = blast_scache128_page_indexed; +} + static void (* r4k_blast_scache)(void); static inline void r4k_blast_scache_setup(void) @@ -318,9 +334,6 @@ static inline void local_r4k_flush_cache { struct mm_struct *mm = args; - if (!cpu_has_dc_aliases) - return; - if (!cpu_context(smp_processor_id(), mm)) return; @@ -340,6 +353,9 @@ static inline void local_r4k_flush_cache static void r4k_flush_cache_mm(struct mm_struct *mm) { + if (!cpu_has_dc_aliases) + return; + on_each_cpu(local_r4k_flush_cache_mm, mm, 1, 1); } @@ -359,13 +375,6 @@ static inline void local_r4k_flush_cache pmd_t *pmdp; pte_t *ptep; - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (cpu_context(smp_processor_id(), mm) == 0) - return; - page &= PAGE_MASK; pgdp = pgd_offset(mm, page); pmdp = pmd_offset(pgdp, page); @@ -385,8 +394,11 @@ static inline void local_r4k_flush_cache * in that case, which doesn't overly flush the cache too much. */ if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) { - if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) + if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) { r4k_blast_dcache_page(page); + if (exec && !cpu_icache_snoops_remote_store) + r4k_blast_scache_page(page); + } if (exec) r4k_blast_icache_page(page); @@ -398,8 +410,11 @@ static inline void local_r4k_flush_cache * to work correctly. */ page = INDEX_BASE + (page & (dcache_size - 1)); - if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) + if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) { r4k_blast_dcache_page_indexed(page); + if (exec && !cpu_icache_snoops_remote_store) + r4k_blast_scache_page_indexed(page); + } if (exec) { if (cpu_has_vtag_icache) { int cpu = smp_processor_id(); @@ -416,6 +431,13 @@ static void r4k_flush_cache_page(struct { struct flush_cache_page_args args; + /* + * If ownes no valid ASID yet, cannot possibly have gotten + * this page into the cache. + */ + if (cpu_context(smp_processor_id(), vma->vm_mm) == 0) + return; + args.vma = vma; args.page = page; @@ -442,14 +464,15 @@ static inline void local_r4k_flush_icach struct flush_icache_range_args *fir_args = args; unsigned long dc_lsize = current_cpu_data.dcache.linesz; unsigned long ic_lsize = current_cpu_data.icache.linesz; + unsigned long sc_lsize = current_cpu_data.scache.linesz; unsigned long start = fir_args->start; unsigned long end = fir_args->end; unsigned long addr, aend; if (!cpu_has_ic_fills_f_dc) { - if (end - start > dcache_size) + if (end - start > dcache_size) { r4k_blast_dcache(); - else { + } else { addr = start & ~(dc_lsize - 1); aend = (end - 1) & ~(dc_lsize - 1); @@ -461,6 +484,23 @@ static inline void local_r4k_flush_icach addr += dc_lsize; } } + + if (!cpu_icache_snoops_remote_store) { + if (end - start > scache_size) { + r4k_blast_scache(); + } else { + addr = start & ~(sc_lsize - 1); + aend = (end - 1) & ~(sc_lsize - 1); + + while (1) { + /* Hit_Writeback_Inv_D */ + protected_writeback_scache_line(addr); + if (addr == aend) + break; + addr += sc_lsize; + } + } + } } if (end - start > icache_size) @@ -527,6 +567,8 @@ static inline void local_r4k_flush_icach if (!cpu_has_ic_fills_f_dc) { unsigned long addr = (unsigned long) page_address(page); r4k_blast_dcache_page(addr); + if (!cpu_icache_snoops_remote_store) + r4k_blast_scache_page(addr); ClearPageDcacheDirty(page); } @@ -669,10 +711,13 @@ static void local_r4k_flush_cache_sigtra { unsigned long ic_lsize = current_cpu_data.icache.linesz; unsigned long dc_lsize = current_cpu_data.dcache.linesz; + unsigned long sc_lsize = current_cpu_data.scache.linesz; unsigned long addr = (unsigned long) arg; R4600_HIT_CACHEOP_WAR_IMPL; protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); + if (!cpu_icache_snoops_remote_store) + protected_writeback_scache_line(addr & ~(sc_lsize - 1)); protected_flush_icache_line(addr & ~(ic_lsize - 1)); if (MIPS4K_ICACHE_REFILL_WAR) { __asm__ __volatile__ ( @@ -739,8 +784,8 @@ static inline void rm7k_erratum31(void) } } -static char *way_string[] = { NULL, "direct mapped", "2-way", "3-way", "4-way", - "5-way", "6-way", "7-way", "8-way" +static char *way_string[] __initdata = { NULL, "direct mapped", "2-way", + "3-way", "4-way", "5-way", "6-way", "7-way", "8-way" }; static void __init probe_pcache(void) @@ -1178,6 +1223,7 @@ void __init ld_mmu_r4xx0(void) r4k_blast_icache_page_indexed_setup(); r4k_blast_icache_setup(); r4k_blast_scache_page_setup(); + r4k_blast_scache_page_indexed_setup(); r4k_blast_scache_setup(); /* diff -puN arch/mips/mm/c-sb1.c~mips-generic-mips-updates arch/mips/mm/c-sb1.c --- 25/arch/mips/mm/c-sb1.c~mips-generic-mips-updates 2005-01-29 11:25:48.657472248 -0800 +++ 25-akpm/arch/mips/mm/c-sb1.c 2005-01-29 11:25:48.767455528 -0800 @@ -503,7 +503,7 @@ void ld_mmu_sb1(void) /* Special cache error handler for SB1 */ memcpy((void *)(CAC_BASE + 0x100), &except_vec2_sb1, 0x80); memcpy((void *)(UNCAC_BASE + 0x100), &except_vec2_sb1, 0x80); - memcpy((void *)KSEG1ADDR(&handle_vec2_sb1), &handle_vec2_sb1, 0x80); + memcpy((void *)CKSEG1ADDR(&handle_vec2_sb1), &handle_vec2_sb1, 0x80); probe_cache_sizes(); diff -puN /dev/null arch/mips/mm/dma-ip32.c --- /dev/null 2003-09-15 06:40:47.000000000 -0700 +++ 25-akpm/arch/mips/mm/dma-ip32.c 2005-01-29 11:25:48.769455224 -0800 @@ -0,0 +1,382 @@ +/* + * 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) 2000 Ani Joshi + * Copyright (C) 2000, 2001 Ralf Baechle + * Copyright (C) 2005 Ilya A. Volynets-Evenbakh + * swiped from i386, and cloned for MIPS by Geert, polished by Ralf. + * IP32 changes by Ilya. + */ +#include +#include +#include +#include +#include + +#include +#include +#include + +/* + * Warning on the terminology - Linux calls an uncached area coherent; + * MIPS terminology calls memory areas with hardware maintained coherency + * coherent. + */ + +/* + * Few notes. + * 1. CPU sees memory as two chunks: 0-256M@0x0, and the rest @0x40000000+256M + * 2. PCI sees memory as one big chunk @0x0 (or we could use 0x40000000 for native-endian) + * 3. All other devices see memory as one big chunk at 0x40000000 + * 4. Non-PCI devices will pass NULL as struct device* + * Thus we translate differently, depending on device. + */ + +#define RAM_OFFSET_MASK 0x3fffffff + +void *dma_alloc_noncoherent(struct device *dev, size_t size, + dma_addr_t * dma_handle, int gfp) +{ + void *ret; + /* ignore region specifiers */ + gfp &= ~(__GFP_DMA | __GFP_HIGHMEM); + + if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff)) + gfp |= GFP_DMA; + ret = (void *) __get_free_pages(gfp, get_order(size)); + + if (ret != NULL) { + unsigned long addr = virt_to_phys(ret)&RAM_OFFSET_MASK; + memset(ret, 0, size); + if(dev==NULL) + addr+= CRIME_HI_MEM_BASE; + *dma_handle = addr; + } + + return ret; +} + +EXPORT_SYMBOL(dma_alloc_noncoherent); + +void *dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t * dma_handle, int gfp) +{ + void *ret; + + ret = dma_alloc_noncoherent(dev, size, dma_handle, gfp); + if (ret) { + dma_cache_wback_inv((unsigned long) ret, size); + ret = UNCAC_ADDR(ret); + } + + return ret; +} + +EXPORT_SYMBOL(dma_alloc_coherent); + +void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr, + dma_addr_t dma_handle) +{ + free_pages((unsigned long) vaddr, get_order(size)); +} + +EXPORT_SYMBOL(dma_free_noncoherent); + +void dma_free_coherent(struct device *dev, size_t size, void *vaddr, + dma_addr_t dma_handle) +{ + unsigned long addr = (unsigned long) vaddr; + + addr = CAC_ADDR(addr); + free_pages(addr, get_order(size)); +} + +EXPORT_SYMBOL(dma_free_coherent); + +static inline void __dma_sync(unsigned long addr, size_t size, + enum dma_data_direction direction) +{ + switch (direction) { + case DMA_TO_DEVICE: + dma_cache_wback(addr, size); + break; + + case DMA_FROM_DEVICE: + dma_cache_inv(addr, size); + break; + + case DMA_BIDIRECTIONAL: + dma_cache_wback_inv(addr, size); + break; + + default: + BUG(); + } +} + +dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, + enum dma_data_direction direction) +{ + unsigned long addr = (unsigned long) ptr; + + switch (direction) { + case DMA_TO_DEVICE: + dma_cache_wback(addr, size); + break; + + case DMA_FROM_DEVICE: + dma_cache_inv(addr, size); + break; + + case DMA_BIDIRECTIONAL: + dma_cache_wback_inv(addr, size); + break; + + default: + BUG(); + } + + addr = virt_to_phys(ptr)&RAM_OFFSET_MASK;; + if(dev == NULL) + addr+=CRIME_HI_MEM_BASE; + return (dma_addr_t)addr; +} + +EXPORT_SYMBOL(dma_map_single); + +void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, + enum dma_data_direction direction) +{ + switch (direction) { + case DMA_TO_DEVICE: + break; + + case DMA_FROM_DEVICE: + break; + + case DMA_BIDIRECTIONAL: + break; + + default: + BUG(); + } +} + +EXPORT_SYMBOL(dma_unmap_single); + +int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, + enum dma_data_direction direction) +{ + int i; + + BUG_ON(direction == DMA_NONE); + + for (i = 0; i < nents; i++, sg++) { + unsigned long addr; + + addr = (unsigned long) page_address(sg->page)+sg->offset; + if (addr) + __dma_sync(addr, sg->length, direction); + addr = __pa(addr)&RAM_OFFSET_MASK;; + if(dev == NULL) + addr += CRIME_HI_MEM_BASE; + sg->dma_address = (dma_addr_t)addr; + } + + return nents; +} + +EXPORT_SYMBOL(dma_map_sg); + +dma_addr_t dma_map_page(struct device *dev, struct page *page, + unsigned long offset, size_t size, enum dma_data_direction direction) +{ + unsigned long addr; + + BUG_ON(direction == DMA_NONE); + + addr = (unsigned long) page_address(page) + offset; + dma_cache_wback_inv(addr, size); + addr = __pa(addr)&RAM_OFFSET_MASK;; + if(dev == NULL) + addr += CRIME_HI_MEM_BASE; + + return (dma_addr_t)addr; +} + +EXPORT_SYMBOL(dma_map_page); + +void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size, + enum dma_data_direction direction) +{ + BUG_ON(direction == DMA_NONE); + + if (direction != DMA_TO_DEVICE) { + unsigned long addr; + + dma_address&=RAM_OFFSET_MASK; + addr = dma_address + PAGE_OFFSET; + if(dma_address>=256*1024*1024) + addr+=CRIME_HI_MEM_BASE; + dma_cache_wback_inv(addr, size); + } +} + +EXPORT_SYMBOL(dma_unmap_page); + +void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, + enum dma_data_direction direction) +{ + unsigned long addr; + int i; + + BUG_ON(direction == DMA_NONE); + + if (direction == DMA_TO_DEVICE) + return; + + for (i = 0; i < nhwentries; i++, sg++) { + addr = (unsigned long) page_address(sg->page); + if (!addr) + continue; + dma_cache_wback_inv(addr + sg->offset, sg->length); + } +} + +EXPORT_SYMBOL(dma_unmap_sg); + +void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, + size_t size, enum dma_data_direction direction) +{ + unsigned long addr; + + BUG_ON(direction == DMA_NONE); + + dma_handle&=RAM_OFFSET_MASK; + addr = dma_handle + PAGE_OFFSET; + if(dma_handle>=256*1024*1024) + addr+=CRIME_HI_MEM_BASE; + __dma_sync(addr, size, direction); +} + +EXPORT_SYMBOL(dma_sync_single_for_cpu); + +void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, + size_t size, enum dma_data_direction direction) +{ + unsigned long addr; + + BUG_ON(direction == DMA_NONE); + + dma_handle&=RAM_OFFSET_MASK; + addr = dma_handle + PAGE_OFFSET; + if(dma_handle>=256*1024*1024) + addr+=CRIME_HI_MEM_BASE; + __dma_sync(addr, size, direction); +} + +EXPORT_SYMBOL(dma_sync_single_for_device); + +void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle, + unsigned long offset, size_t size, enum dma_data_direction direction) +{ + unsigned long addr; + + BUG_ON(direction == DMA_NONE); + + dma_handle&=RAM_OFFSET_MASK; + addr = dma_handle + offset + PAGE_OFFSET; + if(dma_handle>=256*1024*1024) + addr+=CRIME_HI_MEM_BASE; + __dma_sync(addr, size, direction); +} + +EXPORT_SYMBOL(dma_sync_single_range_for_cpu); + +void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle, + unsigned long offset, size_t size, enum dma_data_direction direction) +{ + unsigned long addr; + + BUG_ON(direction == DMA_NONE); + + dma_handle&=RAM_OFFSET_MASK; + addr = dma_handle + offset + PAGE_OFFSET; + if(dma_handle>=256*1024*1024) + addr+=CRIME_HI_MEM_BASE; + __dma_sync(addr, size, direction); +} + +EXPORT_SYMBOL(dma_sync_single_range_for_device); + +void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, + enum dma_data_direction direction) +{ + int i; + + BUG_ON(direction == DMA_NONE); + + /* Make sure that gcc doesn't leave the empty loop body. */ + for (i = 0; i < nelems; i++, sg++) + __dma_sync((unsigned long)page_address(sg->page), + sg->length, direction); +} + +EXPORT_SYMBOL(dma_sync_sg_for_cpu); + +void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, + enum dma_data_direction direction) +{ + int i; + + BUG_ON(direction == DMA_NONE); + + /* Make sure that gcc doesn't leave the empty loop body. */ + for (i = 0; i < nelems; i++, sg++) + __dma_sync((unsigned long)page_address(sg->page), + sg->length, direction); +} + +EXPORT_SYMBOL(dma_sync_sg_for_device); + +int dma_mapping_error(dma_addr_t dma_addr) +{ + return 0; +} + +EXPORT_SYMBOL(dma_mapping_error); + +int dma_supported(struct device *dev, u64 mask) +{ + /* + * we fall back to GFP_DMA when the mask isn't all 1s, + * so we can't guarantee allocations that must be + * within a tighter range than GFP_DMA.. + */ + if (mask < 0x00ffffff) + return 0; + + return 1; +} + +EXPORT_SYMBOL(dma_supported); + +int dma_is_consistent(dma_addr_t dma_addr) +{ + return 1; +} + +EXPORT_SYMBOL(dma_is_consistent); + +void dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction direction) +{ + if (direction == DMA_NONE) + return; + + dma_cache_wback_inv((unsigned long)vaddr, size); +} + +EXPORT_SYMBOL(dma_cache_sync); + diff -puN arch/mips/mm/init.c~mips-generic-mips-updates arch/mips/mm/init.c --- 25/arch/mips/mm/init.c~mips-generic-mips-updates 2005-01-29 11:25:48.659471944 -0800 +++ 25-akpm/arch/mips/mm/init.c 2005-01-29 11:25:48.769455224 -0800 @@ -61,7 +61,7 @@ unsigned long setup_zero_pages(void) else order = 0; - empty_zero_page = __get_free_pages(GFP_KERNEL, order); + empty_zero_page = __get_free_pages(GFP_KERNEL | __GFP_ZERO, order); if (!empty_zero_page) panic("Oh boy, that early out of memory?"); @@ -74,7 +74,6 @@ unsigned long setup_zero_pages(void) size = PAGE_SIZE << order; zero_page_mask = (size - 1) & PAGE_MASK; - memset((void *)empty_zero_page, 0, size); return 1UL << order; } diff -puN arch/mips/mm/Makefile~mips-generic-mips-updates arch/mips/mm/Makefile --- 25/arch/mips/mm/Makefile~mips-generic-mips-updates 2005-01-29 11:25:48.660471792 -0800 +++ 25-akpm/arch/mips/mm/Makefile 2005-01-29 11:25:48.770455072 -0800 @@ -3,7 +3,7 @@ # obj-y += cache.o extable.o fault.o init.o pgtable.o \ - tlbex.o + tlbex.o tlbex-fault.o obj-$(CONFIG_MIPS32) += ioremap.o pgtable-32.o obj-$(CONFIG_MIPS64) += pgtable-64.o @@ -27,40 +27,6 @@ obj-$(CONFIG_CPU_TX39XX) += c-tx39.o pg- obj-$(CONFIG_CPU_TX49XX) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_VR41XX) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o -# -# TLB exception handling code differs between 32-bit and 64-bit kernels. -# -ifdef CONFIG_MIPS32 -obj-$(CONFIG_CPU_R3000) += tlbex32-r3k.o -obj-$(CONFIG_CPU_TX49XX) += tlbex32-r4k.o -obj-$(CONFIG_CPU_R4300) += tlbex32-r4k.o -obj-$(CONFIG_CPU_R4X00) += tlbex32-r4k.o -obj-$(CONFIG_CPU_VR41XX) += tlbex32-r4k.o -obj-$(CONFIG_CPU_R5000) += tlbex32-r4k.o -obj-$(CONFIG_CPU_NEVADA) += tlbex32-r4k.o -obj-$(CONFIG_CPU_R5432) += tlbex32-r4k.o -obj-$(CONFIG_CPU_RM7000) += tlbex32-r4k.o -obj-$(CONFIG_CPU_RM9000) += tlbex32-r4k.o -obj-$(CONFIG_CPU_R10000) += tlbex32-r4k.o -obj-$(CONFIG_CPU_MIPS32) += tlbex32-mips32.o -obj-$(CONFIG_CPU_MIPS64) += tlbex32-r4k.o -obj-$(CONFIG_CPU_SB1) += tlbex32-r4k.o -obj-$(CONFIG_CPU_TX39XX) += tlbex32-r3k.o -endif -ifdef CONFIG_MIPS64 -obj-$(CONFIG_CPU_R4300) += tlb64-glue-r4k.o -obj-$(CONFIG_CPU_R4X00) += tlb64-glue-r4k.o -obj-$(CONFIG_CPU_R5000) += tlb64-glue-r4k.o -obj-$(CONFIG_CPU_NEVADA) += tlb64-glue-r4k.o -obj-$(CONFIG_CPU_R5432) += tlb64-glue-r4k.o -obj-$(CONFIG_CPU_RM7000) += tlb64-glue-r4k.o -obj-$(CONFIG_CPU_RM9000) += tlb64-glue-r4k.o -obj-$(CONFIG_CPU_R10000) += tlb64-glue-r4k.o -obj-$(CONFIG_CPU_SB1) += tlb64-glue-sb1.o -obj-$(CONFIG_CPU_MIPS64) += tlb64-glue-r4k.o -endif - - obj-$(CONFIG_IP22_CPU_SCACHE) += sc-ip22.o obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o obj-$(CONFIG_RM7000_CPU_SCACHE) += sc-rm7k.o @@ -68,8 +34,11 @@ obj-$(CONFIG_RM7000_CPU_SCACHE) += sc-rm # # Choose one DMA coherency model # +ifndef CONFIG_OWN_DMA obj-$(CONFIG_DMA_COHERENT) += dma-coherent.o obj-$(CONFIG_DMA_NONCOHERENT) += dma-noncoherent.o +endif obj-$(CONFIG_DMA_IP27) += dma-ip27.o +obj-$(CONFIG_DMA_IP32) += dma-ip32.o EXTRA_AFLAGS := $(CFLAGS) diff -puN arch/mips/mm/pg-r4k.c~mips-generic-mips-updates arch/mips/mm/pg-r4k.c --- 25/arch/mips/mm/pg-r4k.c~mips-generic-mips-updates 2005-01-29 11:25:48.661471640 -0800 +++ 25-akpm/arch/mips/mm/pg-r4k.c 2005-01-29 11:25:48.771454920 -0800 @@ -3,9 +3,8 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2003, 2004 Ralf Baechle (ralf@linux-mips.org) + * Copyright (C) 2003, 04, 05 Ralf Baechle (ralf@linux-mips.org) */ -#include #include #include #include @@ -58,12 +57,6 @@ void copy_page(void *to, void *from) __a EXPORT_SYMBOL(copy_page); /* - * An address fits into a single register so it's safe to use 64-bit registers - * if we have 64-bit adresses. - */ -#define cpu_has_64bit_registers cpu_has_64bit_addresses - -/* * This is suboptimal for 32-bit kernels; we assume that R10000 is only used * with 64-bit kernels. The prefetch offsets have been experimentally tuned * an Origin 200. @@ -145,7 +138,7 @@ static inline void __build_load_reg(int union mips_instruction mi; unsigned int width; - if (cpu_has_64bit_registers) { + if (cpu_has_64bit_gp_regs) { mi.i_format.opcode = ld_op; width = 8; } else { @@ -266,7 +259,7 @@ static inline void build_addiu_a2_a0(uns BUG_ON(offset > 0x7fff); - mi.i_format.opcode = cpu_has_64bit_addresses ? daddiu_op : addiu_op; + mi.i_format.opcode = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op; mi.i_format.rs = 4; /* $a0 */ mi.i_format.rt = 6; /* $a2 */ mi.i_format.simmediate = offset; @@ -280,7 +273,7 @@ static inline void build_addiu_a1(unsign BUG_ON(offset > 0x7fff); - mi.i_format.opcode = cpu_has_64bit_addresses ? daddiu_op : addiu_op; + mi.i_format.opcode = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op; mi.i_format.rs = 5; /* $a1 */ mi.i_format.rt = 5; /* $a1 */ mi.i_format.simmediate = offset; @@ -296,7 +289,7 @@ static inline void build_addiu_a0(unsign BUG_ON(offset > 0x7fff); - mi.i_format.opcode = cpu_has_64bit_addresses ? daddiu_op : addiu_op; + mi.i_format.opcode = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op; mi.i_format.rs = 4; /* $a0 */ mi.i_format.rt = 4; /* $a0 */ mi.i_format.simmediate = offset; diff -puN arch/mips/mm/pg-sb1.c~mips-generic-mips-updates arch/mips/mm/pg-sb1.c --- 25/arch/mips/mm/pg-sb1.c~mips-generic-mips-updates 2005-01-29 11:25:48.663471336 -0800 +++ 25-akpm/arch/mips/mm/pg-sb1.c 2005-01-29 11:25:48.773454616 -0800 @@ -2,6 +2,7 @@ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org) * Copyright (C) 2000 SiByte, Inc. + * Copyright (C) 2005 Thiemo Seufer * * Written by Justin Carlson of SiByte, Inc. * and Kip Walker of Broadcom Corp. @@ -39,11 +40,7 @@ #define SB1_PREF_STORE_STREAMED_HINT "5" #endif -#ifdef CONFIG_SIBYTE_DMA_PAGEOPS static inline void clear_page_cpu(void *page) -#else -void clear_page(void *page) -#endif { unsigned char *addr = (unsigned char *) page; unsigned char *end = addr + PAGE_SIZE; @@ -57,90 +54,143 @@ void clear_page(void *page) * since we know we're on an SB1, we force the assembler to take * 64-bit operands to speed things up */ - do { - __asm__ __volatile__( - " .set mips4 \n" + __asm__ __volatile__( + " .set push \n" + " .set mips4 \n" + " .set noreorder \n" #ifdef CONFIG_CPU_HAS_PREFETCH - " pref " SB1_PREF_STORE_STREAMED_HINT ", 0(%0) \n" /* Prefetch the first 4 lines */ - " pref " SB1_PREF_STORE_STREAMED_HINT ", 32(%0) \n" - " pref " SB1_PREF_STORE_STREAMED_HINT ", 64(%0) \n" - " pref " SB1_PREF_STORE_STREAMED_HINT ", 96(%0) \n" -#endif - "1: sd $0, 0(%0) \n" /* Throw out a cacheline of 0's */ - " sd $0, 8(%0) \n" - " sd $0, 16(%0) \n" - " sd $0, 24(%0) \n" -#ifdef CONFIG_CPU_HAS_PREFETCH - " pref " SB1_PREF_STORE_STREAMED_HINT ",128(%0) \n" /* Prefetch 4 lines ahead */ + " daddiu %0, %0, 128 \n" + " pref " SB1_PREF_STORE_STREAMED_HINT ", -128(%0) \n" /* Prefetch the first 4 lines */ + " pref " SB1_PREF_STORE_STREAMED_HINT ", -96(%0) \n" + " pref " SB1_PREF_STORE_STREAMED_HINT ", -64(%0) \n" + " pref " SB1_PREF_STORE_STREAMED_HINT ", -32(%0) \n" + "1: sd $0, -128(%0) \n" /* Throw out a cacheline of 0's */ + " sd $0, -120(%0) \n" + " sd $0, -112(%0) \n" + " sd $0, -104(%0) \n" + " daddiu %0, %0, 32 \n" + " bnel %0, %1, 1b \n" + " pref " SB1_PREF_STORE_STREAMED_HINT ", -32(%0) \n" + " daddiu %0, %0, -128 \n" #endif - " .set mips0 \n" - : - : "r" (addr) - : "memory"); - addr += 32; - } while (addr != end); + " sd $0, 0(%0) \n" /* Throw out a cacheline of 0's */ + "1: sd $0, 8(%0) \n" + " sd $0, 16(%0) \n" + " sd $0, 24(%0) \n" + " daddiu %0, %0, 32 \n" + " bnel %0, %1, 1b \n" + " sd $0, 0(%0) \n" + " .set pop \n" + : "+r" (addr) + : "r" (end) + : "memory"); } -#ifdef CONFIG_SIBYTE_DMA_PAGEOPS static inline void copy_page_cpu(void *to, void *from) -#else -void copy_page(void *to, void *from) -#endif { - unsigned char *src = from; - unsigned char *dst = to; + unsigned char *src = (unsigned char *)from; + unsigned char *dst = (unsigned char *)to; unsigned char *end = src + PAGE_SIZE; /* - * This should be optimized in assembly...can't use ld/sd, though, - * because the top 32 bits could be nuked if we took an interrupt - * during the routine. And this is not a good place to be cli()'ing - * * The pref's used here are using "streaming" hints, which cause the * copied data to be kicked out of the cache sooner. A page copy often * ends up copying a lot more data than is commonly used, so this seems * to make sense in terms of reducing cache pollution, but I've no real * performance data to back this up */ - - do { - __asm__ __volatile__( - " .set mips4 \n" + __asm__ __volatile__( + " .set push \n" + " .set mips4 \n" + " .set noreorder \n" #ifdef CONFIG_CPU_HAS_PREFETCH - " pref " SB1_PREF_LOAD_STREAMED_HINT ", 0(%0)\n" /* Prefetch the first 3 lines */ - " pref " SB1_PREF_STORE_STREAMED_HINT ", 0(%1)\n" - " pref " SB1_PREF_LOAD_STREAMED_HINT ", 32(%0)\n" - " pref " SB1_PREF_STORE_STREAMED_HINT ", 32(%1)\n" - " pref " SB1_PREF_LOAD_STREAMED_HINT ", 64(%0)\n" - " pref " SB1_PREF_STORE_STREAMED_HINT ", 64(%1)\n" -#endif - "1: lw $2, 0(%0) \n" /* Block copy a cacheline */ - " lw $3, 4(%0) \n" - " lw $4, 8(%0) \n" - " lw $5, 12(%0) \n" - " lw $6, 16(%0) \n" - " lw $7, 20(%0) \n" - " lw $8, 24(%0) \n" - " lw $9, 28(%0) \n" -#ifdef CONFIG_CPU_HAS_PREFETCH - " pref " SB1_PREF_LOAD_STREAMED_HINT ", 96(%0) \n" /* Prefetch ahead */ - " pref " SB1_PREF_STORE_STREAMED_HINT ", 96(%1) \n" + " daddiu %0, %0, 128 \n" + " daddiu %1, %1, 128 \n" + " pref " SB1_PREF_LOAD_STREAMED_HINT ", -128(%0)\n" /* Prefetch the first 4 lines */ + " pref " SB1_PREF_STORE_STREAMED_HINT ", -128(%1)\n" + " pref " SB1_PREF_LOAD_STREAMED_HINT ", -96(%0)\n" + " pref " SB1_PREF_STORE_STREAMED_HINT ", -96(%1)\n" + " pref " SB1_PREF_LOAD_STREAMED_HINT ", -64(%0)\n" + " pref " SB1_PREF_STORE_STREAMED_HINT ", -64(%1)\n" + " pref " SB1_PREF_LOAD_STREAMED_HINT ", -32(%0)\n" + "1: pref " SB1_PREF_STORE_STREAMED_HINT ", -32(%1)\n" +# ifdef CONFIG_MIPS64 + " ld $8, -128(%0) \n" /* Block copy a cacheline */ + " ld $9, -120(%0) \n" + " ld $10, -112(%0) \n" + " ld $11, -104(%0) \n" + " sd $8, -128(%1) \n" + " sd $9, -120(%1) \n" + " sd $10, -112(%1) \n" + " sd $11, -104(%1) \n" +# else + " lw $2, -128(%0) \n" /* Block copy a cacheline */ + " lw $3, -124(%0) \n" + " lw $6, -120(%0) \n" + " lw $7, -116(%0) \n" + " lw $8, -112(%0) \n" + " lw $9, -108(%0) \n" + " lw $10, -104(%0) \n" + " lw $11, -100(%0) \n" + " sw $2, -128(%1) \n" + " sw $3, -124(%1) \n" + " sw $6, -120(%1) \n" + " sw $7, -116(%1) \n" + " sw $8, -112(%1) \n" + " sw $9, -108(%1) \n" + " sw $10, -104(%1) \n" + " sw $11, -100(%1) \n" +# endif + " daddiu %0, %0, 32 \n" + " daddiu %1, %1, 32 \n" + " bnel %0, %2, 1b \n" + " pref " SB1_PREF_LOAD_STREAMED_HINT ", -32(%0)\n" + " daddiu %0, %0, -128 \n" + " daddiu %1, %1, -128 \n" +#endif +#ifdef CONFIG_MIPS64 + " ld $8, 0(%0) \n" /* Block copy a cacheline */ + "1: ld $9, 8(%0) \n" + " ld $10, 16(%0) \n" + " ld $11, 24(%0) \n" + " sd $8, 0(%1) \n" + " sd $9, 8(%1) \n" + " sd $10, 16(%1) \n" + " sd $11, 24(%1) \n" +#else + " lw $2, 0(%0) \n" /* Block copy a cacheline */ + "1: lw $3, 4(%0) \n" + " lw $6, 8(%0) \n" + " lw $7, 12(%0) \n" + " lw $8, 16(%0) \n" + " lw $9, 20(%0) \n" + " lw $10, 24(%0) \n" + " lw $11, 28(%0) \n" + " sw $2, 0(%1) \n" + " sw $3, 4(%1) \n" + " sw $6, 8(%1) \n" + " sw $7, 12(%1) \n" + " sw $8, 16(%1) \n" + " sw $9, 20(%1) \n" + " sw $10, 24(%1) \n" + " sw $11, 28(%1) \n" +#endif + " daddiu %0, %0, 32 \n" + " daddiu %1, %1, 32 \n" + " bnel %0, %2, 1b \n" +#ifdef CONFIG_MIPS64 + " ld $8, 0(%0) \n" +#else + " lw $2, 0(%0) \n" +#endif + " .set pop \n" + : "+r" (src), "+r" (dst) + : "r" (end) +#ifdef CONFIG_MIPS64 + : "$8","$9","$10","$11","memory"); +#else + : "$2","$3","$6","$7","$8","$9","$10","$11","memory"); #endif - " sw $2, 0(%1) \n" - " sw $3, 4(%1) \n" - " sw $4, 8(%1) \n" - " sw $5, 12(%1) \n" - " sw $6, 16(%1) \n" - " sw $7, 20(%1) \n" - " sw $8, 24(%1) \n" - " sw $9, 28(%1) \n" - " .set mips0 \n" - : - : "r" (src), "r" (dst) - : "$2","$3","$4","$5","$6","$7","$8","$9","memory"); - src += 32; - dst += 32; - } while (src != end); } @@ -151,10 +201,10 @@ void copy_page(void *to, void *from) * particular CPU. */ typedef struct dmadscr_s { - uint64_t dscr_a; - uint64_t dscr_b; - uint64_t pad_a; - uint64_t pad_b; + u64 dscr_a; + u64 dscr_b; + u64 pad_a; + u64 pad_b; } dmadscr_t; static dmadscr_t page_descr[NR_CPUS] __attribute__((aligned(SMP_CACHE_BYTES))); @@ -162,14 +212,14 @@ static dmadscr_t page_descr[NR_CPUS] __a void sb1_dma_init(void) { int cpu = smp_processor_id(); - uint64_t base_val = PHYSADDR(&page_descr[cpu]) | V_DM_DSCR_BASE_RINGSZ(1); + u64 base_val = CPHYSADDR(&page_descr[cpu]) | V_DM_DSCR_BASE_RINGSZ(1); - __raw_writeq(base_val, - IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE))); - __raw_writeq(base_val | M_DM_DSCR_BASE_RESET, - IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE))); - __raw_writeq(base_val | M_DM_DSCR_BASE_ENABL, - IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE))); + bus_writeq(base_val, + (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE))); + bus_writeq(base_val | M_DM_DSCR_BASE_RESET, + (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE))); + bus_writeq(base_val | M_DM_DSCR_BASE_ENABL, + (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE))); } void clear_page(void *page) @@ -177,46 +227,61 @@ void clear_page(void *page) int cpu = smp_processor_id(); /* if the page is above Kseg0, use old way */ - if (KSEGX(page) != CAC_BASE) + if ((long)KSEGX(page) != (long)CKSEG0) return clear_page_cpu(page); - page_descr[cpu].dscr_a = PHYSADDR(page) | M_DM_DSCRA_ZERO_MEM | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT; + page_descr[cpu].dscr_a = CPHYSADDR(page) | M_DM_DSCRA_ZERO_MEM | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT; page_descr[cpu].dscr_b = V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE); - __raw_writeq(1, IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT))); + bus_writeq(1, (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT))); /* * Don't really want to do it this way, but there's no * reliable way to delay completion detection. */ - while (!(__raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) & M_DM_DSCR_BASE_INTERRUPT))) + while (!(bus_readq((void *)(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) & + M_DM_DSCR_BASE_INTERRUPT)))) ; - __raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE))); + bus_readq((void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE))); } void copy_page(void *to, void *from) { - unsigned long from_phys = PHYSADDR(from); - unsigned long to_phys = PHYSADDR(to); + unsigned long from_phys = CPHYSADDR(from); + unsigned long to_phys = CPHYSADDR(to); int cpu = smp_processor_id(); /* if either page is above Kseg0, use old way */ - if ((KSEGX(to) != CAC_BASE) || (KSEGX(from) != CAC_BASE)) + if ((long)KSEGX(to) != (long)CKSEG0 + || (long)KSEGX(from) != (long)CKSEG0) return copy_page_cpu(to, from); - page_descr[cpu].dscr_a = PHYSADDR(to_phys) | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT; - page_descr[cpu].dscr_b = PHYSADDR(from_phys) | V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE); - __raw_writeq(1, IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT))); + page_descr[cpu].dscr_a = CPHYSADDR(to_phys) | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT; + page_descr[cpu].dscr_b = CPHYSADDR(from_phys) | V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE); + bus_writeq(1, (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT))); /* * Don't really want to do it this way, but there's no * reliable way to delay completion detection. */ - while (!(__raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) & M_DM_DSCR_BASE_INTERRUPT))) + while (!(bus_readq((void *)(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) & + M_DM_DSCR_BASE_INTERRUPT)))) ; - __raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE))); + bus_readq((void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE))); } -#endif +#else /* !CONFIG_SIBYTE_DMA_PAGEOPS */ + +void clear_page(void *page) +{ + return clear_page_cpu(page); +} + +void copy_page(void *to, void *from) +{ + return copy_page_cpu(to, from); +} + +#endif /* !CONFIG_SIBYTE_DMA_PAGEOPS */ EXPORT_SYMBOL(clear_page); EXPORT_SYMBOL(copy_page); diff -puN arch/mips/mm/pgtable-32.c~mips-generic-mips-updates arch/mips/mm/pgtable-32.c --- 25/arch/mips/mm/pgtable-32.c~mips-generic-mips-updates 2005-01-29 11:25:48.665471032 -0800 +++ 25-akpm/arch/mips/mm/pgtable-32.c 2005-01-29 11:25:48.773454616 -0800 @@ -71,8 +71,8 @@ void __init pagetable_init(void) /* Initialize the entire pgd. */ pgd_init((unsigned long)swapper_pg_dir); - pgd_init((unsigned long)swapper_pg_dir + - sizeof(pgd_t ) * USER_PTRS_PER_PGD); + pgd_init((unsigned long)swapper_pg_dir + + sizeof(pgd_t) * USER_PTRS_PER_PGD); #ifdef CONFIG_HIGHMEM pgd_base = swapper_pg_dir; diff -puN arch/mips/mm/pgtable-64.c~mips-generic-mips-updates arch/mips/mm/pgtable-64.c --- 25/arch/mips/mm/pgtable-64.c~mips-generic-mips-updates 2005-01-29 11:25:48.666470880 -0800 +++ 25-akpm/arch/mips/mm/pgtable-64.c 2005-01-29 11:25:48.774454464 -0800 @@ -55,5 +55,4 @@ void __init pagetable_init(void) /* Initialize the entire pgd. */ pgd_init((unsigned long)swapper_pg_dir); pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table); - memset((void *)invalid_pte_table, 0, sizeof(pte_t) * PTRS_PER_PTE); } diff -puN arch/mips/mm/pgtable.c~mips-generic-mips-updates arch/mips/mm/pgtable.c --- 25/arch/mips/mm/pgtable.c~mips-generic-mips-updates 2005-01-29 11:25:48.667470728 -0800 +++ 25-akpm/arch/mips/mm/pgtable.c 2005-01-29 11:25:48.774454464 -0800 @@ -1,3 +1,4 @@ +#include #include #include #include diff -puN arch/mips/mm/sc-rm7k.c~mips-generic-mips-updates arch/mips/mm/sc-rm7k.c --- 25/arch/mips/mm/sc-rm7k.c~mips-generic-mips-updates 2005-01-29 11:25:48.669470424 -0800 +++ 25-akpm/arch/mips/mm/sc-rm7k.c 2005-01-29 11:25:48.774454464 -0800 @@ -96,13 +96,13 @@ static void rm7k_sc_inv(unsigned long ad } /* - * This function is executed in the uncached segment KSEG1. + * This function is executed in the uncached segment CKSEG1. * It must not touch the stack, because the stack pointer still points - * into KSEG0. + * into CKSEG0. * * Three options: * - Write it in assembly and guarantee that we don't use the stack. - * - Disable caching for KSEG0 before calling it. + * - Disable caching for CKSEG0 before calling it. * - Pray that GCC doesn't randomly start using the stack. * * This being Linux, we obviously take the least sane of those options - diff -L arch/mips/mm/tlb64-glue-r4k.S -puN arch/mips/mm/tlb64-glue-r4k.S~mips-generic-mips-updates /dev/null --- 25/arch/mips/mm/tlb64-glue-r4k.S +++ /dev/null 2003-09-15 06:40:47.000000000 -0700 @@ -1,41 +0,0 @@ -/* - * 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) 1999 Ralf Baechle - * Copyright (C) 1999 Silicon Graphics, Inc. - */ -#include -#include -#include -#include - - .macro __BUILD_cli - CLI - .endm - - .macro __BUILD_sti - STI - .endm - - .macro __BUILD_kmode - KMODE - .endm - - .macro tlb_handler name interruptible writebit - NESTED(__\name, PT_SIZE, sp) - SAVE_ALL - dmfc0 a2, CP0_BADVADDR - __BUILD_\interruptible - li a1, \writebit - sd a2, PT_BVADDR(sp) - move a0, sp - jal do_page_fault - j ret_from_exception - END(__\name) - .endm - - tlb_handler xtlb_mod kmode 1 - tlb_handler xtlb_tlbl kmode 0 - tlb_handler xtlb_tlbs kmode 1 diff -L arch/mips/mm/tlb64-glue-sb1.S -puN arch/mips/mm/tlb64-glue-sb1.S~mips-generic-mips-updates /dev/null --- 25/arch/mips/mm/tlb64-glue-sb1.S +++ /dev/null 2003-09-15 06:40:47.000000000 -0700 @@ -1,66 +0,0 @@ -/* - * 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) 1999 Ralf Baechle - * Copyright (C) 1999 Silicon Graphics, Inc. - */ -#include -#include -#include -#include -#include -#include - - .macro __BUILD_cli - CLI - .endm - - .macro __BUILD_sti - STI - .endm - - .macro __BUILD_kmode - KMODE - .endm - - .macro tlb_handler name interruptible writebit - NESTED(__\name, PT_SIZE, sp) - SAVE_ALL - dmfc0 a2, CP0_BADVADDR - __BUILD_\interruptible - li a1, \writebit - sd a2, PT_BVADDR(sp) - move a0, sp - jal do_page_fault - j ret_from_exception - END(__\name) - .endm - - .macro tlb_handler_m3 name interruptible writebit - NESTED(__\name, PT_SIZE, sp) - dmfc0 k0, CP0_BADVADDR - dmfc0 k1, CP0_ENTRYHI - xor k0, k1 - dsrl k0, k0, PAGE_SHIFT + 1 - bnez k0, 1f - SAVE_ALL - dmfc0 a2, CP0_BADVADDR - __BUILD_\interruptible - li a1, \writebit - sd a2, PT_BVADDR(sp) - move a0, sp - jal do_page_fault -1: - j ret_from_exception - END(__\name) - .endm - - tlb_handler xtlb_mod kmode 1 -#if BCM1250_M3_WAR - tlb_handler_m3 xtlb_tlbl kmode 0 -#else - tlb_handler xtlb_tlbl kmode 0 -#endif - tlb_handler xtlb_tlbs kmode 1 diff -puN arch/mips/mm/tlb-andes.c~mips-generic-mips-updates arch/mips/mm/tlb-andes.c --- 25/arch/mips/mm/tlb-andes.c~mips-generic-mips-updates 2005-01-29 11:25:48.672469968 -0800 +++ 25-akpm/arch/mips/mm/tlb-andes.c 2005-01-29 11:25:48.776454160 -0800 @@ -7,7 +7,6 @@ * Copyright (C) 1999 Silicon Graphics, Inc. * Copyright (C) 2000 Kanoj Sarcar (kanoj@sgi.com) */ -#include #include #include #include diff -L arch/mips/mm/tlbex32-mips32.S -puN arch/mips/mm/tlbex32-mips32.S~mips-generic-mips-updates /dev/null --- 25/arch/mips/mm/tlbex32-mips32.S +++ /dev/null 2003-09-15 06:40:47.000000000 -0700 @@ -1,253 +0,0 @@ -/* - * TLB exception handling code for MIPS32 CPUs. - * - * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse - * - * Multi-cpu abstraction and reworking: - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * - * Pete Popov, ppopov@pacbell.net - * Added 36 bit phys address support. - * Copyright (C) 2002 MontaVista Software, Inc. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TLB_OPTIMIZE /* If you are paranoid, disable this. */ - -#ifdef CONFIG_64BIT_PHYS_ADDR - -/* We really only support 36 bit physical addresses on MIPS32 */ -#define PTE_L lw -#define PTE_S sw -#define PTE_SRL srl -#define P_MTC0 mtc0 -#define PTE_HALF 4 /* pte_high contains pre-shifted, ready to go entry */ -#define PTE_SIZE 8 -#define PTEP_INDX_MSK 0xff0 -#define PTE_INDX_MSK 0xff8 -#define PTE_INDX_SHIFT 9 -#define CONVERT_PTE(pte) -#define PTE_MAKEWRITE_HIGH(pte, ptr) \ - lw pte, PTE_HALF(ptr); \ - ori pte, (_PAGE_VALID | _PAGE_DIRTY); \ - sw pte, PTE_HALF(ptr); \ - lw pte, 0(ptr); - -#define PTE_MAKEVALID_HIGH(pte, ptr) \ - lw pte, PTE_HALF(ptr); \ - ori pte, pte, _PAGE_VALID; \ - sw pte, PTE_HALF(ptr); \ - lw pte, 0(ptr); - -#else - -#define PTE_L lw -#define PTE_S sw -#define PTE_SRL srl -#define P_MTC0 mtc0 -#define PTE_HALF 0 -#define PTE_SIZE 4 -#define PTEP_INDX_MSK 0xff8 -#define PTE_INDX_MSK 0xffc -#define PTE_INDX_SHIFT 10 -#define CONVERT_PTE(pte) srl pte, pte, 6 -#define PTE_MAKEWRITE_HIGH(pte, ptr) -#define PTE_MAKEVALID_HIGH(pte, ptr) - -#endif /* CONFIG_64BIT_PHYS_ADDR */ - -#ifdef CONFIG_64BIT_PHYS_ADDR -#define GET_PTE_OFF(reg) -#else -#define GET_PTE_OFF(reg) srl reg, reg, 1 -#endif - -/* - * ABUSE of CPP macros 101. - * - * After this macro runs, the pte faulted on is - * in register PTE, a ptr into the table in which - * the pte belongs is in PTR. - */ - -#ifdef CONFIG_SMP -#define GET_PGD(scratch, ptr) \ - mfc0 ptr, CP0_CONTEXT; \ - la scratch, pgd_current;\ - srl ptr, 23; \ - sll ptr, 2; \ - addu ptr, scratch, ptr; \ - lw ptr, (ptr); -#else -#define GET_PGD(scratch, ptr) \ - lw ptr, pgd_current; -#endif - -#define LOAD_PTE(pte, ptr) \ - GET_PGD(pte, ptr) \ - mfc0 pte, CP0_BADVADDR; \ - srl pte, pte, _PGDIR_SHIFT; \ - sll pte, pte, 2; \ - addu ptr, ptr, pte; \ - mfc0 pte, CP0_BADVADDR; \ - lw ptr, (ptr); \ - srl pte, pte, PTE_INDX_SHIFT; \ - and pte, pte, PTE_INDX_MSK; \ - addu ptr, ptr, pte; \ - PTE_L pte, (ptr); - - /* This places the even/odd pte pair in the page - * table at PTR into ENTRYLO0 and ENTRYLO1 using - * TMP as a scratch register. - */ -#define PTE_RELOAD(ptr, tmp) \ - ori ptr, ptr, PTE_SIZE; \ - xori ptr, ptr, PTE_SIZE; \ - PTE_L tmp, (PTE_HALF+PTE_SIZE)(ptr); \ - CONVERT_PTE(tmp); \ - P_MTC0 tmp, CP0_ENTRYLO1; \ - PTE_L ptr, PTE_HALF(ptr); \ - CONVERT_PTE(ptr); \ - P_MTC0 ptr, CP0_ENTRYLO0; - -#define DO_FAULT(write) \ - .set noat; \ - SAVE_ALL; \ - mfc0 a2, CP0_BADVADDR; \ - KMODE; \ - .set at; \ - move a0, sp; \ - jal do_page_fault; \ - li a1, write; \ - j ret_from_exception; \ - nop; \ - .set noat; - - /* Check is PTE is present, if not then jump to LABEL. - * PTR points to the page table where this PTE is located, - * when the macro is done executing PTE will be restored - * with it's original value. - */ -#define PTE_PRESENT(pte, ptr, label) \ - andi pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ - xori pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ - bnez pte, label; \ - PTE_L pte, (ptr); - - /* Make PTE valid, store result in PTR. */ -#define PTE_MAKEVALID(pte, ptr) \ - ori pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \ - PTE_S pte, (ptr); - - /* Check if PTE can be written to, if not branch to LABEL. - * Regardless restore PTE with value from PTR when done. - */ -#define PTE_WRITABLE(pte, ptr, label) \ - andi pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ - xori pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ - bnez pte, label; \ - PTE_L pte, (ptr); - - /* Make PTE writable, update software status bits as well, - * then store at PTR. - */ -#define PTE_MAKEWRITE(pte, ptr) \ - ori pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \ - _PAGE_VALID | _PAGE_DIRTY); \ - PTE_S pte, (ptr); - - .set noreorder - - .align 5 - NESTED(handle_tlbl, PT_SIZE, sp) - .set noat -invalid_tlbl: -#ifdef TLB_OPTIMIZE - /* Test present bit in entry. */ - LOAD_PTE(k0, k1) - tlbp - PTE_PRESENT(k0, k1, nopage_tlbl) - PTE_MAKEVALID_HIGH(k0, k1) - PTE_MAKEVALID(k0, k1) - PTE_RELOAD(k1, k0) - nop - b 1f - tlbwi -1: - nop - .set mips3 - eret - .set mips0 -#endif - -nopage_tlbl: - DO_FAULT(0) - END(handle_tlbl) - - .align 5 - NESTED(handle_tlbs, PT_SIZE, sp) - .set noat -#ifdef TLB_OPTIMIZE - .set mips3 - li k0,0 - LOAD_PTE(k0, k1) - tlbp # find faulting entry - PTE_WRITABLE(k0, k1, nopage_tlbs) - PTE_MAKEWRITE(k0, k1) - PTE_MAKEWRITE_HIGH(k0, k1) - PTE_RELOAD(k1, k0) - nop - b 1f - tlbwi -1: - nop - .set mips3 - eret - .set mips0 -#endif - -nopage_tlbs: - DO_FAULT(1) - END(handle_tlbs) - - .align 5 - NESTED(handle_mod, PT_SIZE, sp) - .set noat -#ifdef TLB_OPTIMIZE - .set mips3 - LOAD_PTE(k0, k1) - tlbp # find faulting entry - andi k0, k0, _PAGE_WRITE - beqz k0, nowrite_mod - PTE_L k0, (k1) - - /* Present and writable bits set, set accessed and dirty bits. */ - PTE_MAKEWRITE(k0, k1) - PTE_MAKEWRITE_HIGH(k0, k1) - /* Now reload the entry into the tlb. */ - PTE_RELOAD(k1, k0) - nop - b 1f - tlbwi -1: - nop - .set mips3 - eret - .set mips0 -#endif - -nowrite_mod: - DO_FAULT(1) - END(handle_mod) - diff -L arch/mips/mm/tlbex32-r3k.S -puN arch/mips/mm/tlbex32-r3k.S~mips-generic-mips-updates /dev/null --- 25/arch/mips/mm/tlbex32-r3k.S +++ /dev/null 2003-09-15 06:40:47.000000000 -0700 @@ -1,194 +0,0 @@ -/* - * TLB exception handling code for R2000/R3000. - * - * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse - * - * Multi-CPU abstraction reworking: - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * - * Further modifications to make this work: - * Copyright (c) 1998 Harald Koerfgen - * Copyright (c) 1998, 1999 Gleb Raiko & Vladimir Roganov - * Copyright (c) 2001 Ralf Baechle - * Copyright (c) 2001 MIPS Technologies, Inc. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TLB_OPTIMIZE /* If you are paranoid, disable this. */ - - /* ABUSE of CPP macros 101. */ - - /* After this macro runs, the pte faulted on is - * in register PTE, a ptr into the table in which - * the pte belongs is in PTR. - */ -#define LOAD_PTE(pte, ptr) \ - mfc0 pte, CP0_BADVADDR; \ - lw ptr, pgd_current; \ - srl pte, pte, 22; \ - sll pte, pte, 2; \ - addu ptr, ptr, pte; \ - mfc0 pte, CP0_CONTEXT; \ - lw ptr, (ptr); \ - andi pte, pte, 0xffc; \ - addu ptr, ptr, pte; \ - lw pte, (ptr); \ - nop; - - /* This places the even/odd pte pair in the page - * table at PTR into ENTRYLO0 and ENTRYLO1 using - * TMP as a scratch register. - */ -#define PTE_RELOAD(ptr) \ - lw ptr, (ptr) ; \ - nop ; \ - mtc0 ptr, CP0_ENTRYLO0; \ - nop; - -#define DO_FAULT(write) \ - .set noat; \ - .set macro; \ - SAVE_ALL; \ - mfc0 a2, CP0_BADVADDR; \ - KMODE; \ - .set at; \ - move a0, sp; \ - jal do_page_fault; \ - li a1, write; \ - j ret_from_exception; \ - nop; \ - .set noat; \ - .set nomacro; - - /* Check is PTE is present, if not then jump to LABEL. - * PTR points to the page table where this PTE is located, - * when the macro is done executing PTE will be restored - * with it's original value. - */ -#define PTE_PRESENT(pte, ptr, label) \ - andi pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ - xori pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ - bnez pte, label; \ - .set push; \ - .set reorder; \ - lw pte, (ptr); \ - .set pop; - - /* Make PTE valid, store result in PTR. */ -#define PTE_MAKEVALID(pte, ptr) \ - ori pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \ - sw pte, (ptr); - - /* Check if PTE can be written to, if not branch to LABEL. - * Regardless restore PTE with value from PTR when done. - */ -#define PTE_WRITABLE(pte, ptr, label) \ - andi pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ - xori pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ - bnez pte, label; \ - .set push; \ - .set reorder; \ - lw pte, (ptr); \ - .set pop; - - - /* Make PTE writable, update software status bits as well, - * then store at PTR. - */ -#define PTE_MAKEWRITE(pte, ptr) \ - ori pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \ - _PAGE_VALID | _PAGE_DIRTY); \ - sw pte, (ptr); - -/* - * The index register may have the probe fail bit set, - * because we would trap on access kseg2, i.e. without refill. - */ -#define TLB_WRITE(reg) \ - mfc0 reg, CP0_INDEX; \ - nop; \ - bltz reg, 1f; \ - nop; \ - tlbwi; \ - j 2f; \ - nop; \ -1: tlbwr; \ -2: - -#define RET(reg) \ - mfc0 reg, CP0_EPC; \ - nop; \ - jr reg; \ - rfe - - .set noreorder - - .align 5 -NESTED(handle_tlbl, PT_SIZE, sp) - .set noat - -#ifdef TLB_OPTIMIZE - /* Test present bit in entry. */ - LOAD_PTE(k0, k1) - tlbp - PTE_PRESENT(k0, k1, nopage_tlbl) - PTE_MAKEVALID(k0, k1) - PTE_RELOAD(k1) - TLB_WRITE(k0) - RET(k0) -nopage_tlbl: -#endif - - DO_FAULT(0) -END(handle_tlbl) - -NESTED(handle_tlbs, PT_SIZE, sp) - .set noat - -#ifdef TLB_OPTIMIZE - LOAD_PTE(k0, k1) - tlbp # find faulting entry - PTE_WRITABLE(k0, k1, nopage_tlbs) - PTE_MAKEWRITE(k0, k1) - PTE_RELOAD(k1) - TLB_WRITE(k0) - RET(k0) -nopage_tlbs: -#endif - - DO_FAULT(1) -END(handle_tlbs) - - .align 5 -NESTED(handle_mod, PT_SIZE, sp) - .set noat -#ifdef TLB_OPTIMIZE - LOAD_PTE(k0, k1) - tlbp # find faulting entry - andi k0, k0, _PAGE_WRITE - beqz k0, nowrite_mod - .set push - .set reorder - lw k0, (k1) - .set pop - - /* Present and writable bits set, set accessed and dirty bits. */ - PTE_MAKEWRITE(k0, k1) - - /* Now reload the entry into the tlb. */ - PTE_RELOAD(k1) - tlbwi - RET(k0) -#endif - -nowrite_mod: - DO_FAULT(1) -END(handle_mod) diff -L arch/mips/mm/tlbex32-r4k.S -puN arch/mips/mm/tlbex32-r4k.S~mips-generic-mips-updates /dev/null --- 25/arch/mips/mm/tlbex32-r4k.S +++ /dev/null 2003-09-15 06:40:47.000000000 -0700 @@ -1,262 +0,0 @@ -/* - * TLB exception handling code for r4k. - * - * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse - * - * Multi-cpu abstraction and reworking: - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - */ -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TLB_OPTIMIZE /* If you are paranoid, disable this. */ - -#ifdef CONFIG_64BIT_PHYS_ADDR -#define PTE_L ld -#define PTE_S sd -#define PTE_SRL dsrl -#define P_MTC0 dmtc0 -#define PTE_SIZE 8 -#define PTEP_INDX_MSK 0xff0 -#define PTE_INDX_MSK 0xff8 -#define PTE_INDX_SHIFT 9 -#else -#define PTE_L lw -#define PTE_S sw -#define PTE_SRL srl -#define P_MTC0 mtc0 -#define PTE_SIZE 4 -#define PTEP_INDX_MSK 0xff8 -#define PTE_INDX_MSK 0xffc -#define PTE_INDX_SHIFT 10 -#endif - -/* - * ABUSE of CPP macros 101. - * - * After this macro runs, the pte faulted on is - * in register PTE, a ptr into the table in which - * the pte belongs is in PTR. - */ - -#ifdef CONFIG_SMP -#define GET_PGD(scratch, ptr) \ - mfc0 ptr, CP0_CONTEXT; \ - la scratch, pgd_current;\ - srl ptr, 23; \ - sll ptr, 2; \ - addu ptr, scratch, ptr; \ - lw ptr, (ptr); -#else -#define GET_PGD(scratch, ptr) \ - lw ptr, pgd_current; -#endif - -#define LOAD_PTE(pte, ptr) \ - GET_PGD(pte, ptr) \ - mfc0 pte, CP0_BADVADDR; \ - srl pte, pte, _PGDIR_SHIFT; \ - sll pte, pte, 2; \ - addu ptr, ptr, pte; \ - mfc0 pte, CP0_BADVADDR; \ - lw ptr, (ptr); \ - srl pte, pte, PTE_INDX_SHIFT; \ - and pte, pte, PTE_INDX_MSK; \ - addu ptr, ptr, pte; \ - PTE_L pte, (ptr); - - /* This places the even/odd pte pair in the page - * table at PTR into ENTRYLO0 and ENTRYLO1 using - * TMP as a scratch register. - */ -#define PTE_RELOAD(ptr, tmp) \ - ori ptr, ptr, PTE_SIZE; \ - xori ptr, ptr, PTE_SIZE; \ - PTE_L tmp, PTE_SIZE(ptr); \ - PTE_L ptr, 0(ptr); \ - PTE_SRL tmp, tmp, 6; \ - P_MTC0 tmp, CP0_ENTRYLO1; \ - PTE_SRL ptr, ptr, 6; \ - P_MTC0 ptr, CP0_ENTRYLO0; - -#define DO_FAULT(write) \ - .set noat; \ - SAVE_ALL; \ - mfc0 a2, CP0_BADVADDR; \ - KMODE; \ - .set at; \ - move a0, sp; \ - jal do_page_fault; \ - li a1, write; \ - j ret_from_exception; \ - nop; \ - .set noat; - - /* Check is PTE is present, if not then jump to LABEL. - * PTR points to the page table where this PTE is located, - * when the macro is done executing PTE will be restored - * with it's original value. - */ -#define PTE_PRESENT(pte, ptr, label) \ - andi pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ - xori pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ - bnez pte, label; \ - PTE_L pte, (ptr); - - /* Make PTE valid, store result in PTR. */ -#define PTE_MAKEVALID(pte, ptr) \ - ori pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \ - PTE_S pte, (ptr); - - /* Check if PTE can be written to, if not branch to LABEL. - * Regardless restore PTE with value from PTR when done. - */ -#define PTE_WRITABLE(pte, ptr, label) \ - andi pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ - xori pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ - bnez pte, label; \ - PTE_L pte, (ptr); - - /* Make PTE writable, update software status bits as well, - * then store at PTR. - */ -#define PTE_MAKEWRITE(pte, ptr) \ - ori pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \ - _PAGE_VALID | _PAGE_DIRTY); \ - PTE_S pte, (ptr); - - - .set noreorder - -/* - * From the IDT errata for the QED RM5230 (Nevada), processor revision 1.0: - * 2. A timing hazard exists for the TLBP instruction. - * - * stalling_instruction - * TLBP - * - * The JTLB is being read for the TLBP throughout the stall generated by the - * previous instruction. This is not really correct as the stalling instruction - * can modify the address used to access the JTLB. The failure symptom is that - * the TLBP instruction will use an address created for the stalling instruction - * and not the address held in C0_ENHI and thus report the wrong results. - * - * The software work-around is to not allow the instruction preceding the TLBP - * to stall - make it an NOP or some other instruction guaranteed not to stall. - * - * Errata 2 will not be fixed. This errata is also on the R5000. - * - * As if we MIPS hackers wouldn't know how to nop pipelines happy ... - */ -#define R5K_HAZARD nop - - /* - * Note for many R4k variants tlb probes cannot be executed out - * of the instruction cache else you get bogus results. - */ - .align 5 - NESTED(handle_tlbl, PT_SIZE, sp) - .set noat -#if BCM1250_M3_WAR - mfc0 k0, CP0_BADVADDR - mfc0 k1, CP0_ENTRYHI - xor k0, k1 - srl k0, k0, PAGE_SHIFT+1 - beqz k0, 1f - nop - .set mips3 - eret - .set mips0 -1: -#endif -invalid_tlbl: -#ifdef TLB_OPTIMIZE - .set mips3 - /* Test present bit in entry. */ - LOAD_PTE(k0, k1) - R5K_HAZARD - tlbp - PTE_PRESENT(k0, k1, nopage_tlbl) - PTE_MAKEVALID(k0, k1) - PTE_RELOAD(k1, k0) - mtc0_tlbw_hazard - tlbwi - nop - tlbw_eret_hazard - .set mips3 - eret - .set mips0 -#endif - -nopage_tlbl: - DO_FAULT(0) - END(handle_tlbl) - - .align 5 - NESTED(handle_tlbs, PT_SIZE, sp) - .set noat -#ifdef TLB_OPTIMIZE - .set mips3 - li k0,0 - LOAD_PTE(k0, k1) - R5K_HAZARD - tlbp # find faulting entry - PTE_WRITABLE(k0, k1, nopage_tlbs) - PTE_MAKEWRITE(k0, k1) - PTE_RELOAD(k1, k0) - mtc0_tlbw_hazard - tlbwi - nop - tlbw_eret_hazard - .set mips3 - eret - .set mips0 -#endif - -nopage_tlbs: - DO_FAULT(1) - END(handle_tlbs) - - .align 5 - NESTED(handle_mod, PT_SIZE, sp) - .set noat -#ifdef TLB_OPTIMIZE - .set mips3 - LOAD_PTE(k0, k1) - R5K_HAZARD - tlbp # find faulting entry - andi k0, k0, _PAGE_WRITE - beqz k0, nowrite_mod - PTE_L k0, (k1) - - /* Present and writable bits set, set accessed and dirty bits. */ - PTE_MAKEWRITE(k0, k1) - - /* Now reload the entry into the tlb. */ - PTE_RELOAD(k1, k0) - mtc0_tlbw_hazard - tlbwi - nop - tlbw_eret_hazard - .set mips3 - eret - .set mips0 -#endif - -nowrite_mod: - DO_FAULT(1) - END(handle_mod) diff -puN arch/mips/mm/tlbex.c~mips-generic-mips-updates arch/mips/mm/tlbex.c --- 25/arch/mips/mm/tlbex.c~mips-generic-mips-updates 2005-01-29 11:25:48.678469056 -0800 +++ 25-akpm/arch/mips/mm/tlbex.c 2005-01-29 11:25:48.787452488 -0800 @@ -5,7 +5,7 @@ * * Synthesize TLB refill handlers at runtime. * - * Copyright (C) 2004 by Thiemo Seufer + * Copyright (C) 2004,2005 by Thiemo Seufer */ #include @@ -19,11 +19,11 @@ #include #include -#include #include #include #include #include +#include /* #define DEBUG_TLB */ @@ -44,6 +44,11 @@ static __init int __attribute__((unused) return BCM1250_M3_WAR; } +static __init int __attribute__((unused)) r10000_llsc_war(void) +{ + return R10000_LLSC_WAR; +} + /* * A little micro-assembler, intended for TLB refill handler * synthesizing. It is intentionally kept simple, does only support @@ -84,13 +89,14 @@ enum fields enum opcode { insn_invalid, insn_addu, insn_addiu, insn_and, insn_andi, insn_beq, - insn_bgez, insn_bgezl, insn_bltz, insn_bltzl, insn_bne, - insn_daddu, insn_daddiu, insn_dmfc0, insn_dmtc0, + insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl, + insn_bne, insn_daddu, insn_daddiu, insn_dmfc0, insn_dmtc0, insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32, insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr, insn_ld, - insn_lui, insn_lw, insn_mfc0, insn_mtc0, insn_ori, insn_rfe, - insn_sd, insn_sll, insn_sra, insn_srl, insn_subu, insn_sw, - insn_tlbp, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori + insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, insn_mtc0, + insn_ori, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll, + insn_sra, insn_srl, insn_subu, insn_sw, insn_tlbp, insn_tlbwi, + insn_tlbwr, insn_xor, insn_xori }; struct insn { @@ -114,6 +120,7 @@ static __initdata struct insn insn_table { insn_and, M(spec_op,0,0,0,0,and_op), RS | RT | RD }, { insn_andi, M(andi_op,0,0,0,0,0), RS | RT | UIMM }, { insn_beq, M(beq_op,0,0,0,0,0), RS | RT | BIMM }, + { insn_beql, M(beql_op,0,0,0,0,0), RS | RT | BIMM }, { insn_bgez, M(bcond_op,0,bgez_op,0,0,0), RS | BIMM }, { insn_bgezl, M(bcond_op,0,bgezl_op,0,0,0), RS | BIMM }, { insn_bltz, M(bcond_op,0,bltz_op,0,0,0), RS | BIMM }, @@ -134,12 +141,16 @@ static __initdata struct insn insn_table { insn_jal, M(jal_op,0,0,0,0,0), JIMM }, { insn_jr, M(spec_op,0,0,0,0,jr_op), RS }, { insn_ld, M(ld_op,0,0,0,0,0), RS | RT | SIMM }, + { insn_ll, M(ll_op,0,0,0,0,0), RS | RT | SIMM }, + { insn_lld, M(lld_op,0,0,0,0,0), RS | RT | SIMM }, { insn_lui, M(lui_op,0,0,0,0,0), RT | SIMM }, { insn_lw, M(lw_op,0,0,0,0,0), RS | RT | SIMM }, { insn_mfc0, M(cop0_op,mfc_op,0,0,0,0), RT | RD }, { insn_mtc0, M(cop0_op,mtc_op,0,0,0,0), RT | RD }, { insn_ori, M(ori_op,0,0,0,0,0), RS | RT | UIMM }, { insn_rfe, M(cop0_op,cop_op,0,0,0,rfe_op), 0 }, + { insn_sc, M(sc_op,0,0,0,0,0), RS | RT | SIMM }, + { insn_scd, M(scd_op,0,0,0,0,0), RS | RT | SIMM }, { insn_sd, M(sd_op,0,0,0,0,0), RS | RT | SIMM }, { insn_sll, M(spec_op,0,0,0,0,sll_op), RT | RD | RE }, { insn_sra, M(spec_op,0,0,0,0,sra_op), RT | RD | RE }, @@ -341,6 +352,7 @@ I_u3u1u2(_addu); I_u2u1u3(_andi); I_u3u1u2(_and); I_u1u2s3(_beq); +I_u1u2s3(_beql); I_u1s2(_bgez); I_u1s2(_bgezl); I_u1s2(_bltz); @@ -361,12 +373,16 @@ I_u1(_j); I_u1(_jal); I_u1(_jr); I_u2s3u1(_ld); +I_u2s3u1(_ll); +I_u2s3u1(_lld); I_u1s2(_lui); I_u2s3u1(_lw); I_u1u2(_mfc0); I_u1u2(_mtc0); I_u2u1u3(_ori); I_0(_rfe); +I_u2s3u1(_sc); +I_u2s3u1(_scd); I_u2s3u1(_sd); I_u2u1u3(_sll); I_u2u1u3(_sra); @@ -389,8 +405,14 @@ enum label_id { label_leave, label_vmalloc, label_vmalloc_done, - label_tlbwr_hazard, - label_split + label_tlbw_hazard, + label_split, + label_nopage_tlbl, + label_nopage_tlbs, + label_nopage_tlbm, + label_smp_pgtable_change, + label_r3000_write_probe_fail, + label_r3000_write_probe_ok }; struct label { @@ -416,8 +438,14 @@ L_LA(_second_part) L_LA(_leave) L_LA(_vmalloc) L_LA(_vmalloc_done) -L_LA(_tlbwr_hazard) +L_LA(_tlbw_hazard) L_LA(_split) +L_LA(_nopage_tlbl) +L_LA(_nopage_tlbs) +L_LA(_nopage_tlbm) +L_LA(_smp_pgtable_change) +L_LA(_r3000_write_probe_fail) +L_LA(_r3000_write_probe_ok) /* convenience macros for instructions */ #ifdef CONFIG_MIPS64 @@ -431,6 +459,8 @@ L_LA(_split) # define i_ADDIU(buf, rs, rt, val) i_daddiu(buf, rs, rt, val) # define i_ADDU(buf, rs, rt, rd) i_daddu(buf, rs, rt, rd) # define i_SUBU(buf, rs, rt, rd) i_dsubu(buf, rs, rt, rd) +# define i_LL(buf, rs, rt, off) i_lld(buf, rs, rt, off) +# define i_SC(buf, rs, rt, off) i_scd(buf, rs, rt, off) #else # define i_LW(buf, rs, rt, off) i_lw(buf, rs, rt, off) # define i_SW(buf, rs, rt, off) i_sw(buf, rs, rt, off) @@ -442,28 +472,33 @@ L_LA(_split) # define i_ADDIU(buf, rs, rt, val) i_addiu(buf, rs, rt, val) # define i_ADDU(buf, rs, rt, rd) i_addu(buf, rs, rt, rd) # define i_SUBU(buf, rs, rt, rd) i_subu(buf, rs, rt, rd) +# define i_LL(buf, rs, rt, off) i_ll(buf, rs, rt, off) +# define i_SC(buf, rs, rt, off) i_sc(buf, rs, rt, off) #endif #define i_b(buf, off) i_beq(buf, 0, 0, off) +#define i_beqz(buf, rs, off) i_beq(buf, rs, 0, off) +#define i_beqzl(buf, rs, off) i_beql(buf, rs, 0, off) #define i_bnez(buf, rs, off) i_bne(buf, rs, 0, off) +#define i_bnezl(buf, rs, off) i_bnel(buf, rs, 0, off) #define i_move(buf, a, b) i_ADDU(buf, a, 0, b) #define i_nop(buf) i_sll(buf, 0, 0, 0) #define i_ssnop(buf) i_sll(buf, 0, 0, 1) #define i_ehb(buf) i_sll(buf, 0, 0, 3) -#if CONFIG_MIPS64 -static __init int in_compat_space_p(long addr) +#ifdef CONFIG_MIPS64 +static __init int __attribute__((unused)) in_compat_space_p(long addr) { /* Is this address in 32bit compat space? */ return (((addr) & 0xffffffff00000000) == 0xffffffff00000000); } -static __init int rel_highest(long val) +static __init int __attribute__((unused)) rel_highest(long val) { return ((((val + 0x800080008000L) >> 48) & 0xffff) ^ 0x8000) - 0x8000; } -static __init int rel_higher(long val) +static __init int __attribute__((unused)) rel_higher(long val) { return ((((val + 0x80008000L) >> 32) & 0xffff) ^ 0x8000) - 0x8000; } @@ -550,22 +585,33 @@ static __init void resolve_relocs(struct __resolve_relocs(rel, l); } -static __init void copy_handler(struct reloc *rel, struct label *lab, - u32 *first, u32 *end, u32* target) +static __init void move_relocs(struct reloc *rel, u32 *first, u32 *end, + long off) { - long off = (long)(target - first); - - memcpy(target, first, (end - first) * sizeof(u32)); - for (; rel->lab != label_invalid; rel++) if (rel->addr >= first && rel->addr < end) rel->addr += off; +} +static __init void move_labels(struct label *lab, u32 *first, u32 *end, + long off) +{ for (; lab->lab != label_invalid; lab++) if (lab->addr >= first && lab->addr < end) lab->addr += off; } +static __init void copy_handler(struct reloc *rel, struct label *lab, + u32 *first, u32 *end, u32 *target) +{ + long off = (long)(target - first); + + memcpy(target, first, (end - first) * sizeof(u32)); + + move_relocs(rel, first, end, off); + move_labels(lab, first, end, off); +} + static __init int __attribute__((unused)) insn_has_bdelay(struct reloc *rel, u32 *addr) { @@ -594,6 +640,20 @@ static void __attribute__((unused)) il_b i_b(p, 0); } +static void il_beqz(u32 **p, struct reloc **r, unsigned int reg, + enum label_id l) +{ + r_mips_pc16(r, *p, l); + i_beqz(p, reg, 0); +} + +static void __attribute__((unused)) +il_beqzl(u32 **p, struct reloc **r, unsigned int reg, enum label_id l) +{ + r_mips_pc16(r, *p, l); + i_beqzl(p, reg, 0); +} + static void il_bnez(u32 **p, struct reloc **r, unsigned int reg, enum label_id l) { @@ -608,7 +668,7 @@ static void il_bgezl(u32 **p, struct rel i_bgezl(p, reg, 0); } -/* The only registers allowed in TLB handlers. */ +/* The only general purpose registers allowed in TLB handlers. */ #define K0 26 #define K1 27 @@ -642,7 +702,6 @@ static __initdata u32 tlb_handler[128]; static __initdata struct label labels[128]; static __initdata struct reloc relocs[128]; -#ifdef CONFIG_MIPS32 /* * The R3000 TLB handler is simple. */ @@ -676,10 +735,11 @@ static void __init build_r3000_tlb_refil panic("TLB refill handler space exceeded"); printk("Synthesized TLB handler (%u instructions).\n", - p - tlb_handler); + (unsigned int)(p - tlb_handler)); #ifdef DEBUG_TLB { int i; + for (i = 0; i < (p - tlb_handler); i++) printk("%08x\n", tlb_handler[i]); } @@ -688,7 +748,6 @@ static void __init build_r3000_tlb_refil memcpy((void *)CAC_BASE, tlb_handler, 0x80); flush_icache_range(CAC_BASE, CAC_BASE + 0x80); } -#endif /* CONFIG_MIPS32 */ /* * The R4000 TLB handler is much more complicated. We have two @@ -738,12 +797,22 @@ static __init void __attribute__((unused } /* - * Write random TLB entry, and care about the hazards from the - * preceeding mtc0 and for the following eret. + * Write random or indexed TLB entry, and care about the hazards from + * the preceeding mtc0 and for the following eret. */ -static __init void build_tlb_write_random_entry(u32 **p, struct label **l, - struct reloc **r) +enum tlb_write_entry { tlb_random, tlb_indexed }; + +static __init void build_tlb_write_entry(u32 **p, struct label **l, + struct reloc **r, + enum tlb_write_entry wmode) { + void(*tlbw)(u32 **) = NULL; + + switch (wmode) { + case tlb_random: tlbw = i_tlbwr; break; + case tlb_indexed: tlbw = i_tlbwi; break; + } + switch (current_cpu_data.cputype) { case CPU_R4000PC: case CPU_R4000SC: @@ -753,11 +822,11 @@ static __init void build_tlb_write_rando case CPU_R4400MC: /* * This branch uses up a mtc0 hazard nop slot and saves - * two nops after the tlbwr. + * two nops after the tlbw instruction. */ - il_bgezl(p, r, 0, label_tlbwr_hazard); - i_tlbwr(p); - l_tlbwr_hazard(l, *p); + il_bgezl(p, r, 0, label_tlbw_hazard); + tlbw(p); + l_tlbw_hazard(l, *p); i_nop(p); break; @@ -766,12 +835,13 @@ static __init void build_tlb_write_rando case CPU_R5000: case CPU_R5000A: case CPU_5KC: + case CPU_TX49XX: case CPU_AU1000: case CPU_AU1100: case CPU_AU1500: case CPU_AU1550: i_nop(p); - i_tlbwr(p); + tlbw(p); break; case CPU_R10000: @@ -781,24 +851,32 @@ static __init void build_tlb_write_rando case CPU_4KSC: case CPU_20KC: case CPU_25KF: - i_tlbwr(p); + tlbw(p); break; case CPU_NEVADA: i_nop(p); /* QED specifies 2 nops hazard */ /* * This branch uses up a mtc0 hazard nop slot and saves - * a nop after the tlbwr. + * a nop after the tlbw instruction. */ - il_bgezl(p, r, 0, label_tlbwr_hazard); - i_tlbwr(p); - l_tlbwr_hazard(l, *p); + il_bgezl(p, r, 0, label_tlbw_hazard); + tlbw(p); + l_tlbw_hazard(l, *p); + break; + + case CPU_RM7000: + i_nop(p); + i_nop(p); + i_nop(p); + i_nop(p); + tlbw(p); break; case CPU_4KEC: case CPU_24K: i_ehb(p); - i_tlbwr(p); + tlbw(p); break; case CPU_RM9000: @@ -812,13 +890,32 @@ static __init void build_tlb_write_rando i_ssnop(p); i_ssnop(p); i_ssnop(p); - i_tlbwr(p); + tlbw(p); i_ssnop(p); i_ssnop(p); i_ssnop(p); i_ssnop(p); break; + case CPU_VR4111: + case CPU_VR4121: + case CPU_VR4122: + case CPU_VR4181: + case CPU_VR4181A: + i_nop(p); + i_nop(p); + tlbw(p); + i_nop(p); + i_nop(p); + break; + + case CPU_VR4131: + case CPU_VR4133: + i_nop(p); + i_nop(p); + tlbw(p); + break; + default: panic("No TLB refill handler yet (CPU type: %d)", current_cpu_data.cputype); @@ -826,7 +923,7 @@ static __init void build_tlb_write_rando } } -#if CONFIG_MIPS64 +#ifdef CONFIG_MIPS64 /* * TMP and PTR are scratch. * TMP will be clobbered, PTR will hold the pmd entry. @@ -844,7 +941,7 @@ build_get_pmde64(u32 **p, struct label * il_bltz(p, r, tmp, label_vmalloc); /* No i_nop needed here, since the next insn doesn't touch TMP. */ -# ifdef CONFIG_SMP +#ifdef CONFIG_SMP /* * 64 bit SMP has the lower part of &pgd_current[smp_processor_id()] * stored in CONTEXT. @@ -852,7 +949,17 @@ build_get_pmde64(u32 **p, struct label * if (in_compat_space_p(pgdc)) { i_dmfc0(p, ptr, C0_CONTEXT); i_dsra(p, ptr, ptr, 23); + i_ld(p, ptr, 0, ptr); } else { +#ifdef CONFIG_BUILD_ELF64 + i_dmfc0(p, ptr, C0_CONTEXT); + i_dsrl(p, ptr, ptr, 23); + i_dsll(p, ptr, ptr, 3); + i_LA_mostly(p, tmp, pgdc); + i_daddu(p, ptr, ptr, tmp); + i_dmfc0(p, tmp, C0_BADVADDR); + i_ld(p, ptr, rel_lo(pgdc), ptr); +#else i_dmfc0(p, ptr, C0_CONTEXT); i_lui(p, tmp, rel_highest(pgdc)); i_dsll(p, ptr, ptr, 9); @@ -860,12 +967,13 @@ build_get_pmde64(u32 **p, struct label * i_dsrl32(p, ptr, ptr, 0); i_and(p, ptr, ptr, tmp); i_dmfc0(p, tmp, C0_BADVADDR); + i_ld(p, ptr, 0, ptr); +#endif } - i_ld(p, ptr, 0, ptr); -# else +#else i_LA_mostly(p, ptr, pgdc); i_ld(p, ptr, rel_lo(pgdc), ptr); -# endif +#endif l_vmalloc_done(l, *p); i_dsrl(p, tmp, tmp, PGDIR_SHIFT-3); /* get pgd offset in bytes */ @@ -902,13 +1010,14 @@ build_get_pgd_vmalloc64(u32 **p, struct } } -#else /* CONFIG_MIPS32 */ +#else /* !CONFIG_MIPS64 */ /* * TMP and PTR are scratch. * TMP will be clobbered, PTR will hold the pgd entry. */ -static __init void build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr) +static __init void __attribute__((unused)) +build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr) { long pgdc = (long)pgd_current; @@ -928,17 +1037,13 @@ static __init void build_get_pgde32(u32 i_sll(p, tmp, tmp, PGD_T_LOG2); i_addu(p, ptr, ptr, tmp); /* add in pgd offset */ } -#endif /* CONFIG_MIPS32 */ + +#endif /* !CONFIG_MIPS64 */ static __init void build_adjust_context(u32 **p, unsigned int ctx) { - unsigned int shift = 0; - unsigned int mask = 0xff0; - -#if !defined(CONFIG_MIPS64) && !defined(CONFIG_64BIT_PHYS_ADDR) - shift++; - mask |= 0x008; -#endif + unsigned int shift = 4 - (PTE_T_LOG2 + 1); + unsigned int mask = (PTRS_PER_PTE / 2 - 1) << (PTE_T_LOG2 + 1); switch (current_cpu_data.cputype) { case CPU_VR41XX: @@ -994,7 +1099,7 @@ static __init void build_update_entries( * Kernel is a special case. Only a few CPUs use it. */ #ifdef CONFIG_64BIT_PHYS_ADDR - if (cpu_has_64bit_gp_regs) { + if (cpu_has_64bits) { i_ld(p, tmp, 0, ptep); /* get even pte */ i_ld(p, ptep, sizeof(pte_t), ptep); /* get odd pte */ i_dsrl(p, tmp, tmp, 6); /* convert to entrylo0 */ @@ -1049,20 +1154,20 @@ static void __init build_r4000_tlb_refil i_MFC0(&p, K0, C0_BADVADDR); i_MFC0(&p, K1, C0_ENTRYHI); i_xor(&p, K0, K0, K1); - i_SRL(&p, K0, K0, PAGE_SHIFT+1); + i_SRL(&p, K0, K0, PAGE_SHIFT + 1); il_bnez(&p, &r, K0, label_leave); /* No need for i_nop */ } #ifdef CONFIG_MIPS64 - build_get_pmde64(&p, &l, &r, K0, K1); /* get pmd ptr in K1 */ + build_get_pmde64(&p, &l, &r, K0, K1); /* get pmd in K1 */ #else - build_get_pgde32(&p, K0, K1); /* get pgd ptr in K1 */ + build_get_pgde32(&p, K0, K1); /* get pgd in K1 */ #endif build_get_ptep(&p, K0, K1); build_update_entries(&p, K0, K1); - build_tlb_write_random_entry(&p, &l, &r); + build_tlb_write_entry(&p, &l, &r, tlb_random); l_leave(&l, p); i_eret(&p); /* return from trap */ @@ -1121,6 +1226,7 @@ static void __init build_r4000_tlb_refil i_nop(&f); else { copy_handler(relocs, labels, split, split + 1, f); + move_labels(labels, f, f + 1, -1); f++; split++; } @@ -1132,7 +1238,8 @@ static void __init build_r4000_tlb_refil #endif /* CONFIG_MIPS64 */ resolve_relocs(relocs, labels); - printk("Synthesized TLB handler (%u instructions).\n", final_len); + printk("Synthesized TLB refill handler (%u instructions).\n", + final_len); #ifdef DEBUG_TLB { @@ -1147,10 +1254,530 @@ static void __init build_r4000_tlb_refil flush_icache_range(CAC_BASE, CAC_BASE + 0x100); } +/* + * TLB load/store/modify handlers. + * + * Only the fastpath gets synthesized at runtime, the slowpath for + * do_page_fault remains normal asm. + */ +extern void tlb_do_page_fault_0(void); +extern void tlb_do_page_fault_1(void); + +#define __tlb_handler_align \ + __attribute__((__aligned__(1 << CONFIG_MIPS_L1_CACHE_SHIFT))) + +/* + * 128 instructions for the fastpath handler is generous and should + * never be exceeded. + */ +#define FASTPATH_SIZE 128 + +u32 __tlb_handler_align handle_tlbl[FASTPATH_SIZE]; +u32 __tlb_handler_align handle_tlbs[FASTPATH_SIZE]; +u32 __tlb_handler_align handle_tlbm[FASTPATH_SIZE]; + +static void __init +iPTE_LW(u32 **p, struct label **l, unsigned int pte, int offset, + unsigned int ptr) +{ +#ifdef CONFIG_SMP +# ifdef CONFIG_64BIT_PHYS_ADDR + if (cpu_has_64bits) + i_lld(p, pte, offset, ptr); + else +# endif + i_LL(p, pte, offset, ptr); +#else +# ifdef CONFIG_64BIT_PHYS_ADDR + if (cpu_has_64bits) + i_ld(p, pte, offset, ptr); + else +# endif + i_LW(p, pte, offset, ptr); +#endif +} + +static void __init +iPTE_SW(u32 **p, struct reloc **r, unsigned int pte, int offset, + unsigned int ptr) +{ +#ifdef CONFIG_SMP +# ifdef CONFIG_64BIT_PHYS_ADDR + if (cpu_has_64bits) + i_scd(p, pte, offset, ptr); + else +# endif + i_SC(p, pte, offset, ptr); + + if (r10000_llsc_war()) + il_beqzl(p, r, pte, label_smp_pgtable_change); + else + il_beqz(p, r, pte, label_smp_pgtable_change); + +# ifdef CONFIG_64BIT_PHYS_ADDR + if (!cpu_has_64bits) { + /* no i_nop needed */ + i_ll(p, pte, sizeof(pte_t) / 2, ptr); + i_ori(p, pte, pte, _PAGE_VALID); + i_sc(p, pte, sizeof(pte_t) / 2, ptr); + il_beqz(p, r, pte, label_smp_pgtable_change); + /* no i_nop needed */ + i_lw(p, pte, 0, ptr); + } else + i_nop(p); +# else + i_nop(p); +# endif +#else +# ifdef CONFIG_64BIT_PHYS_ADDR + if (cpu_has_64bits) + i_sd(p, pte, offset, ptr); + else +# endif + i_SW(p, pte, offset, ptr); + +# ifdef CONFIG_64BIT_PHYS_ADDR + if (!cpu_has_64bits) { + i_lw(p, pte, sizeof(pte_t) / 2, ptr); + i_ori(p, pte, pte, _PAGE_VALID); + i_sw(p, pte, sizeof(pte_t) / 2, ptr); + i_lw(p, pte, 0, ptr); + } +# endif +#endif +} + +/* + * Check if PTE is present, if not then jump to LABEL. PTR points to + * the page table where this PTE is located, PTE will be re-loaded + * with it's original value. + */ +static void __init +build_pte_present(u32 **p, struct label **l, struct reloc **r, + unsigned int pte, unsigned int ptr, enum label_id lid) +{ + i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_READ); + i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_READ); + il_bnez(p, r, pte, lid); + iPTE_LW(p, l, pte, 0, ptr); +} + +/* Make PTE valid, store result in PTR. */ +static void __init +build_make_valid(u32 **p, struct reloc **r, unsigned int pte, + unsigned int ptr) +{ + i_ori(p, pte, pte, _PAGE_VALID | _PAGE_ACCESSED); + iPTE_SW(p, r, pte, 0, ptr); +} + +/* + * Check if PTE can be written to, if not branch to LABEL. Regardless + * restore PTE with value from PTR when done. + */ +static void __init +build_pte_writable(u32 **p, struct label **l, struct reloc **r, + unsigned int pte, unsigned int ptr, enum label_id lid) +{ + i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE); + i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE); + il_bnez(p, r, pte, lid); + iPTE_LW(p, l, pte, 0, ptr); +} + +/* Make PTE writable, update software status bits as well, then store + * at PTR. + */ +static void __init +build_make_write(u32 **p, struct reloc **r, unsigned int pte, + unsigned int ptr) +{ + i_ori(p, pte, pte, + _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID | _PAGE_DIRTY); + iPTE_SW(p, r, pte, 0, ptr); +} + +/* + * Check if PTE can be modified, if not branch to LABEL. Regardless + * restore PTE with value from PTR when done. + */ +static void __init +build_pte_modifiable(u32 **p, struct label **l, struct reloc **r, + unsigned int pte, unsigned int ptr, enum label_id lid) +{ + i_andi(p, pte, pte, _PAGE_WRITE); + il_beqz(p, r, pte, lid); + iPTE_LW(p, l, pte, 0, ptr); +} + +/* + * R3000 style TLB load/store/modify handlers. + */ + +/* This places the pte in the page table at PTR into ENTRYLO0. */ +static void __init +build_r3000_pte_reload(u32 **p, unsigned int ptr) +{ + i_lw(p, ptr, 0, ptr); + i_nop(p); /* load delay */ + i_mtc0(p, ptr, C0_ENTRYLO0); + i_nop(p); /* cp0 delay */ +} + +/* + * The index register may have the probe fail bit set, + * because we would trap on access kseg2, i.e. without refill. + */ +static void __init +build_r3000_tlb_write(u32 **p, struct label **l, struct reloc **r, + unsigned int tmp) +{ + i_mfc0(p, tmp, C0_INDEX); + i_nop(p); /* cp0 delay */ + il_bltz(p, r, tmp, label_r3000_write_probe_fail); + i_nop(p); /* branch delay */ + i_tlbwi(p); + il_b(p, r, label_r3000_write_probe_ok); + i_nop(p); /* branch delay */ + l_r3000_write_probe_fail(l, *p); + i_tlbwr(p); + l_r3000_write_probe_ok(l, *p); +} + +static void __init +build_r3000_tlbchange_handler_head(u32 **p, unsigned int pte, + unsigned int ptr) +{ + long pgdc = (long)pgd_current; + + i_mfc0(p, pte, C0_BADVADDR); + i_lui(p, ptr, rel_hi(pgdc)); /* cp0 delay */ + i_lw(p, ptr, rel_lo(pgdc), ptr); + i_srl(p, pte, pte, 22); /* load delay */ + i_sll(p, pte, pte, 2); + i_addu(p, ptr, ptr, pte); + i_mfc0(p, pte, C0_CONTEXT); + i_lw(p, ptr, 0, ptr); /* cp0 delay */ + i_andi(p, pte, pte, 0xffc); /* load delay */ + i_addu(p, ptr, ptr, pte); + i_lw(p, pte, 0, ptr); + i_nop(p); /* load delay */ + i_tlbp(p); +} + +static void __init +build_r3000_tlbchange_handler_tail(u32 **p, unsigned int tmp) +{ + i_mfc0(p, tmp, C0_EPC); + i_nop(p); /* cp0 delay */ + i_jr(p, tmp); + i_rfe(p); /* branch delay */ +} + +static void __init build_r3000_tlb_load_handler(void) +{ + u32 *p = handle_tlbl; + struct label *l = labels; + struct reloc *r = relocs; + + memset(handle_tlbl, 0, sizeof(handle_tlbl)); + memset(labels, 0, sizeof(labels)); + memset(relocs, 0, sizeof(relocs)); + + build_r3000_tlbchange_handler_head(&p, K0, K1); + build_pte_present(&p, &l, &r, K0, K1, label_nopage_tlbl); + build_make_valid(&p, &r, K0, K1); + build_r3000_pte_reload(&p, K1); + build_r3000_tlb_write(&p, &l, &r, K0); + build_r3000_tlbchange_handler_tail(&p, K0); + + l_nopage_tlbl(&l, p); + i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff); + i_nop(&p); + + if ((p - handle_tlbl) > FASTPATH_SIZE) + panic("TLB load handler fastpath space exceeded"); + + resolve_relocs(relocs, labels); + printk("Synthesized TLB load handler fastpath (%u instructions).\n", + (unsigned int)(p - handle_tlbl)); + +#ifdef DEBUG_TLB + { + int i; + + for (i = 0; i < FASTPATH_SIZE; i++) + printk("%08x\n", handle_tlbl[i]); + } +#endif + + flush_icache_range((unsigned long)handle_tlbl, + (unsigned long)handle_tlbl + FASTPATH_SIZE * sizeof(u32)); +} + +static void __init build_r3000_tlb_store_handler(void) +{ + u32 *p = handle_tlbs; + struct label *l = labels; + struct reloc *r = relocs; + + memset(handle_tlbs, 0, sizeof(handle_tlbs)); + memset(labels, 0, sizeof(labels)); + memset(relocs, 0, sizeof(relocs)); + + build_r3000_tlbchange_handler_head(&p, K0, K1); + build_pte_writable(&p, &l, &r, K0, K1, label_nopage_tlbs); + build_make_write(&p, &r, K0, K1); + build_r3000_pte_reload(&p, K1); + build_r3000_tlb_write(&p, &l, &r, K0); + build_r3000_tlbchange_handler_tail(&p, K0); + + l_nopage_tlbs(&l, p); + i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff); + i_nop(&p); + + if ((p - handle_tlbs) > FASTPATH_SIZE) + panic("TLB store handler fastpath space exceeded"); + + resolve_relocs(relocs, labels); + printk("Synthesized TLB store handler fastpath (%u instructions).\n", + (unsigned int)(p - handle_tlbs)); + +#ifdef DEBUG_TLB + { + int i; + + for (i = 0; i < FASTPATH_SIZE; i++) + printk("%08x\n", handle_tlbs[i]); + } +#endif + + flush_icache_range((unsigned long)handle_tlbs, + (unsigned long)handle_tlbs + FASTPATH_SIZE * sizeof(u32)); +} + +static void __init build_r3000_tlb_modify_handler(void) +{ + u32 *p = handle_tlbm; + struct label *l = labels; + struct reloc *r = relocs; + + memset(handle_tlbm, 0, sizeof(handle_tlbm)); + memset(labels, 0, sizeof(labels)); + memset(relocs, 0, sizeof(relocs)); + + build_r3000_tlbchange_handler_head(&p, K0, K1); + build_pte_modifiable(&p, &l, &r, K0, K1, label_nopage_tlbm); + build_make_write(&p, &r, K0, K1); + build_r3000_pte_reload(&p, K1); + i_tlbwi(&p); + build_r3000_tlbchange_handler_tail(&p, K0); + + l_nopage_tlbm(&l, p); + i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff); + i_nop(&p); + + if ((p - handle_tlbm) > FASTPATH_SIZE) + panic("TLB modify handler fastpath space exceeded"); + + resolve_relocs(relocs, labels); + printk("Synthesized TLB modify handler fastpath (%u instructions).\n", + (unsigned int)(p - handle_tlbm)); + +#ifdef DEBUG_TLB + { + int i; + + for (i = 0; i < FASTPATH_SIZE; i++) + printk("%08x\n", handle_tlbm[i]); + } +#endif + + flush_icache_range((unsigned long)handle_tlbm, + (unsigned long)handle_tlbm + FASTPATH_SIZE * sizeof(u32)); +} + +/* + * R4000 style TLB load/store/modify handlers. + */ +static void __init +build_r4000_tlbchange_handler_head(u32 **p, struct label **l, + struct reloc **r, unsigned int pte, + unsigned int ptr) +{ +#ifdef CONFIG_MIPS64 + build_get_pmde64(p, l, r, pte, ptr); /* get pmd in ptr */ +#else + build_get_pgde32(p, pte, ptr); /* get pgd in ptr */ +#endif + + i_MFC0(p, pte, C0_BADVADDR); + i_LW(p, ptr, 0, ptr); + i_SRL(p, pte, pte, PAGE_SHIFT + PTE_ORDER - PTE_T_LOG2); + i_andi(p, pte, pte, (PTRS_PER_PTE - 1) << PTE_T_LOG2); + i_ADDU(p, ptr, ptr, pte); + +#ifdef CONFIG_SMP + l_smp_pgtable_change(l, *p); +# endif + iPTE_LW(p, l, pte, 0, ptr); /* get even pte */ + build_tlb_probe_entry(p); +} + +static void __init +build_r4000_tlbchange_handler_tail(u32 **p, struct label **l, + struct reloc **r, unsigned int tmp, + unsigned int ptr) +{ + i_ori(p, ptr, ptr, sizeof(pte_t)); + i_xori(p, ptr, ptr, sizeof(pte_t)); + build_update_entries(p, tmp, ptr); + build_tlb_write_entry(p, l, r, tlb_indexed); + l_leave(l, *p); + i_eret(p); /* return from trap */ + +#ifdef CONFIG_MIPS64 + build_get_pgd_vmalloc64(p, l, r, tmp, ptr); +#endif +} + +static void __init build_r4000_tlb_load_handler(void) +{ + u32 *p = handle_tlbl; + struct label *l = labels; + struct reloc *r = relocs; + + memset(handle_tlbl, 0, sizeof(handle_tlbl)); + memset(labels, 0, sizeof(labels)); + memset(relocs, 0, sizeof(relocs)); + + if (bcm1250_m3_war()) { + i_MFC0(&p, K0, C0_BADVADDR); + i_MFC0(&p, K1, C0_ENTRYHI); + i_xor(&p, K0, K0, K1); + i_SRL(&p, K0, K0, PAGE_SHIFT + 1); + il_bnez(&p, &r, K0, label_leave); + /* No need for i_nop */ + } + + build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1); + build_pte_present(&p, &l, &r, K0, K1, label_nopage_tlbl); + build_make_valid(&p, &r, K0, K1); + build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1); + + l_nopage_tlbl(&l, p); + i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff); + i_nop(&p); + + if ((p - handle_tlbl) > FASTPATH_SIZE) + panic("TLB load handler fastpath space exceeded"); + + resolve_relocs(relocs, labels); + printk("Synthesized TLB load handler fastpath (%u instructions).\n", + (unsigned int)(p - handle_tlbl)); + +#ifdef DEBUG_TLB + { + int i; + + for (i = 0; i < FASTPATH_SIZE; i++) + printk("%08x\n", handle_tlbl[i]); + } +#endif + + flush_icache_range((unsigned long)handle_tlbl, + (unsigned long)handle_tlbl + FASTPATH_SIZE * sizeof(u32)); +} + +static void __init build_r4000_tlb_store_handler(void) +{ + u32 *p = handle_tlbs; + struct label *l = labels; + struct reloc *r = relocs; + + memset(handle_tlbs, 0, sizeof(handle_tlbs)); + memset(labels, 0, sizeof(labels)); + memset(relocs, 0, sizeof(relocs)); + + build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1); + build_pte_writable(&p, &l, &r, K0, K1, label_nopage_tlbs); + build_make_write(&p, &r, K0, K1); + build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1); + + l_nopage_tlbs(&l, p); + i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff); + i_nop(&p); + + if ((p - handle_tlbs) > FASTPATH_SIZE) + panic("TLB store handler fastpath space exceeded"); + + resolve_relocs(relocs, labels); + printk("Synthesized TLB store handler fastpath (%u instructions).\n", + (unsigned int)(p - handle_tlbs)); + +#ifdef DEBUG_TLB + { + int i; + + for (i = 0; i < FASTPATH_SIZE; i++) + printk("%08x\n", handle_tlbs[i]); + } +#endif + + flush_icache_range((unsigned long)handle_tlbs, + (unsigned long)handle_tlbs + FASTPATH_SIZE * sizeof(u32)); +} + +static void __init build_r4000_tlb_modify_handler(void) +{ + u32 *p = handle_tlbm; + struct label *l = labels; + struct reloc *r = relocs; + + memset(handle_tlbm, 0, sizeof(handle_tlbm)); + memset(labels, 0, sizeof(labels)); + memset(relocs, 0, sizeof(relocs)); + + build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1); + build_pte_modifiable(&p, &l, &r, K0, K1, label_nopage_tlbm); + /* Present and writable bits set, set accessed and dirty bits. */ + build_make_write(&p, &r, K0, K1); + build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1); + + l_nopage_tlbm(&l, p); + i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff); + i_nop(&p); + + if ((p - handle_tlbm) > FASTPATH_SIZE) + panic("TLB modify handler fastpath space exceeded"); + + resolve_relocs(relocs, labels); + printk("Synthesized TLB modify handler fastpath (%u instructions).\n", + (unsigned int)(p - handle_tlbm)); + +#ifdef DEBUG_TLB + { + int i; + + for (i = 0; i < FASTPATH_SIZE; i++) + printk("%08x\n", handle_tlbm[i]); + } +#endif + + flush_icache_range((unsigned long)handle_tlbm, + (unsigned long)handle_tlbm + FASTPATH_SIZE * sizeof(u32)); +} + void __init build_tlb_refill_handler(void) { + /* + * The refill handler is generated per-CPU, multi-node systems + * may have local storage for it. The other handlers are only + * needed once. + */ + static int run_once = 0; + switch (current_cpu_data.cputype) { -#ifdef CONFIG_MIPS32 case CPU_R2000: case CPU_R3000: case CPU_R3000A: @@ -1159,13 +1786,18 @@ void __init build_tlb_refill_handler(voi case CPU_TX3922: case CPU_TX3927: build_r3000_tlb_refill_handler(); + if (!run_once) { + build_r3000_tlb_load_handler(); + build_r3000_tlb_store_handler(); + build_r3000_tlb_modify_handler(); + run_once++; + } break; case CPU_R6000: case CPU_R6000A: panic("No R6000 TLB refill handler yet"); break; -#endif case CPU_R8000: panic("No R8000 TLB refill handler yet"); @@ -1173,5 +1805,11 @@ void __init build_tlb_refill_handler(voi default: build_r4000_tlb_refill_handler(); + if (!run_once) { + build_r4000_tlb_load_handler(); + build_r4000_tlb_store_handler(); + build_r4000_tlb_modify_handler(); + run_once++; + } } } diff -puN /dev/null arch/mips/mm/tlbex-fault.S --- /dev/null 2003-09-15 06:40:47.000000000 -0700 +++ 25-akpm/arch/mips/mm/tlbex-fault.S 2005-01-29 11:25:48.788452336 -0800 @@ -0,0 +1,28 @@ +/* + * 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) 1999 Ralf Baechle + * Copyright (C) 1999 Silicon Graphics, Inc. + */ +#include +#include +#include +#include + + .macro tlb_do_page_fault, write + NESTED(tlb_do_page_fault_\write, PT_SIZE, sp) + SAVE_ALL + MFC0 a2, CP0_BADVADDR + KMODE + move a0, sp + REG_S a2, PT_BVADDR(sp) + li a1, \write + jal do_page_fault + j ret_from_exception + END(tlb_do_page_fault_\write) + .endm + + tlb_do_page_fault 0 + tlb_do_page_fault 1 diff -puN arch/mips/mm/tlb-sb1.c~mips-generic-mips-updates arch/mips/mm/tlb-sb1.c --- 25/arch/mips/mm/tlb-sb1.c~mips-generic-mips-updates 2005-01-29 11:25:48.679468904 -0800 +++ 25-akpm/arch/mips/mm/tlb-sb1.c 2005-01-29 11:25:48.788452336 -0800 @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include #include #include #include @@ -25,7 +24,7 @@ extern void build_tlb_refill_handler(void); -#define UNIQUE_ENTRYHI(idx) (KSEG0 + ((idx) << (PAGE_SHIFT + 1))) +#define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1))) /* Dump the current entry* and pagemask registers */ static inline void dump_cur_tlb_regs(void) diff -puN /dev/null arch/mips/oprofile/common.c --- /dev/null 2003-09-15 06:40:47.000000000 -0700 +++ 25-akpm/arch/mips/oprofile/common.c 2005-01-29 11:25:48.789452184 -0800 @@ -0,0 +1,106 @@ +/* + * 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) 2004 by Ralf Baechle + */ +#include +#include +#include +#include +#include + +#include "op_impl.h" + +extern struct op_mips_model op_model_mipsxx __attribute__((weak)); +extern struct op_mips_model op_model_rm9000 __attribute__((weak)); + +static struct op_mips_model *model; + +static struct op_counter_config ctr[20]; + +static int op_mips_setup(void) +{ + /* Pre-compute the values to stuff in the hardware registers. */ + model->reg_setup(ctr); + + /* Configure the registers on all cpus. */ + on_each_cpu(model->cpu_setup, 0, 0, 1); + + return 0; +} + +static int op_mips_create_files(struct super_block * sb, struct dentry * root) +{ + int i; + + for (i = 0; i < model->num_counters; ++i) { + struct dentry *dir; + char buf[3]; + + snprintf(buf, sizeof buf, "%d", i); + dir = oprofilefs_mkdir(sb, root, buf); + + oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled); + oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event); + oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count); + /* Dummies. */ + oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel); + oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user); + oprofilefs_create_ulong(sb, dir, "exl", &ctr[i].exl); + oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask); + } + + return 0; +} + +static int op_mips_start(void) +{ + on_each_cpu(model->cpu_start, NULL, 0, 1); + + return 0; +} + +static void op_mips_stop(void) +{ + /* Disable performance monitoring for all counters. */ + on_each_cpu(model->cpu_stop, NULL, 0, 1); +} + +void __init oprofile_arch_init(struct oprofile_operations *ops) +{ + struct op_mips_model *lmodel = NULL; + + switch (current_cpu_data.cputype) { + case CPU_24K: + lmodel = &op_model_mipsxx; + break; + + case CPU_RM9000: + lmodel = &op_model_rm9000; + break; + }; + + if (!lmodel) + return; + + if (lmodel->init()) + return; + + model = lmodel; + + ops->create_files = op_mips_create_files; + ops->setup = op_mips_setup; + ops->start = op_mips_start; + ops->stop = op_mips_stop; + ops->cpu_type = lmodel->cpu_type; + + printk(KERN_INFO "oprofile: using %s performance monitoring.\n", + lmodel->cpu_type); +} + +void oprofile_arch_exit(void) +{ + model->exit(); +} diff -puN /dev/null arch/mips/oprofile/Kconfig --- /dev/null 2003-09-15 06:40:47.000000000 -0700 +++ 25-akpm/arch/mips/oprofile/Kconfig 2005-01-29 11:25:48.790452032 -0800 @@ -0,0 +1,23 @@ + +menu "Profiling support" + depends on EXPERIMENTAL + +config PROFILING + bool "Profiling support (EXPERIMENTAL)" + help + Say Y here to enable the extended profiling support mechanisms used + by profilers such as OProfile. + + +config OPROFILE + tristate "OProfile system profiling (EXPERIMENTAL)" + depends on PROFILING + help + OProfile is a profiling system capable of profiling the + whole system, include the kernel, kernel modules, libraries, + and applications. + + If unsure, say N. + +endmenu + diff -puN /dev/null arch/mips/oprofile/Makefile --- /dev/null 2003-09-15 06:40:47.000000000 -0700 +++ 25-akpm/arch/mips/oprofile/Makefile 2005-01-29 11:25:48.790452032 -0800 @@ -0,0 +1,15 @@ +EXTRA_CFLAGS := -Werror + +obj-$(CONFIG_OPROFILE) += oprofile.o + +DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ + oprof.o cpu_buffer.o buffer_sync.o \ + event_buffer.o oprofile_files.o \ + oprofilefs.o oprofile_stats.o \ + timer_int.o ) + +oprofile-y := $(DRIVER_OBJS) common.o + +oprofile-$(CONFIG_CPU_MIPS32) += op_model_mipsxx.o +oprofile-$(CONFIG_CPU_MIPS64) += op_model_mipsxx.o +oprofile-$(CONFIG_CPU_RM9000) += op_model_rm9000.o diff -puN /dev/null arch/mips/oprofile/op_impl.h --- /dev/null 2003-09-15 06:40:47.000000000 -0700 +++ 25-akpm/arch/mips/oprofile/op_impl.h 2005-01-29 11:25:48.790452032 -0800 @@ -0,0 +1,37 @@ +/** + * @file arch/alpha/oprofile/op_impl.h + * + * @remark Copyright 2002 OProfile authors + * @remark Read the file COPYING + * + * @author Richard Henderson + */ + +#ifndef OP_IMPL_H +#define OP_IMPL_H 1 + +/* Per-counter configuration as set via oprofilefs. */ +struct op_counter_config { + unsigned long enabled; + unsigned long event; + unsigned long count; + /* Dummies because I am too lazy to hack the userspace tools. */ + unsigned long kernel; + unsigned long user; + unsigned long exl; + unsigned long unit_mask; +}; + +/* Per-architecture configury and hooks. */ +struct op_mips_model { + void (*reg_setup) (struct op_counter_config *); + void (*cpu_setup) (void * dummy); + int (*init)(void); + void (*exit)(void); + void (*cpu_start)(void *args); + void (*cpu_stop)(void *args); + char *cpu_type; + unsigned char num_counters; +}; + +#endif diff -puN /dev/null arch/mips/oprofile/op_model_rm9000.c --- /dev/null 2003-09-15 06:40:47.000000000 -0700 +++ 25-akpm/arch/mips/oprofile/op_model_rm9000.c 2005-01-29 11:25:48.791451880 -0800 @@ -0,0 +1,137 @@ +/* + * 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) 2004 by Ralf Baechle + */ +#include +#include +#include + +#include "op_impl.h" + +#define RM9K_COUNTER1_EVENT(event) ((event) << 0) +#define RM9K_COUNTER1_SUPERVISOR (1ULL << 7) +#define RM9K_COUNTER1_KERNEL (1ULL << 8) +#define RM9K_COUNTER1_USER (1ULL << 9) +#define RM9K_COUNTER1_ENABLE (1ULL << 10) +#define RM9K_COUNTER1_OVERFLOW (1ULL << 15) + +#define RM9K_COUNTER2_EVENT(event) ((event) << 16) +#define RM9K_COUNTER2_SUPERVISOR (1ULL << 23) +#define RM9K_COUNTER2_KERNEL (1ULL << 24) +#define RM9K_COUNTER2_USER (1ULL << 25) +#define RM9K_COUNTER2_ENABLE (1ULL << 26) +#define RM9K_COUNTER2_OVERFLOW (1ULL << 31) + +extern unsigned int rm9000_perfcount_irq; + +static struct rm9k_register_config { + unsigned int control; + unsigned int reset_counter1; + unsigned int reset_counter2; +} reg; + +/* Compute all of the registers in preparation for enabling profiling. */ + +static void rm9000_reg_setup(struct op_counter_config *ctr) +{ + unsigned int control = 0; + + /* Compute the performance counter control word. */ + /* For now count kernel and user mode */ + if (ctr[0].enabled) + control |= RM9K_COUNTER1_EVENT(ctr[0].event) | + RM9K_COUNTER1_KERNEL | + RM9K_COUNTER1_USER | + RM9K_COUNTER1_ENABLE; + if (ctr[1].enabled) + control |= RM9K_COUNTER2_EVENT(ctr[1].event) | + RM9K_COUNTER2_KERNEL | + RM9K_COUNTER2_USER | + RM9K_COUNTER2_ENABLE; + reg.control = control; + + reg.reset_counter1 = 0x80000000 - ctr[0].count; + reg.reset_counter2 = 0x80000000 - ctr[1].count; +} + +/* Program all of the registers in preparation for enabling profiling. */ + +static void rm9000_cpu_setup (void *args) +{ + uint64_t perfcount; + + perfcount = ((uint64_t) reg.reset_counter2 << 32) | reg.reset_counter1; + write_c0_perfcount(perfcount); +} + +static void rm9000_cpu_start(void *args) +{ + /* Start all counters on current CPU */ + write_c0_perfcontrol(reg.control); +} + +static void rm9000_cpu_stop(void *args) +{ + /* Stop all counters on current CPU */ + write_c0_perfcontrol(0); +} + +static irqreturn_t rm9000_perfcount_handler(int irq, void * dev_id, + struct pt_regs *regs) +{ + unsigned int control = read_c0_perfcontrol(); + uint32_t counter1, counter2; + uint64_t counters; + + /* + * RM9000 combines two 32-bit performance counters into a single + * 64-bit coprocessor zero register. To avoid a race updating the + * registers we need to stop the counters while we're messing with + * them ... + */ + write_c0_perfcontrol(0); + + counters = read_c0_perfcount(); + counter1 = counters; + counter2 = counters >> 32; + + if (control & RM9K_COUNTER1_OVERFLOW) { + oprofile_add_sample(regs, 0); + counter1 = reg.reset_counter1; + } + if (control & RM9K_COUNTER2_OVERFLOW) { + oprofile_add_sample(regs, 1); + counter2 = reg.reset_counter2; + } + + counters = ((uint64_t)counter2 << 32) | counter1; + write_c0_perfcount(counters); + write_c0_perfcontrol(reg.control); + + return IRQ_HANDLED; +} + +static int rm9000_init(void) +{ + return request_irq(rm9000_perfcount_irq, rm9000_perfcount_handler, + 0, "Perfcounter", NULL); +} + +static void rm9000_exit(void) +{ + free_irq(rm9000_perfcount_irq, NULL); +} + +struct op_mips_model op_model_rm9000 = { + .reg_setup = rm9000_reg_setup, + .cpu_setup = rm9000_cpu_setup, + .init = rm9000_init, + .exit = rm9000_exit, + .cpu_start = rm9000_cpu_start, + .cpu_stop = rm9000_cpu_stop, + .cpu_type = "mips/rm9000", + .num_counters = 2 +}; diff -puN arch/mips/pci/pci.c~mips-generic-mips-updates arch/mips/pci/pci.c --- 25/arch/mips/pci/pci.c~mips-generic-mips-updates 2005-01-29 11:25:48.682468448 -0800 +++ 25-akpm/arch/mips/pci/pci.c 2005-01-29 11:25:48.792451728 -0800 @@ -59,7 +59,7 @@ pcibios_align_resource(void *data, struc if (res->flags & IORESOURCE_IO) { /* Make sure we start at our min on all hoses */ - if (start - hose->io_resource->start < PCIBIOS_MIN_IO) + if (start < PCIBIOS_MIN_IO + hose->io_resource->start) start = PCIBIOS_MIN_IO + hose->io_resource->start; /* @@ -69,7 +69,7 @@ pcibios_align_resource(void *data, struc start = (start + 0x3ff) & ~0x3ff; } else if (res->flags & IORESOURCE_MEM) { /* Make sure we start at our min on all hoses */ - if (start - hose->mem_resource->start < PCIBIOS_MIN_MEM) + if (start < PCIBIOS_MIN_MEM + hose->mem_resource->start) start = PCIBIOS_MIN_MEM + hose->mem_resource->start; } @@ -294,6 +294,8 @@ pcibios_resource_to_bus(struct pci_dev * #ifdef CONFIG_HOTPLUG EXPORT_SYMBOL(pcibios_resource_to_bus); +EXPORT_SYMBOL(PCIBIOS_MIN_IO); +EXPORT_SYMBOL(PCIBIOS_MIN_MEM); #endif char *pcibios_setup(char *str) diff -puN include/asm-mips/addrspace.h~mips-generic-mips-updates include/asm-mips/addrspace.h --- 25/include/asm-mips/addrspace.h~mips-generic-mips-updates 2005-01-29 11:25:48.683468296 -0800 +++ 25-akpm/include/asm-mips/addrspace.h 2005-01-29 11:25:48.792451728 -0800 @@ -126,6 +126,7 @@ || defined (CONFIG_CPU_R4X00) \ || defined (CONFIG_CPU_R5000) \ || defined (CONFIG_CPU_NEVADA) \ + || defined (CONFIG_CPU_TX49XX) \ || defined (CONFIG_CPU_MIPS64) #define KUSIZE 0x0000010000000000 /* 2^^40 */ #define KUSIZE_64 0x0000010000000000 /* 2^^40 */ diff -puN include/asm-mips/bitops.h~mips-generic-mips-updates include/asm-mips/bitops.h --- 25/include/asm-mips/bitops.h~mips-generic-mips-updates 2005-01-29 11:25:48.685467992 -0800 +++ 25-akpm/include/asm-mips/bitops.h 2005-01-29 11:25:48.794451424 -0800 @@ -92,7 +92,7 @@ static inline void set_bit(unsigned long __bi_flags; a += nr >> SZLONG_LOG; - mask = 1 << (nr & SZLONG_MASK); + mask = 1UL << (nr & SZLONG_MASK); __bi_local_irq_save(flags); *a |= mask; __bi_local_irq_restore(flags); @@ -152,7 +152,7 @@ static inline void clear_bit(unsigned lo __bi_flags; a += nr >> SZLONG_LOG; - mask = 1 << (nr & SZLONG_MASK); + mask = 1UL << (nr & SZLONG_MASK); __bi_local_irq_save(flags); *a &= ~mask; __bi_local_irq_restore(flags); @@ -214,7 +214,7 @@ static inline void change_bit(unsigned l __bi_flags; a += nr >> SZLONG_LOG; - mask = 1 << (nr & SZLONG_MASK); + mask = 1UL << (nr & SZLONG_MASK); __bi_local_irq_save(flags); *a ^= mask; __bi_local_irq_restore(flags); @@ -293,7 +293,7 @@ static inline int test_and_set_bit(unsig __bi_flags; a += nr >> SZLONG_LOG; - mask = 1 << (nr & SZLONG_MASK); + mask = 1UL << (nr & SZLONG_MASK); __bi_local_irq_save(flags); retval = (mask & *a) != 0; *a |= mask; @@ -320,7 +320,7 @@ static inline int __test_and_set_bit(uns int retval; a += nr >> SZLONG_LOG; - mask = 1 << (nr & SZLONG_MASK); + mask = 1UL << (nr & SZLONG_MASK); retval = (mask & *a) != 0; *a |= mask; @@ -385,7 +385,7 @@ static inline int test_and_clear_bit(uns __bi_flags; a += nr >> SZLONG_LOG; - mask = 1 << (nr & SZLONG_MASK); + mask = 1UL << (nr & SZLONG_MASK); __bi_local_irq_save(flags); retval = (mask & *a) != 0; *a &= ~mask; @@ -474,7 +474,7 @@ static inline int test_and_change_bit(un __bi_flags; a += nr >> SZLONG_LOG; - mask = 1 << (nr & SZLONG_MASK); + mask = 1UL << (nr & SZLONG_MASK); __bi_local_irq_save(flags); retval = (mask & *a) != 0; *a ^= mask; diff -puN include/asm-mips/bootinfo.h~mips-generic-mips-updates include/asm-mips/bootinfo.h --- 25/include/asm-mips/bootinfo.h~mips-generic-mips-updates 2005-01-29 11:25:48.686467840 -0800 +++ 25-akpm/include/asm-mips/bootinfo.h 2005-01-29 11:25:48.794451424 -0800 @@ -195,6 +195,7 @@ #define MACH_CASIO_E55 5 /* CASIO CASSIOPEIA E-10/15/55/65 */ #define MACH_TANBAC_TB0226 6 /* TANBAC TB0226 (Mbase) */ #define MACH_TANBAC_TB0229 7 /* TANBAC TB0229 (VR4131DIMM) */ +#define MACH_NEC_CMBVR4133 8 /* CMB VR4133 Board */ #define MACH_GROUP_HP_LJ 20 /* Hewlett Packard LaserJet */ #define MACH_HP_LASERJET 1 diff -puN include/asm-mips/break.h~mips-generic-mips-updates include/asm-mips/break.h --- 25/include/asm-mips/break.h~mips-generic-mips-updates 2005-01-29 11:25:48.688467536 -0800 +++ 25-akpm/include/asm-mips/break.h 2005-01-29 11:25:48.794451424 -0800 @@ -27,7 +27,7 @@ #define BRK_STACKOVERFLOW 9 /* For Ada stackchecking */ #define BRK_NORLD 10 /* No rld found - not used by Linux/MIPS */ #define _BRK_THREADBP 11 /* For threads, user bp (used by debuggers) */ -#define BRK_MULOVF 1023 /* Multiply overflow */ #define BRK_BUG 512 /* Used by BUG() */ +#define BRK_MULOVF 1023 /* Multiply overflow */ #endif /* __ASM_BREAK_H */ diff -puN include/asm-mips/cpu-features.h~mips-generic-mips-updates include/asm-mips/cpu-features.h --- 25/include/asm-mips/cpu-features.h~mips-generic-mips-updates 2005-01-29 11:25:48.689467384 -0800 +++ 25-akpm/include/asm-mips/cpu-features.h 2005-01-29 11:25:48.795451272 -0800 @@ -3,11 +3,13 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2003 Ralf Baechle + * Copyright (C) 2003, 2004 Ralf Baechle */ #ifndef __ASM_CPU_FEATURES_H #define __ASM_CPU_FEATURES_H +#include + #include #include #include @@ -75,6 +77,25 @@ #endif /* + * I-Cache snoops remote store. This only matters on SMP. Some multiprocessors + * such as the R10000 have I-Caches that snoop local stores; the embedded ones + * don't. For maintaining I-cache coherency this means we need to flush the + * D-cache all the way back to whever the I-cache does refills from, so the + * I-cache has a chance to see the new data at all. Then we have to flush the + * I-cache also. + * Note we may have been rescheduled and may no longer be running on the CPU + * that did the store so we can't optimize this into only doing the flush on + * the local CPU. + */ +#ifndef cpu_icache_snoops_remote_store +#ifdef CONFIG_SMP +#define cpu_icache_snoops_remote_store (cpu_data[0].icache.flags & MIPS_IC_SNOOPS_REMOTE) +#else +#define cpu_icache_snoops_remote_store 1 +#endif +#endif + +/* * Certain CPUs may throw bizarre exceptions if not the whole cacheline * contains valid instructions. For these we ensure proper alignment of * signal trampolines and pad them to the size of a full cache lines with diff -puN include/asm-mips/cpu-info.h~mips-generic-mips-updates include/asm-mips/cpu-info.h --- 25/include/asm-mips/cpu-info.h~mips-generic-mips-updates 2005-01-29 11:25:48.691467080 -0800 +++ 25-akpm/include/asm-mips/cpu-info.h 2005-01-29 11:25:48.795451272 -0800 @@ -37,6 +37,7 @@ struct cache_desc { #define MIPS_CACHE_VTAG 0x00000002 /* Virtually tagged cache */ #define MIPS_CACHE_ALIASES 0x00000004 /* Cache could have aliases */ #define MIPS_CACHE_IC_F_DC 0x00000008 /* Ic can refill from D-cache */ +#define MIPS_IC_SNOOPS_REMOTE 0x00000010 /* Ic snoops remote stores */ struct cpuinfo_mips { unsigned long udelay_val; diff -puN include/asm-mips/debug.h~mips-generic-mips-updates include/asm-mips/debug.h --- 25/include/asm-mips/debug.h~mips-generic-mips-updates 2005-01-29 11:25:48.692466928 -0800 +++ 25-akpm/include/asm-mips/debug.h 2005-01-29 11:25:48.796451120 -0800 @@ -29,9 +29,9 @@ #include #define db_assert(x) if (!(x)) { \ - panic("assertion failed at %s:%d: %s\n", __FILE__, __LINE__, #x); } + panic("assertion failed at %s:%d: %s", __FILE__, __LINE__, #x); } #define db_warn(x) if (!(x)) { \ - printk(KERN_WARNING "warning at %s:%d: %s\n", __FILE__, __LINE__, #x); } + printk(KERN_WARNING "warning at %s:%d: %s", __FILE__, __LINE__, #x); } #define db_verify(x, y) db_assert(x y) #define db_verify_warn(x, y) db_warn(x y) #define db_run(x) do { x; } while (0) diff -puN include/asm-mips/elf.h~mips-generic-mips-updates include/asm-mips/elf.h --- 25/include/asm-mips/elf.h~mips-generic-mips-updates 2005-01-29 11:25:48.693466776 -0800 +++ 25-akpm/include/asm-mips/elf.h 2005-01-29 11:25:48.797450968 -0800 @@ -23,7 +23,8 @@ #define EF_MIPS_ABI_O64 0x00002000 /* O32 extended for 64 bit. */ #define PT_MIPS_REGINFO 0x70000000 -#define PT_MIPS_OPTIONS 0x70000001 +#define PT_MIPS_RTPROC 0x70000001 +#define PT_MIPS_OPTIONS 0x70000002 /* Flags in the e_flags field of the header */ #define EF_MIPS_NOREORDER 0x00000001 @@ -40,9 +41,10 @@ #define DT_MIPS_ICHECKSUM 0x70000003 #define DT_MIPS_IVERSION 0x70000004 #define DT_MIPS_FLAGS 0x70000005 - #define RHF_NONE 0 - #define RHF_HARDWAY 1 - #define RHF_NOTPOT 2 + #define RHF_NONE 0x00000000 + #define RHF_HARDWAY 0x00000001 + #define RHF_NOTPOT 0x00000002 + #define RHF_SGI_ONLY 0x00000010 #define DT_MIPS_BASE_ADDRESS 0x70000006 #define DT_MIPS_CONFLICT 0x70000008 #define DT_MIPS_LIBLIST 0x70000009 @@ -222,18 +224,22 @@ do { current->thread.mflags &= ~MF_ABI_M #endif /* CONFIG_MIPS64 */ +extern void dump_regs(elf_greg_t *, struct pt_regs *regs); +extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *); + +#define ELF_CORE_COPY_REGS(elf_regs, regs) \ + dump_regs((elf_greg_t *)&(elf_regs), regs); +#define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) \ + dump_task_fpu(tsk, elf_fpregs) + #endif /* __KERNEL__ */ /* This one accepts IRIX binaries. */ -#define irix_elf_check_arch(hdr) ((hdr)->e_machine == EM_MIPS) +#define irix_elf_check_arch(hdr) ((hdr)->e_flags & RHF_SGI_ONLY) #define USE_ELF_CORE_DUMP #define ELF_EXEC_PAGESIZE PAGE_SIZE -#define ELF_CORE_COPY_REGS(_dest,_regs) \ - memcpy((char *) &_dest, (char *) _regs, \ - sizeof(struct pt_regs)); - /* This yields a mask that user programs can use to figure out what instruction set this cpu supports. This could be done in userspace, but it's not easy, and we've already done it here. */ diff -puN include/asm-mips/gt64120.h~mips-generic-mips-updates include/asm-mips/gt64120.h --- 25/include/asm-mips/gt64120.h~mips-generic-mips-updates 2005-01-29 11:25:48.695466472 -0800 +++ 25-akpm/include/asm-mips/gt64120.h 2005-01-29 11:25:48.799450664 -0800 @@ -1,6 +1,9 @@ /* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. + * Copyright (C) 2000, 2004, 2005 MIPS Technologies, Inc. + * All rights reserved. + * Authors: Carsten Langgaard + * Maciej W. Rozycki + * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org) * * This program is free software; you can distribute it and/or modify it * under the terms of the GNU General Public License (Version 2) as @@ -18,20 +21,20 @@ #ifndef _ASM_GT64120_H #define _ASM_GT64120_H -#include #include #include -#define MSK(n) ((1 << (n)) - 1) +#define MSK(n) ((1 << (n)) - 1) /* * Register offset addresses */ +/* CPU Configuration. */ #define GT_CPU_OFS 0x000 -/* - * Interrupt Registers - */ +#define GT_MULTI_OFS 0x120 + +/* CPU Address Decode. */ #define GT_SCS10LD_OFS 0x008 #define GT_SCS10HD_OFS 0x010 #define GT_SCS32LD_OFS 0x018 @@ -45,6 +48,7 @@ #define GT_PCI0M0LD_OFS 0x058 #define GT_PCI0M0HD_OFS 0x060 #define GT_ISD_OFS 0x068 + #define GT_PCI0M1LD_OFS 0x080 #define GT_PCI0M1HD_OFS 0x088 #define GT_PCI1IOLD_OFS 0x090 @@ -53,10 +57,14 @@ #define GT_PCI1M0HD_OFS 0x0a8 #define GT_PCI1M1LD_OFS 0x0b0 #define GT_PCI1M1HD_OFS 0x0b8 +#define GT_PCI1M1LD_OFS 0x0b0 +#define GT_PCI1M1HD_OFS 0x0b8 + +#define GT_SCS10AR_OFS 0x0d0 +#define GT_SCS32AR_OFS 0x0d8 +#define GT_CS20R_OFS 0x0e0 +#define GT_CS3BOOTR_OFS 0x0e8 -/* - * GT64120A only - */ #define GT_PCI0IOREMAP_OFS 0x0f0 #define GT_PCI0M0REMAP_OFS 0x0f8 #define GT_PCI0M1REMAP_OFS 0x100 @@ -64,6 +72,19 @@ #define GT_PCI1M0REMAP_OFS 0x110 #define GT_PCI1M1REMAP_OFS 0x118 +/* CPU Error Report. */ +#define GT_CPUERR_ADDRLO_OFS 0x070 +#define GT_CPUERR_ADDRHI_OFS 0x078 + +#define GT_CPUERR_DATALO_OFS 0x128 /* GT-64120A only */ +#define GT_CPUERR_DATAHI_OFS 0x130 /* GT-64120A only */ +#define GT_CPUERR_PARITY_OFS 0x138 /* GT-64120A only */ + +/* CPU Sync Barrier. */ +#define GT_PCI0SYNC_OFS 0x0c0 +#define GT_PCI1SYNC_OFS 0x0c8 + +/* SDRAM and Device Address Decode. */ #define GT_SCS0LD_OFS 0x400 #define GT_SCS0HD_OFS 0x404 #define GT_SCS1LD_OFS 0x408 @@ -83,37 +104,138 @@ #define GT_BOOTLD_OFS 0x440 #define GT_BOOTHD_OFS 0x444 -#define GT_SDRAM_B0_OFS 0x44c +#define GT_ADERR_OFS 0x470 + +/* SDRAM Configuration. */ #define GT_SDRAM_CFG_OFS 0x448 -#define GT_SDRAM_B2_OFS 0x454 + #define GT_SDRAM_OPMODE_OFS 0x474 #define GT_SDRAM_BM_OFS 0x478 #define GT_SDRAM_ADDRDECODE_OFS 0x47c -#define GT_PCI0_CMD_OFS 0xc00 /* GT64120A only */ +/* SDRAM Parameters. */ +#define GT_SDRAM_B0_OFS 0x44c +#define GT_SDRAM_B1_OFS 0x450 +#define GT_SDRAM_B2_OFS 0x454 +#define GT_SDRAM_B3_OFS 0x458 + +/* Device Parameters. */ +#define GT_DEV_B0_OFS 0x45c +#define GT_DEV_B1_OFS 0x460 +#define GT_DEV_B2_OFS 0x464 +#define GT_DEV_B3_OFS 0x468 +#define GT_DEV_BOOT_OFS 0x46c + +/* ECC. */ +#define GT_ECC_ERRDATALO 0x480 /* GT-64120A only */ +#define GT_ECC_ERRDATAHI 0x484 /* GT-64120A only */ +#define GT_ECC_MEM 0x488 /* GT-64120A only */ +#define GT_ECC_CALC 0x48c /* GT-64120A only */ +#define GT_ECC_ERRADDR 0x490 /* GT-64120A only */ + +/* DMA Record. */ +#define GT_DMA0_CNT_OFS 0x800 +#define GT_DMA1_CNT_OFS 0x804 +#define GT_DMA2_CNT_OFS 0x808 +#define GT_DMA3_CNT_OFS 0x80c +#define GT_DMA0_SA_OFS 0x810 +#define GT_DMA1_SA_OFS 0x814 +#define GT_DMA2_SA_OFS 0x818 +#define GT_DMA3_SA_OFS 0x81c +#define GT_DMA0_DA_OFS 0x820 +#define GT_DMA1_DA_OFS 0x824 +#define GT_DMA2_DA_OFS 0x828 +#define GT_DMA3_DA_OFS 0x82c +#define GT_DMA0_NEXT_OFS 0x830 +#define GT_DMA1_NEXT_OFS 0x834 +#define GT_DMA2_NEXT_OFS 0x838 +#define GT_DMA3_NEXT_OFS 0x83c + +#define GT_DMA0_CUR_OFS 0x870 +#define GT_DMA1_CUR_OFS 0x874 +#define GT_DMA2_CUR_OFS 0x878 +#define GT_DMA3_CUR_OFS 0x87c + +/* DMA Channel Control. */ +#define GT_DMA0_CTRL_OFS 0x840 +#define GT_DMA1_CTRL_OFS 0x844 +#define GT_DMA2_CTRL_OFS 0x848 +#define GT_DMA3_CTRL_OFS 0x84c + +/* DMA Arbiter. */ +#define GT_DMA_ARB_OFS 0x860 + +/* Timer/Counter. */ +#define GT_TC0_OFS 0x850 +#define GT_TC1_OFS 0x854 +#define GT_TC2_OFS 0x858 +#define GT_TC3_OFS 0x85c + +#define GT_TC_CONTROL_OFS 0x864 + +/* PCI Internal. */ +#define GT_PCI0_CMD_OFS 0xc00 #define GT_PCI0_TOR_OFS 0xc04 -#define GT_PCI0_BS_SCS10_OFS 0xc08 -#define GT_PCI0_BS_SCS32_OFS 0xc0c -#define GT_INTRCAUSE_OFS 0xc18 -#define GT_INTRMASK_OFS 0xc1c /* GT64120A only */ +#define GT_PCI0_BS_SCS10_OFS 0xc08 +#define GT_PCI0_BS_SCS32_OFS 0xc0c +#define GT_PCI0_BS_CS20_OFS 0xc10 +#define GT_PCI0_BS_CS3BT_OFS 0xc14 + +#define GT_PCI1_IACK_OFS 0xc30 #define GT_PCI0_IACK_OFS 0xc34 + #define GT_PCI0_BARE_OFS 0xc3c -#define GT_HINTRCAUSE_OFS 0xc98 /* GT64120A only */ -#define GT_HINTRMASK_OFS 0xc9c /* GT64120A only */ -#define GT_PCI1_CFGADDR_OFS 0xcf0 /* GT64120A only */ -#define GT_PCI1_CFGDATA_OFS 0xcf4 /* GT64120A only */ +#define GT_PCI0_PREFMBR_OFS 0xc40 + +#define GT_PCI0_SCS10_BAR_OFS 0xc48 +#define GT_PCI0_SCS32_BAR_OFS 0xc4c +#define GT_PCI0_CS20_BAR_OFS 0xc50 +#define GT_PCI0_CS3BT_BAR_OFS 0xc54 +#define GT_PCI0_SSCS10_BAR_OFS 0xc58 +#define GT_PCI0_SSCS32_BAR_OFS 0xc5c + +#define GT_PCI0_SCS3BT_BAR_OFS 0xc64 + +#define GT_PCI1_CMD_OFS 0xc80 +#define GT_PCI1_TOR_OFS 0xc84 +#define GT_PCI1_BS_SCS10_OFS 0xc88 +#define GT_PCI1_BS_SCS32_OFS 0xc8c +#define GT_PCI1_BS_CS20_OFS 0xc90 +#define GT_PCI1_BS_CS3BT_OFS 0xc94 + +#define GT_PCI1_BARE_OFS 0xcbc +#define GT_PCI1_PREFMBR_OFS 0xcc0 + +#define GT_PCI1_SCS10_BAR_OFS 0xcc8 +#define GT_PCI1_SCS32_BAR_OFS 0xccc +#define GT_PCI1_CS20_BAR_OFS 0xcd0 +#define GT_PCI1_CS3BT_BAR_OFS 0xcd4 +#define GT_PCI1_SSCS10_BAR_OFS 0xcd8 +#define GT_PCI1_SSCS32_BAR_OFS 0xcdc + +#define GT_PCI1_SCS3BT_BAR_OFS 0xce4 + +#define GT_PCI1_CFGADDR_OFS 0xcf0 +#define GT_PCI1_CFGDATA_OFS 0xcf4 #define GT_PCI0_CFGADDR_OFS 0xcf8 #define GT_PCI0_CFGDATA_OFS 0xcfc +/* Interrupts. */ +#define GT_INTRCAUSE_OFS 0xc18 +#define GT_INTRMASK_OFS 0xc1c + +#define GT_PCI0_ICMASK_OFS 0xc24 +#define GT_PCI0_SERR0MASK_OFS 0xc28 + +#define GT_CPU_INTSEL_OFS 0xc70 +#define GT_PCI0_INTSEL_OFS 0xc74 + +#define GT_HINTRCAUSE_OFS 0xc98 +#define GT_HINTRMASK_OFS 0xc9c + +#define GT_PCI0_HICMASK_OFS 0xca4 +#define GT_PCI1_SERR1MASK_OFS 0xca8 -/* - * Timer/Counter. GT64120A only. - */ -#define GT_TC0_OFS 0x850 -#define GT_TC1_OFS 0x854 -#define GT_TC2_OFS 0x858 -#define GT_TC3_OFS 0x85C -#define GT_TC_CONTROL_OFS 0x864 /* * I2O Support Registers @@ -167,9 +289,9 @@ /* * Register encodings */ -#define GT_CPU_ENDIAN_SHF 12 -#define GT_CPU_ENDIAN_MSK (MSK(1) << GT_CPU_ENDIAN_SHF) -#define GT_CPU_ENDIAN_BIT GT_CPU_ENDIAN_MSK +#define GT_CPU_ENDIAN_SHF 12 +#define GT_CPU_ENDIAN_MSK (MSK(1) << GT_CPU_ENDIAN_SHF) +#define GT_CPU_ENDIAN_BIT GT_CPU_ENDIAN_MSK #define GT_CPU_WR_SHF 16 #define GT_CPU_WR_MSK (MSK(1) << GT_CPU_WR_SHF) #define GT_CPU_WR_BIT GT_CPU_WR_MSK @@ -177,6 +299,15 @@ #define GT_CPU_WR_DDDD 1 +#define GT_PCI_DCRM_SHF 21 +#define GT_PCI_LD_SHF 0 +#define GT_PCI_LD_MSK (MSK(15) << GT_PCI_LD_SHF) +#define GT_PCI_HD_SHF 0 +#define GT_PCI_HD_MSK (MSK(7) << GT_PCI_HD_SHF) +#define GT_PCI_REMAP_SHF 0 +#define GT_PCI_REMAP_MSK (MSK(11) << GT_PCI_REMAP_SHF) + + #define GT_CFGADDR_CFGEN_SHF 31 #define GT_CFGADDR_CFGEN_MSK (MSK(1) << GT_CFGADDR_CFGEN_SHF) #define GT_CFGADDR_CFGEN_BIT GT_CFGADDR_CFGEN_MSK @@ -285,7 +416,7 @@ #define GT_SDRAM_CFG_REFINT_MSK (MSK(14) << GT_SDRAM_CFG_REFINT_SHF) #define GT_SDRAM_CFG_NINTERLEAVE_SHF 14 -#define GT_SDRAM_CFG_NINTERLEAVE_MSK (MSK(1) << GT_SDRAM_CFG_NINTERLEAVE_SHF) +#define GT_SDRAM_CFG_NINTERLEAVE_MSK (MSK(1) << GT_SDRAM_CFG_NINTERLEAVE_SHF) #define GT_SDRAM_CFG_NINTERLEAVE_BIT GT_SDRAM_CFG_NINTERLEAVE_MSK #define GT_SDRAM_CFG_RMW_SHF 15 @@ -370,7 +501,7 @@ #define GT_PCI0_CFGADDR_REGNUM_SHF 2 #define GT_PCI0_CFGADDR_REGNUM_MSK (MSK(6) << GT_PCI0_CFGADDR_REGNUM_SHF) #define GT_PCI0_CFGADDR_FUNCTNUM_SHF 8 -#define GT_PCI0_CFGADDR_FUNCTNUM_MSK (MSK(3) << GT_PCI0_CFGADDR_FUNCTNUM_SHF) +#define GT_PCI0_CFGADDR_FUNCTNUM_MSK (MSK(3) << GT_PCI0_CFGADDR_FUNCTNUM_SHF) #define GT_PCI0_CFGADDR_DEVNUM_SHF 11 #define GT_PCI0_CFGADDR_DEVNUM_MSK (MSK(5) << GT_PCI0_CFGADDR_DEVNUM_SHF) #define GT_PCI0_CFGADDR_BUSNUM_SHF 16 @@ -379,18 +510,18 @@ #define GT_PCI0_CFGADDR_CONFIGEN_MSK (MSK(1) << GT_PCI0_CFGADDR_CONFIGEN_SHF) #define GT_PCI0_CFGADDR_CONFIGEN_BIT GT_PCI0_CFGADDR_CONFIGEN_MSK -#define GT_PCI0_CMD_MBYTESWAP_SHF 0 -#define GT_PCI0_CMD_MBYTESWAP_MSK (MSK(1) << GT_PCI0_CMD_MBYTESWAP_SHF) -#define GT_PCI0_CMD_MBYTESWAP_BIT GT_PCI0_CMD_MBYTESWAP_MSK -#define GT_PCI0_CMD_MWORDSWAP_SHF 10 -#define GT_PCI0_CMD_MWORDSWAP_MSK (MSK(1) << GT_PCI0_CMD_MWORDSWAP_SHF) -#define GT_PCI0_CMD_MWORDSWAP_BIT GT_PCI0_CMD_MWORDSWAP_MSK -#define GT_PCI0_CMD_SBYTESWAP_SHF 16 -#define GT_PCI0_CMD_SBYTESWAP_MSK (MSK(1) << GT_PCI0_CMD_SBYTESWAP_SHF) -#define GT_PCI0_CMD_SBYTESWAP_BIT GT_PCI0_CMD_SBYTESWAP_MSK -#define GT_PCI0_CMD_SWORDSWAP_SHF 11 -#define GT_PCI0_CMD_SWORDSWAP_MSK (MSK(1) << GT_PCI0_CMD_SWORDSWAP_SHF) -#define GT_PCI0_CMD_SWORDSWAP_BIT GT_PCI0_CMD_SWORDSWAP_MSK +#define GT_PCI0_CMD_MBYTESWAP_SHF 0 +#define GT_PCI0_CMD_MBYTESWAP_MSK (MSK(1) << GT_PCI0_CMD_MBYTESWAP_SHF) +#define GT_PCI0_CMD_MBYTESWAP_BIT GT_PCI0_CMD_MBYTESWAP_MSK +#define GT_PCI0_CMD_MWORDSWAP_SHF 10 +#define GT_PCI0_CMD_MWORDSWAP_MSK (MSK(1) << GT_PCI0_CMD_MWORDSWAP_SHF) +#define GT_PCI0_CMD_MWORDSWAP_BIT GT_PCI0_CMD_MWORDSWAP_MSK +#define GT_PCI0_CMD_SBYTESWAP_SHF 16 +#define GT_PCI0_CMD_SBYTESWAP_MSK (MSK(1) << GT_PCI0_CMD_SBYTESWAP_SHF) +#define GT_PCI0_CMD_SBYTESWAP_BIT GT_PCI0_CMD_SBYTESWAP_MSK +#define GT_PCI0_CMD_SWORDSWAP_SHF 11 +#define GT_PCI0_CMD_SWORDSWAP_MSK (MSK(1) << GT_PCI0_CMD_SWORDSWAP_SHF) +#define GT_PCI0_CMD_SWORDSWAP_BIT GT_PCI0_CMD_SWORDSWAP_MSK /* * Misc @@ -401,8 +532,8 @@ #define GT_DEF_PCI0_MEM0_SIZE 0x02000000UL #define GT_DEF_BASE 0x14000000UL -#define GT_MAX_BANKSIZE (256 * 1024 * 1024) /* Max 256MB bank */ -#define GT_LATTIM_MIN 6 /* Minimum lat */ +#define GT_MAX_BANKSIZE (256 * 1024 * 1024) /* Max 256MB bank */ +#define GT_LATTIM_MIN 6 /* Minimum lat */ /* * The gt64120_dep.h file must define the following macros diff -puN include/asm-mips/hardirq.h~mips-generic-mips-updates include/asm-mips/hardirq.h --- 25/include/asm-mips/hardirq.h~mips-generic-mips-updates 2005-01-29 11:25:48.696466320 -0800 +++ 25-akpm/include/asm-mips/hardirq.h 2005-01-29 11:25:48.799450664 -0800 @@ -3,14 +3,13 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1997, 1998, 1999, 2000, 2001 by Ralf Baechle + * Copyright (C) 1997, 98, 99, 2000, 01, 05 Ralf Baechle (ralf@linux-mips.org) * Copyright (C) 1999, 2000 Silicon Graphics, Inc. * Copyright (C) 2001 MIPS Technologies, Inc. */ #ifndef _ASM_HARDIRQ_H #define _ASM_HARDIRQ_H -#include #include #include diff -puN include/asm-mips/hazards.h~mips-generic-mips-updates include/asm-mips/hazards.h --- 25/include/asm-mips/hazards.h~mips-generic-mips-updates 2005-01-29 11:25:48.697466168 -0800 +++ 25-akpm/include/asm-mips/hazards.h 2005-01-29 11:25:48.800450512 -0800 @@ -16,6 +16,10 @@ sll $0, $0, 1 .endm + .macro _ehb + sll $0, $0, 3 + .endm + /* * RM9000 hazards. When the JTLB is updated by tlbwi or tlbwr, a subsequent * use of the JTLB for instructions should not occur for 4 cpu cycles and use @@ -23,17 +27,19 @@ */ #ifdef CONFIG_CPU_RM9000 -#define mtc0_tlbw_hazard \ - .set push; \ - .set mips32; \ - _ssnop; _ssnop; _ssnop; _ssnop; \ + .macro mtc0_tlbw_hazard + .set push + .set mips32 + _ssnop; _ssnop; _ssnop; _ssnop .set pop + .endm -#define tlbw_eret_hazard \ - .set push; \ - .set mips32; \ - _ssnop; _ssnop; _ssnop; _ssnop; \ + .macro tlbw_eret_hazard + .set push + .set mips32 + _ssnop; _ssnop; _ssnop; _ssnop .set pop + .endm #else @@ -43,9 +49,12 @@ * hazard so this is nice trick to have an optimal code for a range of * processors. */ -#define mtc0_tlbw_hazard \ + .macro mtc0_tlbw_hazard b . + 8 -#define tlbw_eret_hazard + .endm + + .macro tlbw_eret_hazard + .endm #endif /* @@ -58,31 +67,51 @@ /* * Use a macro for ehb unless explicit support for MIPSR2 is enabled */ - .macro ehb - sll $0, $0, 3 - .endm -#define irq_enable_hazard \ - ehb # irq_enable_hazard +#define irq_enable_hazard + _ehb -#define irq_disable_hazard \ - ehb # irq_disable_hazard +#define irq_disable_hazard + _ehb -#else +#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000) + +/* + * R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer. + */ #define irq_enable_hazard + #define irq_disable_hazard +#else + +/* + * Classic MIPS needs 1 - 3 nops or ssnops + */ +#define irq_enable_hazard +#define irq_disable_hazard \ + _ssnop; _ssnop; _ssnop + #endif #else /* __ASSEMBLY__ */ +__asm__( + " .macro _ssnop \n\t" + " sll $0, $2, 1 \n\t" + " .endm \n\t" + " \n\t" + " .macro _ehb \n\t" + " sll $0, $0, 3 \n\t" + " .endm \n\t"); + +#ifdef CONFIG_CPU_RM9000 /* * RM9000 hazards. When the JTLB is updated by tlbwi or tlbwr, a subsequent * use of the JTLB for instructions should not occur for 4 cpu cycles and use * for data translations should not occur for 3 cpu cycles. */ -#ifdef CONFIG_CPU_RM9000 #define mtc0_tlbw_hazard() \ __asm__ __volatile__( \ @@ -125,27 +154,23 @@ * Use a macro for ehb unless explicit support for MIPSR2 is enabled */ __asm__( - " .macro ehb \n\t" - " sll $0, $0, 3 \n\t" - " .endm \n\t" - " \n\t" " .macro\tirq_enable_hazard \n\t" - " ehb \n\t" + " _ehb \n\t" " .endm \n\t" " \n\t" " .macro\tirq_disable_hazard \n\t" - " ehb \n\t" + " _ehb \n\t" " .endm"); #define irq_enable_hazard() \ __asm__ __volatile__( \ - "ehb\t\t\t\t# irq_enable_hazard") + "_ehb\t\t\t\t# irq_enable_hazard") #define irq_disable_hazard() \ __asm__ __volatile__( \ - "ehb\t\t\t\t# irq_disable_hazard") + "_ehb\t\t\t\t# irq_disable_hazard") -#elif defined(CONFIG_CPU_R10000) +#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000) /* * R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer. @@ -170,10 +195,6 @@ __asm__( */ __asm__( - " .macro _ssnop \n\t" - " sll $0, $2, 1 \n\t" - " .endm \n\t" - " \n\t" " # \n\t" " # There is a hazard but we do not care \n\t" " # \n\t" diff -puN include/asm-mips/io.h~mips-generic-mips-updates include/asm-mips/io.h --- 25/include/asm-mips/io.h~mips-generic-mips-updates 2005-01-29 11:25:48.699465864 -0800 +++ 25-akpm/include/asm-mips/io.h 2005-01-29 11:25:48.804449904 -0800 @@ -6,21 +6,26 @@ * Copyright (C) 1994, 1995 Waldorf GmbH * Copyright (C) 1994 - 2000 Ralf Baechle * Copyright (C) 1999, 2000 Silicon Graphics, Inc. + * Copyright (C) 2004, 2005 MIPS Technologies, Inc. All rights reserved. + * Author: Maciej W. Rozycki */ #ifndef _ASM_IO_H #define _ASM_IO_H #include #include +#include #include #include +#include +#include #include #include #include #include #include -#include + #include /* @@ -29,34 +34,54 @@ #undef CONF_SLOWDOWN_IO /* - * Sane hardware offers swapping of I/O space accesses in hardware; less - * sane hardware forces software to fiddle with this ... + * Raw operations are never swapped in software. Otoh values that raw + * operations are working on may or may not have been swapped by the bus + * hardware. An example use would be for flash memory that's used for + * execute in place. */ -#if defined(CONFIG_SWAP_IO_SPACE) && defined(__MIPSEB__) +# define __raw_ioswabb(x) (x) +# define __raw_ioswabw(x) (x) +# define __raw_ioswabl(x) (x) +# define __raw_ioswabq(x) (x) -#define __ioswab8(x) (x) +/* + * Sane hardware offers swapping of PCI/ISA I/O space accesses in hardware; + * less sane hardware forces software to fiddle with this... + */ +#if defined(CONFIG_SWAP_IO_SPACE) -#ifdef CONFIG_SGI_IP22 +# define ioswabb(x) (x) +# ifdef CONFIG_SGI_IP22 /* * IP22 seems braindead enough to swap 16bits values in hardware, but * not 32bits. Go figure... Can't tell without documentation. */ -#define __ioswab16(x) (x) -#else -#define __ioswab16(x) swab16(x) -#endif -#define __ioswab32(x) swab32(x) -#define __ioswab64(x) swab64(x) +# define ioswabw(x) (x) +# else +# define ioswabw(x) le16_to_cpu(x) +# endif +# define ioswabl(x) le32_to_cpu(x) +# define ioswabq(x) le64_to_cpu(x) #else -#define __ioswab8(x) (x) -#define __ioswab16(x) (x) -#define __ioswab32(x) (x) -#define __ioswab64(x) (x) +# define ioswabb(x) (x) +# define ioswabw(x) (x) +# define ioswabl(x) (x) +# define ioswabq(x) (x) #endif +/* + * Native bus accesses never swapped. + */ +#define bus_ioswabb(x) (x) +#define bus_ioswabw(x) (x) +#define bus_ioswabl(x) (x) +#define bus_ioswabq(x) (x) + +#define __bus_ioswabq bus_ioswabq + #define IO_SPACE_LIMIT 0xffff /* @@ -239,114 +264,214 @@ static inline void * __ioremap_mode(phys static inline void iounmap(volatile void __iomem *addr) { - if (cpu_has_64bits) + if (cpu_has_64bit_addresses) return; __iounmap(addr); } -#define __raw_readb(addr) \ - (*(volatile unsigned char *) __swizzle_addr_b((unsigned long)(addr))) -#define __raw_readw(addr) \ - (*(volatile unsigned short *) __swizzle_addr_w((unsigned long)(addr))) -#define __raw_readl(addr) \ - (*(volatile unsigned int *) __swizzle_addr_l((unsigned long)(addr))) -#ifdef CONFIG_MIPS32 -#define ____raw_readq(addr) \ -({ \ - u64 __res; \ - \ - __asm__ __volatile__ ( \ - " .set mips3 # ____raw_readq \n" \ - " ld %L0, (%1) \n" \ - " dsra32 %M0, %L0, 0 \n" \ - " sll %L0, %L0, 0 \n" \ - " .set mips0 \n" \ - : "=r" (__res) \ - : "r" (__swizzle_addr_q((unsigned long)(addr)))); \ - __res; \ -}) -#define __raw_readq(addr) \ -({ \ - unsigned long __flags; \ - u64 __res; \ - \ - local_irq_save(__flags); \ - __res = ____raw_readq(addr); \ - local_irq_restore(__flags); \ - __res; \ -}) -#endif -#ifdef CONFIG_MIPS64 -#define ____raw_readq(addr) \ - (*(volatile unsigned long *)__swizzle_addr_q((unsigned long)(addr))) -#define __raw_readq(addr) ____raw_readq(addr) -#endif -#define readb(addr) __ioswab8(__raw_readb(addr)) -#define readw(addr) __ioswab16(__raw_readw(addr)) -#define readl(addr) __ioswab32(__raw_readl(addr)) -#define readq(addr) __ioswab64(__raw_readq(addr)) -#define readb_relaxed(addr) readb(addr) -#define readw_relaxed(addr) readw(addr) -#define readl_relaxed(addr) readl(addr) -#define readq_relaxed(addr) readq(addr) - -#define __raw_writeb(b,addr) \ -do { \ - ((*(volatile unsigned char *)__swizzle_addr_b((unsigned long)(addr))) = (b)); \ -} while (0) - -#define __raw_writew(w,addr) \ -do { \ - ((*(volatile unsigned short *)__swizzle_addr_w((unsigned long)(addr))) = (w)); \ -} while (0) - -#define __raw_writel(l,addr) \ -do { \ - ((*(volatile unsigned int *)__swizzle_addr_l((unsigned long)(addr))) = (l)); \ -} while (0) - -#ifdef CONFIG_MIPS32 -#define ____raw_writeq(val,addr) \ -do { \ - u64 __tmp; \ - \ - __asm__ __volatile__ ( \ - " .set mips3 \n" \ - " dsll32 %L0, %L0, 0 # ____raw_writeq\n" \ - " dsrl32 %L0, %L0, 0 \n" \ - " dsll32 %M0, %M0, 0 \n" \ - " or %L0, %L0, %M0 \n" \ - " sd %L0, (%2) \n" \ - " .set mips0 \n" \ - : "=r" (__tmp) \ - : "0" ((unsigned long long)val), \ - "r" (__swizzle_addr_q((unsigned long)(addr)))); \ -} while (0) - -#define __raw_writeq(val,addr) \ -do { \ - unsigned long __flags; \ - \ - local_irq_save(__flags); \ - ____raw_writeq(val, addr); \ - local_irq_restore(__flags); \ -} while (0) -#endif -#ifdef CONFIG_MIPS64 -#define ____raw_writeq(q,addr) \ -do { \ - *(volatile unsigned long *)__swizzle_addr_q((unsigned long)(addr)) = (q); \ -} while (0) +#define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, irq) \ + \ +static inline void pfx##write##bwlq(type val, \ + volatile void __iomem *mem) \ +{ \ + volatile type *__mem; \ + type __val; \ + \ + __mem = (void *)__swizzle_addr_##bwlq((unsigned long)(mem)); \ + \ + __val = pfx##ioswab##bwlq(val); \ + \ + if (sizeof(type) != sizeof(u64) || sizeof(u64) == sizeof(long)) \ + *__mem = __val; \ + else if (cpu_has_64bits) { \ + unsigned long __flags; \ + type __tmp; \ + \ + if (irq) \ + local_irq_save(__flags); \ + __asm__ __volatile__( \ + ".set mips3" "\t\t# __writeq""\n\t" \ + "dsll32 %L0, %L0, 0" "\n\t" \ + "dsrl32 %L0, %L0, 0" "\n\t" \ + "dsll32 %M0, %M0, 0" "\n\t" \ + "or %L0, %L0, %M0" "\n\t" \ + "sd %L0, %2" "\n\t" \ + ".set mips0" "\n" \ + : "=r" (__tmp) \ + : "0" (__val), "m" (*__mem)); \ + if (irq) \ + local_irq_restore(__flags); \ + } else \ + BUG(); \ +} \ + \ +static inline type pfx##read##bwlq(volatile void __iomem *mem) \ +{ \ + volatile type *__mem; \ + type __val; \ + \ + __mem = (void *)__swizzle_addr_##bwlq((unsigned long)(mem)); \ + \ + if (sizeof(type) != sizeof(u64) || sizeof(u64) == sizeof(long)) \ + __val = *__mem; \ + else if (cpu_has_64bits) { \ + unsigned long __flags; \ + \ + local_irq_save(__flags); \ + __asm__ __volatile__( \ + ".set mips3" "\t\t# __readq" "\n\t" \ + "ld %L0, %1" "\n\t" \ + "dsra32 %M0, %L0, 0" "\n\t" \ + "sll %L0, %L0, 0" "\n\t" \ + ".set mips0" "\n" \ + : "=r" (__val) \ + : "m" (*__mem)); \ + local_irq_restore(__flags); \ + } else { \ + __val = 0; \ + BUG(); \ + } \ + \ + return pfx##ioswab##bwlq(__val); \ +} -#define __raw_writeq(q,addr) ____raw_writeq(q, addr) -#endif +#define __BUILD_IOPORT_SINGLE(pfx, bwlq, type, p, slow) \ + \ +static inline void pfx##out##bwlq##p(type val, unsigned long port) \ +{ \ + volatile type *__addr; \ + type __val; \ + \ + port = __swizzle_addr_##bwlq(port); \ + __addr = (void *)(mips_io_port_base + port); \ + \ + __val = pfx##ioswab##bwlq(val); \ + \ + if (sizeof(type) != sizeof(u64)) { \ + *__addr = __val; \ + slow; \ + } else \ + BUILD_BUG(); \ +} \ + \ +static inline type pfx##in##bwlq##p(unsigned long port) \ +{ \ + volatile type *__addr; \ + type __val; \ + \ + port = __swizzle_addr_##bwlq(port); \ + __addr = (void *)(mips_io_port_base + port); \ + \ + if (sizeof(type) != sizeof(u64)) { \ + __val = *__addr; \ + slow; \ + } else { \ + __val = 0; \ + BUILD_BUG(); \ + } \ + \ + return pfx##ioswab##bwlq(__val); \ +} + +#define __BUILD_MEMORY_PFX(bus, bwlq, type) \ + \ +__BUILD_MEMORY_SINGLE(bus, bwlq, type, 1) + +#define __BUILD_IOPORT_PFX(bus, bwlq, type) \ + \ +__BUILD_IOPORT_SINGLE(bus, bwlq, type, ,) \ +__BUILD_IOPORT_SINGLE(bus, bwlq, type, _p, SLOW_DOWN_IO) + +#define BUILDIO(bwlq, type) \ + \ +__BUILD_MEMORY_PFX(, bwlq, type) \ +__BUILD_MEMORY_PFX(__raw_, bwlq, type) \ +__BUILD_MEMORY_PFX(bus_, bwlq, type) \ +__BUILD_IOPORT_PFX(, bwlq, type) \ +__BUILD_IOPORT_PFX(__raw_, bwlq, type) + +#define __BUILDIO(bwlq, type) \ + \ +__BUILD_MEMORY_SINGLE(__bus_, bwlq, type, 0) + +BUILDIO(b, u8) +BUILDIO(w, u16) +BUILDIO(l, u32) +BUILDIO(q, u64) + +__BUILDIO(q, u64) + +#define readb_relaxed readb +#define readw_relaxed readw +#define readl_relaxed readl +#define readq_relaxed readq + +/* + * Some code tests for these symbols + */ +#define readq readq +#define writeq writeq + +#define __BUILD_MEMORY_STRING(bwlq, type) \ + \ +static inline void writes##bwlq(volatile void __iomem *mem, void *addr, \ + unsigned int count) \ +{ \ + volatile type *__addr = addr; \ + \ + while (count--) { \ + __raw_write##bwlq(*__addr, mem); \ + __addr++; \ + } \ +} \ + \ +static inline void reads##bwlq(volatile void __iomem *mem, void *addr, \ + unsigned int count) \ +{ \ + volatile type *__addr = addr; \ + \ + while (count--) { \ + *__addr = __raw_read##bwlq(mem); \ + __addr++; \ + } \ +} + +#define __BUILD_IOPORT_STRING(bwlq, type) \ + \ +static inline void outs##bwlq(unsigned long port, void *addr, \ + unsigned int count) \ +{ \ + volatile type *__addr = addr; \ + \ + while (count--) { \ + __raw_out##bwlq(*__addr, port); \ + __addr++; \ + } \ +} \ + \ +static inline void ins##bwlq(unsigned long port, void *addr, \ + unsigned int count) \ +{ \ + volatile type *__addr = addr; \ + \ + while (count--) { \ + *__addr = __raw_in##bwlq(port); \ + __addr++; \ + } \ +} + +#define BUILDSTRING(bwlq, type) \ + \ +__BUILD_MEMORY_STRING(bwlq, type) \ +__BUILD_IOPORT_STRING(bwlq, type) + +BUILDSTRING(b, u8) +BUILDSTRING(w, u16) +BUILDSTRING(l, u32) +BUILDSTRING(q, u64) -#define writeb(b,addr) __raw_writeb(__ioswab8(b),(addr)) -#define writew(w,addr) __raw_writew(__ioswab16(w),(addr)) -#define writel(l,addr) __raw_writel(__ioswab32(l),(addr)) -#define writeq(q,addr) __raw_writeq(__ioswab64(q),(addr)) /* Depends on MIPS II instruction set */ #define mmiowb() asm volatile ("sync" ::: "memory") @@ -394,7 +519,7 @@ do { \ * address should have been obtained by ioremap. * Returns 1 on a match. */ -static inline int check_signature(unsigned long io_addr, +static inline int check_signature(char __iomem *io_addr, const unsigned char *signature, int length) { int retval = 0; @@ -410,177 +535,6 @@ out: return retval; } -static inline void __outb(unsigned char val, unsigned long port) -{ - port = __swizzle_addr_b(port); - - *(volatile u8 *)(mips_io_port_base + port) = __ioswab8(val); -} - -static inline void __outw(unsigned short val, unsigned long port) -{ - port = __swizzle_addr_w(port); - - *(volatile u16 *)(mips_io_port_base + port) = __ioswab16(val); -} - -static inline void __outl(unsigned int val, unsigned long port) -{ - port = __swizzle_addr_l(port); - - *(volatile u32 *)(mips_io_port_base + port) = __ioswab32(val); -} - -static inline void __outb_p(unsigned char val, unsigned long port) -{ - port = __swizzle_addr_b(port); - - *(volatile u8 *)(mips_io_port_base + port) = __ioswab8(val); - SLOW_DOWN_IO; -} - -static inline void __outw_p(unsigned short val, unsigned long port) -{ - port = __swizzle_addr_w(port); - - *(volatile u16 *)(mips_io_port_base + port) = __ioswab16(val); - SLOW_DOWN_IO; -} - -static inline void __outl_p(unsigned int val, unsigned long port) -{ - port = __swizzle_addr_l(port); - - *(volatile u32 *)(mips_io_port_base + port) = __ioswab32(val); - SLOW_DOWN_IO; -} - -#define outb(val, port) __outb(val, port) -#define outw(val, port) __outw(val, port) -#define outl(val, port) __outl(val, port) -#define outb_p(val, port) __outb_p(val, port) -#define outw_p(val, port) __outw_p(val, port) -#define outl_p(val, port) __outl_p(val, port) - -static inline unsigned char __inb(unsigned long port) -{ - port = __swizzle_addr_b(port); - - return __ioswab8(*(volatile u8 *)(mips_io_port_base + port)); -} - -static inline unsigned short __inw(unsigned long port) -{ - port = __swizzle_addr_w(port); - - return __ioswab16(*(volatile u16 *)(mips_io_port_base + port)); -} - -static inline unsigned int __inl(unsigned long port) -{ - port = __swizzle_addr_l(port); - - return __ioswab32(*(volatile u32 *)(mips_io_port_base + port)); -} - -static inline unsigned char __inb_p(unsigned long port) -{ - u8 __val; - - port = __swizzle_addr_b(port); - - __val = *(volatile u8 *)(mips_io_port_base + port); - SLOW_DOWN_IO; - - return __ioswab8(__val); -} - -static inline unsigned short __inw_p(unsigned long port) -{ - u16 __val; - - port = __swizzle_addr_w(port); - - __val = *(volatile u16 *)(mips_io_port_base + port); - SLOW_DOWN_IO; - - return __ioswab16(__val); -} - -static inline unsigned int __inl_p(unsigned long port) -{ - u32 __val; - - port = __swizzle_addr_l(port); - - __val = *(volatile u32 *)(mips_io_port_base + port); - SLOW_DOWN_IO; - - return __ioswab32(__val); -} - -#define inb(port) __inb(port) -#define inw(port) __inw(port) -#define inl(port) __inl(port) -#define inb_p(port) __inb_p(port) -#define inw_p(port) __inw_p(port) -#define inl_p(port) __inl_p(port) - -static inline void __outsb(unsigned long port, void *addr, unsigned int count) -{ - while (count--) { - outb(*(u8 *)addr, port); - addr++; - } -} - -static inline void __insb(unsigned long port, void *addr, unsigned int count) -{ - while (count--) { - *(u8 *)addr = inb(port); - addr++; - } -} - -static inline void __outsw(unsigned long port, void *addr, unsigned int count) -{ - while (count--) { - outw(*(u16 *)addr, port); - addr += 2; - } -} - -static inline void __insw(unsigned long port, void *addr, unsigned int count) -{ - while (count--) { - *(u16 *)addr = inw(port); - addr += 2; - } -} - -static inline void __outsl(unsigned long port, void *addr, unsigned int count) -{ - while (count--) { - outl(*(u32 *)addr, port); - addr += 4; - } -} - -static inline void __insl(unsigned long port, void *addr, unsigned int count) -{ - while (count--) { - *(u32 *)addr = inl(port); - addr += 4; - } -} - -#define outsb(port, addr, count) __outsb(port, addr, count) -#define insb(port, addr, count) __insb(port, addr, count) -#define outsw(port, addr, count) __outsw(port, addr, count) -#define insw(port, addr, count) __insw(port, addr, count) -#define outsl(port, addr, count) __outsl(port, addr, count) -#define insl(port, addr, count) __insl(port, addr, count) - /* * The caches on some architectures aren't dma-coherent and have need to * handle this in software. There are three types of operations that diff -puN include/asm-mips/irq_cpu.h~mips-generic-mips-updates include/asm-mips/irq_cpu.h --- 25/include/asm-mips/irq_cpu.h~mips-generic-mips-updates 2005-01-29 11:25:48.700465712 -0800 +++ 25-akpm/include/asm-mips/irq_cpu.h 2005-01-29 11:25:48.804449904 -0800 @@ -15,5 +15,6 @@ extern void mips_cpu_irq_init(int irq_base); extern void rm7k_cpu_irq_init(int irq_base); +extern void rm9k_cpu_irq_init(int irq_base); #endif /* _ASM_IRQ_CPU_H */ diff -puN /dev/null include/asm-mips/m48t37.h --- /dev/null 2003-09-15 06:40:47.000000000 -0700 +++ 25-akpm/include/asm-mips/m48t37.h 2005-01-29 11:25:48.804449904 -0800 @@ -0,0 +1,35 @@ +/* + * Registers for the SGS-Thomson M48T37 Timekeeper RAM chip + */ +#ifndef _ASM_M48T37_H +#define _ASM_M48T37_H + +#include + +extern spinlock_t rtc_lock; + +struct m48t37_rtc { + volatile u8 pad[0x7ff0]; /* NVRAM */ + volatile u8 flags; + volatile u8 century; + volatile u8 alarm_sec; + volatile u8 alarm_min; + volatile u8 alarm_hour; + volatile u8 alarm_data; + volatile u8 interrupts; + volatile u8 watchdog; + volatile u8 control; + volatile u8 sec; + volatile u8 min; + volatile u8 hour; + volatile u8 day; + volatile u8 date; + volatile u8 month; + volatile u8 year; +}; + +#define M48T37_RTC_SET 0x80 +#define M48T37_RTC_STOPPED 0x80 +#define M48T37_RTC_READ 0x40 + +#endif /* _ASM_M48T37_H */ diff -puN include/asm-mips/mach-generic/ide.h~mips-generic-mips-updates include/asm-mips/mach-generic/ide.h --- 25/include/asm-mips/mach-generic/ide.h~mips-generic-mips-updates 2005-01-29 11:25:48.701465560 -0800 +++ 25-akpm/include/asm-mips/mach-generic/ide.h 2005-01-29 11:25:48.805449752 -0800 @@ -16,6 +16,8 @@ #ifdef __KERNEL__ #include +#include +#include #ifndef MAX_HWIFS # ifdef CONFIG_BLK_DEV_IDEPCI @@ -27,32 +29,68 @@ #define IDE_ARCH_OBSOLETE_DEFAULTS +static __inline__ int ide_probe_legacy(void) +{ +#ifdef CONFIG_PCI + struct pci_dev *dev; + if ((dev = pci_get_class(PCI_CLASS_BRIDGE_EISA << 8, NULL)) != NULL || + (dev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL)) != NULL) { + pci_dev_put(dev); + + return 1; + } + return 0; +#elif defined(CONFIG_EISA) || defined(CONFIG_ISA) + return 1; +#else + return 0; +#endif +} + static __inline__ int ide_default_irq(unsigned long base) { - switch (base) { - case 0x1f0: return 14; - case 0x170: return 15; - case 0x1e8: return 11; - case 0x168: return 10; - case 0x1e0: return 8; - case 0x160: return 12; + if (ide_probe_legacy()) + switch (base) { + case 0x1f0: + return 14; + case 0x170: + return 15; + case 0x1e8: + return 11; + case 0x168: + return 10; + case 0x1e0: + return 8; + case 0x160: + return 12; default: return 0; - } + } + else + return 0; } static __inline__ unsigned long ide_default_io_base(int index) { - switch (index) { - case 0: return 0x1f0; - case 1: return 0x170; - case 2: return 0x1e8; - case 3: return 0x168; - case 4: return 0x1e0; - case 5: return 0x160; + if (ide_probe_legacy()) + switch (index) { + case 0: + return 0x1f0; + case 1: + return 0x170; + case 2: + return 0x1e8; + case 3: + return 0x168; + case 4: + return 0x1e0; + case 5: + return 0x160; default: return 0; - } + } + else + return 0; } #define IDE_ARCH_OBSOLETE_INIT @@ -64,7 +102,17 @@ static __inline__ unsigned long ide_defa #define ide_init_default_irq(base) ide_default_irq(base) #endif -#include +/* MIPS port and memory-mapped I/O string operations. */ + +#define __ide_insw insw +#define __ide_insl insl +#define __ide_outsw outsw +#define __ide_outsl outsl + +#define __ide_mm_insw readsw +#define __ide_mm_insl readsl +#define __ide_mm_outsw writesw +#define __ide_mm_outsl writesl #endif /* __KERNEL__ */ diff -puN include/asm-mips/mipsregs.h~mips-generic-mips-updates include/asm-mips/mipsregs.h --- 25/include/asm-mips/mipsregs.h~mips-generic-mips-updates 2005-01-29 11:25:48.703465256 -0800 +++ 25-akpm/include/asm-mips/mipsregs.h 2005-01-29 11:25:48.807449448 -0800 @@ -533,31 +533,50 @@ #ifndef __ASSEMBLY__ /* - * Functions to access the r10k performance counter and control registers + * Functions to access the R10000 performance counters. These are basically + * mfc0 and mtc0 instructions from and to coprocessor register with a 5-bit + * performance counter number encoded into bits 1 ... 5 of the instruction. + * Only performance counters 0 to 1 actually exist, so for a non-R10000 aware + * disassembler these will look like an access to sel 0 or 1. */ -#define read_r10k_perf_cntr(counter) \ -({ unsigned int __res; \ - __asm__ __volatile__( \ - "mfpc\t%0, "STR(counter) \ - : "=r" (__res)); \ - __res;}) +#define read_r10k_perf_cntr(counter) \ +({ \ + unsigned int __res; \ + __asm__ __volatile__( \ + "mfpc\t%0, %1" \ + : "=r" (__res) \ + : "i" (counter)); \ + \ + __res; \ +}) #define write_r10k_perf_cntr(counter,val) \ - __asm__ __volatile__( \ - "mtpc\t%0, "STR(counter) \ - : : "r" (val)); - -#define read_r10k_perf_cntl(counter) \ -({ unsigned int __res; \ - __asm__ __volatile__( \ - "mfps\t%0, "STR(counter) \ - : "=r" (__res)); \ - __res;}) +do { \ + __asm__ __volatile__( \ + "mtpc\t%0, %1" \ + : \ + : "r" (val), "i" (counter)); \ +} while (0) + +#define read_r10k_perf_event(counter) \ +({ \ + unsigned int __res; \ + __asm__ __volatile__( \ + "mfps\t%0, %1" \ + : "=r" (__res) \ + : "i" (counter)); \ + \ + __res; \ +}) #define write_r10k_perf_cntl(counter,val) \ - __asm__ __volatile__( \ - "mtps\t%0, "STR(counter) \ - : : "r" (val)); +do { \ + __asm__ __volatile__( \ + "mtps\t%0, %1" \ + : \ + : "r" (val), "i" (counter)); \ +} while (0) + /* * Macros to access the system control coprocessor @@ -579,8 +598,10 @@ }) #define __read_64bit_c0_register(source, sel) \ -({ unsigned long __res; \ - if (sel == 0) \ +({ unsigned long long __res; \ + if (sizeof(unsigned long) == 4) \ + __res = __read_64bit_c0_split(source, sel); \ + else if (sel == 0) \ __asm__ __volatile__( \ ".set\tmips3\n\t" \ "dmfc0\t%0, " #source "\n\t" \ @@ -611,7 +632,9 @@ do { \ #define __write_64bit_c0_register(register, sel, value) \ do { \ - if (sel == 0) \ + if (sizeof(unsigned long) == 4) \ + __write_64bit_c0_split(register, sel, value); \ + else if (sel == 0) \ __asm__ __volatile__( \ ".set\tmips3\n\t" \ "dmtc0\t%z0, " #register "\n\t" \ @@ -627,8 +650,8 @@ do { \ #define __read_ulong_c0_register(reg, sel) \ ((sizeof(unsigned long) == 4) ? \ - __read_32bit_c0_register(reg, sel) : \ - __read_64bit_c0_register(reg, sel)) + (unsigned long) __read_32bit_c0_register(reg, sel) : \ + (unsigned long) __read_64bit_c0_register(reg, sel)) #define __write_ulong_c0_register(reg, sel, val) \ do { \ @@ -822,6 +845,10 @@ do { \ #define read_c0_framemask() __read_32bit_c0_register($21, 0) #define write_c0_framemask(val) __write_32bit_c0_register($21, 0, val) +/* RM9000 PerfControl performance counter control register */ +#define read_c0_perfcontrol() __read_32bit_c0_register($22, 0) +#define write_c0_perfcontrol(val) __write_32bit_c0_register($22, 0, val) + #define read_c0_diag() __read_32bit_c0_register($22, 0) #define write_c0_diag(val) __write_32bit_c0_register($22, 0, val) @@ -846,6 +873,30 @@ do { \ #define read_c0_depc() __read_ulong_c0_register($24, 0) #define write_c0_depc(val) __write_ulong_c0_register($24, 0, val) +/* + * MIPS32 / MIPS64 performance counters + */ +#define read_c0_perfctrl0() __read_32bit_c0_register($25, 0) +#define write_c0_perfctrl0(val) __write_32bit_c0_register($25, 0, val) +#define read_c0_perfcntr0() __read_32bit_c0_register($25, 1) +#define write_c0_perfcntr0(val) __write_32bit_c0_register($25, 1, val) +#define read_c0_perfctrl1() __read_32bit_c0_register($25, 2) +#define write_c0_perfctrl1(val) __write_32bit_c0_register($25, 2, val) +#define read_c0_perfcntr1() __read_32bit_c0_register($25, 3) +#define write_c0_perfcntr1(val) __write_32bit_c0_register($25, 3, val) +#define read_c0_perfctrl2() __read_32bit_c0_register($25, 4) +#define write_c0_perfctrl2(val) __write_32bit_c0_register($25, 4, val) +#define read_c0_perfcntr2() __read_32bit_c0_register($25, 5) +#define write_c0_perfcntr2(val) __write_32bit_c0_register($25, 5, val) +#define read_c0_perfctrl3() __read_32bit_c0_register($25, 6) +#define write_c0_perfctrl3(val) __write_32bit_c0_register($25, 6, val) +#define read_c0_perfcntr3() __read_32bit_c0_register($25, 7) +#define write_c0_perfcntr3(val) __write_32bit_c0_register($25, 7, val) + +/* RM9000 PerfCount performance counter register */ +#define read_c0_perfcount() __read_64bit_c0_register($25, 0) +#define write_c0_perfcount(val) __write_64bit_c0_register($25, 0, val) + #define read_c0_ecc() __read_32bit_c0_register($26, 0) #define write_c0_ecc(val) __write_32bit_c0_register($26, 0, val) diff -puN include/asm-mips/mmu_context.h~mips-generic-mips-updates include/asm-mips/mmu_context.h --- 25/include/asm-mips/mmu_context.h~mips-generic-mips-updates 2005-01-29 11:25:48.704465104 -0800 +++ 25-akpm/include/asm-mips/mmu_context.h 2005-01-29 11:25:48.807449448 -0800 @@ -19,26 +19,30 @@ #include /* - * For the fast tlb miss handlers, we currently keep a per cpu array - * of pointers to the current pgd for each processor. Also, the proc. - * id is stuffed into the context register. This should be changed to - * use the processor id via current->processor, where current is stored - * in watchhi/lo. The context register should be used to contiguously - * map the page tables. + * For the fast tlb miss handlers, we keep a per cpu array of pointers + * to the current pgd for each processor. Also, the proc. id is stuffed + * into the context register. */ +extern unsigned long pgd_current[]; + #define TLBMISS_HANDLER_SETUP_PGD(pgd) \ pgd_current[smp_processor_id()] = (unsigned long)(pgd) + #ifdef CONFIG_MIPS32 -#define TLBMISS_HANDLER_SETUP() \ - write_c0_context((unsigned long) smp_processor_id() << 23); \ +#define TLBMISS_HANDLER_SETUP() \ + write_c0_context((unsigned long) smp_processor_id() << 23); \ TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir) #endif -#ifdef CONFIG_MIPS64 -#define TLBMISS_HANDLER_SETUP() \ +#if defined(CONFIG_MIPS64) && !defined(CONFIG_BUILD_ELF64) +#define TLBMISS_HANDLER_SETUP() \ write_c0_context((unsigned long) &pgd_current[smp_processor_id()] << 23); \ TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir) #endif -extern unsigned long pgd_current[]; +#if defined(CONFIG_MIPS64) && defined(CONFIG_BUILD_ELF64) +#define TLBMISS_HANDLER_SETUP() \ + write_c0_context((unsigned long) smp_processor_id() << 23); \ + TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir) +#endif #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) @@ -150,7 +154,7 @@ static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next) { unsigned long flags; - int cpu = smp_processor_id(); + unsigned int cpu = smp_processor_id(); local_irq_save(flags); diff -puN include/asm-mips/pgtable-32.h~mips-generic-mips-updates include/asm-mips/pgtable-32.h --- 25/include/asm-mips/pgtable-32.h~mips-generic-mips-updates 2005-01-29 11:25:48.706464800 -0800 +++ 25-akpm/include/asm-mips/pgtable-32.h 2005-01-29 11:25:48.808449296 -0800 @@ -98,7 +98,7 @@ extern int add_temporary_entry(unsigned extern void load_pgd(unsigned long pg_dir); -extern pmd_t invalid_pte_table[PAGE_SIZE/sizeof(pmd_t)]; +extern pte_t invalid_pte_table[PAGE_SIZE/sizeof(pte_t)]; /* * Empty pgd/pmd entries point to the invalid_pte_table. diff -puN include/asm-mips/pmon.h~mips-generic-mips-updates include/asm-mips/pmon.h --- 25/include/asm-mips/pmon.h~mips-generic-mips-updates 2005-01-29 11:25:48.707464648 -0800 +++ 25-akpm/include/asm-mips/pmon.h 2005-01-29 11:25:48.809449144 -0800 @@ -4,22 +4,43 @@ * for more details. * * Copyright (C) 2004 by Ralf Baechle + * + * The cpustart method is a PMC-Sierra's function to start the secondary CPU. + * Stock PMON 2000 has the smpfork, semlock and semunlock methods instead. */ #ifndef _ASM_PMON_H #define _ASM_PMON_H struct callvectors { - int (*open) (char*, int, int); /* 0 */ - int (*close) (int); /* 4 */ - int (*read) (int, void*, int); /* 8 */ - int (*write) (int, void*, int); /* 12 */ - off_t (*lseek) (int, off_t, int); /* 16 */ - int (*printf) (const char*, ...); /* 20 */ - void (*cacheflush) (void); /* 24 */ - char* (*gets) (char*); /* 28 */ - int (*cpustart) (int, void *, int, int); /* 32 */ + int (*open) (char*, int, int); + int (*close) (int); + int (*read) (int, void*, int); + int (*write) (int, void*, int); + off_t (*lseek) (int, off_t, int); + int (*printf) (const char*, ...); + void (*cacheflush) (void); + char* (*gets) (char*); + union { + int (*smpfork) (unsigned long cp, char *sp); + int (*cpustart) (long, long, long, long); + } _s; + int (*semlock) (int sem); + void (*semunlock) (int sem); }; extern struct callvectors *debug_vectors; +#define pmon_open(name, flags, mode) debug_vectors->open(name, flage, mode) +#define pmon_close(fd) debug_vectors->close(fd) +#define pmon_read(fd, buf, count) debug_vectors->read(fd, buf, count) +#define pmon_write(fd, buf, count) debug_vectors->write(fd, buf, count) +#define pmon_lseek(fd, off, whence) debug_vectors->lseek(fd, off, whence) +#define pmon_printf(fmt...) debug_vectors->printf(fmt) +#define pmon_cacheflush() debug_vectors->cacheflush() +#define pmon_gets(s) debug_vectors->gets(s) +#define pmon_cpustart(n, f, sp, gp) debug_vectors->_s.cpustart(n, f, sp, gp) +#define pmon_smpfork(cp, sp) debug_vectors->_s.smpfork(cp, sp) +#define pmon_semlock(sem) debug_vectors->semlock(sem) +#define pmon_semunlock(sem) debug_vectors->semunlock(sem) + #endif /* _ASM_PMON_H */ diff -puN include/asm-mips/prefetch.h~mips-generic-mips-updates include/asm-mips/prefetch.h --- 25/include/asm-mips/prefetch.h~mips-generic-mips-updates 2005-01-29 11:25:48.708464496 -0800 +++ 25-akpm/include/asm-mips/prefetch.h 2005-01-29 11:25:48.809449144 -0800 @@ -8,6 +8,8 @@ #ifndef __ASM_PREFETCH_H #define __ASM_PREFETCH_H +#include + /* * R5000 and RM5200 implements pref and prefx instructions but they're nops, so * rather than wasting time we pretend these processors don't support @@ -41,4 +43,46 @@ #define Pref_WriteBackInvalidate 25 #define Pref_PrepareForStore 30 +#ifdef __ASSEMBLY__ + + .macro __pref hint addr +#ifdef CONFIG_CPU_HAS_PREFETCH + pref \hint, \addr +#endif + .endm + + .macro pref_load addr + __pref Pref_Load, \addr + .endm + + .macro pref_store addr + __pref Pref_Store, \addr + .endm + + .macro pref_load_streamed addr + __pref Pref_LoadStreamed, \addr + .endm + + .macro pref_store_streamed addr + __pref Pref_StoreStreamed, \addr + .endm + + .macro pref_load_retained addr + __pref Pref_LoadRetained, \addr + .endm + + .macro pref_store_retained addr + __pref Pref_StoreRetained, \addr + .endm + + .macro pref_wback_inv addr + __pref Pref_WriteBackInvalidate, \addr + .endm + + .macro pref_prepare_for_store addr + __pref Pref_PrepareForStore, \addr + .endm + +#endif + #endif /* __ASM_PREFETCH_H */ diff -puN include/asm-mips/processor.h~mips-generic-mips-updates include/asm-mips/processor.h --- 25/include/asm-mips/processor.h~mips-generic-mips-updates 2005-01-29 11:25:48.710464192 -0800 +++ 25-akpm/include/asm-mips/processor.h 2005-01-29 11:25:48.809449144 -0800 @@ -66,11 +66,6 @@ extern unsigned int vced_count, vcei_cou PAGE_ALIGN(TASK_SIZE32 / 3) : PAGE_ALIGN(TASK_SIZE / 3)) #endif -/* - * Size of io_bitmap in longwords. - */ -#define IO_BITMAP_SIZE 2048 - #define NUM_FPU_REGS 32 typedef __u64 fpureg_t; diff -puN include/asm-mips/r4kcache.h~mips-generic-mips-updates include/asm-mips/r4kcache.h --- 25/include/asm-mips/r4kcache.h~mips-generic-mips-updates 2005-01-29 11:25:48.711464040 -0800 +++ 25-akpm/include/asm-mips/r4kcache.h 2005-01-29 11:25:48.810448992 -0800 @@ -117,6 +117,21 @@ static inline void protected_writeback_d : "i" (Hit_Writeback_Inv_D), "r" (addr)); } +static inline void protected_writeback_scache_line(unsigned long addr) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + ".set mips3\n" + "1:\tcache %0,(%1)\n" + "2:\t.set mips0\n\t" + ".set reorder\n\t" + ".section\t__ex_table,\"a\"\n\t" + STR(PTR)"\t1b,2b\n\t" + ".previous" + : + : "i" (Hit_Writeback_Inv_SD), "r" (addr)); +} + /* * This one is RM7000-specific */ diff -puN /dev/null include/asm-mips/reg.h --- /dev/null 2003-09-15 06:40:47.000000000 -0700 +++ 25-akpm/include/asm-mips/reg.h 2005-01-29 11:25:48.811448840 -0800 @@ -0,0 +1,129 @@ +/* + * Various register offset definitions for debuggers, core file + * examiners and whatnot. + * + * 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, 1999 Ralf Baechle + * Copyright (C) 1995, 1999 Silicon Graphics + */ +#ifndef __ASM_MIPS_REG_H +#define __ASM_MIPS_REG_H + +#include + +#if defined(CONFIG_MIPS32) || defined(WANT_COMPAT_REG_H) + +#define EF_R0 6 +#define EF_R1 7 +#define EF_R2 8 +#define EF_R3 9 +#define EF_R4 10 +#define EF_R5 11 +#define EF_R6 12 +#define EF_R7 13 +#define EF_R8 14 +#define EF_R9 15 +#define EF_R10 16 +#define EF_R11 17 +#define EF_R12 18 +#define EF_R13 19 +#define EF_R14 20 +#define EF_R15 21 +#define EF_R16 22 +#define EF_R17 23 +#define EF_R18 24 +#define EF_R19 25 +#define EF_R20 26 +#define EF_R21 27 +#define EF_R22 28 +#define EF_R23 29 +#define EF_R24 30 +#define EF_R25 31 + +/* + * k0/k1 unsaved + */ +#define EF_R26 32 +#define EF_R27 33 + +#define EF_R28 34 +#define EF_R29 35 +#define EF_R30 36 +#define EF_R31 37 + +/* + * Saved special registers + */ +#define EF_LO 38 +#define EF_HI 39 + +#define EF_CP0_EPC 40 +#define EF_CP0_BADVADDR 41 +#define EF_CP0_STATUS 42 +#define EF_CP0_CAUSE 43 +#define EF_UNUSED0 44 + +#define EF_SIZE 180 + +#endif + +#if CONFIG_MIPS64 + +#define EF_R0 0 +#define EF_R1 1 +#define EF_R2 2 +#define EF_R3 3 +#define EF_R4 4 +#define EF_R5 5 +#define EF_R6 6 +#define EF_R7 7 +#define EF_R8 8 +#define EF_R9 9 +#define EF_R10 10 +#define EF_R11 11 +#define EF_R12 12 +#define EF_R13 13 +#define EF_R14 14 +#define EF_R15 15 +#define EF_R16 16 +#define EF_R17 17 +#define EF_R18 18 +#define EF_R19 19 +#define EF_R20 20 +#define EF_R21 21 +#define EF_R22 22 +#define EF_R23 23 +#define EF_R24 24 +#define EF_R25 25 + +/* + * k0/k1 unsaved + */ +#define EF_R26 26 +#define EF_R27 27 + + +#define EF_R28 28 +#define EF_R29 29 +#define EF_R30 30 +#define EF_R31 31 + +/* + * Saved special registers + */ +#define EF_LO 32 +#define EF_HI 33 + +#define EF_CP0_EPC 34 +#define EF_CP0_BADVADDR 35 +#define EF_CP0_STATUS 36 +#define EF_CP0_CAUSE 37 + +#define EF_SIZE 304 /* size in bytes */ + +#endif /* CONFIG_MIPS64 */ + +#endif /* __ASM_MIPS_REG_H */ diff -puN include/asm-mips/sigcontext.h~mips-generic-mips-updates include/asm-mips/sigcontext.h --- 25/include/asm-mips/sigcontext.h~mips-generic-mips-updates 2005-01-29 11:25:48.713463736 -0800 +++ 25-akpm/include/asm-mips/sigcontext.h 2005-01-29 11:25:48.811448840 -0800 @@ -41,8 +41,6 @@ struct sigcontext { #if _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32 -#include - /* * Keep this struct definition in sync with the sigcontext fragment * in arch/mips/tools/offset.c @@ -66,6 +64,9 @@ struct sigcontext { }; #ifdef __KERNEL__ + +#include + struct sigcontext32 { __u32 sc_regmask; /* Unused */ __u32 sc_status; diff -puN include/asm-mips/spinlock.h~mips-generic-mips-updates include/asm-mips/spinlock.h --- 25/include/asm-mips/spinlock.h~mips-generic-mips-updates 2005-01-29 11:25:48.714463584 -0800 +++ 25-akpm/include/asm-mips/spinlock.h 2005-01-29 11:25:48.812448688 -0800 @@ -9,6 +9,7 @@ #ifndef _ASM_SPINLOCK_H #define _ASM_SPINLOCK_H +#include #include /* diff -puN include/asm-mips/stackframe.h~mips-generic-mips-updates include/asm-mips/stackframe.h --- 25/include/asm-mips/stackframe.h~mips-generic-mips-updates 2005-01-29 11:25:48.716463280 -0800 +++ 25-akpm/include/asm-mips/stackframe.h 2005-01-29 11:25:48.812448688 -0800 @@ -64,7 +64,7 @@ addu k1, k0 LONG_L k1, %lo(kernelsp)(k1) #endif -#ifdef CONFIG_MIPS64 +#if defined(CONFIG_MIPS64) && !defined(CONFIG_BUILD_ELF64) MFC0 k1, CP0_CONTEXT dsra k1, 23 lui k0, %hi(pgd_current) @@ -74,6 +74,12 @@ daddu k1, k0 LONG_L k1, %lo(kernelsp)(k1) #endif +#if defined(CONFIG_MIPS64) && defined(CONFIG_BUILD_ELF64) + MFC0 k1, CP0_CONTEXT + dsrl k1, 23 + dsll k1, k1, 3 + LONG_L k1, kernelsp(k1) +#endif .endm .macro set_saved_sp stackp temp temp2 @@ -83,13 +89,18 @@ sll \temp, 2 LONG_S \stackp, kernelsp(\temp) #endif -#ifdef CONFIG_MIPS64 +#if defined(CONFIG_MIPS64) && !defined(CONFIG_BUILD_ELF64) lw \temp, TI_CPU(gp) dsll \temp, 3 lui \temp2, %hi(kernelsp) daddu \temp, \temp2 LONG_S \stackp, %lo(kernelsp)(\temp) #endif +#if defined(CONFIG_MIPS64) && defined(CONFIG_BUILD_ELF64) + lw \temp, TI_CPU(gp) + dsll \temp, 3 + LONG_S \stackp, kernelsp(\temp) +#endif .endm #else .macro get_saved_sp /* Uniprocessor variation */ @@ -104,6 +115,7 @@ .macro SAVE_SOME .set push + .set noat .set reorder mfc0 k0, CP0_STATUS sll k0, 3 /* extract cu0 bit */ @@ -278,16 +290,16 @@ .macro RESTORE_ALL RESTORE_TEMP - RESTORE_AT RESTORE_STATIC + RESTORE_AT RESTORE_SOME RESTORE_SP .endm .macro RESTORE_ALL_AND_RET RESTORE_TEMP - RESTORE_AT RESTORE_STATIC + RESTORE_AT RESTORE_SOME RESTORE_SP_AND_RET .endm diff -puN include/asm-mips/string.h~mips-generic-mips-updates include/asm-mips/string.h --- 25/include/asm-mips/string.h~mips-generic-mips-updates 2005-01-29 11:25:48.717463128 -0800 +++ 25-akpm/include/asm-mips/string.h 2005-01-29 11:25:48.813448536 -0800 @@ -18,6 +18,8 @@ */ #ifdef CONFIG_MIPS32 +#ifndef IN_STRING_C + #define __HAVE_ARCH_STRCPY static __inline__ char *strcpy(char *__dest, __const__ char *__src) { @@ -96,6 +98,8 @@ static __inline__ int strcmp(__const__ c return __res; } +#endif /* !defined(IN_STRING_C) */ + #define __HAVE_ARCH_STRNCMP static __inline__ int strncmp(__const__ char *__cs, __const__ char *__ct, size_t __count) diff -puN include/asm-mips/uaccess.h~mips-generic-mips-updates include/asm-mips/uaccess.h --- 25/include/asm-mips/uaccess.h~mips-generic-mips-updates 2005-01-29 11:25:48.719462824 -0800 +++ 25-akpm/include/asm-mips/uaccess.h 2005-01-29 11:25:48.814448384 -0800 @@ -150,7 +150,7 @@ static inline int verify_area(int type, * Returns zero on success, or -EFAULT on error. */ #define put_user(x,ptr) \ - __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) + __put_user_check((x),(ptr),sizeof(*(ptr))) /* * get_user: - Get a simple variable from user space. @@ -170,7 +170,7 @@ static inline int verify_area(int type, * On error, the variable @x is set to zero. */ #define get_user(x,ptr) \ - __get_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) + __get_user_check((x),(ptr),sizeof(*(ptr))) /* * __put_user: - Write a simple value into user space, with less checking. @@ -192,7 +192,7 @@ static inline int verify_area(int type, * Returns zero on success, or -EFAULT on error. */ #define __put_user(x,ptr) \ - __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) + __put_user_nocheck((x),(ptr),sizeof(*(ptr))) /* * __get_user: - Get a simple variable from user space, with less checking. @@ -215,7 +215,7 @@ static inline int verify_area(int type, * On error, the variable @x is set to zero. */ #define __get_user(x,ptr) \ - __get_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) + __get_user_nocheck((x),(ptr),sizeof(*(ptr))) struct __large_struct { unsigned long buf[100]; }; #define __m(x) (*(struct __large_struct *)(x)) @@ -232,9 +232,10 @@ struct __large_struct { unsigned long bu #define __get_user_nocheck(x,ptr,size) \ ({ \ - long __gu_err = 0; \ __typeof(*(ptr)) __gu_val = 0; \ long __gu_addr; \ + long __gu_err = 0; \ + \ might_sleep(); \ __gu_addr = (long) (ptr); \ switch (size) { \ @@ -244,17 +245,18 @@ struct __large_struct { unsigned long bu case 8: __GET_USER_DW(__gu_err); break; \ default: __get_user_unknown(); break; \ } \ - x = (__typeof__(*(ptr))) __gu_val; \ + x = (__typeof__(*(ptr))) __gu_val; \ __gu_err; \ }) #define __get_user_check(x,ptr,size) \ ({ \ __typeof__(*(ptr)) __gu_val = 0; \ - long __gu_addr = (long) (ptr); \ + long __gu_addr; \ long __gu_err; \ \ might_sleep(); \ + __gu_addr = (long) (ptr); \ __gu_err = verify_area(VERIFY_READ, (void *) __gu_addr, size); \ \ if (likely(!__gu_err)) { \ @@ -267,7 +269,7 @@ struct __large_struct { unsigned long bu } \ } \ x = (__typeof__(*(ptr))) __gu_val; \ - __gu_err; \ + __gu_err; \ }) #define __get_user_asm(insn,__gu_err) \ @@ -324,9 +326,10 @@ extern void __get_user_unknown(void); #define __put_user_nocheck(x,ptr,size) \ ({ \ - long __pu_err = 0; \ __typeof__(*(ptr)) __pu_val; \ long __pu_addr; \ + long __pu_err = 0; \ + \ might_sleep(); \ __pu_val = (x); \ __pu_addr = (long) (ptr); \ @@ -342,11 +345,13 @@ extern void __get_user_unknown(void); #define __put_user_check(x,ptr,size) \ ({ \ - __typeof__(*(ptr)) __pu_val = (x); \ - long __pu_addr = (long) (ptr); \ + __typeof__(*(ptr)) __pu_val; \ + long __pu_addr; \ long __pu_err; \ \ might_sleep(); \ + __pu_val = (x); \ + __pu_addr = (long) (ptr); \ __pu_err = verify_area(VERIFY_WRITE, (void *) __pu_addr, size); \ \ if (likely(!__pu_err)) { \ diff -puN include/asm-mips/unistd.h~mips-generic-mips-updates include/asm-mips/unistd.h --- 25/include/asm-mips/unistd.h~mips-generic-mips-updates 2005-01-29 11:25:48.720462672 -0800 +++ 25-akpm/include/asm-mips/unistd.h 2005-01-29 11:25:48.815448232 -0800 @@ -1100,6 +1100,9 @@ type name (atype a,btype b,ctype c,dtype #endif /* (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) */ #ifdef __KERNEL__ + +#include + #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_SYS_ALARM _