commented early_printk patch because of rejects.
[linux-flexiantxendom0-3.2.10.git] / arch / mips / mm / tlb-r4k.c
index 36126b5..6eaac44 100644 (file)
@@ -3,17 +3,12 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * r4xx0.c: R4000 processor variant specific MMU/Cache routines.
- *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org
- *
- * To do:
- *
- *  - this code is a overbloated pig
- *  - many of the bug workarounds are not efficient at all, but at
- *    least they are functional ...
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2002 MIPS Technologies, Inc.  All rights reserved.
  */
+#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
 
-#undef DEBUG_TLB
-#undef DEBUG_TLBUPDATE
-
-extern char except_vec0_nevada, except_vec0_r4000, except_vec0_r4600;
+extern void except_vec0_nevada(void);
+extern void except_vec0_r4000(void);
+extern void except_vec0_r4600(void);
+extern void except_vec1_r4k(void);
 
 /* CP0 hazard avoidance. */
 #define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
@@ -40,13 +35,9 @@ void local_flush_tlb_all(void)
        unsigned long old_ctx;
        int entry;
 
-#ifdef DEBUG_TLB
-       printk("[tlball]");
-#endif
-
        local_irq_save(flags);
        /* Save old context and create impossible VPN2 value */
-       old_ctx = (read_c0_entryhi() & ASID_MASK);
+       old_ctx = read_c0_entryhi() & ASID_MASK;
        write_c0_entrylo0(0);
        write_c0_entrylo1(0);
        BARRIER;
@@ -59,7 +50,7 @@ void local_flush_tlb_all(void)
                 * Make sure all entries differ.  If they're not different
                 * MIPS32 will take revenge ...
                 */
-               write_c0_entryhi(KSEG0 + entry*0x2000);
+               write_c0_entryhi(KSEG0 + entry * 0x2000);
                write_c0_index(entry);
                BARRIER;
                tlb_write_indexed();
@@ -75,12 +66,8 @@ void local_flush_tlb_mm(struct mm_struct *mm)
 {
        int cpu = smp_processor_id();
 
-       if (cpu_context(cpu, mm) != 0) {
-#ifdef DEBUG_TLB
-               printk("[tlbmm<%d>]", cpu_context(cpu, mm));
-#endif
+       if (cpu_context(cpu, mm) != 0)
                drop_mmu_context(mm,cpu);
-       }
 }
 
 void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
@@ -93,16 +80,12 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
                unsigned long flags;
                int size;
 
