From: Paul M. <le...@us...> - 2001-10-22 19:16:48
|
Update of /cvsroot/linux-mips/linux/arch/mips/mm In directory usw-pr-cvs1:/tmp/cvs-serv11592/arch/mips/mm Modified Files: Makefile andes.c mips32.c r2300.c r4xx0.c r5432.c rm7k.c sb1.c Log Message: Further syncing with OSS 2.4.10. Massive restructuring of TLB handling. Index: Makefile =================================================================== RCS file: /cvsroot/linux-mips/linux/arch/mips/mm/Makefile,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- Makefile 2001/10/08 16:29:33 1.4 +++ Makefile 2001/10/22 19:16:45 1.5 @@ -5,23 +5,27 @@ # removes any old dependencies. DON'T put your own dependencies here # unless it's something special (ie not a .c file). # -# Note 2! The CFLAGS definition is now in the main makefile... +.S.s: + $(CPP) $(AFLAGS) $< -o $@ +.S.o: + $(CC) $(AFLAGS) -c $< -o $@ + O_TARGET := mm.o export-objs += ioremap.o umap.o obj-y += extable.o init.o ioremap.o fault.o loadmmu.o -obj-$(CONFIG_CPU_R3000) += pg-r2300.o r2300.o -obj-$(CONFIG_CPU_R4300) += pg-r4xx0.o r4xx0.o -obj-$(CONFIG_CPU_R4X00) += pg-r4xx0.o r4xx0.o -obj-$(CONFIG_CPU_VR41XX) += pg-r4xx0.o r4xx0.o -obj-$(CONFIG_CPU_R5000) += pg-r4xx0.o r4xx0.o -obj-$(CONFIG_CPU_NEVADA) += pg-r4xx0.o r4xx0.o -obj-$(CONFIG_CPU_R5432) += pg-r5432.o r5432.o -obj-$(CONFIG_CPU_RM7000) += pg-rm7k.o rm7k.o -obj-$(CONFIG_CPU_MIPS32) += pg-mips32.o mips32.o -obj-$(CONFIG_CPU_MIPS64) += pg-mips32.o mips32.o +obj-$(CONFIG_CPU_R3000) += pg-r3k.o r2300.o tlb-r3k.o tlbex-r3k.o +obj-$(CONFIG_CPU_R4300) += pg-r4k.o r4xx0.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_R4X00) += pg-r4k.o r4xx0.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_VR41XX) += pg-r4k.o r4xx0.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_R5000) += pg-r4k.o r4xx0.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_NEVADA) += pg-r4k.o r4xx0.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_R5432) += pg-r5432.o r5432.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_RM7000) += pg-rm7k.o rm7k.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_MIPS32) += pg-mips32.o mips32.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_MIPS64) += pg-mips32.o mips32.o tlb-r4k.o tlbex-r4k.o obj-$(CONFIG_SGI_IP22) += umap.o obj-$(CONFIG_BAGET_MIPS) += umap.o Index: andes.c =================================================================== RCS file: /cvsroot/linux-mips/linux/arch/mips/mm/andes.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- andes.c 2001/10/11 22:44:25 1.5 +++ andes.c 2001/10/22 19:16:45 1.6 @@ -13,6 +13,8 @@ #include <asm/sgialib.h> #include <asm/mmu_context.h> +extern void r4k_tlb_init(void); + /* Cache operations. XXX Write these dave... */ static inline void andes_flush_cache_all(void) { @@ -59,38 +61,10 @@ protected_flush_icache_line(addr & ~(ic_lsize - 1)); } -/* TLB operations. XXX Write these dave... */ -void local_flush_tlb_all(void) -{ - /* XXX */ -} - -void local_flush_tlb_mm(struct mm_struct *mm) -{ - /* XXX */ -} - -void local_flush_tlb_range(struct mm_struct *mm, unsigned long start, - unsigned long end) -{ - /* XXX */ -} - -void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) -{ - /* XXX */ -} - void pgd_init(unsigned long page) { } -void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, - unsigned long entryhi, unsigned long pagemask) -{ - /* XXX */ -} - void __init ld_mmu_andes(void) { _clear_page = andes_clear_page; @@ -106,14 +80,6 @@ _flush_icache_page = andes_flush_icache_page; _flush_icache_range = andes_flush_icache_range; - write_32bit_cp0_register(CP0_FRAMEMASK, 0); - flush_cache_all(); - local_flush_tlb_all(); - - /* - * The R10k might even work for Linux/MIPS - but we're paranoid - * and refuse to run until this is tested on real silicon - */ - panic("CPU too expensive - making holiday in the ANDES!"); + r4k_tlb_init(); } Index: mips32.c =================================================================== RCS file: /cvsroot/linux-mips/linux/arch/mips/mm/mips32.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- mips32.c 2001/10/09 21:54:13 1.5 +++ mips32.c 2001/10/22 19:16:45 1.6 @@ -31,6 +31,9 @@ #include <asm/system.h> #include <asm/mmu_context.h> +extern void r4k_tlb_init(void); +extern char except_vec0_r4000; + /* CP0 hazard avoidance. */ #define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ "nop; nop; nop; nop; nop; nop;\n\t" \ @@ -413,144 +416,6 @@ protected_flush_icache_line(addr & ~(ic_lsize - 1)); } -#undef DEBUG_TLB -#undef DEBUG_TLBUPDATE - -void local_flush_tlb_all(void) -{ - unsigned long flags; - unsigned long old_ctx; - int entry; - -#ifdef DEBUG_TLB - printk("[tlball]"); -#endif - - __save_and_cli(flags); - /* Save old context and create impossible VPN2 value */ - old_ctx = (get_entryhi() & 0xff); - set_entryhi(KSEG0); - set_entrylo0(0); - set_entrylo1(0); - BARRIER; - - entry = get_wired(); - - /* Blast 'em all away. */ - while(entry < mips_cpu.tlbsize) { - /* Make sure all entries differ. */ - set_entryhi(KSEG0+entry*0x2000); - set_index(entry); - BARRIER; - tlb_write_indexed(); - BARRIER; - entry++; - } - BARRIER; - set_entryhi(old_ctx); - __restore_flags(flags); -} - -void local_flush_tlb_mm(struct mm_struct *mm) -{ - if (mm->context != 0) { - unsigned long flags; - -#ifdef DEBUG_TLB - printk("[tlbmm<%d>]", mm->context); -#endif - __save_and_cli(flags); - get_new_cpu_mmu_context(mm, smp_processor_id()); - if (mm == current->active_mm) - set_entryhi(mm->context & 0xff); - __restore_flags(flags); - } -} - -void local_flush_tlb_range(struct mm_struct *mm, unsigned long start, - unsigned long end) -{ - if(mm->context != 0) { - unsigned long flags; - int size; - -#ifdef DEBUG_TLB - printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff), - start, end); -#endif - __save_and_cli(flags); - size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - size = (size + 1) >> 1; - if(size <= mips_cpu.tlbsize/2) { - int oldpid = (get_entryhi() & 0xff); - int newpid = (mm->context & 0xff); - - start &= (PAGE_MASK << 1); - end += ((PAGE_SIZE << 1) - 1); - end &= (PAGE_MASK << 1); - while(start < end) { - int idx; - - set_entryhi(start | newpid); - start += (PAGE_SIZE << 1); - BARRIER; - tlb_probe(); - BARRIER; - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - if(idx < 0) - continue; - /* Make sure all entries differ. */ - set_entryhi(KSEG0+idx*0x2000); - BARRIER; - tlb_write_indexed(); - BARRIER; - } - set_entryhi(oldpid); - } else { - get_new_cpu_mmu_context(mm, smp_processor_id()); - if (mm == current->active_mm) - set_entryhi(mm->context & 0xff); - } - __restore_flags(flags); - } -} - -void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) -{ - if (vma->vm_mm->context != 0) { - unsigned long flags; - int oldpid, newpid, idx; - -#ifdef DEBUG_TLB - printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page); -#endif - newpid = (vma->vm_mm->context & 0xff); - page &= (PAGE_MASK << 1); - __save_and_cli(flags); - oldpid = (get_entryhi() & 0xff); - set_entryhi(page | newpid); - BARRIER; - tlb_probe(); - BARRIER; - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - if(idx < 0) - goto finish; - /* Make sure all entries differ. */ - set_entryhi(KSEG0+idx*0x2000); - BARRIER; - tlb_write_indexed(); - - finish: - BARRIER; - set_entryhi(oldpid); - __restore_flags(flags); - } -} - void pgd_init(unsigned long page) { unsigned long *p = (unsigned long *) page; @@ -568,59 +433,6 @@ } } -/* - * Updates the TLB with the new pte(s). - */ -void update_mmu_cache(struct vm_area_struct * vma, - unsigned long address, pte_t pte) -{ - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - int idx, pid; - - /* - * Handle debugger faulting in for debugee. - */ - if (current->active_mm != vma->vm_mm) - return; - - pid = get_entryhi() & 0xff; - -#ifdef DEBUG_TLB - if((pid != (vma->vm_mm->context & 0xff)) || (vma->vm_mm->context == 0)) { - printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n", - (int) (vma->vm_mm->context & 0xff), pid); - } -#endif - - __save_and_cli(flags); - address &= (PAGE_MASK << 1); - set_entryhi(address | (pid)); - pgdp = pgd_offset(vma->vm_mm, address); - BARRIER; - tlb_probe(); - BARRIER; - pmdp = pmd_offset(pgdp, address); - idx = get_index(); - ptep = pte_offset(pmdp, address); - BARRIER; - set_entrylo0(pte_val(*ptep++) >> 6); - set_entrylo1(pte_val(*ptep) >> 6); - set_entryhi(address | (pid)); - BARRIER; - if(idx < 0) { - tlb_write_random(); - } else { - tlb_write_indexed(); - } - BARRIER; - set_entryhi(pid); - BARRIER; - __restore_flags(flags); -} - void show_regs(struct pt_regs * regs) { /* Saved main processor registers. */ @@ -646,37 +458,6 @@ regs->cp0_epc, regs->cp0_status, regs->cp0_cause); } -void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, - unsigned long entryhi, unsigned long pagemask) -{ - unsigned long flags; - unsigned long wired; - unsigned long old_pagemask; - unsigned long old_ctx; - - __save_and_cli(flags); - /* Save old context and create impossible VPN2 value */ - old_ctx = (get_entryhi() & 0xff); - old_pagemask = get_pagemask(); - wired = get_wired(); - set_wired (wired + 1); - set_index (wired); - BARRIER; - set_pagemask (pagemask); - set_entryhi(entryhi); - set_entrylo0(entrylo0); - set_entrylo1(entrylo1); - BARRIER; - tlb_write_indexed(); - BARRIER; - - set_entryhi(old_ctx); - BARRIER; - set_pagemask (old_pagemask); - local_flush_tlb_all(); - __restore_flags(flags); -} - /* Detect and size the various caches. */ static void __init probe_icache(unsigned long config) { @@ -955,13 +736,5 @@ _flush_icache_range = mips32_flush_icache_range; /* Ouch */ __flush_cache_all(); - write_32bit_cp0_register(CP0_WIRED, 0); - - /* - * You should never change this register: - * - The entire mm handling assumes the c0_pagemask register to - * be set for 4kb pages. - */ - write_32bit_cp0_register(CP0_PAGEMASK, PM_4K); - local_flush_tlb_all(); + r4k_tlb_init(); } Index: r2300.c =================================================================== RCS file: /cvsroot/linux-mips/linux/arch/mips/mm/r2300.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- r2300.c 2001/10/09 21:54:13 1.5 +++ r2300.c 2001/10/22 19:16:45 1.6 @@ -23,6 +23,8 @@ #include <asm/bootinfo.h> #include <asm/cpu.h> +extern char except_vec0_r2300; + /* * According to the paper written by D. Miller about Linux cache & TLB * flush implementation, DMA/Driver coherence should be done at the @@ -38,7 +40,6 @@ #include <asm/cacheops.h> #include <asm/r4kcache.h> -#undef DEBUG_TLB #undef DEBUG_CACHE unsigned long __init r3k_cache_size(unsigned long ca_flags) @@ -369,116 +370,6 @@ r3k_flush_dcache_range(start, start + size); } -/* TLB operations. */ -void local_flush_tlb_all(void) -{ - unsigned long flags; - unsigned long old_ctx; - int entry; - -#ifdef DEBUG_TLB - printk("[tlball]"); -#endif - - save_and_cli(flags); - old_ctx = (get_entryhi() & 0xfc0); - write_32bit_cp0_register(CP0_ENTRYLO0, 0); - for (entry = 8; entry < mips_cpu.tlbsize; entry++) { - write_32bit_cp0_register(CP0_INDEX, entry << 8); - write_32bit_cp0_register(CP0_ENTRYHI, ((entry | 0x80000) << 12)); - __asm__ __volatile__("tlbwi"); - } - set_entryhi(old_ctx); - restore_flags(flags); -} - -void local_flush_tlb_mm(struct mm_struct *mm) -{ - if (mm->context != 0) { - unsigned long flags; - -#ifdef DEBUG_TLB - printk("[tlbmm<%lu>]", (unsigned long) mm->context); -#endif - save_and_cli(flags); - get_new_cpu_mmu_context(mm, smp_processor_id()); - if (mm == current->active_mm) - set_entryhi(mm->context & 0xfc0); - restore_flags(flags); - } -} - -void local_flush_tlb_range(struct mm_struct *mm, unsigned long start, - unsigned long end) -{ - if (mm->context != 0) { - unsigned long flags; - int size; - -#ifdef DEBUG_TLB - printk("[tlbrange<%lu,0x%08lx,0x%08lx>]", - (mm->context & 0xfc0), start, end); -#endif - save_and_cli(flags); - size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - if(size <= mips_cpu.tlbsize) { - int oldpid = (get_entryhi() & 0xfc0); - int newpid = (mm->context & 0xfc0); - - start &= PAGE_MASK; - end += (PAGE_SIZE - 1); - end &= PAGE_MASK; - while(start < end) { - int idx; - - set_entryhi(start | newpid); - start += PAGE_SIZE; - tlb_probe(); - idx = get_index(); - set_entrylo0(0); - set_entryhi(KSEG0); - if(idx < 0) - continue; - tlb_write_indexed(); - } - set_entryhi(oldpid); - } else { - get_new_cpu_mmu_context(mm, smp_processor_id()); - if (mm == current->active_mm) - set_entryhi(mm->context & 0xfc0); - } - restore_flags(flags); - } -} - -void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) -{ - if(vma->vm_mm->context != 0) { - unsigned long flags; - int oldpid, newpid, idx; - -#ifdef DEBUG_TLB - printk("[tlbpage<%lu,0x%08lx>]", vma->vm_mm->context, page); -#endif - newpid = (vma->vm_mm->context & 0xfc0); - page &= PAGE_MASK; - save_and_cli(flags); - oldpid = (get_entryhi() & 0xfc0); - set_entryhi(page | newpid); - tlb_probe(); - idx = get_index(); - set_entrylo0(0); - set_entryhi(KSEG0); - if(idx < 0) - goto finish; - tlb_write_indexed(); - -finish: - set_entryhi(oldpid); - restore_flags(flags); - } -} - /* * Initialize new page directory with pointers to invalid ptes */ @@ -511,55 +402,6 @@ "1" (PAGE_SIZE/(sizeof(pmd_t)*8))); } -void update_mmu_cache(struct vm_area_struct * vma, unsigned long address, - pte_t pte) -{ - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - int idx, pid; - - /* - * Handle debugger faulting in for debugee. - */ - if (current->active_mm != vma->vm_mm) - return; - - pid = get_entryhi() & 0xfc0; - -#ifdef DEBUG_TLB - if((pid != (vma->vm_mm->context & 0xfc0)) || (vma->vm_mm->context == 0)) { - printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%lu tlbpid=%d\n", - (vma->vm_mm->context & 0xfc0), pid); - } -#endif - - save_and_cli(flags); - address &= PAGE_MASK; - set_entryhi(address | (pid)); - pgdp = pgd_offset(vma->vm_mm, address); - tlb_probe(); - pmdp = pmd_offset(pgdp, address); - idx = get_index(); - ptep = pte_offset(pmdp, address); - set_entrylo0(pte_val(*ptep)); - set_entryhi(address | (pid)); - if(idx < 0) { - tlb_write_random(); -#if 0 - printk("[MISS]"); -#endif - } else { - tlb_write_indexed(); -#if 0 - printk("[HIT]"); -#endif - } - set_entryhi(pid); - restore_flags(flags); -} - void show_regs(struct pt_regs * regs) { /* @@ -593,28 +435,6 @@ (unsigned int) regs->cp0_cause); } -/* Todo: handle r4k-style TX39 TLB */ -void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, - unsigned long entryhi, unsigned long pagemask) -{ - unsigned long flags; - unsigned long old_ctx; - static unsigned long wired = 0; - - if (wired < 8) { - save_and_cli(flags); - old_ctx = get_entryhi() & 0xfc0; - set_entrylo0(entrylo0); - set_entryhi(entryhi); - set_index(wired); - wired++; - tlb_write_indexed(); - set_entryhi(old_ctx); - local_flush_tlb_all(); - restore_flags(flags); - } -} - static void tx39_flush_icache_all(void ) { @@ -724,4 +544,6 @@ (int) (dcache_size >> 10), (int) dcache_lsize); local_flush_tlb_all(); + memcpy((void *)KSEG0, &except_vec0_r2300, 0x80); + flush_icache_range(KSEG0, KSEG0 + 0x80); } Index: r4xx0.c =================================================================== RCS file: /cvsroot/linux-mips/linux/arch/mips/mm/r4xx0.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- r4xx0.c 2001/10/09 21:54:13 1.8 +++ r4xx0.c 2001/10/22 19:16:45 1.9 @@ -28,10 +28,7 @@ #include <asm/system.h> #include <asm/mmu_context.h> -/* CP0 hazard avoidance. */ -#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ - "nop; nop; nop; nop; nop; nop;\n\t" \ - ".set reorder\n\t") +extern void r4k_tlb_init(void); /* Primary cache parameters. */ static int icache_size, dcache_size; /* Size in bytes */ @@ -1279,140 +1276,6 @@ __restore_flags(flags); } -#undef DEBUG_TLB -#undef DEBUG_TLBUPDATE - -void local_flush_tlb_all(void) -{ - unsigned long flags; - unsigned long old_ctx; - int entry; - -#ifdef DEBUG_TLB - printk("[tlball]"); -#endif - - __save_and_cli(flags); - /* Save old context and create impossible VPN2 value */ - old_ctx = (get_entryhi() & 0xff); - set_entryhi(KSEG0); - set_entrylo0(0); - set_entrylo1(0); - BARRIER; - - entry = get_wired(); - - /* Blast 'em all away. */ - while(entry < mips_cpu.tlbsize) { - set_index(entry); - BARRIER; - tlb_write_indexed(); - BARRIER; - entry++; - } - BARRIER; - set_entryhi(old_ctx); - __restore_flags(flags); -} - -void local_flush_tlb_mm(struct mm_struct *mm) -{ - if (mm->context != 0) { - unsigned long flags; - -#ifdef DEBUG_TLB - printk("[tlbmm<%d>]", mm->context); -#endif - __save_and_cli(flags); - get_new_cpu_mmu_context(mm, smp_processor_id()); - if (mm == current->active_mm) - set_entryhi(mm->context & 0xff); - __restore_flags(flags); - } -} - -void local_flush_tlb_range(struct mm_struct *mm, unsigned long start, - unsigned long end) -{ - if(mm->context != 0) { - unsigned long flags; - int size; - -#ifdef DEBUG_TLB - printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff), - start, end); -#endif - __save_and_cli(flags); - size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - size = (size + 1) >> 1; - if(size <= mips_cpu.tlbsize/2) { - int oldpid = (get_entryhi() & 0xff); - int newpid = (mm->context & 0xff); - - start &= (PAGE_MASK << 1); - end += ((PAGE_SIZE << 1) - 1); - end &= (PAGE_MASK << 1); - while(start < end) { - int idx; - - set_entryhi(start | newpid); - start += (PAGE_SIZE << 1); - BARRIER; - tlb_probe(); - BARRIER; - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - set_entryhi(KSEG0); - BARRIER; - if(idx < 0) - continue; - tlb_write_indexed(); - BARRIER; - } - set_entryhi(oldpid); - } else { - get_new_cpu_mmu_context(mm, smp_processor_id()); - if (mm == current->active_mm) - set_entryhi(mm->context & 0xff); - } - __restore_flags(flags); - } -} - -void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) -{ - if (vma->vm_mm->context != 0) { - unsigned long flags; - int oldpid, newpid, idx; - -#ifdef DEBUG_TLB - printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page); -#endif - newpid = (vma->vm_mm->context & 0xff); - page &= (PAGE_MASK << 1); - __save_and_cli(flags); - oldpid = (get_entryhi() & 0xff); - set_entryhi(page | newpid); - BARRIER; - tlb_probe(); - BARRIER; - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - set_entryhi(KSEG0); - if(idx < 0) - goto finish; - BARRIER; - tlb_write_indexed(); - - finish: - BARRIER; - set_entryhi(oldpid); - __restore_flags(flags); - } -} - void pgd_init(unsigned long page) { unsigned long *p = (unsigned long *) page; @@ -1430,90 +1293,6 @@ } } -/* 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. - */ -void update_mmu_cache(struct vm_area_struct * vma, - unsigned long address, pte_t pte) -{ - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - int idx, pid; - - /* - * Handle debugger faulting in for debugee. - */ - if (current->active_mm != vma->vm_mm) - return; - - pid = get_entryhi() & 0xff; - -#ifdef DEBUG_TLB - if((pid != (vma->vm_mm->context & 0xff)) || (vma->vm_mm->context == 0)) { - printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n", - (int) (vma->vm_mm->context & 0xff), pid); - } -#endif - - __save_and_cli(flags); - address &= (PAGE_MASK << 1); - set_entryhi(address | (pid)); - pgdp = pgd_offset(vma->vm_mm, address); - BARRIER; - tlb_probe(); - BARRIER; - pmdp = pmd_offset(pgdp, address); - idx = get_index(); - ptep = pte_offset(pmdp, address); - BARRIER; - set_entrylo0(pte_val(*ptep++) >> 6); - set_entrylo1(pte_val(*ptep) >> 6); - set_entryhi(address | (pid)); - BARRIER; - if(idx < 0) { - tlb_write_random(); - } else { - tlb_write_indexed(); - } - BARRIER; - set_entryhi(pid); - BARRIER; - __restore_flags(flags); -} - -#if 0 -static void r4k_update_mmu_cache_hwbug(struct vm_area_struct * vma, - unsigned long address, pte_t pte) -{ - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - int idx; - - __save_and_cli(flags); - address &= (PAGE_MASK << 1); - set_entryhi(address | (get_entryhi() & 0xff)); - pgdp = pgd_offset(vma->vm_mm, address); - tlb_probe(); - pmdp = pmd_offset(pgdp, address); - idx = get_index(); - ptep = pte_offset(pmdp, address); - set_entrylo0(pte_val(*ptep++) >> 6); - set_entrylo1(pte_val(*ptep) >> 6); - BARRIER; - if(idx < 0) - tlb_write_random(); - else - tlb_write_indexed(); - BARRIER; - __restore_flags(flags); -} -#endif - void show_regs(struct pt_regs * regs) { /* Saved main processor registers. */ @@ -1539,37 +1318,6 @@ regs->cp0_epc, regs->cp0_status, regs->cp0_cause); } -void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, - unsigned long entryhi, unsigned long pagemask) -{ - unsigned long flags; - unsigned long wired; - unsigned long old_pagemask; - unsigned long old_ctx; - - __save_and_cli(flags); - /* Save old context and create impossible VPN2 value */ - old_ctx = (get_entryhi() & 0xff); - old_pagemask = get_pagemask(); - wired = get_wired(); - set_wired (wired + 1); - set_index (wired); - BARRIER; - set_pagemask (pagemask); - set_entryhi(entryhi); - set_entrylo0(entrylo0); - set_entrylo1(entrylo1); - BARRIER; - tlb_write_indexed(); - BARRIER; - - set_entryhi(old_ctx); - BARRIER; - set_pagemask (old_pagemask); - local_flush_tlb_all(); - __restore_flags(flags); -} - /* Detect and size the various r4k caches. */ static void __init probe_icache(unsigned long config) { @@ -1870,15 +1618,5 @@ } __flush_cache_all(); - write_32bit_cp0_register(CP0_WIRED, 0); - - /* - * You should never change this register: - * - On R4600 1.7 the tlbp never hits for pages smaller than - * the value in the c0_pagemask register. - * - The entire mm handling assumes the c0_pagemask register to - * be set for 4kb pages. - */ - set_pagemask(PM_4K); - local_flush_tlb_all(); + r4k_tlb_init(); } Index: r5432.c =================================================================== RCS file: /cvsroot/linux-mips/linux/arch/mips/mm/r5432.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- r5432.c 2001/10/09 21:54:13 1.4 +++ r5432.c 2001/10/22 19:16:45 1.5 @@ -34,6 +34,8 @@ #include <asm/bootinfo.h> #include <asm/mmu_context.h> +extern void r4k_tlb_init(void); + /* CP0 hazard avoidance. */ #define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ "nop; nop; nop; nop; nop; nop;\n\t" \ @@ -441,144 +443,6 @@ protected_flush_icache_line(addr & ~(ic_lsize - 1)); } -#undef DEBUG_TLB -#undef DEBUG_TLBUPDATE - -#define NTLB_ENTRIES 48 /* Fixed on all R4XX0 variants... */ - -#define NTLB_ENTRIES_HALF 24 /* Fixed on all R4XX0 variants... */ - -void local_flush_tlb_all(void) -{ - unsigned long old_ctx; - int entry; - unsigned long flags; - -#ifdef DEBUG_TLB - printk("[tlball]"); -#endif - - __save_and_cli(flags); - /* Save old context and create impossible VPN2 value */ - old_ctx = (get_entryhi() & 0xff); - set_entryhi(KSEG0); - set_entrylo0(0); - set_entrylo1(0); - BARRIER; - - entry = get_wired(); - - /* Blast 'em all away. */ - while(entry < NTLB_ENTRIES) { - set_index(entry); - BARRIER; - tlb_write_indexed(); - BARRIER; - entry++; - } - BARRIER; - set_entryhi(old_ctx); - __restore_flags(flags); -} - -void local_flush_tlb_mm(struct mm_struct *mm) -{ - if (mm->context != 0) { - unsigned long flags; - -#ifdef DEBUG_TLB - printk("[tlbmm<%d>]", mm->context); -#endif - __save_and_cli(flags); - get_new_cpu_mmu_context(mm, smp_processor_id()); - if (mm == current->active_mm) - set_entryhi(mm->context & 0xff); - __restore_flags(flags); - } -} - -void local_flush_tlb_range(struct mm_struct *mm, unsigned long start, - unsigned long end) -{ - if(mm->context != 0) { - unsigned long flags; - int size; - -#ifdef DEBUG_TLB - printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff), - start, end); -#endif - __save_and_cli(flags); - size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - size = (size + 1) >> 1; - if(size <= NTLB_ENTRIES_HALF) { - int oldpid = (get_entryhi() & 0xff); - int newpid = (mm->context & 0xff); - - start &= (PAGE_MASK << 1); - end += ((PAGE_SIZE << 1) - 1); - end &= (PAGE_MASK << 1); - while(start < end) { - int idx; - - set_entryhi(start | newpid); - start += (PAGE_SIZE << 1); - BARRIER; - tlb_probe(); - BARRIER; - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - set_entryhi(KSEG0); - BARRIER; - if(idx < 0) - continue; - tlb_write_indexed(); - BARRIER; - } - set_entryhi(oldpid); - } else { - get_new_cpu_mmu_context(mm, smp_processor_id()); - if (mm == current->active_mm) - set_entryhi(mm->context & 0xff); - } - __restore_flags(flags); - } -} - -void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) -{ - if (vma->vm_mm->context != 0) { - unsigned long flags; - int oldpid, newpid, idx; - -#ifdef DEBUG_TLB - printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page); -#endif - newpid = (vma->vm_mm->context & 0xff); - page &= (PAGE_MASK << 1); - __save_and_cli(flags); - oldpid = (get_entryhi() & 0xff); - set_entryhi(page | newpid); - BARRIER; - tlb_probe(); - BARRIER; - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - set_entryhi(KSEG0); - if(idx < 0) - goto finish; - BARRIER; - tlb_write_indexed(); - - finish: - BARRIER; - set_entryhi(oldpid); - __restore_flags(flags); - } -} - void pgd_init(unsigned long page) { unsigned long *p = (unsigned long *) page; @@ -596,60 +460,6 @@ } } -/* 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. - */ -void update_mmu_cache(struct vm_area_struct * vma, - unsigned long address, pte_t pte) -{ - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - int idx, pid; - - /* - * Handle debugger faulting in for debugee. - */ - if (current->active_mm != vma->vm_mm) - return; - - pid = get_entryhi() & 0xff; - -#ifdef DEBUG_TLB - if((pid != (vma->vm_mm->context & 0xff)) || (vma->vm_mm->context == 0)) { - printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n", - (int) (vma->vm_mm->context & 0xff), pid); - } -#endif - - __save_and_cli(flags); - address &= (PAGE_MASK << 1); - set_entryhi(address | (pid)); - pgdp = pgd_offset(vma->vm_mm, address); - BARRIER; - tlb_probe(); - BARRIER; - pmdp = pmd_offset(pgdp, address); - idx = get_index(); - ptep = pte_offset(pmdp, address); - BARRIER; - set_entrylo0(pte_val(*ptep++) >> 6); - set_entrylo1(pte_val(*ptep) >> 6); - set_entryhi(address | (pid)); - BARRIER; - if(idx < 0) { - tlb_write_random(); - } else { - tlb_write_indexed(); - } - BARRIER; - set_entryhi(pid); - BARRIER; - __restore_flags(flags); -} - void show_regs(struct pt_regs * regs) { /* Saved main processor registers. */ @@ -675,37 +485,6 @@ regs->cp0_epc, regs->cp0_status, regs->cp0_cause); } -void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, - unsigned long entryhi, unsigned long pagemask) -{ - unsigned long flags; - unsigned long wired; - unsigned long old_pagemask; - unsigned long old_ctx; - - __save_and_cli(flags); - /* Save old context and create impossible VPN2 value */ - old_ctx = (get_entryhi() & 0xff); - old_pagemask = get_pagemask(); - wired = get_wired(); - set_wired (wired + 1); - set_index (wired); - BARRIER; - set_pagemask (pagemask); - set_entryhi(entryhi); - set_entrylo0(entrylo0); - set_entrylo1(entrylo1); - BARRIER; - tlb_write_indexed(); - BARRIER; - - set_entryhi(old_ctx); - BARRIER; - set_pagemask (old_pagemask); - local_flush_tlb_all(); - __restore_flags(flags); -} - /* Detect and size the various r4k caches. */ static void __init probe_icache(unsigned long config) { @@ -754,15 +533,5 @@ _flush_icache_range = r5432_flush_icache_range; /* Ouch */ __flush_cache_all(); - write_32bit_cp0_register(CP0_WIRED, 0); - - /* - * You should never change this register: - * - On R4600 1.7 the tlbp never hits for pages smaller than - * the value in the c0_pagemask register. - * - The entire mm handling assumes the c0_pagemask register to - * be set for 4kb pages. - */ - write_32bit_cp0_register(CP0_PAGEMASK, PM_4K); - local_flush_tlb_all(); + r4k_tlb_init(); } Index: rm7k.c =================================================================== RCS file: /cvsroot/linux-mips/linux/arch/mips/mm/rm7k.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- rm7k.c 2001/10/11 16:41:30 1.3 +++ rm7k.c 2001/10/22 19:16:45 1.4 @@ -26,6 +26,8 @@ #include <asm/bootinfo.h> #include <asm/mmu_context.h> +extern void r4k_tlb_init(void); + /* CP0 hazard avoidance. */ #define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ "nop; nop; nop; nop; nop; nop;\n\t" \ @@ -194,138 +196,6 @@ protected_flush_icache_line(addr & ~(ic_lsize - 1)); } -/* - * Undocumented RM7000: Bit 29 in the info register of the RM7000 v2.0 - * indicates if the TLB has 48 or 64 entries. - * - * 29 1 => 64 entry JTLB - * 0 => 48 entry JTLB - */ -static inline int __attribute__((const)) ntlb_entries(void) -{ - if (get_info() & (1 << 29)) - return 64; - - return 48; -} - -void local_flush_tlb_all(void) -{ - unsigned long flags; - unsigned long old_ctx; - int entry; - - __save_and_cli(flags); - /* Save old context and create impossible VPN2 value */ - old_ctx = get_entryhi() & 0xff; - set_entryhi(KSEG0); - set_entrylo0(0); - set_entrylo1(0); - BARRIER; - - entry = get_wired(); - - /* Blast 'em all away. */ - while (entry < ntlb_entries()) { - set_index(entry); - BARRIER; - tlb_write_indexed(); - BARRIER; - entry++; - } - BARRIER; - set_entryhi(old_ctx); - __restore_flags(flags); -} - -void local_flush_tlb_mm(struct mm_struct *mm) -{ - if(mm->context != 0) { - unsigned long flags; - - __save_and_cli(flags); - get_new_cpu_mmu_context(mm, smp_processor_id()); - if (mm == current->mm) - set_entryhi(mm->context & 0xff); - __restore_flags(flags); - } -} - -void local_flush_tlb_range(struct mm_struct *mm, unsigned long start, - unsigned long end) -{ - if(mm->context != 0) { - unsigned long flags; - int size; - - __save_and_cli(flags); - size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - size = (size + 1) >> 1; - if (size <= (ntlb_entries() / 2)) { - int oldpid = (get_entryhi() & 0xff); - int newpid = (mm->context & 0xff); - - start &= (PAGE_MASK << 1); - end += ((PAGE_SIZE << 1) - 1); - end &= (PAGE_MASK << 1); - while(start < end) { - int idx; - - set_entryhi(start | newpid); - start += (PAGE_SIZE << 1); - BARRIER; - tlb_probe(); - BARRIER; - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - set_entryhi(KSEG0); - BARRIER; - if(idx < 0) - continue; - tlb_write_indexed(); - BARRIER; - } - set_entryhi(oldpid); - } else { - get_new_cpu_mmu_context(mm, smp_processor_id()); - if(mm == current->mm) - set_entryhi(mm->context & 0xff); - } - __restore_flags(flags); - } -} - -void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) -{ - if(vma->vm_mm->context != 0) { - unsigned long flags; - int oldpid, newpid, idx; - - newpid = (vma->vm_mm->context & 0xff); - page &= (PAGE_MASK << 1); - __save_and_cli(flags); - oldpid = (get_entryhi() & 0xff); - set_entryhi(page | newpid); - BARRIER; - tlb_probe(); - BARRIER; - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - set_entryhi(KSEG0); - if(idx < 0) - goto finish; - BARRIER; - tlb_write_indexed(); - - finish: - BARRIER; - set_entryhi(oldpid); - __restore_flags(flags); - } -} - void pgd_init(unsigned long page) { unsigned long *p = (unsigned long *) page; @@ -343,54 +213,6 @@ } } -/* - * 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. - */ -void update_mmu_cache(struct vm_area_struct * vma, - unsigned long address, pte_t pte) -{ - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - int idx, pid; - - /* - * Handle debugger faulting in for debugee. - */ - if (current->active_mm != vma->vm_mm) - return; - - pid = get_entryhi() & 0xff; - - __save_and_cli(flags); - address &= (PAGE_MASK << 1); - set_entryhi(address | (pid)); - pgdp = pgd_offset(vma->vm_mm, address); - BARRIER; - tlb_probe(); - BARRIER; - pmdp = pmd_offset(pgdp, address); - idx = get_index(); - ptep = pte_offset(pmdp, address); - BARRIER; - set_entrylo0(pte_val(*ptep++) >> 6); - set_entrylo1(pte_val(*ptep) >> 6); - set_entryhi(address | (pid)); - BARRIER; - if (idx < 0) { - tlb_write_random(); - } else { - tlb_write_indexed(); - } - BARRIER; - set_entryhi(pid); - BARRIER; - __restore_flags(flags); -} - void show_regs(struct pt_regs * regs) { /* Saved main processor registers. */ @@ -416,83 +238,6 @@ regs->cp0_epc, regs->cp0_status, regs->cp0_cause); } -void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, - unsigned long entryhi, unsigned long pagemask) -{ - unsigned long flags; - unsigned long wired; - unsigned long old_pagemask; - unsigned long old_ctx; - - __save_and_cli(flags); - /* Save old context and create impossible VPN2 value */ - old_ctx = (get_entryhi() & 0xff); - old_pagemask = get_pagemask(); - wired = get_wired(); - set_wired (wired + 1); - set_index (wired); - BARRIER; - set_pagemask (pagemask); - set_entryhi(entryhi); - set_entrylo0(entrylo0); - set_entrylo1(entrylo1); - BARRIER; - tlb_write_indexed(); - BARRIER; - - set_entryhi(old_ctx); - BARRIER; - set_pagemask (old_pagemask); - local_flush_tlb_all(); - __restore_flags(flags); -} - -/* Used for loading TLB entries before trap_init() has started, when we - don't actually want to add a wired entry which remains throughout the - lifetime of the system */ - -static int temp_tlb_entry __initdata; - -__init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1, - unsigned long entryhi, unsigned long pagemask) -{ - int ret = 0; - unsigned long flags; - unsigned long wired; - unsigned long old_pagemask; - unsigned long old_ctx; - - __save_and_cli(flags); - /* Save old context and create impossible VPN2 value */ - old_ctx = (get_entryhi() & 0xff); - old_pagemask = get_pagemask(); - wired = get_wired(); - if (--temp_tlb_entry < wired) { - printk(KERN_WARNING "No TLB space left for add_temporary_entry\n"); - ret = -ENOSPC; - goto out; - } - - set_index (temp_tlb_entry); - BARRIER; - set_pagemask (pagemask); - set_entryhi(entryhi); - set_entrylo0(entrylo0); - set_entrylo1(entrylo1); - BARRIER; - tlb_write_indexed(); - BARRIER; - - set_entryhi(old_ctx); - BARRIER; - set_pagemask (old_pagemask); - out: - __restore_flags(flags); - return ret; -} - - - /* Detect and size the caches. */ static inline void probe_icache(unsigned long config) { @@ -629,8 +374,6 @@ probe_scache(config); probe_tcache(config); - printk("TLB has %d entries.\n", ntlb_entries()); - _clear_page = rm7k_clear_page; _copy_page = rm7k_copy_page; @@ -649,8 +392,5 @@ _dma_cache_inv = rm7k_dma_cache_inv; __flush_cache_all_d32i32(); - write_32bit_cp0_register(CP0_WIRED, 0); - temp_tlb_entry = ntlb_entries() - 1; - write_32bit_cp0_register(CP0_PAGEMASK, PM_4K); - local_flush_tlb_all(); + r4k_tlb_init(); } Index: sb1.c =================================================================== RCS file: /cvsroot/linux-mips/linux/arch/mips/mm/sb1.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- sb1.c 2001/10/11 22:44:25 1.4 +++ sb1.c 2001/10/22 19:16:45 1.5 @@ -26,6 +26,8 @@ #include <asm/mmu_context.h> +extern void r4k_tlb_init(void); + /* These are probed at ld_mmu time */ static unsigned int icache_size; static unsigned int dcache_size; @@ -416,7 +418,7 @@ * at this level instead of as common code in loadmmu()? */ flush_cache_all(); - local_flush_tlb_all(); + r4k_tlb_init(); /* Turn on caching in kseg0 */ set_cp0_config(CONF_CM_CMASK, 0); |
From: James S. <jsi...@tr...> - 2001-10-22 19:21:47
|
>Modified Files: > Makefile andes.c mips32.c r2300.c r4xx0.c r5432.c rm7k.c sb1.c >Log Message: >Further syncing with OSS 2.4.10. Massive restructuring of TLB handling. Thanks. I have been playing around with the tulip driver this morning. Anyone here want to test out a tulip card on anotehr type of mips device. That would be great. I plan to also change the qube over to the new time and new pci code. It will give me a better feel for the new code. |
From: Paul M. <pm...@mv...> - 2001-10-22 19:25:31
|
On Mon, Oct 22, 2001 at 12:21:42PM -0700, James Simmons wrote: > >Modified Files: > > Makefile andes.c mips32.c r2300.c r4xx0.c r5432.c rm7k.c sb1.c > >Log Message: > >Further syncing with OSS 2.4.10. Massive restructuring of TLB handling. >=20 > Thanks. I have been playing around with the tulip driver this morning. > Anyone here want to test out a tulip card on anotehr type of mips device.= =20 > That would be great. I plan to also change the qube over to the new time > and new pci code. It will give me a better feel for the new code. >=20 Just happen to have a tulip card sitting next to me, will stick it in the I= TE board and see if it behaves properly. Regards, --=20 Paul Mundt <pm...@mv...> MontaVista Software, Inc. |