diff options
Diffstat (limited to 'arch/mips/mm')
-rw-r--r-- | arch/mips/mm/Makefile | 2 | ||||
-rw-r--r-- | arch/mips/mm/c-r3k.c | 18 | ||||
-rw-r--r-- | arch/mips/mm/c-r4k.c | 1 | ||||
-rw-r--r-- | arch/mips/mm/dma-ip32.c | 6 | ||||
-rw-r--r-- | arch/mips/mm/init.c | 15 | ||||
-rw-r--r-- | arch/mips/mm/pg-r4k.c | 10 | ||||
-rw-r--r-- | arch/mips/mm/sc-rm7k.c | 25 | ||||
-rw-r--r-- | arch/mips/mm/tlb-andes.c | 259 | ||||
-rw-r--r-- | arch/mips/mm/tlb-r4k.c | 5 | ||||
-rw-r--r-- | arch/mips/mm/tlbex.c | 13 |
10 files changed, 43 insertions, 311 deletions
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile index b0178da019f..4a6220116c9 100644 --- a/arch/mips/mm/Makefile +++ b/arch/mips/mm/Makefile @@ -12,7 +12,7 @@ obj-$(CONFIG_HIGHMEM) += highmem.o obj-$(CONFIG_CPU_MIPS32) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_MIPS64) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_NEVADA) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o -obj-$(CONFIG_CPU_R10000) += c-r4k.o cex-gen.o pg-r4k.o tlb-andes.o +obj-$(CONFIG_CPU_R10000) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_R3000) += c-r3k.o tlb-r3k.o pg-r4k.o obj-$(CONFIG_CPU_R4300) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_R4X00) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o diff --git a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c index 27f4fa25e8c..9dd1352d574 100644 --- a/arch/mips/mm/c-r3k.c +++ b/arch/mips/mm/c-r3k.c @@ -129,7 +129,7 @@ static void r3k_flush_icache_range(unsigned long start, unsigned long end) "sb\t$0, 0x014(%0)\n\t" "sb\t$0, 0x018(%0)\n\t" "sb\t$0, 0x01c(%0)\n\t" - "sb\t$0, 0x020(%0)\n\t" + "sb\t$0, 0x020(%0)\n\t" "sb\t$0, 0x024(%0)\n\t" "sb\t$0, 0x028(%0)\n\t" "sb\t$0, 0x02c(%0)\n\t" @@ -145,7 +145,7 @@ static void r3k_flush_icache_range(unsigned long start, unsigned long end) "sb\t$0, 0x054(%0)\n\t" "sb\t$0, 0x058(%0)\n\t" "sb\t$0, 0x05c(%0)\n\t" - "sb\t$0, 0x060(%0)\n\t" + "sb\t$0, 0x060(%0)\n\t" "sb\t$0, 0x064(%0)\n\t" "sb\t$0, 0x068(%0)\n\t" "sb\t$0, 0x06c(%0)\n\t" @@ -182,31 +182,31 @@ static void r3k_flush_dcache_range(unsigned long start, unsigned long end) "sb\t$0, 0x004(%0)\n\t" "sb\t$0, 0x008(%0)\n\t" "sb\t$0, 0x00c(%0)\n\t" - "sb\t$0, 0x010(%0)\n\t" + "sb\t$0, 0x010(%0)\n\t" "sb\t$0, 0x014(%0)\n\t" "sb\t$0, 0x018(%0)\n\t" "sb\t$0, 0x01c(%0)\n\t" - "sb\t$0, 0x020(%0)\n\t" + "sb\t$0, 0x020(%0)\n\t" "sb\t$0, 0x024(%0)\n\t" "sb\t$0, 0x028(%0)\n\t" "sb\t$0, 0x02c(%0)\n\t" - "sb\t$0, 0x030(%0)\n\t" + "sb\t$0, 0x030(%0)\n\t" "sb\t$0, 0x034(%0)\n\t" "sb\t$0, 0x038(%0)\n\t" "sb\t$0, 0x03c(%0)\n\t" - "sb\t$0, 0x040(%0)\n\t" + "sb\t$0, 0x040(%0)\n\t" "sb\t$0, 0x044(%0)\n\t" "sb\t$0, 0x048(%0)\n\t" "sb\t$0, 0x04c(%0)\n\t" - "sb\t$0, 0x050(%0)\n\t" + "sb\t$0, 0x050(%0)\n\t" "sb\t$0, 0x054(%0)\n\t" "sb\t$0, 0x058(%0)\n\t" "sb\t$0, 0x05c(%0)\n\t" - "sb\t$0, 0x060(%0)\n\t" + "sb\t$0, 0x060(%0)\n\t" "sb\t$0, 0x064(%0)\n\t" "sb\t$0, 0x068(%0)\n\t" "sb\t$0, 0x06c(%0)\n\t" - "sb\t$0, 0x070(%0)\n\t" + "sb\t$0, 0x070(%0)\n\t" "sb\t$0, 0x074(%0)\n\t" "sb\t$0, 0x078(%0)\n\t" "sb\t$0, 0x07c(%0)\n\t" diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 9572ed44f0d..32b7f6aeb98 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -786,6 +786,7 @@ static void __init probe_pcache(void) c->dcache.waybit = 0; c->options |= MIPS_CPU_CACHE_CDEX_P; + c->options |= MIPS_CPU_PREFETCH; break; case CPU_R4000PC: diff --git a/arch/mips/mm/dma-ip32.c b/arch/mips/mm/dma-ip32.c index a7e3072ff78..ec54ed0d26f 100644 --- a/arch/mips/mm/dma-ip32.c +++ b/arch/mips/mm/dma-ip32.c @@ -138,7 +138,7 @@ dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, BUG(); } - addr = virt_to_phys(ptr)&RAM_OFFSET_MASK;; + addr = virt_to_phys(ptr)&RAM_OFFSET_MASK; if(dev == NULL) addr+=CRIME_HI_MEM_BASE; return (dma_addr_t)addr; @@ -179,7 +179,7 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, addr = (unsigned long) page_address(sg->page)+sg->offset; if (addr) __dma_sync(addr, sg->length, direction); - addr = __pa(addr)&RAM_OFFSET_MASK;; + addr = __pa(addr)&RAM_OFFSET_MASK; if(dev == NULL) addr += CRIME_HI_MEM_BASE; sg->dma_address = (dma_addr_t)addr; @@ -199,7 +199,7 @@ dma_addr_t dma_map_page(struct device *dev, struct page *page, addr = (unsigned long) page_address(page) + offset; dma_cache_wback_inv(addr, size); - addr = __pa(addr)&RAM_OFFSET_MASK;; + addr = __pa(addr)&RAM_OFFSET_MASK; if(dev == NULL) addr += CRIME_HI_MEM_BASE; diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 0ff9a348b84..ad89c442f29 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -25,6 +25,7 @@ #include <linux/highmem.h> #include <linux/swap.h> #include <linux/proc_fs.h> +#include <linux/pfn.h> #include <asm/bootinfo.h> #include <asm/cachectl.h> @@ -54,7 +55,8 @@ unsigned long empty_zero_page, zero_page_mask; */ unsigned long setup_zero_pages(void) { - unsigned long order, size; + unsigned int order; + unsigned long size; struct page *page; if (cpu_has_vce) @@ -67,9 +69,9 @@ unsigned long setup_zero_pages(void) panic("Oh boy, that early out of memory?"); page = virt_to_page(empty_zero_page); + split_page(page, order); while (page < virt_to_page(empty_zero_page + (PAGE_SIZE << order))) { SetPageReserved(page); - set_page_count(page, 1); page++; } @@ -176,9 +178,6 @@ void __init paging_init(void) free_area_init(zones_size); } -#define PFN_UP(x) (((x) + PAGE_SIZE - 1) >> PAGE_SHIFT) -#define PFN_DOWN(x) ((x) >> PAGE_SHIFT) - static inline int page_is_ram(unsigned long pagenr) { int i; @@ -244,7 +243,7 @@ void __init mem_init(void) #ifdef CONFIG_LIMITED_DMA set_page_address(page, lowmem_page_address(page)); #endif - set_page_count(page, 1); + init_page_count(page); __free_page(page); totalhigh_pages++; } @@ -291,7 +290,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) for (; start < end; start += PAGE_SIZE) { ClearPageReserved(virt_to_page(start)); - set_page_count(virt_to_page(start), 1); + init_page_count(virt_to_page(start)); free_page(start); totalram_pages++; } @@ -314,7 +313,7 @@ void free_initmem(void) page = addr; #endif ClearPageReserved(virt_to_page(page)); - set_page_count(virt_to_page(page), 1); + init_page_count(virt_to_page(page)); free_page(page); totalram_pages++; freed += PAGE_SIZE; diff --git a/arch/mips/mm/pg-r4k.c b/arch/mips/mm/pg-r4k.c index f51e180072e..e4390dc3eb4 100644 --- a/arch/mips/mm/pg-r4k.c +++ b/arch/mips/mm/pg-r4k.c @@ -124,7 +124,7 @@ static inline void build_nop(void) static inline void build_src_pref(int advance) { - if (!(load_offset & (cpu_dcache_line_size() - 1))) { + if (!(load_offset & (cpu_dcache_line_size() - 1)) && advance) { union mips_instruction mi; mi.i_format.opcode = pref_op; @@ -166,7 +166,7 @@ static inline void build_load_reg(int reg) static inline void build_dst_pref(int advance) { - if (!(store_offset & (cpu_dcache_line_size() - 1))) { + if (!(store_offset & (cpu_dcache_line_size() - 1)) && advance) { union mips_instruction mi; mi.i_format.opcode = pref_op; @@ -340,6 +340,12 @@ void __init build_clear_page(void) if (cpu_has_prefetch) { switch (current_cpu_data.cputype) { + case CPU_TX49XX: + /* TX49 supports only Pref_Load */ + pref_offset_clear = 0; + pref_offset_copy = 0; + break; + case CPU_RM9000: /* * As a workaround for erratum G105 which make the diff --git a/arch/mips/mm/sc-rm7k.c b/arch/mips/mm/sc-rm7k.c index 9e8ff8badb1..3b6cc9ba1b0 100644 --- a/arch/mips/mm/sc-rm7k.c +++ b/arch/mips/mm/sc-rm7k.c @@ -9,6 +9,7 @@ #include <linux/init.h> #include <linux/kernel.h> #include <linux/mm.h> +#include <linux/bitops.h> #include <asm/addrspace.h> #include <asm/bcache.h> @@ -43,14 +44,7 @@ static void rm7k_sc_wback_inv(unsigned long addr, unsigned long size) /* Catch bad driver code */ BUG_ON(size == 0); - a = addr & ~(sc_lsize - 1); - end = (addr + size - 1) & ~(sc_lsize - 1); - while (1) { - flush_scache_line(a); /* Hit_Writeback_Inv_SD */ - if (a == end) - break; - a += sc_lsize; - } + blast_scache_range(addr, addr + size); if (!rm7k_tcache_enabled) return; @@ -74,14 +68,7 @@ static void rm7k_sc_inv(unsigned long addr, unsigned long size) /* Catch bad driver code */ BUG_ON(size == 0); - a = addr & ~(sc_lsize - 1); - end = (addr + size - 1) & ~(sc_lsize - 1); - while (1) { - invalidate_scache_line(a); /* Hit_Invalidate_SD */ - if (a == end) - break; - a += sc_lsize; - } + blast_inv_scache_range(addr, addr + size); if (!rm7k_tcache_enabled) return; @@ -143,11 +130,17 @@ struct bcache_ops rm7k_sc_ops = { void __init rm7k_sc_init(void) { + struct cpuinfo_mips *c = ¤t_cpu_data; unsigned int config = read_c0_config(); if ((config & RM7K_CONF_SC)) return; + c->scache.linesz = sc_lsize; + c->scache.ways = 4; + c->scache.waybit= ffs(scache_size / c->scache.ways) - 1; + c->scache.waysize = scache_size / c->scache.ways; + c->scache.sets = scache_size / (c->scache.linesz * c->scache.ways); printk(KERN_INFO "Secondary cache size %dK, linesize %d bytes.\n", (scache_size >> 10), sc_lsize); diff --git a/arch/mips/mm/tlb-andes.c b/arch/mips/mm/tlb-andes.c deleted file mode 100644 index 3f422a849c4..00000000000 --- a/arch/mips/mm/tlb-andes.c +++ /dev/null @@ -1,259 +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) 1997, 1998, 1999 Ralf Baechle (ralf@gnu.org) - * Copyright (C) 1999 Silicon Graphics, Inc. - * Copyright (C) 2000 Kanoj Sarcar (kanoj@sgi.com) - */ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/mm.h> -#include <asm/page.h> -#include <asm/pgtable.h> -#include <asm/system.h> -#include <asm/mmu_context.h> - -extern void build_tlb_refill_handler(void); - -#define NTLB_ENTRIES 64 -#define NTLB_ENTRIES_HALF 32 - -void local_flush_tlb_all(void) -{ - unsigned long flags; - unsigned long old_ctx; - unsigned long entry; - - local_irq_save(flags); - /* Save old context and create impossible VPN2 value */ - old_ctx = read_c0_entryhi() & ASID_MASK; - write_c0_entryhi(CKSEG0); - write_c0_entrylo0(0); - write_c0_entrylo1(0); - - entry = read_c0_wired(); - - /* Blast 'em all away. */ - while (entry < NTLB_ENTRIES) { - write_c0_index(entry); - tlb_write_indexed(); - entry++; - } - write_c0_entryhi(old_ctx); - local_irq_restore(flags); -} - -void local_flush_tlb_mm(struct mm_struct *mm) -{ - int cpu = smp_processor_id(); - if (cpu_context(cpu, mm) != 0) { - drop_mmu_context(mm,cpu); - } -} - -void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, - unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - int cpu = smp_processor_id(); - - if (cpu_context(cpu, mm) != 0) { - unsigned long flags; - int size; - - local_irq_save(flags); - size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - size = (size + 1) >> 1; - if (size <= NTLB_ENTRIES_HALF) { - int oldpid = (read_c0_entryhi() & ASID_MASK); - int newpid = (cpu_context(smp_processor_id(), mm) - & ASID_MASK); - - start &= (PAGE_MASK << 1); - end += ((PAGE_SIZE << 1) - 1); - end &= (PAGE_MASK << 1); - while(start < end) { - int idx; - - write_c0_entryhi(start | newpid); - start += (PAGE_SIZE << 1); - tlb_probe(); - idx = read_c0_index(); - write_c0_entrylo0(0); - write_c0_entrylo1(0); - write_c0_entryhi(CKSEG0); - if(idx < 0) - continue; - tlb_write_indexed(); - } - write_c0_entryhi(oldpid); - } else { - drop_mmu_context(mm, cpu); - } - local_irq_restore(flags); - } -} - -void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) -{ - unsigned long flags; - int size; - - size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - size = (size + 1) >> 1; - - local_irq_save(flags); - if (size <= NTLB_ENTRIES_HALF) { - int pid = read_c0_entryhi(); - - start &= (PAGE_MASK << 1); - end += ((PAGE_SIZE << 1) - 1); - end &= (PAGE_MASK << 1); - - while (start < end) { - int idx; - - write_c0_entryhi(start); - start += (PAGE_SIZE << 1); - tlb_probe(); - idx = read_c0_index(); - write_c0_entrylo0(0); - write_c0_entrylo1(0); - write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT+1))); - if (idx < 0) - continue; - tlb_write_indexed(); - } - write_c0_entryhi(pid); - } else { - local_flush_tlb_all(); - } - local_irq_restore(flags); -} - -void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) -{ - if (cpu_context(smp_processor_id(), vma->vm_mm) != 0) { - unsigned long flags; - int oldpid, newpid, idx; - - newpid = (cpu_context(smp_processor_id(), vma->vm_mm) & - ASID_MASK); - page &= (PAGE_MASK << 1); - local_irq_save(flags); - oldpid = (read_c0_entryhi() & ASID_MASK); - write_c0_entryhi(page | newpid); - tlb_probe(); - idx = read_c0_index(); - write_c0_entrylo0(0); - write_c0_entrylo1(0); - write_c0_entryhi(CKSEG0); - if (idx < 0) - goto finish; - tlb_write_indexed(); - - finish: - write_c0_entryhi(oldpid); - local_irq_restore(flags); - } -} - -/* - * This one is only used for pages with the global bit set so we don't care - * much about the ASID. - */ -void local_flush_tlb_one(unsigned long page) -{ - unsigned long flags; - int oldpid, idx; - - local_irq_save(flags); - page &= (PAGE_MASK << 1); - oldpid = read_c0_entryhi() & 0xff; - write_c0_entryhi(page); - tlb_probe(); - idx = read_c0_index(); - write_c0_entrylo0(0); - write_c0_entrylo1(0); - if (idx >= 0) { - /* Make sure all entries differ. */ - write_c0_entryhi(CKSEG0+(idx<<(PAGE_SHIFT+1))); - tlb_write_indexed(); - } - write_c0_entryhi(oldpid); - - local_irq_restore(flags); -} - -/* XXX Simplify this. On the R10000 writing a TLB entry for an virtual - address that already exists will overwrite the old entry and not result - in TLB malfunction or TLB shutdown. */ -void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) -{ - unsigned long flags; - pgd_t *pgdp; - pud_t *pudp; - pmd_t *pmdp; - pte_t *ptep; - int idx, pid; - - /* - * Handle debugger faulting in for debugee. - */ - if (current->active_mm != vma->vm_mm) - return; - - pid = read_c0_entryhi() & ASID_MASK; - - if ((pid != (cpu_context(smp_processor_id(), vma->vm_mm) & ASID_MASK)) - || (cpu_context(smp_processor_id(), vma->vm_mm) == 0)) { - printk(KERN_WARNING - "%s: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n", - __FUNCTION__, (int) (cpu_context(smp_processor_id(), - vma->vm_mm) & ASID_MASK), pid); - } - - local_irq_save(flags); - address &= (PAGE_MASK << 1); - write_c0_entryhi(address | (pid)); - pgdp = pgd_offset(vma->vm_mm, address); - tlb_probe(); - pudp = pud_offset(pgdp, address); - pmdp = pmd_offset(pudp, address); - idx = read_c0_index(); - ptep = pte_offset_map(pmdp, address); - write_c0_entrylo0(pte_val(*ptep++) >> 6); - write_c0_entrylo1(pte_val(*ptep) >> 6); - write_c0_entryhi(address | pid); - if (idx < 0) { - tlb_write_random(); - } else { - tlb_write_indexed(); - } - write_c0_entryhi(pid); - local_irq_restore(flags); -} - -void __init tlb_init(void) -{ - /* - * 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_c0_pagemask(PM_4K); - write_c0_wired(0); - write_c0_framemask(0); - - /* From this point on the ARC firmware is dead. */ - local_flush_tlb_all(); - - /* Did I tell you that ARC SUCKS? */ - - build_tlb_refill_handler(); -} diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index 8297970f0bb..a865f2394cb 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c @@ -424,8 +424,13 @@ void __init tlb_init(void) probe_tlb(config); write_c0_pagemask(PM_DEFAULT_MASK); write_c0_wired(0); + write_c0_framemask(0); temp_tlb_entry = current_cpu_data.tlbsize - 1; + + /* From this point on the ARC firmware is dead. */ local_flush_tlb_all(); + /* Did I tell you that ARC SUCKS? */ + build_tlb_refill_handler(); } diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index ac4f4bfaae5..599b3c29718 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -951,7 +951,6 @@ build_get_pmde64(u32 **p, struct label **l, struct reloc **r, /* No i_nop needed here, since the next insn doesn't touch TMP. */ #ifdef CONFIG_SMP -# ifdef CONFIG_BUILD_ELF64 /* * 64 bit SMP running in XKPHYS has smp_processor_id() << 3 * stored in CONTEXT. @@ -962,18 +961,6 @@ build_get_pmde64(u32 **p, struct label **l, struct reloc **r, i_daddu(p, ptr, ptr, tmp); i_dmfc0(p, tmp, C0_BADVADDR); i_ld(p, ptr, rel_lo(pgdc), ptr); -# else - /* - * 64 bit SMP running in compat space has the lower part of - * &pgd_current[smp_processor_id()] stored in CONTEXT. - */ - if (!in_compat_space_p(pgdc)) - panic("Invalid page directory address!"); - - i_dmfc0(p, ptr, C0_CONTEXT); - i_dsra(p, ptr, ptr, 23); - i_ld(p, ptr, 0, ptr); -# endif #else i_LA_mostly(p, ptr, pgdc); i_ld(p, ptr, rel_lo(pgdc), ptr); |