root/arch/microblaze/kernel/cpu/cache.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. __enable_icache_msr
  2. __disable_icache_msr
  3. __enable_dcache_msr
  4. __disable_dcache_msr
  5. __enable_icache_nomsr
  6. __disable_icache_nomsr
  7. __enable_dcache_nomsr
  8. __disable_dcache_nomsr
  9. __flush_icache_range_msr_irq
  10. __flush_icache_range_nomsr_irq
  11. __flush_icache_range_noirq
  12. __flush_icache_all_msr_irq
  13. __flush_icache_all_nomsr_irq
  14. __flush_icache_all_noirq
  15. __invalidate_dcache_all_msr_irq
  16. __invalidate_dcache_all_nomsr_irq
  17. __invalidate_dcache_all_noirq_wt
  18. __invalidate_dcache_all_wb
  19. __invalidate_dcache_range_wb
  20. __invalidate_dcache_range_nomsr_wt
  21. __invalidate_dcache_range_msr_irq_wt
  22. __invalidate_dcache_range_nomsr_irq
  23. __flush_dcache_all_wb
  24. __flush_dcache_range_wb
  25. microblaze_cache_init

   1 /*
   2  * Cache control for MicroBlaze cache memories
   3  *
   4  * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
   5  * Copyright (C) 2007-2009 PetaLogix
   6  * Copyright (C) 2007-2009 John Williams <john.williams@petalogix.com>
   7  *
   8  * This file is subject to the terms and conditions of the GNU General
   9  * Public License. See the file COPYING in the main directory of this
  10  * archive for more details.
  11  */
  12 
  13 #include <asm/cacheflush.h>
  14 #include <linux/cache.h>
  15 #include <asm/cpuinfo.h>
  16 #include <asm/pvr.h>
  17 
  18 static inline void __enable_icache_msr(void)
  19 {
  20         __asm__ __volatile__ ("  msrset r0, %0;"        \
  21                                 "nop;"                  \
  22                         : : "i" (MSR_ICE) : "memory");
  23 }
  24 
  25 static inline void __disable_icache_msr(void)
  26 {
  27         __asm__ __volatile__ ("  msrclr r0, %0;"        \
  28                                 "nop;"                  \
  29                         : : "i" (MSR_ICE) : "memory");
  30 }
  31 
  32 static inline void __enable_dcache_msr(void)
  33 {
  34         __asm__ __volatile__ ("  msrset r0, %0;"        \
  35                                 "nop;"                  \
  36                         : : "i" (MSR_DCE) : "memory");
  37 }
  38 
  39 static inline void __disable_dcache_msr(void)
  40 {
  41         __asm__ __volatile__ ("  msrclr r0, %0;"        \
  42                                 "nop; "                 \
  43                         : : "i" (MSR_DCE) : "memory");
  44 }
  45 
  46 static inline void __enable_icache_nomsr(void)
  47 {
  48         __asm__ __volatile__ ("  mfs    r12, rmsr;"     \
  49                                 "nop;"                  \
  50                                 "ori    r12, r12, %0;"  \
  51                                 "mts    rmsr, r12;"     \
  52                                 "nop;"                  \
  53                         : : "i" (MSR_ICE) : "memory", "r12");
  54 }
  55 
  56 static inline void __disable_icache_nomsr(void)
  57 {
  58         __asm__ __volatile__ ("  mfs    r12, rmsr;"     \
  59                                 "nop;"                  \
  60                                 "andi   r12, r12, ~%0;" \
  61                                 "mts    rmsr, r12;"     \
  62                                 "nop;"                  \
  63                         : : "i" (MSR_ICE) : "memory", "r12");
  64 }
  65 
  66 static inline void __enable_dcache_nomsr(void)
  67 {
  68         __asm__ __volatile__ ("  mfs    r12, rmsr;"     \
  69                                 "nop;"                  \
  70                                 "ori    r12, r12, %0;"  \
  71                                 "mts    rmsr, r12;"     \
  72                                 "nop;"                  \
  73                         : : "i" (MSR_DCE) : "memory", "r12");
  74 }
  75 
  76 static inline void __disable_dcache_nomsr(void)
  77 {
  78         __asm__ __volatile__ ("  mfs    r12, rmsr;"     \
  79                                 "nop;"                  \
  80                                 "andi   r12, r12, ~%0;" \
  81                                 "mts    rmsr, r12;"     \
  82                                 "nop;"                  \
  83                         : : "i" (MSR_DCE) : "memory", "r12");
  84 }
  85 
  86 
  87 /* Helper macro for computing the limits of cache range loops
  88  *
  89  * End address can be unaligned which is OK for C implementation.
  90  * ASM implementation align it in ASM macros
  91  */
  92 #define CACHE_LOOP_LIMITS(start, end, cache_line_length, cache_size)    \
  93 do {                                                                    \
  94         int align = ~(cache_line_length - 1);                           \
  95         if (start <  UINT_MAX - cache_size)                             \
  96                 end = min(start + cache_size, end);                     \
  97         start &= align;                                                 \
  98 } while (0)
  99 
 100 /*
 101  * Helper macro to loop over the specified cache_size/line_length and
 102  * execute 'op' on that cacheline
 103  */
 104 #define CACHE_ALL_LOOP(cache_size, line_length, op)                     \
 105 do {                                                                    \
 106         unsigned int len = cache_size - line_length;                    \
 107         int step = -line_length;                                        \
 108         WARN_ON(step >= 0);                                             \
 109                                                                         \
 110         __asm__ __volatile__ (" 1:      " #op " %0, r0;"                \
 111                                         "bgtid   %0, 1b;"               \
 112                                         "addk    %0, %0, %1;"           \
 113                                         : : "r" (len), "r" (step)       \
 114                                         : "memory");                    \
 115 } while (0)
 116 
 117 /* Used for wdc.flush/clear which can use rB for offset which is not possible
 118  * to use for simple wdc or wic.
 119  *
 120  * start address is cache aligned
 121  * end address is not aligned, if end is aligned then I have to subtract
 122  * cacheline length because I can't flush/invalidate the next cacheline.
 123  * If is not, I align it because I will flush/invalidate whole line.
 124  */
 125 #define CACHE_RANGE_LOOP_2(start, end, line_length, op)                 \
 126 do {                                                                    \
 127         int step = -line_length;                                        \
 128         int align = ~(line_length - 1);                                 \
 129         int count;                                                      \
 130         end = ((end & align) == end) ? end - line_length : end & align; \
 131         count = end - start;                                            \
 132         WARN_ON(count < 0);                                             \
 133                                                                         \
 134         __asm__ __volatile__ (" 1:      " #op " %0, %1;"                \
 135                                         "bgtid  %1, 1b;"                \
 136                                         "addk   %1, %1, %2;"            \
 137                                         : : "r" (start), "r" (count),   \
 138                                         "r" (step) : "memory");         \
 139 } while (0)
 140 
 141 /* It is used only first parameter for OP - for wic, wdc */
 142 #define CACHE_RANGE_LOOP_1(start, end, line_length, op)                 \
 143 do {                                                                    \
 144         unsigned int volatile temp = 0;                                         \
 145         unsigned int align = ~(line_length - 1);                                        \
 146         end = ((end & align) == end) ? end - line_length : end & align; \
 147         WARN_ON(end < start);                                   \
 148                                                                         \
 149         __asm__ __volatile__ (" 1:      " #op " %1, r0;"                \
 150                                         "cmpu   %0, %1, %2;"            \
 151                                         "bgtid  %0, 1b;"                \
 152                                         "addk   %1, %1, %3;"            \
 153                                 : : "r" (temp), "r" (start), "r" (end), \
 154                                         "r" (line_length) : "memory");  \
 155 } while (0)
 156 
 157 #define ASM_LOOP
 158 
 159 static void __flush_icache_range_msr_irq(unsigned long start, unsigned long end)
 160 {
 161         unsigned long flags;
 162 #ifndef ASM_LOOP
 163         int i;
 164 #endif
 165         pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
 166                                 (unsigned int)start, (unsigned int) end);
 167 
 168         CACHE_LOOP_LIMITS(start, end,
 169                         cpuinfo.icache_line_length, cpuinfo.icache_size);
 170 
 171         local_irq_save(flags);
 172         __disable_icache_msr();
 173 
 174 #ifdef ASM_LOOP
 175         CACHE_RANGE_LOOP_1(start, end, cpuinfo.icache_line_length, wic);
 176 #else
 177         for (i = start; i < end; i += cpuinfo.icache_line_length)
 178                 __asm__ __volatile__ ("wic      %0, r0;"        \
 179                                 : : "r" (i));
 180 #endif
 181         __enable_icache_msr();
 182         local_irq_restore(flags);
 183 }
 184 
 185 static void __flush_icache_range_nomsr_irq(unsigned long start,
 186                                 unsigned long end)
 187 {
 188         unsigned long flags;
 189 #ifndef ASM_LOOP
 190         int i;
 191 #endif
 192         pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
 193                                 (unsigned int)start, (unsigned int) end);
 194 
 195         CACHE_LOOP_LIMITS(start, end,
 196                         cpuinfo.icache_line_length, cpuinfo.icache_size);
 197 
 198         local_irq_save(flags);
 199         __disable_icache_nomsr();
 200 
 201 #ifdef ASM_LOOP
 202         CACHE_RANGE_LOOP_1(start, end, cpuinfo.icache_line_length, wic);
 203 #else
 204         for (i = start; i < end; i += cpuinfo.icache_line_length)
 205                 __asm__ __volatile__ ("wic      %0, r0;"        \
 206                                 : : "r" (i));
 207 #endif
 208 
 209         __enable_icache_nomsr();
 210         local_irq_restore(flags);
 211 }
 212 
 213 static void __flush_icache_range_noirq(unsigned long start,
 214                                 unsigned long end)
 215 {
 216 #ifndef ASM_LOOP
 217         int i;
 218 #endif
 219         pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
 220                                 (unsigned int)start, (unsigned int) end);
 221 
 222         CACHE_LOOP_LIMITS(start, end,
 223                         cpuinfo.icache_line_length, cpuinfo.icache_size);
 224 #ifdef ASM_LOOP
 225         CACHE_RANGE_LOOP_1(start, end, cpuinfo.icache_line_length, wic);
 226 #else
 227         for (i = start; i < end; i += cpuinfo.icache_line_length)
 228                 __asm__ __volatile__ ("wic      %0, r0;"        \
 229                                 : : "r" (i));
 230 #endif
 231 }
 232 
 233 static void __flush_icache_all_msr_irq(void)
 234 {
 235         unsigned long flags;
 236 #ifndef ASM_LOOP
 237         int i;
 238 #endif
 239         pr_debug("%s\n", __func__);
 240 
 241         local_irq_save(flags);
 242         __disable_icache_msr();
 243 #ifdef ASM_LOOP
 244         CACHE_ALL_LOOP(cpuinfo.icache_size, cpuinfo.icache_line_length, wic);
 245 #else
 246         for (i = 0; i < cpuinfo.icache_size;
 247                  i += cpuinfo.icache_line_length)
 248                         __asm__ __volatile__ ("wic      %0, r0;" \
 249                                         : : "r" (i));
 250 #endif
 251         __enable_icache_msr();
 252         local_irq_restore(flags);
 253 }
 254 
 255 static void __flush_icache_all_nomsr_irq(void)
 256 {
 257         unsigned long flags;
 258 #ifndef ASM_LOOP
 259         int i;
 260 #endif
 261         pr_debug("%s\n", __func__);
 262 
 263         local_irq_save(flags);
 264         __disable_icache_nomsr();
 265 #ifdef ASM_LOOP
 266         CACHE_ALL_LOOP(cpuinfo.icache_size, cpuinfo.icache_line_length, wic);
 267 #else
 268         for (i = 0; i < cpuinfo.icache_size;
 269                  i += cpuinfo.icache_line_length)
 270                         __asm__ __volatile__ ("wic      %0, r0;" \
 271                                         : : "r" (i));
 272 #endif
 273         __enable_icache_nomsr();
 274         local_irq_restore(flags);
 275 }
 276 
 277 static void __flush_icache_all_noirq(void)
 278 {
 279 #ifndef ASM_LOOP
 280         int i;
 281 #endif
 282         pr_debug("%s\n", __func__);
 283 #ifdef ASM_LOOP
 284         CACHE_ALL_LOOP(cpuinfo.icache_size, cpuinfo.icache_line_length, wic);
 285 #else
 286         for (i = 0; i < cpuinfo.icache_size;
 287                  i += cpuinfo.icache_line_length)
 288                         __asm__ __volatile__ ("wic      %0, r0;" \
 289                                         : : "r" (i));
 290 #endif
 291 }
 292 
 293 static void __invalidate_dcache_all_msr_irq(void)
 294 {
 295         unsigned long flags;
 296 #ifndef ASM_LOOP
 297         int i;
 298 #endif
 299         pr_debug("%s\n", __func__);
 300 
 301         local_irq_save(flags);
 302         __disable_dcache_msr();
 303 #ifdef ASM_LOOP
 304         CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length, wdc);
 305 #else
 306         for (i = 0; i < cpuinfo.dcache_size;
 307                  i += cpuinfo.dcache_line_length)
 308                         __asm__ __volatile__ ("wdc      %0, r0;" \
 309                                         : : "r" (i));
 310 #endif
 311         __enable_dcache_msr();
 312         local_irq_restore(flags);
 313 }
 314 
 315 static void __invalidate_dcache_all_nomsr_irq(void)
 316 {
 317         unsigned long flags;
 318 #ifndef ASM_LOOP
 319         int i;
 320 #endif
 321         pr_debug("%s\n", __func__);
 322 
 323         local_irq_save(flags);
 324         __disable_dcache_nomsr();
 325 #ifdef ASM_LOOP
 326         CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length, wdc);
 327 #else
 328         for (i = 0; i < cpuinfo.dcache_size;
 329                  i += cpuinfo.dcache_line_length)
 330                         __asm__ __volatile__ ("wdc      %0, r0;" \
 331                                         : : "r" (i));
 332 #endif
 333         __enable_dcache_nomsr();
 334         local_irq_restore(flags);
 335 }
 336 
 337 static void __invalidate_dcache_all_noirq_wt(void)
 338 {
 339 #ifndef ASM_LOOP
 340         int i;
 341 #endif
 342         pr_debug("%s\n", __func__);
 343 #ifdef ASM_LOOP
 344         CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length, wdc);
 345 #else
 346         for (i = 0; i < cpuinfo.dcache_size;
 347                  i += cpuinfo.dcache_line_length)
 348                         __asm__ __volatile__ ("wdc      %0, r0;" \
 349                                         : : "r" (i));
 350 #endif
 351 }
 352 
 353 /*
 354  * FIXME It is blindly invalidation as is expected
 355  * but can't be called on noMMU in microblaze_cache_init below
 356  *
 357  * MS: noMMU kernel won't boot if simple wdc is used
 358  * The reason should be that there are discared data which kernel needs
 359  */
 360 static void __invalidate_dcache_all_wb(void)
 361 {
 362 #ifndef ASM_LOOP
 363         int i;
 364 #endif
 365         pr_debug("%s\n", __func__);
 366 #ifdef ASM_LOOP
 367         CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length,
 368                                         wdc);
 369 #else
 370         for (i = 0; i < cpuinfo.dcache_size;
 371                  i += cpuinfo.dcache_line_length)
 372                         __asm__ __volatile__ ("wdc      %0, r0;" \
 373                                         : : "r" (i));
 374 #endif
 375 }
 376 
 377 static void __invalidate_dcache_range_wb(unsigned long start,
 378                                                 unsigned long end)
 379 {
 380 #ifndef ASM_LOOP
 381         int i;
 382 #endif
 383         pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
 384                                 (unsigned int)start, (unsigned int) end);
 385 
 386         CACHE_LOOP_LIMITS(start, end,
 387                         cpuinfo.dcache_line_length, cpuinfo.dcache_size);
 388 #ifdef ASM_LOOP
 389         CACHE_RANGE_LOOP_2(start, end, cpuinfo.dcache_line_length, wdc.clear);
 390 #else
 391         for (i = start; i < end; i += cpuinfo.dcache_line_length)
 392                 __asm__ __volatile__ ("wdc.clear        %0, r0;"        \
 393                                 : : "r" (i));
 394 #endif
 395 }
 396 
 397 static void __invalidate_dcache_range_nomsr_wt(unsigned long start,
 398                                                         unsigned long end)
 399 {
 400 #ifndef ASM_LOOP
 401         int i;
 402 #endif
 403         pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
 404                                 (unsigned int)start, (unsigned int) end);
 405         CACHE_LOOP_LIMITS(start, end,
 406                         cpuinfo.dcache_line_length, cpuinfo.dcache_size);
 407 
 408 #ifdef ASM_LOOP
 409         CACHE_RANGE_LOOP_1(start, end, cpuinfo.dcache_line_length, wdc);
 410 #else
 411         for (i = start; i < end; i += cpuinfo.dcache_line_length)
 412                 __asm__ __volatile__ ("wdc      %0, r0;"        \
 413                                 : : "r" (i));
 414 #endif
 415 }
 416 
 417 static void __invalidate_dcache_range_msr_irq_wt(unsigned long start,
 418                                                         unsigned long end)
 419 {
 420         unsigned long flags;
 421 #ifndef ASM_LOOP
 422         int i;
 423 #endif
 424         pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
 425                                 (unsigned int)start, (unsigned int) end);
 426         CACHE_LOOP_LIMITS(start, end,
 427                         cpuinfo.dcache_line_length, cpuinfo.dcache_size);
 428 
 429         local_irq_save(flags);
 430         __disable_dcache_msr();
 431 
 432 #ifdef ASM_LOOP
 433         CACHE_RANGE_LOOP_1(start, end, cpuinfo.dcache_line_length, wdc);
 434 #else
 435         for (i = start; i < end; i += cpuinfo.dcache_line_length)
 436                 __asm__ __volatile__ ("wdc      %0, r0;"        \
 437                                 : : "r" (i));
 438 #endif
 439 
 440         __enable_dcache_msr();
 441         local_irq_restore(flags);
 442 }
 443 
 444 static void __invalidate_dcache_range_nomsr_irq(unsigned long start,
 445                                                         unsigned long end)
 446 {
 447         unsigned long flags;
 448 #ifndef ASM_LOOP
 449         int i;
 450 #endif
 451         pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
 452                                 (unsigned int)start, (unsigned int) end);
 453 
 454         CACHE_LOOP_LIMITS(start, end,
 455                         cpuinfo.dcache_line_length, cpuinfo.dcache_size);
 456 
 457         local_irq_save(flags);
 458         __disable_dcache_nomsr();
 459 
 460 #ifdef ASM_LOOP
 461         CACHE_RANGE_LOOP_1(start, end, cpuinfo.dcache_line_length, wdc);
 462 #else
 463         for (i = start; i < end; i += cpuinfo.dcache_line_length)
 464                 __asm__ __volatile__ ("wdc      %0, r0;"        \
 465                                 : : "r" (i));
 466 #endif
 467 
 468         __enable_dcache_nomsr();
 469         local_irq_restore(flags);
 470 }
 471 
 472 static void __flush_dcache_all_wb(void)
 473 {
 474 #ifndef ASM_LOOP
 475         int i;
 476 #endif
 477         pr_debug("%s\n", __func__);
 478 #ifdef ASM_LOOP
 479         CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length,
 480                                 wdc.flush);
 481 #else
 482         for (i = 0; i < cpuinfo.dcache_size;
 483                  i += cpuinfo.dcache_line_length)
 484                         __asm__ __volatile__ ("wdc.flush        %0, r0;" \
 485                                         : : "r" (i));
 486 #endif
 487 }
 488 
 489 static void __flush_dcache_range_wb(unsigned long start, unsigned long end)
 490 {
 491 #ifndef ASM_LOOP
 492         int i;
 493 #endif
 494         pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
 495                                 (unsigned int)start, (unsigned int) end);
 496 
 497         CACHE_LOOP_LIMITS(start, end,
 498                         cpuinfo.dcache_line_length, cpuinfo.dcache_size);
 499 #ifdef ASM_LOOP
 500         CACHE_RANGE_LOOP_2(start, end, cpuinfo.dcache_line_length, wdc.flush);
 501 #else
 502         for (i = start; i < end; i += cpuinfo.dcache_line_length)
 503                 __asm__ __volatile__ ("wdc.flush        %0, r0;"        \
 504                                 : : "r" (i));
 505 #endif
 506 }
 507 
 508 /* struct for wb caches and for wt caches */
 509 struct scache *mbc;
 510 
 511 /* new wb cache model */
 512 static const struct scache wb_msr = {
 513         .ie = __enable_icache_msr,
 514         .id = __disable_icache_msr,
 515         .ifl = __flush_icache_all_noirq,
 516         .iflr = __flush_icache_range_noirq,
 517         .iin = __flush_icache_all_noirq,
 518         .iinr = __flush_icache_range_noirq,
 519         .de = __enable_dcache_msr,
 520         .dd = __disable_dcache_msr,
 521         .dfl = __flush_dcache_all_wb,
 522         .dflr = __flush_dcache_range_wb,
 523         .din = __invalidate_dcache_all_wb,
 524         .dinr = __invalidate_dcache_range_wb,
 525 };
 526 
 527 /* There is only difference in ie, id, de, dd functions */
 528 static const struct scache wb_nomsr = {
 529         .ie = __enable_icache_nomsr,
 530         .id = __disable_icache_nomsr,
 531         .ifl = __flush_icache_all_noirq,
 532         .iflr = __flush_icache_range_noirq,
 533         .iin = __flush_icache_all_noirq,
 534         .iinr = __flush_icache_range_noirq,
 535         .de = __enable_dcache_nomsr,
 536         .dd = __disable_dcache_nomsr,
 537         .dfl = __flush_dcache_all_wb,
 538         .dflr = __flush_dcache_range_wb,
 539         .din = __invalidate_dcache_all_wb,
 540         .dinr = __invalidate_dcache_range_wb,
 541 };
 542 
 543 /* Old wt cache model with disabling irq and turn off cache */
 544 static const struct scache wt_msr = {
 545         .ie = __enable_icache_msr,
 546         .id = __disable_icache_msr,
 547         .ifl = __flush_icache_all_msr_irq,
 548         .iflr = __flush_icache_range_msr_irq,
 549         .iin = __flush_icache_all_msr_irq,
 550         .iinr = __flush_icache_range_msr_irq,
 551         .de = __enable_dcache_msr,
 552         .dd = __disable_dcache_msr,
 553         .dfl = __invalidate_dcache_all_msr_irq,
 554         .dflr = __invalidate_dcache_range_msr_irq_wt,
 555         .din = __invalidate_dcache_all_msr_irq,
 556         .dinr = __invalidate_dcache_range_msr_irq_wt,
 557 };
 558 
 559 static const struct scache wt_nomsr = {
 560         .ie = __enable_icache_nomsr,
 561         .id = __disable_icache_nomsr,
 562         .ifl = __flush_icache_all_nomsr_irq,
 563         .iflr = __flush_icache_range_nomsr_irq,
 564         .iin = __flush_icache_all_nomsr_irq,
 565         .iinr = __flush_icache_range_nomsr_irq,
 566         .de = __enable_dcache_nomsr,
 567         .dd = __disable_dcache_nomsr,
 568         .dfl = __invalidate_dcache_all_nomsr_irq,
 569         .dflr = __invalidate_dcache_range_nomsr_irq,
 570         .din = __invalidate_dcache_all_nomsr_irq,
 571         .dinr = __invalidate_dcache_range_nomsr_irq,
 572 };
 573 
 574 /* New wt cache model for newer Microblaze versions */
 575 static const struct scache wt_msr_noirq = {
 576         .ie = __enable_icache_msr,
 577         .id = __disable_icache_msr,
 578         .ifl = __flush_icache_all_noirq,
 579         .iflr = __flush_icache_range_noirq,
 580         .iin = __flush_icache_all_noirq,
 581         .iinr = __flush_icache_range_noirq,
 582         .de = __enable_dcache_msr,
 583         .dd = __disable_dcache_msr,
 584         .dfl = __invalidate_dcache_all_noirq_wt,
 585         .dflr = __invalidate_dcache_range_nomsr_wt,
 586         .din = __invalidate_dcache_all_noirq_wt,
 587         .dinr = __invalidate_dcache_range_nomsr_wt,
 588 };
 589 
 590 static const struct scache wt_nomsr_noirq = {
 591         .ie = __enable_icache_nomsr,
 592         .id = __disable_icache_nomsr,
 593         .ifl = __flush_icache_all_noirq,
 594         .iflr = __flush_icache_range_noirq,
 595         .iin = __flush_icache_all_noirq,
 596         .iinr = __flush_icache_range_noirq,
 597         .de = __enable_dcache_nomsr,
 598         .dd = __disable_dcache_nomsr,
 599         .dfl = __invalidate_dcache_all_noirq_wt,
 600         .dflr = __invalidate_dcache_range_nomsr_wt,
 601         .din = __invalidate_dcache_all_noirq_wt,
 602         .dinr = __invalidate_dcache_range_nomsr_wt,
 603 };
 604 
 605 /* CPU version code for 7.20.c - see arch/microblaze/kernel/cpu/cpuinfo.c */
 606 #define CPUVER_7_20_A   0x0c
 607 #define CPUVER_7_20_D   0x0f
 608 
 609 void microblaze_cache_init(void)
 610 {
 611         if (cpuinfo.use_instr & PVR2_USE_MSR_INSTR) {
 612                 if (cpuinfo.dcache_wb) {
 613                         pr_info("wb_msr\n");
 614                         mbc = (struct scache *)&wb_msr;
 615                         if (cpuinfo.ver_code <= CPUVER_7_20_D) {
 616                                 /* MS: problem with signal handling - hw bug */
 617                                 pr_info("WB won't work properly\n");
 618                         }
 619                 } else {
 620                         if (cpuinfo.ver_code >= CPUVER_7_20_A) {
 621                                 pr_info("wt_msr_noirq\n");
 622                                 mbc = (struct scache *)&wt_msr_noirq;
 623                         } else {
 624                                 pr_info("wt_msr\n");
 625                                 mbc = (struct scache *)&wt_msr;
 626                         }
 627                 }
 628         } else {
 629                 if (cpuinfo.dcache_wb) {
 630                         pr_info("wb_nomsr\n");
 631                         mbc = (struct scache *)&wb_nomsr;
 632                         if (cpuinfo.ver_code <= CPUVER_7_20_D) {
 633                                 /* MS: problem with signal handling - hw bug */
 634                                 pr_info("WB won't work properly\n");
 635                         }
 636                 } else {
 637                         if (cpuinfo.ver_code >= CPUVER_7_20_A) {
 638                                 pr_info("wt_nomsr_noirq\n");
 639                                 mbc = (struct scache *)&wt_nomsr_noirq;
 640                         } else {
 641                                 pr_info("wt_nomsr\n");
 642                                 mbc = (struct scache *)&wt_nomsr;
 643                         }
 644                 }
 645         }
 646         /*
 647          * FIXME Invalidation is done in U-BOOT
 648          * WT cache: Data is already written to main memory
 649          * WB cache: Discard data on noMMU which caused that kernel doesn't boot
 650          */
 651         /* invalidate_dcache(); */
 652         enable_dcache();
 653 
 654         invalidate_icache();
 655         enable_icache();
 656 }

/* [<][>][^][v][top][bottom][index][help] */