-#ifdef DEBUG_TLB
-               printk("[tlbrange<%02x,%08lx,%08lx>]", cpu_context(cpu, mm) & ASID_MASK,
-                      start, end);
-#endif
                local_irq_save(flags);
                size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
                size = (size + 1) >> 1;
                if (size <= current_cpu_data.tlbsize/2) {
                        int oldpid = read_c0_entryhi() & ASID_MASK;
-                       int newpid = cpu_context(cpu, mm) & ASID_MASK;
+                       int newpid = cpu_asid(cpu, mm);
 
                        start &= (PAGE_MASK << 1);
                        end += ((PAGE_SIZE << 1) - 1);
@@ -121,7 +104,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
                                if (idx < 0)
                                        continue;
                                /* Make sure all entries differ. */
-                               write_c0_entryhi(KSEG0 + idx*0x2000);
+                               write_c0_entryhi(KSEG0 + idx * 0x2000);
                                BARRIER;
                                tlb_write_indexed();
                                BARRIER;
@@ -139,9 +122,6 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
        unsigned long flags;
        int size;
 
-#ifdef DEBUG_TLB
-       printk("[tlbkernelrange<%02x,%08lx,%08lx>]", start, end);
-#endif
        local_irq_save(flags);
        size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
        size = (size + 1) >> 1;
@@ -166,7 +146,7 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
                        if (idx < 0)
                                continue;
                        /* Make sure all entries differ. */
-                       write_c0_entryhi(KSEG0 + idx*0x2000);
+                       write_c0_entryhi(KSEG0 + idx * 0x2000);
                        BARRIER;
                        tlb_write_indexed();
                        BARRIER;
@@ -182,18 +162,14 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
 {
        int cpu = smp_processor_id();
 
-       if (!vma || cpu_context(cpu, vma->vm_mm) != 0) {
+       if (cpu_context(cpu, vma->vm_mm) != 0) {
                unsigned long flags;
                int oldpid, newpid, idx;
 
-#ifdef DEBUG_TLB
-               printk("[tlbpage<%d,%08lx>]", cpu_context(cpu, vma->vm_mm),
-                      page);
-#endif
-               newpid = (cpu_context(cpu, vma->vm_mm) & ASID_MASK);
+               newpid = cpu_asid(cpu, vma->vm_mm);
                page &= (PAGE_MASK << 1);
                local_irq_save(flags);
-               oldpid = (read_c0_entryhi() & ASID_MASK);
+               oldpid = read_c0_entryhi() & ASID_MASK;
                write_c0_entryhi(page | newpid);
                BARRIER;
                tlb_probe();
@@ -201,10 +177,10 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
                idx = read_c0_index();
                write_c0_entrylo0(0);
                write_c0_entrylo1(0);
-               if(idx < 0)
+               if (idx < 0)
                        goto finish;
                /* Make sure all entries differ. */
-               write_c0_entryhi(KSEG0+idx*0x2000);
+               write_c0_entryhi(KSEG0 + idx * 0x2000);
                BARRIER;
                tlb_write_indexed();
 
@@ -246,7 +222,8 @@ void local_flush_tlb_one(unsigned long page)
        local_irq_restore(flags);
 }
 
-/* We will need multiple versions of update_mmu_cache(), one that just
+/*
+ * We will need multiple versions of update_mmu_cache(), one that just
  * updates the TLB with the new pte(s), and another which also checks
  * for the R4k "end of page" hardware bug and does the needy.
  */
@@ -266,15 +243,6 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
 
        pid = read_c0_entryhi() & ASID_MASK;
 
-#ifdef DEBUG_TLB
-       if ((pid != cpu_context(cpu, vma->vm_mm) & ASID_MASK) ||
-           (cpu_context(vma->vm_mm) == 0)) {
-               printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d "
-                      "tlbpid=%d\n",
-                      (int) (cpu_context(cpu, vma->vm_mm) & ASID_MASK), pid);
-       }
-#endif
-
        local_irq_save(flags);
        address &= (PAGE_MASK << 1);
        write_c0_entryhi(address | pid);
@@ -332,7 +300,7 @@ static void r4k_update_mmu_cache_hwbug(struct vm_area_struct * vma,
 #endif
 
 void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
-                    unsigned long entryhi, unsigned long pagemask)
+       unsigned long entryhi, unsigned long pagemask)
 {
        unsigned long flags;
        unsigned long wired;
@@ -415,24 +383,22 @@ static void __init probe_tlb(unsigned long config)
        prid = read_c0_prid() & ASID_MASK;
        if (prid == PRID_IMP_RM7000 || !(config & (1 << 31)))
                /*
-                * Not a MIPS32 complianant CPU.  Config 1 register not
+                * Not a MIPS32/MIPS64 CPU..  Config 1 register not
                 * supported, we assume R4k style.  Cpu probing already figured
                 * out the number of tlb entries.
                 */
                return;
 
-#if defined(CONFIG_CPU_MIPS32) || defined (CONFIG_CPU_MIPS64)
        config1 = read_c0_config1();
        if (!((config >> 7) & 3))
                panic("No MMU present");
        else
                current_cpu_data.tlbsize = ((config1 >> 25) & 0x3f) + 1;
-#endif
 }
 
 void __init r4k_tlb_init(void)
 {
-       u32 config = read_c0_config();
+       unsigned int config = read_c0_config();
 
        /*
         * You should never change this register:
@@ -447,13 +413,17 @@ void __init r4k_tlb_init(void)
        temp_tlb_entry = current_cpu_data.tlbsize - 1;
        local_flush_tlb_all();
 
-       if (cpu_has_4kex && cpu_has_4ktlb) {
-               if (current_cpu_data.cputype == CPU_NEVADA)
-                       memcpy((void *)KSEG0, &except_vec0_nevada, 0x80);
-               else if (current_cpu_data.cputype == CPU_R4600)
-                       memcpy((void *)KSEG0, &except_vec0_r4600, 0x80);
-               else
-                       memcpy((void *)KSEG0, &except_vec0_r4000, 0x80);
-               flush_icache_range(KSEG0, KSEG0 + 0x80);
-       }
+#ifdef CONFIG_MIPS32
+       if (current_cpu_data.cputype == CPU_NEVADA)
+               memcpy((void *)KSEG0, &except_vec0_nevada, 0x80);
+       else if (current_cpu_data.cputype == CPU_R4600)
+               memcpy((void *)KSEG0, &except_vec0_r4600, 0x80);
+       else
+               memcpy((void *)KSEG0, &except_vec0_r4000, 0x80);
+       flush_icache_range(KSEG0, KSEG0 + 0x80);
+#endif
+#ifdef CONFIG_MIPS64
+       memcpy((void *)(KSEG0 + 0x80), except_vec1_r4k, 0x80);
+       flush_icache_range(KSEG0 + 0x80, KSEG0 + 0x100);
+#endif
 }