VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / arch / sh / mm / cache-sh4.c
index dde3de3..adb99d8 100644 (file)
@@ -30,7 +30,7 @@ static void __flush_dcache_all_ex(void);
 
 int __init detect_cpu_and_cache_system(void)
 {
-       unsigned long pvr, prr, ccr, cvr;
+       unsigned long pvr, prr, cvr;
        unsigned long size;
 
        static unsigned long sizes[16] = {
@@ -48,7 +48,7 @@ int __init detect_cpu_and_cache_system(void)
        /*
         * Setup some sane SH-4 defaults for the icache
         */
-       cpu_data->icache.way_shift      = 13;
+       cpu_data->icache.way_incr       = (1 << 13);
        cpu_data->icache.entry_shift    = 5;
        cpu_data->icache.entry_mask     = 0x1fe0;
        cpu_data->icache.sets           = 256;
@@ -58,7 +58,7 @@ int __init detect_cpu_and_cache_system(void)
        /*
         * And again for the dcache ..
         */
-       cpu_data->dcache.way_shift      = 14;
+       cpu_data->dcache.way_incr       = (1 << 14);
        cpu_data->dcache.entry_shift    = 5;
        cpu_data->dcache.entry_mask     = 0x3fe0;
        cpu_data->dcache.sets           = 512;
@@ -66,7 +66,7 @@ int __init detect_cpu_and_cache_system(void)
        cpu_data->dcache.linesz         = L1_CACHE_BYTES;
 
        /* Set the FPU flag, virtually all SH-4's have one */
-       set_bit(CPU_HAS_FPU, &(cpu_data->flags));
+       cpu_data->flags |= CPU_HAS_FPU;
 
        /*
         * Probe the underlying processor version/revision and
@@ -75,7 +75,7 @@ int __init detect_cpu_and_cache_system(void)
        switch (pvr) {
        case 0x205:
                cpu_data->type = CPU_SH7750;
-               set_bit(CPU_HAS_P2_FLUSH_BUG, &(cpu_data->flags));
+               cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG;
                break;
        case 0x206:
                cpu_data->type = CPU_SH7750S;
@@ -84,7 +84,7 @@ int __init detect_cpu_and_cache_system(void)
                 * FIXME: This is needed for 7750, but do we need it for the
                 * 7750S too? For now, assume we do.. -- PFM
                 */
-               set_bit(CPU_HAS_P2_FLUSH_BUG, &(cpu_data->flags));
+               cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG;
 
                break;
        case 0x1100:
@@ -102,7 +102,7 @@ int __init detect_cpu_and_cache_system(void)
                cpu_data->dcache.ways = 2;
 
                /* No FPU on the SH4-500 series.. */
-               clear_bit(CPU_HAS_FPU, &(cpu_data->flags));
+               cpu_data->flags &= ~CPU_HAS_FPU;
                break;
        case 0x600:
                cpu_data->type = CPU_SH4_202;
@@ -129,27 +129,20 @@ int __init detect_cpu_and_cache_system(void)
         * On anything that's not a direct-mapped cache, look to the CVR
         * for I/D-cache specifics.
         */
-       if (cpu_data->dcache.ways > 1) {
-               jump_to_P2();
-               ccr = ctrl_inl(CCR);
-
-               /* Force EMODE */
-               if (!(ccr & CCR_CACHE_EMODE)) {
-                       ccr |= CCR_CACHE_EMODE;
-                       ctrl_outl(ccr, CCR);
-               }
-
-               back_to_P1();
-
+       if (cpu_data->icache.ways > 1) {
                size = sizes[(cvr >> 20) & 0xf];
-               cpu_data->icache.way_shift      =  (size >> 1);
-               cpu_data->icache.entry_mask     = ((size >> 2) - (1 << 5));
-               cpu_data->icache.sets           =  (size >> 6);
+               cpu_data->icache.way_incr       = size / cpu_data->icache.ways;
+               cpu_data->icache.sets           = (size >> 6);
+               cpu_data->icache.entry_mask     =
+                       ((size / cpu_data->icache.ways) - (1 << 5));
+       }
 
+       if (cpu_data->dcache.ways > 1) {
                size = sizes[(cvr >> 16) & 0xf];
-               cpu_data->dcache.way_shift      =  (size >> 1);
-               cpu_data->dcache.entry_mask     = ((size >> 2) - (1 << 5));
-               cpu_data->dcache.sets           =  (size >> 6);
+               cpu_data->dcache.way_incr       = size / cpu_data->dcache.ways;
+               cpu_data->dcache.sets           = (size >> 6);
+               cpu_data->dcache.entry_mask     =
+                       ((size / cpu_data->dcache.ways) - (1 << 5));
        }
 
        return 0;
@@ -250,7 +243,7 @@ static void __flush_cache_4096_all_ex(unsigned long start)
        int i;
 
        entry_offset = 1 << cpu_data->dcache.entry_shift;
-       for (i = 0; i < cpu_data->dcache.ways; i++, start += (1 << cpu_data->dcache.way_shift)) {
+       for (i = 0; i < cpu_data->dcache.ways; i++, start += cpu_data->dcache.way_incr) {
                for (addr = CACHE_OC_ADDRESS_ARRAY + start;
                     addr < CACHE_OC_ADDRESS_ARRAY + 4096 + start;
                     addr += entry_offset) {
@@ -297,7 +290,7 @@ void flush_cache_sigtramp(unsigned long addr)
 
        local_irq_save(flags);
        jump_to_P2();
-       for(i = 0; i < cpu_data->icache.ways; i++, index += (1 << cpu_data->icache.way_shift))
+       for(i = 0; i < cpu_data->icache.ways; i++, index += cpu_data->icache.way_incr)
                ctrl_outl(0, index);    /* Clear out Valid-bit */
        back_to_P1();
        local_irq_restore(flags);
@@ -313,12 +306,13 @@ static inline void flush_cache_4096(unsigned long start,
         * SH7751, SH7751R, and ST40 have no restriction to handle cache.
         * (While SH7750 must do that at P2 area.)
         */
-       if (test_bit(CPU_HAS_P2_FLUSH_BUG, &(cpu_data->flags))) {
+       if ((cpu_data->flags & CPU_HAS_P2_FLUSH_BUG)
+          || start < CACHE_OC_ADDRESS_ARRAY) {
                local_irq_save(flags);
-               __flush_cache_4096(start | SH_CACHE_ASSOC, phys | 0x80000000, 0x20000000);
+               __flush_cache_4096(start | SH_CACHE_ASSOC, P1SEGADDR(phys), 0x20000000);
                local_irq_restore(flags);
-       } else if (start >= CACHE_OC_ADDRESS_ARRAY) {
-               __flush_cache_4096(start | SH_CACHE_ASSOC, phys | 0x80000000, 0);
+       } else {
+               __flush_cache_4096(start | SH_CACHE_ASSOC, P1SEGADDR(phys), 0);
        }
 }