Changeset 8165


Ignore:
Timestamp:
2007-07-26T06:35:23+02:00 (11 years ago)
Author:
nbd
Message:

brcm47xx-2.6: add a few nops here, some irq saving there, blast the full cache on page icache flushes
i really hate the broadcom cpu bugs, but it's much more stable now.
PS: A /* Ouch */ in the original source showed me the way ;)

Files:
2 edited

Legend:

Unmodified
Added
Removed
  • tags/kamikaze_7.07/target/linux/brcm47xx-2.6/patches-2.6.22/150-cpu_fixes.patch

    r7865 r8165  
    1 Index: linux-2.6.22-rc6/arch/mips/kernel/genex.S 
     1Index: linux-2.6.22/arch/mips/kernel/genex.S 
    22=================================================================== 
    3 --- linux-2.6.22-rc6.orig/arch/mips/kernel/genex.S      2007-07-04 01:52:47.812492000 +0200 
    4 +++ linux-2.6.22-rc6/arch/mips/kernel/genex.S   2007-07-04 01:53:01.585352750 +0200 
     3--- linux-2.6.22.orig/arch/mips/kernel/genex.S  2007-07-26 06:29:25.057170943 +0200 
     4+++ linux-2.6.22/arch/mips/kernel/genex.S       2007-07-26 06:29:40.890073208 +0200 
    55@@ -51,6 +51,10 @@ 
    66 NESTED(except_vec3_generic, 0, sp) 
     
    1414        mfc0    k0, CP0_INDEX 
    1515 #endif 
    16 Index: linux-2.6.22-rc6/arch/mips/mm/c-r4k.c 
     16Index: linux-2.6.22/arch/mips/mm/c-r4k.c 
    1717=================================================================== 
    18 --- linux-2.6.22-rc6.orig/arch/mips/mm/c-r4k.c  2007-07-04 01:53:01.545350250 +0200 
    19 +++ linux-2.6.22-rc6/arch/mips/mm/c-r4k.c       2007-07-04 02:17:11.435962750 +0200 
     18--- linux-2.6.22.orig/arch/mips/mm/c-r4k.c      2007-07-26 06:29:40.826069560 +0200 
     19+++ linux-2.6.22/arch/mips/mm/c-r4k.c   2007-07-26 06:32:45.956619550 +0200 
    2020@@ -29,6 +29,9 @@ 
    2121 #include <asm/cacheflush.h> /* for run_uncached() */ 
     
    2828  * Special Variant of smp_call_function for use by cache functions: 
    2929  * 
    30 @@ -93,6 +96,9 @@ 
     30@@ -85,14 +88,21 @@ 
     31  
     32 static inline void r4k_blast_dcache_page_dc32(unsigned long addr) 
     33 { 
     34+       unsigned long flags; 
     35+ 
     36+       local_irq_save(flags); 
     37        R4600_HIT_CACHEOP_WAR_IMPL; 
     38        blast_dcache32_page(addr); 
     39+       local_irq_restore(flags); 
     40 } 
     41  
     42 static void __init r4k_blast_dcache_page_setup(void) 
    3143 { 
    3244        unsigned long  dc_lsize = cpu_dcache_line_size(); 
     
    3850                r4k_blast_dcache_page = (void *)cache_noop; 
    3951        else if (dc_lsize == 16) 
    40 @@ -107,6 +113,9 @@ 
     52@@ -107,6 +117,9 @@ 
    4153 { 
    4254        unsigned long dc_lsize = cpu_dcache_line_size(); 
     
    4860                r4k_blast_dcache_page_indexed = (void *)cache_noop; 
    4961        else if (dc_lsize == 16) 
    50 @@ -121,6 +130,9 @@ 
     62@@ -121,6 +134,9 @@ 
    5163 { 
    5264        unsigned long dc_lsize = cpu_dcache_line_size(); 
     
    5870                r4k_blast_dcache = (void *)cache_noop; 
    5971        else if (dc_lsize == 16) 
    60 @@ -538,6 +550,9 @@ 
    61                 r4k_blast_icache(); 
    62         else 
    63                 protected_blast_icache_range(start, end); 
    64 + 
    65 +       if (bcm4710) 
    66 +               r4k_flush_cache_all(); 
    67  } 
     72@@ -202,8 +218,12 @@ 
     73  
     74 static void (* r4k_blast_icache_page)(unsigned long addr); 
     75  
     76+static void r4k_flush_cache_all(void); 
     77 static void __init r4k_blast_icache_page_setup(void) 
     78 { 
     79+#ifdef CONFIG_BCM947XX 
     80+       r4k_blast_icache_page = (void *)r4k_flush_cache_all; 
     81+#else 
     82        unsigned long ic_lsize = cpu_icache_line_size(); 
     83  
     84        if (ic_lsize == 0) 
     85@@ -214,6 +234,7 @@ 
     86                r4k_blast_icache_page = blast_icache32_page; 
     87        else if (ic_lsize == 64) 
     88                r4k_blast_icache_page = blast_icache64_page; 
     89+#endif 
     90 } 
     91  
     92  
     93@@ -221,6 +242,9 @@ 
     94  
     95 static void __init r4k_blast_icache_page_indexed_setup(void) 
     96 { 
     97+#ifdef CONFIG_BCM947XX 
     98+       r4k_blast_icache_page_indexed = (void *)r4k_flush_cache_all; 
     99+#else 
     100        unsigned long ic_lsize = cpu_icache_line_size(); 
     101  
     102        if (ic_lsize == 0) 
     103@@ -239,6 +263,7 @@ 
     104                                blast_icache32_page_indexed; 
     105        } else if (ic_lsize == 64) 
     106                r4k_blast_icache_page_indexed = blast_icache64_page_indexed; 
     107+#endif 
     108 } 
     109  
     110 static void (* r4k_blast_icache)(void); 
     111@@ -322,12 +347,17 @@ 
     112  */ 
     113 static inline void local_r4k_flush_cache_all(void * args) 
     114 { 
     115+       unsigned long flags; 
     116+ 
     117+       local_irq_save(flags); 
     118        r4k_blast_dcache(); 
     119+       r4k_blast_icache(); 
     120+       local_irq_restore(flags); 
     121 } 
     122  
     123 static void r4k_flush_cache_all(void) 
     124 { 
     125-       if (!cpu_has_dc_aliases) 
     126+       if (!cpu_has_dc_aliases && cpu_use_kmap_coherent) 
     127                return; 
     128  
     129        r4k_on_each_cpu(local_r4k_flush_cache_all, NULL, 1, 1); 
     130@@ -335,6 +365,9 @@ 
     131  
     132 static inline void local_r4k___flush_cache_all(void * args) 
     133 { 
     134+       unsigned long flags; 
     135+ 
     136+       local_irq_save(flags); 
     137        r4k_blast_dcache(); 
     138        r4k_blast_icache(); 
     139  
     140@@ -348,6 +381,7 @@ 
     141        case CPU_R14000: 
     142                r4k_blast_scache(); 
     143        } 
     144+       local_irq_restore(flags); 
     145 } 
     146  
     147 static void r4k___flush_cache_all(void) 
     148@@ -358,17 +392,21 @@ 
     149 static inline void local_r4k_flush_cache_range(void * args) 
     150 { 
     151        struct vm_area_struct *vma = args; 
     152+       unsigned long flags; 
     153  
     154        if (!(cpu_context(smp_processor_id(), vma->vm_mm))) 
     155                return; 
     156  
     157+       local_irq_save(flags); 
     158        r4k_blast_dcache(); 
     159+       r4k_blast_icache(); 
     160+       local_irq_restore(flags); 
     161 } 
     162  
     163 static void r4k_flush_cache_range(struct vm_area_struct *vma, 
     164        unsigned long start, unsigned long end) 
     165 { 
     166-       if (!cpu_has_dc_aliases) 
     167+       if (!cpu_has_dc_aliases && cpu_use_kmap_coherent) 
     168                return; 
     169  
     170        r4k_on_each_cpu(local_r4k_flush_cache_range, vma, 1, 1); 
     171@@ -377,6 +415,7 @@ 
     172 static inline void local_r4k_flush_cache_mm(void * args) 
     173 { 
     174        struct mm_struct *mm = args; 
     175+       unsigned long flags; 
     176  
     177        if (!cpu_context(smp_processor_id(), mm)) 
     178                return; 
     179@@ -395,12 +434,15 @@ 
     180                return; 
     181        } 
     182  
     183+       local_irq_save(flags); 
     184        r4k_blast_dcache(); 
     185+       r4k_blast_icache(); 
     186+       local_irq_restore(flags); 
     187 } 
     188  
     189 static void r4k_flush_cache_mm(struct mm_struct *mm) 
     190 { 
     191-       if (!cpu_has_dc_aliases) 
     192+       if (!cpu_has_dc_aliases && cpu_use_kmap_coherent) 
     193                return; 
     194  
     195        r4k_on_each_cpu(local_r4k_flush_cache_mm, mm, 1, 1); 
     196@@ -420,6 +462,7 @@ 
     197        unsigned long paddr = fcp_args->pfn << PAGE_SHIFT; 
     198        int exec = vma->vm_flags & VM_EXEC; 
     199        struct mm_struct *mm = vma->vm_mm; 
     200+       unsigned long flags; 
     201        pgd_t *pgdp; 
     202        pud_t *pudp; 
     203        pmd_t *pmdp; 
     204@@ -451,8 +494,9 @@ 
     205         * for every cache flush operation.  So we do indexed flushes 
     206         * in that case, which doesn't overly flush the cache too much. 
     207         */ 
     208+       local_irq_save(flags); 
     209        if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) { 
     210-               if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) { 
     211+               if (!cpu_use_kmap_coherent || cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) { 
     212                        r4k_blast_dcache_page(addr); 
     213                        if (exec && !cpu_icache_snoops_remote_store) 
     214                                r4k_blast_scache_page(addr); 
     215@@ -460,14 +504,14 @@ 
     216                if (exec) 
     217                        r4k_blast_icache_page(addr); 
     218  
     219-               return; 
     220+               goto done; 
     221        } 
     222  
     223        /* 
     224         * Do indexed flush, too much work to get the (possible) TLB refills 
     225         * to work correctly. 
     226         */ 
     227-       if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) { 
     228+       if (!cpu_use_kmap_coherent || cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) { 
     229                r4k_blast_dcache_page_indexed(cpu_has_pindexed_dcache ? 
     230                                              paddr : addr); 
     231                if (exec && !cpu_icache_snoops_remote_store) { 
     232@@ -483,6 +527,8 @@ 
     233                } else 
     234                        r4k_blast_icache_page_indexed(addr); 
     235        } 
     236+done: 
     237+       local_irq_restore(flags); 
     238 } 
     239  
     240 static void r4k_flush_cache_page(struct vm_area_struct *vma, 
     241@@ -499,7 +545,11 @@ 
     242  
     243 static inline void local_r4k_flush_data_cache_page(void * addr) 
     244 { 
     245+       unsigned long flags; 
     246+ 
     247+       local_irq_save(flags); 
     248        r4k_blast_dcache_page((unsigned long) addr); 
     249+       local_irq_restore(flags); 
     250 } 
     251  
     252 static void r4k_flush_data_cache_page(unsigned long addr) 
     253@@ -542,6 +592,9 @@ 
    68254  
    69255 static void r4k_flush_icache_range(unsigned long start, unsigned long end) 
    70 @@ -618,6 +633,8 @@ 
     256 { 
     257+#ifdef CONFIG_BCM947XX 
     258+       r4k_flush_cache_all(); 
     259+#else 
     260        struct flush_icache_range_args args; 
     261  
     262        args.start = start; 
     263@@ -549,12 +602,15 @@ 
     264  
     265        r4k_on_each_cpu(local_r4k_flush_icache_range, &args, 1, 1); 
     266        instruction_hazard(); 
     267+#endif 
     268 } 
     269  
     270 #ifdef CONFIG_DMA_NONCOHERENT 
     271  
     272 static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) 
     273 { 
     274+       unsigned long flags; 
     275+ 
     276        /* Catch bad driver code */ 
     277        BUG_ON(size == 0); 
     278  
     279@@ -571,18 +627,21 @@ 
     280         * subset property so we have to flush the primary caches 
     281         * explicitly 
     282         */ 
     283+       local_irq_save(flags); 
     284        if (size >= dcache_size) { 
     285                r4k_blast_dcache(); 
     286        } else { 
     287                R4600_HIT_CACHEOP_WAR_IMPL; 
     288                blast_dcache_range(addr, addr + size); 
     289        } 
     290- 
     291        bc_wback_inv(addr, size); 
     292+       local_irq_restore(flags); 
     293 } 
     294  
     295 static void r4k_dma_cache_inv(unsigned long addr, unsigned long size) 
     296 { 
     297+       unsigned long flags; 
     298+ 
     299        /* Catch bad driver code */ 
     300        BUG_ON(size == 0); 
     301  
     302@@ -594,6 +653,7 @@ 
     303                return; 
     304        } 
     305  
     306+       local_irq_save(flags); 
     307        if (size >= dcache_size) { 
     308                r4k_blast_dcache(); 
     309        } else { 
     310@@ -602,6 +662,7 @@ 
     311        } 
     312  
     313        bc_inv(addr, size); 
     314+       local_irq_restore(flags); 
     315 } 
     316 #endif /* CONFIG_DMA_NONCOHERENT */ 
     317  
     318@@ -616,8 +677,12 @@ 
     319        unsigned long dc_lsize = cpu_dcache_line_size(); 
     320        unsigned long sc_lsize = cpu_scache_line_size(); 
    71321        unsigned long addr = (unsigned long) arg; 
    72   
     322+       unsigned long flags; 
     323  
     324+       local_irq_save(flags); 
    73325        R4600_HIT_CACHEOP_WAR_IMPL; 
    74326+       BCM4710_PROTECTED_FILL_TLB(addr); 
     
    77329                protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); 
    78330        if (!cpu_icache_snoops_remote_store && scache_size) 
    79 @@ -1144,6 +1161,17 @@ 
     331@@ -644,6 +709,7 @@ 
     332        } 
     333        if (MIPS_CACHE_SYNC_WAR) 
     334                __asm__ __volatile__ ("sync"); 
     335+       local_irq_restore(flags); 
     336 } 
     337  
     338 static void r4k_flush_cache_sigtramp(unsigned long addr) 
     339@@ -1144,6 +1210,17 @@ 
    80340         * silly idea of putting something else there ... 
    81341         */ 
     
    95355        case CPU_R4000SC: 
    96356        case CPU_R4000MC: 
    97 @@ -1174,6 +1202,15 @@ 
     357@@ -1174,6 +1251,15 @@ 
    98358        /* Default cache error handler for R4000 and R5000 family */ 
    99359        set_uncached_handler (0x100, &except_vec2_generic, 0x80); 
     
    111371        setup_scache(); 
    112372  
    113 @@ -1219,5 +1256,13 @@ 
     373@@ -1219,5 +1305,13 @@ 
    114374        build_clear_page(); 
    115375        build_copy_page(); 
     
    125385+#endif 
    126386 } 
    127 Index: linux-2.6.22-rc6/arch/mips/mm/tlbex.c 
     387Index: linux-2.6.22/arch/mips/mm/tlbex.c 
    128388=================================================================== 
    129 --- linux-2.6.22-rc6.orig/arch/mips/mm/tlbex.c  2007-07-04 01:53:01.193328250 +0200 
    130 +++ linux-2.6.22-rc6/arch/mips/mm/tlbex.c       2007-07-04 02:17:26.112880000 +0200 
     389--- linux-2.6.22.orig/arch/mips/mm/tlbex.c      2007-07-26 06:29:40.582055658 +0200 
     390+++ linux-2.6.22/arch/mips/mm/tlbex.c   2007-07-26 06:32:45.964620005 +0200 
    131391@@ -1229,6 +1229,10 @@ 
    132392 #endif 
     
    140400 { 
    141401        u32 *p = tlb_handler; 
    142 @@ -1243,6 +1247,11 @@ 
     402@@ -1243,6 +1247,10 @@ 
    143403        memset(relocs, 0, sizeof(relocs)); 
    144404        memset(final_handler, 0, sizeof(final_handler)); 
    145405  
    146406+#ifdef CONFIG_BCM947XX 
    147 +       if (current_cpu_data.cputype == CPU_BCM3302) 
    148 +               i_nop(&p); 
     407+       i_nop(&p); 
    149408+#endif 
    150409+ 
     
    152411         * create the plain linear handler 
    153412         */ 
    154 Index: linux-2.6.22-rc6/include/asm-mips/r4kcache.h 
     413@@ -1736,6 +1744,9 @@ 
     414        memset(labels, 0, sizeof(labels)); 
     415        memset(relocs, 0, sizeof(relocs)); 
     416  
     417+#ifdef CONFIG_BCM947XX 
     418+       i_nop(&p); 
     419+#endif 
     420        if (bcm1250_m3_war()) { 
     421                i_MFC0(&p, K0, C0_BADVADDR); 
     422                i_MFC0(&p, K1, C0_ENTRYHI); 
     423Index: linux-2.6.22/include/asm-mips/r4kcache.h 
    155424=================================================================== 
    156 --- linux-2.6.22-rc6.orig/include/asm-mips/r4kcache.h   2007-07-04 01:52:47.840493750 +0200 
    157 +++ linux-2.6.22-rc6/include/asm-mips/r4kcache.h        2007-07-04 01:53:01.673358250 +0200 
     425--- linux-2.6.22.orig/include/asm-mips/r4kcache.h       2007-07-26 06:29:25.085172538 +0200 
     426+++ linux-2.6.22/include/asm-mips/r4kcache.h    2007-07-26 06:29:40.938075943 +0200 
    158427@@ -17,6 +17,20 @@ 
    159428 #include <asm/cpu-features.h> 
     
    358627  
    359628 #endif /* _ASM_R4KCACHE_H */ 
    360 Index: linux-2.6.22-rc6/include/asm-mips/stackframe.h 
     629Index: linux-2.6.22/include/asm-mips/stackframe.h 
    361630=================================================================== 
    362 --- linux-2.6.22-rc6.orig/include/asm-mips/stackframe.h 2007-07-04 01:52:47.852494500 +0200 
    363 +++ linux-2.6.22-rc6/include/asm-mips/stackframe.h      2007-07-04 01:53:01.697359750 +0200 
     631--- linux-2.6.22.orig/include/asm-mips/stackframe.h     2007-07-26 06:29:25.093172994 +0200 
     632+++ linux-2.6.22/include/asm-mips/stackframe.h  2007-07-26 06:29:40.962077312 +0200 
    364633@@ -350,6 +350,10 @@ 
    365634                .macro  RESTORE_SP_AND_RET 
  • trunk/target/linux/brcm47xx-2.6/patches-2.6.22/150-cpu_fixes.patch

    r7865 r8165  
    1 Index: linux-2.6.22-rc6/arch/mips/kernel/genex.S 
     1Index: linux-2.6.22/arch/mips/kernel/genex.S 
    22=================================================================== 
    3 --- linux-2.6.22-rc6.orig/arch/mips/kernel/genex.S      2007-07-04 01:52:47.812492000 +0200 
    4 +++ linux-2.6.22-rc6/arch/mips/kernel/genex.S   2007-07-04 01:53:01.585352750 +0200 
     3--- linux-2.6.22.orig/arch/mips/kernel/genex.S  2007-07-26 06:29:25.057170943 +0200 
     4+++ linux-2.6.22/arch/mips/kernel/genex.S       2007-07-26 06:29:40.890073208 +0200 
    55@@ -51,6 +51,10 @@ 
    66 NESTED(except_vec3_generic, 0, sp) 
     
    1414        mfc0    k0, CP0_INDEX 
    1515 #endif 
    16 Index: linux-2.6.22-rc6/arch/mips/mm/c-r4k.c 
     16Index: linux-2.6.22/arch/mips/mm/c-r4k.c 
    1717=================================================================== 
    18 --- linux-2.6.22-rc6.orig/arch/mips/mm/c-r4k.c  2007-07-04 01:53:01.545350250 +0200 
    19 +++ linux-2.6.22-rc6/arch/mips/mm/c-r4k.c       2007-07-04 02:17:11.435962750 +0200 
     18--- linux-2.6.22.orig/arch/mips/mm/c-r4k.c      2007-07-26 06:29:40.826069560 +0200 
     19+++ linux-2.6.22/arch/mips/mm/c-r4k.c   2007-07-26 06:32:45.956619550 +0200 
    2020@@ -29,6 +29,9 @@ 
    2121 #include <asm/cacheflush.h> /* for run_uncached() */ 
     
    2828  * Special Variant of smp_call_function for use by cache functions: 
    2929  * 
    30 @@ -93,6 +96,9 @@ 
     30@@ -85,14 +88,21 @@ 
     31  
     32 static inline void r4k_blast_dcache_page_dc32(unsigned long addr) 
     33 { 
     34+       unsigned long flags; 
     35+ 
     36+       local_irq_save(flags); 
     37        R4600_HIT_CACHEOP_WAR_IMPL; 
     38        blast_dcache32_page(addr); 
     39+       local_irq_restore(flags); 
     40 } 
     41  
     42 static void __init r4k_blast_dcache_page_setup(void) 
    3143 { 
    3244        unsigned long  dc_lsize = cpu_dcache_line_size(); 
     
    3850                r4k_blast_dcache_page = (void *)cache_noop; 
    3951        else if (dc_lsize == 16) 
    40 @@ -107,6 +113,9 @@ 
     52@@ -107,6 +117,9 @@ 
    4153 { 
    4254        unsigned long dc_lsize = cpu_dcache_line_size(); 
     
    4860                r4k_blast_dcache_page_indexed = (void *)cache_noop; 
    4961        else if (dc_lsize == 16) 
    50 @@ -121,6 +130,9 @@ 
     62@@ -121,6 +134,9 @@ 
    5163 { 
    5264        unsigned long dc_lsize = cpu_dcache_line_size(); 
     
    5870                r4k_blast_dcache = (void *)cache_noop; 
    5971        else if (dc_lsize == 16) 
    60 @@ -538,6 +550,9 @@ 
    61                 r4k_blast_icache(); 
    62         else 
    63                 protected_blast_icache_range(start, end); 
    64 + 
    65 +       if (bcm4710) 
    66 +               r4k_flush_cache_all(); 
    67  } 
     72@@ -202,8 +218,12 @@ 
     73  
     74 static void (* r4k_blast_icache_page)(unsigned long addr); 
     75  
     76+static void r4k_flush_cache_all(void); 
     77 static void __init r4k_blast_icache_page_setup(void) 
     78 { 
     79+#ifdef CONFIG_BCM947XX 
     80+       r4k_blast_icache_page = (void *)r4k_flush_cache_all; 
     81+#else 
     82        unsigned long ic_lsize = cpu_icache_line_size(); 
     83  
     84        if (ic_lsize == 0) 
     85@@ -214,6 +234,7 @@ 
     86                r4k_blast_icache_page = blast_icache32_page; 
     87        else if (ic_lsize == 64) 
     88                r4k_blast_icache_page = blast_icache64_page; 
     89+#endif 
     90 } 
     91  
     92  
     93@@ -221,6 +242,9 @@ 
     94  
     95 static void __init r4k_blast_icache_page_indexed_setup(void) 
     96 { 
     97+#ifdef CONFIG_BCM947XX 
     98+       r4k_blast_icache_page_indexed = (void *)r4k_flush_cache_all; 
     99+#else 
     100        unsigned long ic_lsize = cpu_icache_line_size(); 
     101  
     102        if (ic_lsize == 0) 
     103@@ -239,6 +263,7 @@ 
     104                                blast_icache32_page_indexed; 
     105        } else if (ic_lsize == 64) 
     106                r4k_blast_icache_page_indexed = blast_icache64_page_indexed; 
     107+#endif 
     108 } 
     109  
     110 static void (* r4k_blast_icache)(void); 
     111@@ -322,12 +347,17 @@ 
     112  */ 
     113 static inline void local_r4k_flush_cache_all(void * args) 
     114 { 
     115+       unsigned long flags; 
     116+ 
     117+       local_irq_save(flags); 
     118        r4k_blast_dcache(); 
     119+       r4k_blast_icache(); 
     120+       local_irq_restore(flags); 
     121 } 
     122  
     123 static void r4k_flush_cache_all(void) 
     124 { 
     125-       if (!cpu_has_dc_aliases) 
     126+       if (!cpu_has_dc_aliases && cpu_use_kmap_coherent) 
     127                return; 
     128  
     129        r4k_on_each_cpu(local_r4k_flush_cache_all, NULL, 1, 1); 
     130@@ -335,6 +365,9 @@ 
     131  
     132 static inline void local_r4k___flush_cache_all(void * args) 
     133 { 
     134+       unsigned long flags; 
     135+ 
     136+       local_irq_save(flags); 
     137        r4k_blast_dcache(); 
     138        r4k_blast_icache(); 
     139  
     140@@ -348,6 +381,7 @@ 
     141        case CPU_R14000: 
     142                r4k_blast_scache(); 
     143        } 
     144+       local_irq_restore(flags); 
     145 } 
     146  
     147 static void r4k___flush_cache_all(void) 
     148@@ -358,17 +392,21 @@ 
     149 static inline void local_r4k_flush_cache_range(void * args) 
     150 { 
     151        struct vm_area_struct *vma = args; 
     152+       unsigned long flags; 
     153  
     154        if (!(cpu_context(smp_processor_id(), vma->vm_mm))) 
     155                return; 
     156  
     157+       local_irq_save(flags); 
     158        r4k_blast_dcache(); 
     159+       r4k_blast_icache(); 
     160+       local_irq_restore(flags); 
     161 } 
     162  
     163 static void r4k_flush_cache_range(struct vm_area_struct *vma, 
     164        unsigned long start, unsigned long end) 
     165 { 
     166-       if (!cpu_has_dc_aliases) 
     167+       if (!cpu_has_dc_aliases && cpu_use_kmap_coherent) 
     168                return; 
     169  
     170        r4k_on_each_cpu(local_r4k_flush_cache_range, vma, 1, 1); 
     171@@ -377,6 +415,7 @@ 
     172 static inline void local_r4k_flush_cache_mm(void * args) 
     173 { 
     174        struct mm_struct *mm = args; 
     175+       unsigned long flags; 
     176  
     177        if (!cpu_context(smp_processor_id(), mm)) 
     178                return; 
     179@@ -395,12 +434,15 @@ 
     180                return; 
     181        } 
     182  
     183+       local_irq_save(flags); 
     184        r4k_blast_dcache(); 
     185+       r4k_blast_icache(); 
     186+       local_irq_restore(flags); 
     187 } 
     188  
     189 static void r4k_flush_cache_mm(struct mm_struct *mm) 
     190 { 
     191-       if (!cpu_has_dc_aliases) 
     192+       if (!cpu_has_dc_aliases && cpu_use_kmap_coherent) 
     193                return; 
     194  
     195        r4k_on_each_cpu(local_r4k_flush_cache_mm, mm, 1, 1); 
     196@@ -420,6 +462,7 @@ 
     197        unsigned long paddr = fcp_args->pfn << PAGE_SHIFT; 
     198        int exec = vma->vm_flags & VM_EXEC; 
     199        struct mm_struct *mm = vma->vm_mm; 
     200+       unsigned long flags; 
     201        pgd_t *pgdp; 
     202        pud_t *pudp; 
     203        pmd_t *pmdp; 
     204@@ -451,8 +494,9 @@ 
     205         * for every cache flush operation.  So we do indexed flushes 
     206         * in that case, which doesn't overly flush the cache too much. 
     207         */ 
     208+       local_irq_save(flags); 
     209        if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) { 
     210-               if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) { 
     211+               if (!cpu_use_kmap_coherent || cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) { 
     212                        r4k_blast_dcache_page(addr); 
     213                        if (exec && !cpu_icache_snoops_remote_store) 
     214                                r4k_blast_scache_page(addr); 
     215@@ -460,14 +504,14 @@ 
     216                if (exec) 
     217                        r4k_blast_icache_page(addr); 
     218  
     219-               return; 
     220+               goto done; 
     221        } 
     222  
     223        /* 
     224         * Do indexed flush, too much work to get the (possible) TLB refills 
     225         * to work correctly. 
     226         */ 
     227-       if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) { 
     228+       if (!cpu_use_kmap_coherent || cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) { 
     229                r4k_blast_dcache_page_indexed(cpu_has_pindexed_dcache ? 
     230                                              paddr : addr); 
     231                if (exec && !cpu_icache_snoops_remote_store) { 
     232@@ -483,6 +527,8 @@ 
     233                } else 
     234                        r4k_blast_icache_page_indexed(addr); 
     235        } 
     236+done: 
     237+       local_irq_restore(flags); 
     238 } 
     239  
     240 static void r4k_flush_cache_page(struct vm_area_struct *vma, 
     241@@ -499,7 +545,11 @@ 
     242  
     243 static inline void local_r4k_flush_data_cache_page(void * addr) 
     244 { 
     245+       unsigned long flags; 
     246+ 
     247+       local_irq_save(flags); 
     248        r4k_blast_dcache_page((unsigned long) addr); 
     249+       local_irq_restore(flags); 
     250 } 
     251  
     252 static void r4k_flush_data_cache_page(unsigned long addr) 
     253@@ -542,6 +592,9 @@ 
    68254  
    69255 static void r4k_flush_icache_range(unsigned long start, unsigned long end) 
    70 @@ -618,6 +633,8 @@ 
     256 { 
     257+#ifdef CONFIG_BCM947XX 
     258+       r4k_flush_cache_all(); 
     259+#else 
     260        struct flush_icache_range_args args; 
     261  
     262        args.start = start; 
     263@@ -549,12 +602,15 @@ 
     264  
     265        r4k_on_each_cpu(local_r4k_flush_icache_range, &args, 1, 1); 
     266        instruction_hazard(); 
     267+#endif 
     268 } 
     269  
     270 #ifdef CONFIG_DMA_NONCOHERENT 
     271  
     272 static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) 
     273 { 
     274+       unsigned long flags; 
     275+ 
     276        /* Catch bad driver code */ 
     277        BUG_ON(size == 0); 
     278  
     279@@ -571,18 +627,21 @@ 
     280         * subset property so we have to flush the primary caches 
     281         * explicitly 
     282         */ 
     283+       local_irq_save(flags); 
     284        if (size >= dcache_size) { 
     285                r4k_blast_dcache(); 
     286        } else { 
     287                R4600_HIT_CACHEOP_WAR_IMPL; 
     288                blast_dcache_range(addr, addr + size); 
     289        } 
     290- 
     291        bc_wback_inv(addr, size); 
     292+       local_irq_restore(flags); 
     293 } 
     294  
     295 static void r4k_dma_cache_inv(unsigned long addr, unsigned long size) 
     296 { 
     297+       unsigned long flags; 
     298+ 
     299        /* Catch bad driver code */ 
     300        BUG_ON(size == 0); 
     301  
     302@@ -594,6 +653,7 @@ 
     303                return; 
     304        } 
     305  
     306+       local_irq_save(flags); 
     307        if (size >= dcache_size) { 
     308                r4k_blast_dcache(); 
     309        } else { 
     310@@ -602,6 +662,7 @@ 
     311        } 
     312  
     313        bc_inv(addr, size); 
     314+       local_irq_restore(flags); 
     315 } 
     316 #endif /* CONFIG_DMA_NONCOHERENT */ 
     317  
     318@@ -616,8 +677,12 @@ 
     319        unsigned long dc_lsize = cpu_dcache_line_size(); 
     320        unsigned long sc_lsize = cpu_scache_line_size(); 
    71321        unsigned long addr = (unsigned long) arg; 
    72   
     322+       unsigned long flags; 
     323  
     324+       local_irq_save(flags); 
    73325        R4600_HIT_CACHEOP_WAR_IMPL; 
    74326+       BCM4710_PROTECTED_FILL_TLB(addr); 
     
    77329                protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); 
    78330        if (!cpu_icache_snoops_remote_store && scache_size) 
    79 @@ -1144,6 +1161,17 @@ 
     331@@ -644,6 +709,7 @@ 
     332        } 
     333        if (MIPS_CACHE_SYNC_WAR) 
     334                __asm__ __volatile__ ("sync"); 
     335+       local_irq_restore(flags); 
     336 } 
     337  
     338 static void r4k_flush_cache_sigtramp(unsigned long addr) 
     339@@ -1144,6 +1210,17 @@ 
    80340         * silly idea of putting something else there ... 
    81341         */ 
     
    95355        case CPU_R4000SC: 
    96356        case CPU_R4000MC: 
    97 @@ -1174,6 +1202,15 @@ 
     357@@ -1174,6 +1251,15 @@ 
    98358        /* Default cache error handler for R4000 and R5000 family */ 
    99359        set_uncached_handler (0x100, &except_vec2_generic, 0x80); 
     
    111371        setup_scache(); 
    112372  
    113 @@ -1219,5 +1256,13 @@ 
     373@@ -1219,5 +1305,13 @@ 
    114374        build_clear_page(); 
    115375        build_copy_page(); 
     
    125385+#endif 
    126386 } 
    127 Index: linux-2.6.22-rc6/arch/mips/mm/tlbex.c 
     387Index: linux-2.6.22/arch/mips/mm/tlbex.c 
    128388=================================================================== 
    129 --- linux-2.6.22-rc6.orig/arch/mips/mm/tlbex.c  2007-07-04 01:53:01.193328250 +0200 
    130 +++ linux-2.6.22-rc6/arch/mips/mm/tlbex.c       2007-07-04 02:17:26.112880000 +0200 
     389--- linux-2.6.22.orig/arch/mips/mm/tlbex.c      2007-07-26 06:29:40.582055658 +0200 
     390+++ linux-2.6.22/arch/mips/mm/tlbex.c   2007-07-26 06:32:45.964620005 +0200 
    131391@@ -1229,6 +1229,10 @@ 
    132392 #endif 
     
    140400 { 
    141401        u32 *p = tlb_handler; 
    142 @@ -1243,6 +1247,11 @@ 
     402@@ -1243,6 +1247,10 @@ 
    143403        memset(relocs, 0, sizeof(relocs)); 
    144404        memset(final_handler, 0, sizeof(final_handler)); 
    145405  
    146406+#ifdef CONFIG_BCM947XX 
    147 +       if (current_cpu_data.cputype == CPU_BCM3302) 
    148 +               i_nop(&p); 
     407+       i_nop(&p); 
    149408+#endif 
    150409+ 
     
    152411         * create the plain linear handler 
    153412         */ 
    154 Index: linux-2.6.22-rc6/include/asm-mips/r4kcache.h 
     413@@ -1736,6 +1744,9 @@ 
     414        memset(labels, 0, sizeof(labels)); 
     415        memset(relocs, 0, sizeof(relocs)); 
     416  
     417+#ifdef CONFIG_BCM947XX 
     418+       i_nop(&p); 
     419+#endif 
     420        if (bcm1250_m3_war()) { 
     421                i_MFC0(&p, K0, C0_BADVADDR); 
     422                i_MFC0(&p, K1, C0_ENTRYHI); 
     423Index: linux-2.6.22/include/asm-mips/r4kcache.h 
    155424=================================================================== 
    156 --- linux-2.6.22-rc6.orig/include/asm-mips/r4kcache.h   2007-07-04 01:52:47.840493750 +0200 
    157 +++ linux-2.6.22-rc6/include/asm-mips/r4kcache.h        2007-07-04 01:53:01.673358250 +0200 
     425--- linux-2.6.22.orig/include/asm-mips/r4kcache.h       2007-07-26 06:29:25.085172538 +0200 
     426+++ linux-2.6.22/include/asm-mips/r4kcache.h    2007-07-26 06:29:40.938075943 +0200 
    158427@@ -17,6 +17,20 @@ 
    159428 #include <asm/cpu-features.h> 
     
    358627  
    359628 #endif /* _ASM_R4KCACHE_H */ 
    360 Index: linux-2.6.22-rc6/include/asm-mips/stackframe.h 
     629Index: linux-2.6.22/include/asm-mips/stackframe.h 
    361630=================================================================== 
    362 --- linux-2.6.22-rc6.orig/include/asm-mips/stackframe.h 2007-07-04 01:52:47.852494500 +0200 
    363 +++ linux-2.6.22-rc6/include/asm-mips/stackframe.h      2007-07-04 01:53:01.697359750 +0200 
     631--- linux-2.6.22.orig/include/asm-mips/stackframe.h     2007-07-26 06:29:25.093172994 +0200 
     632+++ linux-2.6.22/include/asm-mips/stackframe.h  2007-07-26 06:29:40.962077312 +0200 
    364633@@ -350,6 +350,10 @@ 
    365634                .macro  RESTORE_SP_AND_RET 
Note: See TracChangeset for help on using the changeset viewer.