X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fmips%2Fmm%2Fc-sb1.c;h=f9b129491b1e4e038019d715e0d4d63ae4b34629;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=5bae2b0e916654cf07724cde9d0ff304782cf0de;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/arch/mips/mm/c-sb1.c b/arch/mips/mm/c-sb1.c index 5bae2b0e9..f9b129491 100644 --- a/arch/mips/mm/c-sb1.c +++ b/arch/mips/mm/c-sb1.c @@ -20,10 +20,13 @@ */ #include #include -#include + +#include #include #include #include +#include +#include #include extern void sb1_dma_init(void); @@ -32,17 +35,17 @@ extern void sb1_dma_init(void); static unsigned long icache_size; static unsigned long dcache_size; -static unsigned long icache_line_size; -static unsigned long dcache_line_size; +static unsigned short icache_line_size; +static unsigned short dcache_line_size; static unsigned int icache_index_mask; static unsigned int dcache_index_mask; -static unsigned long icache_assoc; -static unsigned long dcache_assoc; +static unsigned short icache_assoc; +static unsigned short dcache_assoc; -static unsigned int icache_sets; -static unsigned int dcache_sets; +static unsigned short icache_sets; +static unsigned short dcache_sets; static unsigned int icache_range_cutoff; static unsigned int dcache_range_cutoff; @@ -157,8 +160,7 @@ static inline void __sb1_flush_icache_all(void) * dcache first, then invalidate the icache. If the page isn't * executable, nothing is required. */ -static void local_sb1_flush_cache_page(struct vm_area_struct *vma, - unsigned long addr) +static void local_sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn) { int cpu = smp_processor_id(); @@ -180,17 +182,18 @@ static void local_sb1_flush_cache_page(struct vm_area_struct *vma, struct flush_cache_page_args { struct vm_area_struct *vma; unsigned long addr; + unsigned long pfn; }; static void sb1_flush_cache_page_ipi(void *info) { struct flush_cache_page_args *args = info; - local_sb1_flush_cache_page(args->vma, args->addr); + local_sb1_flush_cache_page(args->vma, args->addr, args->pfn); } /* Dirty dcache could be on another CPU, so do the IPIs */ -static void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr) +static void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn) { struct flush_cache_page_args args; @@ -200,10 +203,11 @@ static void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr) addr &= PAGE_MASK; args.vma = vma; args.addr = addr; + args.pfn = pfn; on_each_cpu(sb1_flush_cache_page_ipi, (void *) &args, 1, 1); } #else -void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr) +void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn) __attribute__((alias("local_sb1_flush_cache_page"))); #endif @@ -231,7 +235,7 @@ static inline void __sb1_flush_icache_range(unsigned long start, /* * Invalidate all caches on this CPU */ -static void local_sb1___flush_cache_all(void) +static void __attribute_used__ local_sb1___flush_cache_all(void) { __sb1_writeback_inv_dcache_all(); __sb1_flush_icache_all(); @@ -266,7 +270,7 @@ static void local_sb1_flush_icache_range(unsigned long start, __sb1_writeback_inv_dcache_all(); else __sb1_writeback_inv_dcache_range(start, end); - + /* Just flush the whole icache if the range is big enough */ if ((end - start) > icache_range_cutoff) __sb1_flush_icache_all(); @@ -449,6 +453,11 @@ static unsigned int decode_cache_line_size(unsigned int config_field) * 9:7 Dcache Associativity */ +static char *way_string[] = { + "direct mapped", "2-way", "3-way", "4-way", + "5-way", "6-way", "7-way", "8-way", +}; + static __init void probe_cache_sizes(void) { u32 config1; @@ -473,22 +482,27 @@ static __init void probe_cache_sizes(void) */ icache_range_cutoff = icache_sets * icache_line_size; dcache_range_cutoff = (dcache_sets / 2) * icache_line_size; + + printk("Primary instruction cache %ldkB, %s, linesize %d bytes.\n", + icache_size >> 10, way_string[icache_assoc - 1], + icache_line_size); + printk("Primary data cache %ldkB, %s, linesize %d bytes.\n", + dcache_size >> 10, way_string[dcache_assoc - 1], + dcache_line_size); } /* - * This is called from loadmmu.c. We have to set up all the + * This is called from cache.c. We have to set up all the * memory management function pointers, as well as initialize * the caches and tlbs */ -void ld_mmu_sb1(void) +void sb1_cache_init(void) { extern char except_vec2_sb1; extern char handle_vec2_sb1; /* 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); + set_uncached_handler (0x100, &except_vec2_sb1, 0x80); probe_cache_sizes(); @@ -514,6 +528,7 @@ void ld_mmu_sb1(void) flush_cache_page = sb1_flush_cache_page; flush_cache_sigtramp = sb1_flush_cache_sigtramp; + local_flush_data_cache_page = (void *) sb1_nop; flush_data_cache_page = (void *) sb1_nop; /* Full flush */ @@ -526,15 +541,14 @@ void ld_mmu_sb1(void) * before subsequent instruction fetch. */ __asm__ __volatile__( + ".set push \n" " .set noat \n" " .set noreorder \n" - " .set mips3\n\t \n" - " la $1, 1f \n" - " mtc0 $1, $14 \n" + " .set mips3 \n" + " " STR(PTR_LA) " $1, 1f \n" + " " STR(MTC0) " $1, $14 \n" " eret \n" - "1: .set mips0\n\t \n" - " .set at \n" - " .set reorder" + "1: .set pop" : : : "memory");