linux-bk/arch/mips/mm/r4xx0.c
<<
>>
Prefs
   1/*
   2 * This file is subject to the terms and conditions of the GNU General Public
   3 * License.  See the file "COPYING" in the main directory of this archive
   4 * for more details.
   5 *
   6 * r4xx0.c: R4000 processor variant specific MMU/Cache routines.
   7 *
   8 * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
   9 * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org
  10 *
  11 * To do:
  12 *
  13 *  - this code is a overbloated pig
  14 *  - many of the bug workarounds are not efficient at all, but at
  15 *    least they are functional ...
  16 */
  17#include <linux/init.h>
  18#include <linux/kernel.h>
  19#include <linux/sched.h>
  20#include <linux/mm.h>
  21
  22#include <asm/bootinfo.h>
  23#include <asm/cpu.h>
  24#include <asm/bcache.h>
  25#include <asm/io.h>
  26#include <asm/page.h>
  27#include <asm/pgtable.h>
  28#include <asm/system.h>
  29#include <asm/mmu_context.h>
  30
  31/* CP0 hazard avoidance. */
  32#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
  33                                     "nop; nop; nop; nop; nop; nop;\n\t" \
  34                                     ".set reorder\n\t")
  35
  36/* Primary cache parameters. */
  37static int icache_size, dcache_size; /* Size in bytes */
  38static int ic_lsize, dc_lsize;       /* LineSize in bytes */
  39
  40/* Secondary cache (if present) parameters. */
  41static unsigned int scache_size, sc_lsize;      /* Again, in bytes */
  42
  43#include <asm/cacheops.h>
  44#include <asm/r4kcache.h>
  45
  46#undef DEBUG_CACHE
  47
  48/*
  49 * Dummy cache handling routines for machines without boardcaches
  50 */
  51static void no_sc_noop(void) {}
  52
  53static struct bcache_ops no_sc_ops = {
  54        (void *)no_sc_noop, (void *)no_sc_noop,
  55        (void *)no_sc_noop, (void *)no_sc_noop
  56};
  57
  58struct bcache_ops *bcops = &no_sc_ops;
  59
  60/*
  61 * On processors with QED R4600 style two set assosicative cache
  62 * this is the bit which selects the way in the cache for the
  63 * indexed cachops.
  64 */
  65#define icache_waybit (icache_size >> 1)
  66#define dcache_waybit (dcache_size >> 1)
  67
  68/*
  69 * Zero an entire page.  Basically a simple unrolled loop should do the
  70 * job but we want more performance by saving memory bus bandwidth.  We
  71 * have five flavours of the routine available for:
  72 *
  73 * - 16byte cachelines and no second level cache
  74 * - 32byte cachelines second level cache
  75 * - a version which handles the buggy R4600 v1.x
  76 * - a version which handles the buggy R4600 v2.0
  77 * - Finally a last version without fancy cache games for the SC and MC
  78 *   versions of R4000 and R4400.
  79 */
  80
  81static void r4k_clear_page_d16(void * page)
  82{
  83        __asm__ __volatile__(
  84                ".set\tnoreorder\n\t"
  85                ".set\tnoat\n\t"
  86                ".set\tmips3\n\t"
  87                "daddiu\t$1,%0,%2\n"
  88                "1:\tcache\t%3,(%0)\n\t"
  89                "sd\t$0,(%0)\n\t"
  90                "sd\t$0,8(%0)\n\t"
  91                "cache\t%3,16(%0)\n\t"
  92                "sd\t$0,16(%0)\n\t"
  93                "sd\t$0,24(%0)\n\t"
  94                "daddiu\t%0,64\n\t"
  95                "cache\t%3,-32(%0)\n\t"
  96                "sd\t$0,-32(%0)\n\t"
  97                "sd\t$0,-24(%0)\n\t"
  98                "cache\t%3,-16(%0)\n\t"
  99                "sd\t$0,-16(%0)\n\t"
 100                "bne\t$1,%0,1b\n\t"
 101                "sd\t$0,-8(%0)\n\t"
 102                ".set\tmips0\n\t"
 103                ".set\tat\n\t"
 104                ".set\treorder"
 105                :"=r" (page)
 106                :"0" (page),
 107                 "I" (PAGE_SIZE),
 108                 "i" (Create_Dirty_Excl_D)
 109                :"$1","memory");
 110}
 111
 112static void r4k_clear_page_d32(void * page)
 113{
 114        __asm__ __volatile__(
 115                ".set\tnoreorder\n\t"
 116                ".set\tnoat\n\t"
 117                ".set\tmips3\n\t"
 118                "daddiu\t$1,%0,%2\n"
 119                "1:\tcache\t%3,(%0)\n\t"
 120                "sd\t$0,(%0)\n\t"
 121                "sd\t$0,8(%0)\n\t"
 122                "sd\t$0,16(%0)\n\t"
 123                "sd\t$0,24(%0)\n\t"
 124                "daddiu\t%0,64\n\t"
 125                "cache\t%3,-32(%0)\n\t"
 126                "sd\t$0,-32(%0)\n\t"
 127                "sd\t$0,-24(%0)\n\t"
 128                "sd\t$0,-16(%0)\n\t"
 129                "bne\t$1,%0,1b\n\t"
 130                "sd\t$0,-8(%0)\n\t"
 131                ".set\tmips0\n\t"
 132                ".set\tat\n\t"
 133                ".set\treorder"
 134                :"=r" (page)
 135                :"0" (page),
 136                 "I" (PAGE_SIZE),
 137                 "i" (Create_Dirty_Excl_D)
 138                :"$1","memory");
 139}
 140
 141
 142/*
 143 * This flavour of r4k_clear_page is for the R4600 V1.x.  Cite from the
 144 * IDT R4600 V1.7 errata:
 145 *
 146 *  18. The CACHE instructions Hit_Writeback_Invalidate_D, Hit_Writeback_D,
 147 *      Hit_Invalidate_D and Create_Dirty_Excl_D should only be
 148 *      executed if there is no other dcache activity. If the dcache is
 149 *      accessed for another instruction immeidately preceding when these
 150 *      cache instructions are executing, it is possible that the dcache 
 151 *      tag match outputs used by these cache instructions will be 
 152 *      incorrect. These cache instructions should be preceded by at least
 153 *      four instructions that are not any kind of load or store 
 154 *      instruction.
 155 *
 156 *      This is not allowed:    lw
 157 *                              nop
 158 *                              nop
 159 *                              nop
 160 *                              cache       Hit_Writeback_Invalidate_D
 161 *
 162 *      This is allowed:        lw
 163 *                              nop
 164 *                              nop
 165 *                              nop
 166 *                              nop
 167 *                              cache       Hit_Writeback_Invalidate_D
 168 */
 169static void r4k_clear_page_r4600_v1(void * page)
 170{
 171        __asm__ __volatile__(
 172                ".set\tnoreorder\n\t"
 173                ".set\tnoat\n\t"
 174                ".set\tmips3\n\t"
 175                "daddiu\t$1,%0,%2\n"
 176                "1:\tnop\n\t"
 177                "nop\n\t"
 178                "nop\n\t"
 179                "nop\n\t"
 180                "cache\t%3,(%0)\n\t"
 181                "sd\t$0,(%0)\n\t"
 182                "sd\t$0,8(%0)\n\t"
 183                "sd\t$0,16(%0)\n\t"
 184                "sd\t$0,24(%0)\n\t"
 185                "daddiu\t%0,64\n\t"
 186                "nop\n\t"
 187                "nop\n\t"
 188                "nop\n\t"
 189                "cache\t%3,-32(%0)\n\t"
 190                "sd\t$0,-32(%0)\n\t"
 191                "sd\t$0,-24(%0)\n\t"
 192                "sd\t$0,-16(%0)\n\t"
 193                "bne\t$1,%0,1b\n\t"
 194                "sd\t$0,-8(%0)\n\t"
 195                ".set\tmips0\n\t"
 196                ".set\tat\n\t"
 197                ".set\treorder"
 198                :"=r" (page)
 199                :"0" (page),
 200                 "I" (PAGE_SIZE),
 201                 "i" (Create_Dirty_Excl_D)
 202                :"$1","memory");
 203}
 204
 205/*
 206 * And this one is for the R4600 V2.0
 207 */
 208static void r4k_clear_page_r4600_v2(void * page)
 209{
 210        unsigned int flags;
 211
 212        local_irq_save(flags);
 213        *(volatile unsigned int *)KSEG1;
 214        __asm__ __volatile__(
 215                ".set\tnoreorder\n\t"
 216                ".set\tnoat\n\t"
 217                ".set\tmips3\n\t"
 218                "daddiu\t$1,%0,%2\n"
 219                "1:\tcache\t%3,(%0)\n\t"
 220                "sd\t$0,(%0)\n\t"
 221                "sd\t$0,8(%0)\n\t"
 222                "sd\t$0,16(%0)\n\t"
 223                "sd\t$0,24(%0)\n\t"
 224                "daddiu\t%0,64\n\t"
 225                "cache\t%3,-32(%0)\n\t"
 226                "sd\t$0,-32(%0)\n\t"
 227                "sd\t$0,-24(%0)\n\t"
 228                "sd\t$0,-16(%0)\n\t"
 229                "bne\t$1,%0,1b\n\t"
 230                "sd\t$0,-8(%0)\n\t"
 231                ".set\tmips0\n\t"
 232                ".set\tat\n\t"
 233                ".set\treorder"
 234                :"=r" (page)
 235                :"0" (page),
 236                 "I" (PAGE_SIZE),
 237                 "i" (Create_Dirty_Excl_D)
 238                :"$1","memory");
 239        local_irq_restore(flags);
 240}
 241
 242/*
 243 * The next 4 versions are optimized for all possible scache configurations
 244 * of the SC / MC versions of R4000 and R4400 ...
 245 *
 246 * Todo: For even better performance we should have a routine optimized for
 247 * every legal combination of dcache / scache linesize.  When I (Ralf) tried
 248 * this the kernel crashed shortly after mounting the root filesystem.  CPU
 249 * bug?  Weirdo cache instruction semantics?
 250 */
 251static void r4k_clear_page_s16(void * page)
 252{
 253        __asm__ __volatile__(
 254                ".set\tnoreorder\n\t"
 255                ".set\tnoat\n\t"
 256                ".set\tmips3\n\t"
 257                "daddiu\t$1,%0,%2\n"
 258                "1:\tcache\t%3,(%0)\n\t"
 259                "sd\t$0,(%0)\n\t"
 260                "sd\t$0,8(%0)\n\t"
 261                "cache\t%3,16(%0)\n\t"
 262                "sd\t$0,16(%0)\n\t"
 263                "sd\t$0,24(%0)\n\t"
 264                "daddiu\t%0,64\n\t"
 265                "cache\t%3,-32(%0)\n\t"
 266                "sd\t$0,-32(%0)\n\t"
 267                "sd\t$0,-24(%0)\n\t"
 268                "cache\t%3,-16(%0)\n\t"
 269                "sd\t$0,-16(%0)\n\t"
 270                "bne\t$1,%0,1b\n\t"
 271                "sd\t$0,-8(%0)\n\t"
 272                ".set\tmips0\n\t"
 273                ".set\tat\n\t"
 274                ".set\treorder"
 275                :"=r" (page)
 276                :"0" (page),
 277                 "I" (PAGE_SIZE),
 278                 "i" (Create_Dirty_Excl_SD)
 279                :"$1","memory");
 280}
 281
 282static void r4k_clear_page_s32(void * page)
 283{
 284        __asm__ __volatile__(
 285                ".set\tnoreorder\n\t"
 286                ".set\tnoat\n\t"
 287                ".set\tmips3\n\t"
 288                "daddiu\t$1,%0,%2\n"
 289                "1:\tcache\t%3,(%0)\n\t"
 290                "sd\t$0,(%0)\n\t"
 291                "sd\t$0,8(%0)\n\t"
 292                "sd\t$0,16(%0)\n\t"
 293                "sd\t$0,24(%0)\n\t"
 294                "daddiu\t%0,64\n\t"
 295                "cache\t%3,-32(%0)\n\t"
 296                "sd\t$0,-32(%0)\n\t"
 297                "sd\t$0,-24(%0)\n\t"
 298                "sd\t$0,-16(%0)\n\t"
 299                "bne\t$1,%0,1b\n\t"
 300                "sd\t$0,-8(%0)\n\t"
 301                ".set\tmips0\n\t"
 302                ".set\tat\n\t"
 303                ".set\treorder"
 304                :"=r" (page)
 305                :"0" (page),
 306                 "I" (PAGE_SIZE),
 307                 "i" (Create_Dirty_Excl_SD)
 308                :"$1","memory");
 309}
 310
 311static void r4k_clear_page_s64(void * page)
 312{
 313        __asm__ __volatile__(
 314                ".set\tnoreorder\n\t"
 315                ".set\tnoat\n\t"
 316                ".set\tmips3\n\t"
 317                "daddiu\t$1,%0,%2\n"
 318                "1:\tcache\t%3,(%0)\n\t"
 319                "sd\t$0,(%0)\n\t"
 320                "sd\t$0,8(%0)\n\t"
 321                "sd\t$0,16(%0)\n\t"
 322                "sd\t$0,24(%0)\n\t"
 323                "daddiu\t%0,64\n\t"
 324                "sd\t$0,-32(%0)\n\t"
 325                "sd\t$0,-24(%0)\n\t"
 326                "sd\t$0,-16(%0)\n\t"
 327                "bne\t$1,%0,1b\n\t"
 328                "sd\t$0,-8(%0)\n\t"
 329                ".set\tmips0\n\t"
 330                ".set\tat\n\t"
 331                ".set\treorder"
 332                :"=r" (page)
 333                :"0" (page),
 334                 "I" (PAGE_SIZE),
 335                 "i" (Create_Dirty_Excl_SD)
 336                :"$1","memory");
 337}
 338
 339static void r4k_clear_page_s128(void * page)
 340{
 341        __asm__ __volatile__(
 342                ".set\tnoreorder\n\t"
 343                ".set\tnoat\n\t"
 344                ".set\tmips3\n\t"
 345                "daddiu\t$1,%0,%2\n"
 346                "1:\tcache\t%3,(%0)\n\t"
 347                "sd\t$0,(%0)\n\t"
 348                "sd\t$0,8(%0)\n\t"
 349                "sd\t$0,16(%0)\n\t"
 350                "sd\t$0,24(%0)\n\t"
 351                "sd\t$0,32(%0)\n\t"
 352                "sd\t$0,40(%0)\n\t"
 353                "sd\t$0,48(%0)\n\t"
 354                "sd\t$0,56(%0)\n\t"
 355                "daddiu\t%0,128\n\t"
 356                "sd\t$0,-64(%0)\n\t"
 357                "sd\t$0,-56(%0)\n\t"
 358                "sd\t$0,-48(%0)\n\t"
 359                "sd\t$0,-40(%0)\n\t"
 360                "sd\t$0,-32(%0)\n\t"
 361                "sd\t$0,-24(%0)\n\t"
 362                "sd\t$0,-16(%0)\n\t"
 363                "bne\t$1,%0,1b\n\t"
 364                "sd\t$0,-8(%0)\n\t"
 365                ".set\tmips0\n\t"
 366                ".set\tat\n\t"
 367                ".set\treorder"
 368                :"=r" (page)
 369                :"0" (page),
 370                 "I" (PAGE_SIZE),
 371                 "i" (Create_Dirty_Excl_SD)
 372                :"$1","memory");
 373}
 374
 375
 376/*
 377 * This is still inefficient.  We only can do better if we know the
 378 * virtual address where the copy will be accessed.
 379 */
 380
 381static void r4k_copy_page_d16(void * to, void * from)
 382{
 383        unsigned long dummy1, dummy2;
 384        unsigned long reg1, reg2, reg3, reg4;
 385
 386        __asm__ __volatile__(
 387                ".set\tnoreorder\n\t"
 388                ".set\tnoat\n\t"
 389                ".set\tmips3\n\t"
 390                "daddiu\t$1,%0,%8\n"
 391                "1:\tcache\t%9,(%0)\n\t"
 392                "lw\t%2,(%1)\n\t"
 393                "lw\t%3,4(%1)\n\t"
 394                "lw\t%4,8(%1)\n\t"
 395                "lw\t%5,12(%1)\n\t"
 396                "sw\t%2,(%0)\n\t"
 397                "sw\t%3,4(%0)\n\t"
 398                "sw\t%4,8(%0)\n\t"
 399                "sw\t%5,12(%0)\n\t"
 400                "cache\t%9,16(%0)\n\t"
 401                "lw\t%2,16(%1)\n\t"
 402                "lw\t%3,20(%1)\n\t"
 403                "lw\t%4,24(%1)\n\t"
 404                "lw\t%5,28(%1)\n\t"
 405                "sw\t%2,16(%0)\n\t"
 406                "sw\t%3,20(%0)\n\t"
 407                "sw\t%4,24(%0)\n\t"
 408                "sw\t%5,28(%0)\n\t"
 409                "cache\t%9,32(%0)\n\t"
 410                "daddiu\t%0,64\n\t"
 411                "daddiu\t%1,64\n\t"
 412                "lw\t%2,-32(%1)\n\t"
 413                "lw\t%3,-28(%1)\n\t"
 414                "lw\t%4,-24(%1)\n\t"
 415                "lw\t%5,-20(%1)\n\t"
 416                "sw\t%2,-32(%0)\n\t"
 417                "sw\t%3,-28(%0)\n\t"
 418                "sw\t%4,-24(%0)\n\t"
 419                "sw\t%5,-20(%0)\n\t"
 420                "cache\t%9,-16(%0)\n\t"
 421                "lw\t%2,-16(%1)\n\t"
 422                "lw\t%3,-12(%1)\n\t"
 423                "lw\t%4,-8(%1)\n\t"
 424                "lw\t%5,-4(%1)\n\t"
 425                "sw\t%2,-16(%0)\n\t"
 426                "sw\t%3,-12(%0)\n\t"
 427                "sw\t%4,-8(%0)\n\t"
 428                "bne\t$1,%0,1b\n\t"
 429                "sw\t%5,-4(%0)\n\t"
 430                ".set\tmips0\n\t"
 431                ".set\tat\n\t"
 432                ".set\treorder"
 433                :"=r" (dummy1), "=r" (dummy2),
 434                 "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
 435                :"0" (to), "1" (from),
 436                 "I" (PAGE_SIZE),
 437                 "i" (Create_Dirty_Excl_D));
 438}
 439
 440static void r4k_copy_page_d32(void * to, void * from)
 441{
 442        unsigned long dummy1, dummy2;
 443        unsigned long reg1, reg2, reg3, reg4;
 444
 445        __asm__ __volatile__(
 446                ".set\tnoreorder\n\t"
 447                ".set\tnoat\n\t"
 448                ".set\tmips3\n\t"
 449                "daddiu\t$1,%0,%8\n"
 450                "1:\tcache\t%9,(%0)\n\t"
 451                "lw\t%2,(%1)\n\t"
 452                "lw\t%3,4(%1)\n\t"
 453                "lw\t%4,8(%1)\n\t"
 454                "lw\t%5,12(%1)\n\t"
 455                "sw\t%2,(%0)\n\t"
 456                "sw\t%3,4(%0)\n\t"
 457                "sw\t%4,8(%0)\n\t"
 458                "sw\t%5,12(%0)\n\t"
 459                "lw\t%2,16(%1)\n\t"
 460                "lw\t%3,20(%1)\n\t"
 461                "lw\t%4,24(%1)\n\t"
 462                "lw\t%5,28(%1)\n\t"
 463                "sw\t%2,16(%0)\n\t"
 464                "sw\t%3,20(%0)\n\t"
 465                "sw\t%4,24(%0)\n\t"
 466                "sw\t%5,28(%0)\n\t"
 467                "cache\t%9,32(%0)\n\t"
 468                "daddiu\t%0,64\n\t"
 469                "daddiu\t%1,64\n\t"
 470                "lw\t%2,-32(%1)\n\t"
 471                "lw\t%3,-28(%1)\n\t"
 472                "lw\t%4,-24(%1)\n\t"
 473                "lw\t%5,-20(%1)\n\t"
 474                "sw\t%2,-32(%0)\n\t"
 475                "sw\t%3,-28(%0)\n\t"
 476                "sw\t%4,-24(%0)\n\t"
 477                "sw\t%5,-20(%0)\n\t"
 478                "lw\t%2,-16(%1)\n\t"
 479                "lw\t%3,-12(%1)\n\t"
 480                "lw\t%4,-8(%1)\n\t"
 481                "lw\t%5,-4(%1)\n\t"
 482                "sw\t%2,-16(%0)\n\t"
 483                "sw\t%3,-12(%0)\n\t"
 484                "sw\t%4,-8(%0)\n\t"
 485                "bne\t$1,%0,1b\n\t"
 486                "sw\t%5,-4(%0)\n\t"
 487                ".set\tmips0\n\t"
 488                ".set\tat\n\t"
 489                ".set\treorder"
 490                :"=r" (dummy1), "=r" (dummy2),
 491                 "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
 492                :"0" (to), "1" (from),
 493                 "I" (PAGE_SIZE),
 494                 "i" (Create_Dirty_Excl_D));
 495}
 496
 497/*
 498 * Again a special version for the R4600 V1.x
 499 */
 500static void r4k_copy_page_r4600_v1(void * to, void * from)
 501{
 502        unsigned long dummy1, dummy2;
 503        unsigned long reg1, reg2, reg3, reg4;
 504
 505        __asm__ __volatile__(
 506                ".set\tnoreorder\n\t"
 507                ".set\tnoat\n\t"
 508                ".set\tmips3\n\t"
 509                "daddiu\t$1,%0,%8\n"
 510                "1:\tnop\n\t"
 511                "nop\n\t"
 512                "nop\n\t"
 513                "nop\n\t"
 514                "\tcache\t%9,(%0)\n\t"
 515                "lw\t%2,(%1)\n\t"
 516                "lw\t%3,4(%1)\n\t"
 517                "lw\t%4,8(%1)\n\t"
 518                "lw\t%5,12(%1)\n\t"
 519                "sw\t%2,(%0)\n\t"
 520                "sw\t%3,4(%0)\n\t"
 521                "sw\t%4,8(%0)\n\t"
 522                "sw\t%5,12(%0)\n\t"
 523                "lw\t%2,16(%1)\n\t"
 524                "lw\t%3,20(%1)\n\t"
 525                "lw\t%4,24(%1)\n\t"
 526                "lw\t%5,28(%1)\n\t"
 527                "sw\t%2,16(%0)\n\t"
 528                "sw\t%3,20(%0)\n\t"
 529                "sw\t%4,24(%0)\n\t"
 530                "sw\t%5,28(%0)\n\t"
 531                "nop\n\t"
 532                "nop\n\t"
 533                "nop\n\t"
 534                "nop\n\t"
 535                "cache\t%9,32(%0)\n\t"
 536                "daddiu\t%0,64\n\t"
 537                "daddiu\t%1,64\n\t"
 538                "lw\t%2,-32(%1)\n\t"
 539                "lw\t%3,-28(%1)\n\t"
 540                "lw\t%4,-24(%1)\n\t"
 541                "lw\t%5,-20(%1)\n\t"
 542                "sw\t%2,-32(%0)\n\t"
 543                "sw\t%3,-28(%0)\n\t"
 544                "sw\t%4,-24(%0)\n\t"
 545                "sw\t%5,-20(%0)\n\t"
 546                "lw\t%2,-16(%1)\n\t"
 547                "lw\t%3,-12(%1)\n\t"
 548                "lw\t%4,-8(%1)\n\t"
 549                "lw\t%5,-4(%1)\n\t"
 550                "sw\t%2,-16(%0)\n\t"
 551                "sw\t%3,-12(%0)\n\t"
 552                "sw\t%4,-8(%0)\n\t"
 553                "bne\t$1,%0,1b\n\t"
 554                "sw\t%5,-4(%0)\n\t"
 555                ".set\tmips0\n\t"
 556                ".set\tat\n\t"
 557                ".set\treorder"
 558                :"=r" (dummy1), "=r" (dummy2),
 559                 "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
 560                :"0" (to), "1" (from),
 561                 "I" (PAGE_SIZE),
 562                 "i" (Create_Dirty_Excl_D));
 563}
 564
 565static void r4k_copy_page_r4600_v2(void * to, void * from)
 566{
 567        unsigned long dummy1, dummy2;
 568        unsigned long reg1, reg2, reg3, reg4;
 569        unsigned int flags;
 570
 571        local_irq_save(flags);
 572        __asm__ __volatile__(
 573                ".set\tnoreorder\n\t"
 574                ".set\tnoat\n\t"
 575                ".set\tmips3\n\t"
 576                "daddiu\t$1,%0,%8\n"
 577                "1:\tnop\n\t"
 578                "nop\n\t"
 579                "nop\n\t"
 580                "nop\n\t"
 581                "\tcache\t%9,(%0)\n\t"
 582                "lw\t%2,(%1)\n\t"
 583                "lw\t%3,4(%1)\n\t"
 584                "lw\t%4,8(%1)\n\t"
 585                "lw\t%5,12(%1)\n\t"
 586                "sw\t%2,(%0)\n\t"
 587                "sw\t%3,4(%0)\n\t"
 588                "sw\t%4,8(%0)\n\t"
 589                "sw\t%5,12(%0)\n\t"
 590                "lw\t%2,16(%1)\n\t"
 591                "lw\t%3,20(%1)\n\t"
 592                "lw\t%4,24(%1)\n\t"
 593                "lw\t%5,28(%1)\n\t"
 594                "sw\t%2,16(%0)\n\t"
 595                "sw\t%3,20(%0)\n\t"
 596                "sw\t%4,24(%0)\n\t"
 597                "sw\t%5,28(%0)\n\t"
 598                "nop\n\t"
 599                "nop\n\t"
 600                "nop\n\t"
 601                "nop\n\t"
 602                "cache\t%9,32(%0)\n\t"
 603                "daddiu\t%0,64\n\t"
 604                "daddiu\t%1,64\n\t"
 605                "lw\t%2,-32(%1)\n\t"
 606                "lw\t%3,-28(%1)\n\t"
 607                "lw\t%4,-24(%1)\n\t"
 608                "lw\t%5,-20(%1)\n\t"
 609                "sw\t%2,-32(%0)\n\t"
 610                "sw\t%3,-28(%0)\n\t"
 611                "sw\t%4,-24(%0)\n\t"
 612                "sw\t%5,-20(%0)\n\t"
 613                "lw\t%2,-16(%1)\n\t"
 614                "lw\t%3,-12(%1)\n\t"
 615                "lw\t%4,-8(%1)\n\t"
 616                "lw\t%5,-4(%1)\n\t"
 617                "sw\t%2,-16(%0)\n\t"
 618                "sw\t%3,-12(%0)\n\t"
 619                "sw\t%4,-8(%0)\n\t"
 620                "bne\t$1,%0,1b\n\t"
 621                "sw\t%5,-4(%0)\n\t"
 622                ".set\tmips0\n\t"
 623                ".set\tat\n\t"
 624                ".set\treorder"
 625                :"=r" (dummy1), "=r" (dummy2),
 626                 "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
 627                :"0" (to), "1" (from),
 628                 "I" (PAGE_SIZE),
 629                 "i" (Create_Dirty_Excl_D));
 630        local_irq_restore(flags);
 631}
 632
 633/*
 634 * These are for R4000SC / R4400MC
 635 */
 636static void r4k_copy_page_s16(void * to, void * from)
 637{
 638        unsigned long dummy1, dummy2;
 639        unsigned long reg1, reg2, reg3, reg4;
 640
 641        __asm__ __volatile__(
 642                ".set\tnoreorder\n\t"
 643                ".set\tnoat\n\t"
 644                ".set\tmips3\n\t"
 645                "daddiu\t$1,%0,%8\n"
 646                "1:\tcache\t%9,(%0)\n\t"
 647                "lw\t%2,(%1)\n\t"
 648                "lw\t%3,4(%1)\n\t"
 649                "lw\t%4,8(%1)\n\t"
 650                "lw\t%5,12(%1)\n\t"
 651                "sw\t%2,(%0)\n\t"
 652                "sw\t%3,4(%0)\n\t"
 653                "sw\t%4,8(%0)\n\t"
 654                "sw\t%5,12(%0)\n\t"
 655                "cache\t%9,16(%0)\n\t"
 656                "lw\t%2,16(%1)\n\t"
 657                "lw\t%3,20(%1)\n\t"
 658                "lw\t%4,24(%1)\n\t"
 659                "lw\t%5,28(%1)\n\t"
 660                "sw\t%2,16(%0)\n\t"
 661                "sw\t%3,20(%0)\n\t"
 662                "sw\t%4,24(%0)\n\t"
 663                "sw\t%5,28(%0)\n\t"
 664                "cache\t%9,32(%0)\n\t"
 665                "daddiu\t%0,64\n\t"
 666                "daddiu\t%1,64\n\t"
 667                "lw\t%2,-32(%1)\n\t"
 668                "lw\t%3,-28(%1)\n\t"
 669                "lw\t%4,-24(%1)\n\t"
 670                "lw\t%5,-20(%1)\n\t"
 671                "sw\t%2,-32(%0)\n\t"
 672                "sw\t%3,-28(%0)\n\t"
 673                "sw\t%4,-24(%0)\n\t"
 674                "sw\t%5,-20(%0)\n\t"
 675                "cache\t%9,-16(%0)\n\t"
 676                "lw\t%2,-16(%1)\n\t"
 677                "lw\t%3,-12(%1)\n\t"
 678                "lw\t%4,-8(%1)\n\t"
 679                "lw\t%5,-4(%1)\n\t"
 680                "sw\t%2,-16(%0)\n\t"
 681                "sw\t%3,-12(%0)\n\t"
 682                "sw\t%4,-8(%0)\n\t"
 683                "bne\t$1,%0,1b\n\t"
 684                "sw\t%5,-4(%0)\n\t"
 685                ".set\tmips0\n\t"
 686                ".set\tat\n\t"
 687                ".set\treorder"
 688                :"=r" (dummy1), "=r" (dummy2),
 689                 "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
 690                :"0" (to), "1" (from),
 691                 "I" (PAGE_SIZE),
 692                 "i" (Create_Dirty_Excl_SD));
 693}
 694
 695static void r4k_copy_page_s32(void * to, void * from)
 696{
 697        unsigned long dummy1, dummy2;
 698        unsigned long reg1, reg2, reg3, reg4;
 699
 700        __asm__ __volatile__(
 701                ".set\tnoreorder\n\t"
 702                ".set\tnoat\n\t"
 703                ".set\tmips3\n\t"
 704                "daddiu\t$1,%0,%8\n"
 705                "1:\tcache\t%9,(%0)\n\t"
 706                "lw\t%2,(%1)\n\t"
 707                "lw\t%3,4(%1)\n\t"
 708                "lw\t%4,8(%1)\n\t"
 709                "lw\t%5,12(%1)\n\t"
 710                "sw\t%2,(%0)\n\t"
 711                "sw\t%3,4(%0)\n\t"
 712                "sw\t%4,8(%0)\n\t"
 713                "sw\t%5,12(%0)\n\t"
 714                "lw\t%2,16(%1)\n\t"
 715                "lw\t%3,20(%1)\n\t"
 716                "lw\t%4,24(%1)\n\t"
 717                "lw\t%5,28(%1)\n\t"
 718                "sw\t%2,16(%0)\n\t"
 719                "sw\t%3,20(%0)\n\t"
 720                "sw\t%4,24(%0)\n\t"
 721                "sw\t%5,28(%0)\n\t"
 722                "cache\t%9,32(%0)\n\t"
 723                "daddiu\t%0,64\n\t"
 724                "daddiu\t%1,64\n\t"
 725                "lw\t%2,-32(%1)\n\t"
 726                "lw\t%3,-28(%1)\n\t"
 727                "lw\t%4,-24(%1)\n\t"
 728                "lw\t%5,-20(%1)\n\t"
 729                "sw\t%2,-32(%0)\n\t"
 730                "sw\t%3,-28(%0)\n\t"
 731                "sw\t%4,-24(%0)\n\t"
 732                "sw\t%5,-20(%0)\n\t"
 733                "lw\t%2,-16(%1)\n\t"
 734                "lw\t%3,-12(%1)\n\t"
 735                "lw\t%4,-8(%1)\n\t"
 736                "lw\t%5,-4(%1)\n\t"
 737                "sw\t%2,-16(%0)\n\t"
 738                "sw\t%3,-12(%0)\n\t"
 739                "sw\t%4,-8(%0)\n\t"
 740                "bne\t$1,%0,1b\n\t"
 741                "sw\t%5,-4(%0)\n\t"
 742                ".set\tmips0\n\t"
 743                ".set\tat\n\t"
 744                ".set\treorder"
 745                :"=r" (dummy1), "=r" (dummy2),
 746                 "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
 747                :"0" (to), "1" (from),
 748                 "I" (PAGE_SIZE),
 749                 "i" (Create_Dirty_Excl_SD));
 750}
 751
 752static void r4k_copy_page_s64(void * to, void * from)
 753{
 754        unsigned long dummy1, dummy2;
 755        unsigned long reg1, reg2, reg3, reg4;
 756
 757        __asm__ __volatile__(
 758                ".set\tnoreorder\n\t"
 759                ".set\tnoat\n\t"
 760                ".set\tmips3\n\t"
 761                "daddiu\t$1,%0,%8\n"
 762                "1:\tcache\t%9,(%0)\n\t"
 763                "lw\t%2,(%1)\n\t"
 764                "lw\t%3,4(%1)\n\t"
 765                "lw\t%4,8(%1)\n\t"
 766                "lw\t%5,12(%1)\n\t"
 767                "sw\t%2,(%0)\n\t"
 768                "sw\t%3,4(%0)\n\t"
 769                "sw\t%4,8(%0)\n\t"
 770                "sw\t%5,12(%0)\n\t"
 771                "lw\t%2,16(%1)\n\t"
 772                "lw\t%3,20(%1)\n\t"
 773                "lw\t%4,24(%1)\n\t"
 774                "lw\t%5,28(%1)\n\t"
 775                "sw\t%2,16(%0)\n\t"
 776                "sw\t%3,20(%0)\n\t"
 777                "sw\t%4,24(%0)\n\t"
 778                "sw\t%5,28(%0)\n\t"
 779                "daddiu\t%0,64\n\t"
 780                "daddiu\t%1,64\n\t"
 781                "lw\t%2,-32(%1)\n\t"
 782                "lw\t%3,-28(%1)\n\t"
 783                "lw\t%4,-24(%1)\n\t"
 784                "lw\t%5,-20(%1)\n\t"
 785                "sw\t%2,-32(%0)\n\t"
 786                "sw\t%3,-28(%0)\n\t"
 787                "sw\t%4,-24(%0)\n\t"
 788                "sw\t%5,-20(%0)\n\t"
 789                "lw\t%2,-16(%1)\n\t"
 790                "lw\t%3,-12(%1)\n\t"
 791                "lw\t%4,-8(%1)\n\t"
 792                "lw\t%5,-4(%1)\n\t"
 793                "sw\t%2,-16(%0)\n\t"
 794                "sw\t%3,-12(%0)\n\t"
 795                "sw\t%4,-8(%0)\n\t"
 796                "bne\t$1,%0,1b\n\t"
 797                "sw\t%5,-4(%0)\n\t"
 798                ".set\tmips0\n\t"
 799                ".set\tat\n\t"
 800                ".set\treorder"
 801                :"=r" (dummy1), "=r" (dummy2),
 802                 "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
 803                :"0" (to), "1" (from),
 804                 "I" (PAGE_SIZE),
 805                 "i" (Create_Dirty_Excl_SD));
 806}
 807
 808static void r4k_copy_page_s128(void * to, void * from)
 809{
 810        unsigned long dummy1, dummy2;
 811        unsigned long reg1, reg2, reg3, reg4;
 812
 813        __asm__ __volatile__(
 814                ".set\tnoreorder\n\t"
 815                ".set\tnoat\n\t"
 816                ".set\tmips3\n\t"
 817                "daddiu\t$1,%0,%8\n"
 818                "1:\tcache\t%9,(%0)\n\t"
 819                "lw\t%2,(%1)\n\t"
 820                "lw\t%3,4(%1)\n\t"
 821                "lw\t%4,8(%1)\n\t"
 822                "lw\t%5,12(%1)\n\t"
 823                "sw\t%2,(%0)\n\t"
 824                "sw\t%3,4(%0)\n\t"
 825                "sw\t%4,8(%0)\n\t"
 826                "sw\t%5,12(%0)\n\t"
 827                "lw\t%2,16(%1)\n\t"
 828                "lw\t%3,20(%1)\n\t"
 829                "lw\t%4,24(%1)\n\t"
 830                "lw\t%5,28(%1)\n\t"
 831                "sw\t%2,16(%0)\n\t"
 832                "sw\t%3,20(%0)\n\t"
 833                "sw\t%4,24(%0)\n\t"
 834                "sw\t%5,28(%0)\n\t"
 835                "lw\t%2,32(%1)\n\t"
 836                "lw\t%3,36(%1)\n\t"
 837                "lw\t%4,40(%1)\n\t"
 838                "lw\t%5,44(%1)\n\t"
 839                "sw\t%2,32(%0)\n\t"
 840                "sw\t%3,36(%0)\n\t"
 841                "sw\t%4,40(%0)\n\t"
 842                "sw\t%5,44(%0)\n\t"
 843                "lw\t%2,48(%1)\n\t"
 844                "lw\t%3,52(%1)\n\t"
 845                "lw\t%4,56(%1)\n\t"
 846                "lw\t%5,60(%1)\n\t"
 847                "sw\t%2,48(%0)\n\t"
 848                "sw\t%3,52(%0)\n\t"
 849                "sw\t%4,56(%0)\n\t"
 850                "sw\t%5,60(%0)\n\t"
 851                "daddiu\t%0,128\n\t"
 852                "daddiu\t%1,128\n\t"
 853                "lw\t%2,-64(%1)\n\t"
 854                "lw\t%3,-60(%1)\n\t"
 855                "lw\t%4,-56(%1)\n\t"
 856                "lw\t%5,-52(%1)\n\t"
 857                "sw\t%2,-64(%0)\n\t"
 858                "sw\t%3,-60(%0)\n\t"
 859                "sw\t%4,-56(%0)\n\t"
 860                "sw\t%5,-52(%0)\n\t"
 861                "lw\t%2,-48(%1)\n\t"
 862                "lw\t%3,-44(%1)\n\t"
 863                "lw\t%4,-40(%1)\n\t"
 864                "lw\t%5,-36(%1)\n\t"
 865                "sw\t%2,-48(%0)\n\t"
 866                "sw\t%3,-44(%0)\n\t"
 867                "sw\t%4,-40(%0)\n\t"
 868                "sw\t%5,-36(%0)\n\t"
 869                "lw\t%2,-32(%1)\n\t"
 870                "lw\t%3,-28(%1)\n\t"
 871                "lw\t%4,-24(%1)\n\t"
 872                "lw\t%5,-20(%1)\n\t"
 873                "sw\t%2,-32(%0)\n\t"
 874                "sw\t%3,-28(%0)\n\t"
 875                "sw\t%4,-24(%0)\n\t"
 876                "sw\t%5,-20(%0)\n\t"
 877                "lw\t%2,-16(%1)\n\t"
 878                "lw\t%3,-12(%1)\n\t"
 879                "lw\t%4,-8(%1)\n\t"
 880                "lw\t%5,-4(%1)\n\t"
 881                "sw\t%2,-16(%0)\n\t"
 882                "sw\t%3,-12(%0)\n\t"
 883                "sw\t%4,-8(%0)\n\t"
 884                "bne\t$1,%0,1b\n\t"
 885                "sw\t%5,-4(%0)\n\t"
 886                ".set\tmips0\n\t"
 887                ".set\tat\n\t"
 888                ".set\treorder"
 889                :"=r" (dummy1), "=r" (dummy2),
 890                 "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
 891                :"0" (to), "1" (from),
 892                 "I" (PAGE_SIZE),
 893                 "i" (Create_Dirty_Excl_SD));
 894}
 895
 896
 897/*
 898 * If you think for one second that this stuff coming up is a lot
 899 * of bulky code eating too many kernel cache lines.  Think _again_.
 900 *
 901 * Consider:
 902 * 1) Taken branches have a 3 cycle penalty on R4k
 903 * 2) The branch itself is a real dead cycle on even R4600/R5000.
 904 * 3) Only one of the following variants of each type is even used by
 905 *    the kernel based upon the cache parameters we detect at boot time.
 906 *
 907 * QED.
 908 */
 909
 910static inline void r4k_flush_cache_all_s16d16i16(void)
 911{
 912        unsigned long flags;
 913
 914        local_irq_save(flags);
 915        blast_dcache16(); blast_icache16(); blast_scache16();
 916        local_irq_restore(flags);
 917}
 918
 919static inline void r4k_flush_cache_all_s32d16i16(void)
 920{
 921        unsigned long flags;
 922
 923        local_irq_save(flags);
 924        blast_dcache16(); blast_icache16(); blast_scache32();
 925        local_irq_restore(flags);
 926}
 927
 928static inline void r4k_flush_cache_all_s64d16i16(void)
 929{
 930        unsigned long flags;
 931
 932        local_irq_save(flags);
 933        blast_dcache16(); blast_icache16(); blast_scache64();
 934        local_irq_restore(flags);
 935}
 936
 937static inline void r4k_flush_cache_all_s128d16i16(void)
 938{
 939        unsigned long flags;
 940
 941        local_irq_save(flags);
 942        blast_dcache16(); blast_icache16(); blast_scache128();
 943        local_irq_restore(flags);
 944}
 945
 946static inline void r4k_flush_cache_all_s32d32i32(void)
 947{
 948        unsigned long flags;
 949
 950        local_irq_save(flags);
 951        blast_dcache32(); blast_icache32(); blast_scache32();
 952        local_irq_restore(flags);
 953}
 954
 955static inline void r4k_flush_cache_all_s64d32i32(void)
 956{
 957        unsigned long flags;
 958
 959        local_irq_save(flags);
 960        blast_dcache32(); blast_icache32(); blast_scache64();
 961        local_irq_restore(flags);
 962}
 963
 964static inline void r4k_flush_cache_all_s128d32i32(void)
 965{
 966        unsigned long flags;
 967
 968        local_irq_save(flags);
 969        blast_dcache32(); blast_icache32(); blast_scache128();
 970        local_irq_restore(flags);
 971}
 972
 973static inline void r4k_flush_cache_all_d16i16(void)
 974{
 975        unsigned long flags;
 976
 977        local_irq_save(flags);
 978        blast_dcache16(); blast_icache16();
 979        local_irq_restore(flags);
 980}
 981
 982static inline void r4k_flush_cache_all_d32i32(void)
 983{
 984        unsigned long flags;
 985
 986        local_irq_save(flags);
 987        blast_dcache32(); blast_icache32();
 988        local_irq_restore(flags);
 989}
 990
 991static void
 992r4k_flush_cache_range_s16d16i16(struct vm_area_struct *vma,
 993                                unsigned long start,
 994                                unsigned long end)
 995{
 996        struct mm_struct *mm = vma->vm_mm;
 997        unsigned long flags;
 998
 999        if (mm->context == 0)
1000                return;
1001
1002        start &= PAGE_MASK;
1003#ifdef DEBUG_CACHE
1004        printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
1005#endif
1006        if (vma) {
1007                if (mm->context != current->active_mm->context) {
1008                        r4k_flush_cache_all_s16d16i16();
1009                } else {
1010                        pgd_t *pgd;
1011                        pmd_t *pmd;
1012                        pte_t *pte;
1013
1014                        local_irq_save(flags);
1015                        while(start < end) {
1016                                pgd = pgd_offset(mm, start);
1017                                pmd = pmd_offset(pgd, start);
1018                                pte = pte_offset(pmd, start);
1019
1020                                if(pte_val(*pte) & _PAGE_VALID)
1021                                        blast_scache16_page(start);
1022                                start += PAGE_SIZE;
1023                        }
1024                        local_irq_restore(flags);
1025                }
1026        }
1027}
1028
1029static void
1030r4k_flush_cache_range_s32d16i16(struct vm_area_struct *vma,
1031                                unsigned long start,
1032                                unsigned long end)
1033{
1034        struct mm_struct *mm = vma->vm_mm;
1035        unsigned long flags;
1036
1037        if (mm->context == 0)
1038                return;
1039
1040        start &= PAGE_MASK;
1041#ifdef DEBUG_CACHE
1042        printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
1043#endif
1044        if (vma) {
1045                if (mm->context != current->active_mm->context) {
1046                        r4k_flush_cache_all_s32d16i16();
1047                } else {
1048                        pgd_t *pgd;
1049                        pmd_t *pmd;
1050                        pte_t *pte;
1051
1052                        local_irq_save(flags);
1053                        while(start < end) {
1054                                pgd = pgd_offset(mm, start);
1055                                pmd = pmd_offset(pgd, start);
1056                                pte = pte_offset(pmd, start);
1057
1058                                if(pte_val(*pte) & _PAGE_VALID)
1059                                        blast_scache32_page(start);
1060                                start += PAGE_SIZE;
1061                        }
1062                        local_irq_restore(flags);
1063                }
1064        }
1065}
1066
1067static void r4k_flush_cache_range_s64d16i16(struct vm_area_struct *vma,
1068                                            unsigned long start,
1069                                            unsigned long end)
1070{
1071        struct mm_struct *mm = vma->vm_mm;
1072        unsigned long flags;
1073
1074        if (mm->context == 0)
1075                return;
1076
1077        start &= PAGE_MASK;
1078#ifdef DEBUG_CACHE
1079        printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
1080#endif
1081        if(vma) {
1082                if (mm->context != current->active_mm->context) {
1083                        r4k_flush_cache_all_s64d16i16();
1084                } else {
1085                        pgd_t *pgd;
1086                        pmd_t *pmd;
1087                        pte_t *pte;
1088
1089                        local_irq_save(flags);
1090                        while(start < end) {
1091                                pgd = pgd_offset(mm, start);
1092                                pmd = pmd_offset(pgd, start);
1093                                pte = pte_offset(pmd, start);
1094
1095                                if(pte_val(*pte) & _PAGE_VALID)
1096                                        blast_scache64_page(start);
1097                                start += PAGE_SIZE;
1098                        }
1099                        local_irq_restore(flags);
1100                }
1101        }
1102}
1103
1104static void r4k_flush_cache_range_s128d16i16(struct vm_area_struct *vma,
1105                                             unsigned long start,
1106                                             unsigned long end)
1107{
1108        struct mm_struct *mm = vma->vm_mm;
1109        unsigned long flags;
1110
1111        if (mm->context == 0)
1112                return;
1113
1114        start &= PAGE_MASK;
1115#ifdef DEBUG_CACHE
1116        printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
1117#endif
1118        if (vma) {
1119                if (mm->context != current->active_mm->context) {
1120                        r4k_flush_cache_all_s128d16i16();
1121                } else {
1122                        pgd_t *pgd;
1123                        pmd_t *pmd;
1124                        pte_t *pte;
1125
1126                        local_irq_save(flags);
1127                        while(start < end) {
1128                                pgd = pgd_offset(mm, start);
1129                                pmd = pmd_offset(pgd, start);
1130                                pte = pte_offset(pmd, start);
1131
1132                                if(pte_val(*pte) & _PAGE_VALID)
1133                                        blast_scache128_page(start);
1134                                start += PAGE_SIZE;
1135                        }
1136                        local_irq_restore(flags);
1137                }
1138        }
1139}
1140
1141static void r4k_flush_cache_range_s32d32i32(struct vm_area_struct *vma,
1142                                            unsigned long start,
1143                                            unsigned long end)
1144{
1145        struct mm_struct *mm = vma->vm_mm;
1146        unsigned long flags;
1147
1148        if (mm->context == 0)
1149                return;
1150
1151        start &= PAGE_MASK;
1152#ifdef DEBUG_CACHE
1153        printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
1154#endif
1155        if (vma) {
1156                if (mm->context != current->active_mm->context) {
1157                        r4k_flush_cache_all_s32d32i32();
1158                } else {
1159                        pgd_t *pgd;
1160                        pmd_t *pmd;
1161                        pte_t *pte;
1162
1163                        local_irq_save(flags);
1164                        while(start < end) {
1165                                pgd = pgd_offset(mm, start);
1166                                pmd = pmd_offset(pgd, start);
1167                                pte = pte_offset(pmd, start);
1168
1169                                if(pte_val(*pte) & _PAGE_VALID)
1170                                        blast_scache32_page(start);
1171                                start += PAGE_SIZE;
1172                        }
1173                        local_irq_restore(flags);
1174                }
1175        }
1176}
1177
1178static void r4k_flush_cache_range_s64d32i32(struct vm_area_struct *vma,
1179                                            unsigned long start,
1180                                            unsigned long end)
1181{
1182        struct mm_struct *mm = vma->vm_mm;
1183        unsigned long flags;
1184
1185        if (mm->context == 0)
1186                return;
1187
1188        start &= PAGE_MASK;
1189#ifdef DEBUG_CACHE
1190        printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
1191#endif
1192        if (vma) {
1193                if (mm->context != current->active_mm->context) {
1194                        r4k_flush_cache_all_s64d32i32();
1195                } else {
1196                        pgd_t *pgd;
1197                        pmd_t *pmd;
1198                        pte_t *pte;
1199
1200                        local_irq_save(flags);
1201                        while(start < end) {
1202                                pgd = pgd_offset(mm, start);
1203                                pmd = pmd_offset(pgd, start);
1204                                pte = pte_offset(pmd, start);
1205
1206                                if(pte_val(*pte) & _PAGE_VALID)
1207                                        blast_scache64_page(start);
1208                                start += PAGE_SIZE;
1209                        }
1210                        local_irq_restore(flags);
1211                }
1212        }
1213}
1214
1215static void r4k_flush_cache_range_s128d32i32(struct vm_area_struct *vma,
1216                                             unsigned long start,
1217                                             unsigned long end)
1218{
1219        struct mm_struct *mm = vma->vm_mm;
1220        unsigned long flags;
1221
1222        if (mm->context == 0)
1223                return;
1224
1225        start &= PAGE_MASK;
1226#ifdef DEBUG_CACHE
1227        printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
1228#endif
1229        if (vma) {
1230                if (mm->context != current->active_mm->context) {
1231                        r4k_flush_cache_all_s128d32i32();
1232                } else {
1233                        pgd_t *pgd;
1234                        pmd_t *pmd;
1235                        pte_t *pte;
1236
1237                        local_irq_save(flags);
1238                        while(start < end) {
1239                                pgd = pgd_offset(mm, start);
1240                                pmd = pmd_offset(pgd, start);
1241                                pte = pte_offset(pmd, start);
1242
1243                                if(pte_val(*pte) & _PAGE_VALID)
1244                                        blast_scache128_page(start);
1245                                start += PAGE_SIZE;
1246                        }
1247                        local_irq_restore(flags);
1248                }
1249        }
1250}
1251
1252static void r4k_flush_cache_range_d16i16(struct mm_struct *vma,
1253                                         unsigned long start,
1254                                         unsigned long end)
1255{
1256        struct mm_struct *mm = vma->vm_mm;
1257
1258        if (mm->context != 0) {
1259                unsigned long flags;
1260
1261#ifdef DEBUG_CACHE
1262                printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
1263#endif
1264                local_irq_save(flags);
1265                blast_dcache16(); blast_icache16();
1266                local_irq_restore(flags);
1267        }
1268}
1269
1270static void r4k_flush_cache_range_d32i32(struct vm_area_struct *vma,
1271                                         unsigned long start,
1272                                         unsigned long end)
1273{
1274        struct mm_struct *mm = vma->vm_mm;
1275
1276        if (mm->context != 0) {
1277                unsigned long flags;
1278
1279#ifdef DEBUG_CACHE
1280                printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
1281#endif
1282                local_irq_save(flags);
1283                blast_dcache32(); blast_icache32();
1284                local_irq_restore(flags);
1285        }
1286}
1287
1288/*
1289 * On architectures like the Sparc, we could get rid of lines in
1290 * the cache created only by a certain context, but on the MIPS
1291 * (and actually certain Sparc's) we cannot.
1292 */
1293static void r4k_flush_cache_mm_s16d16i16(struct mm_struct *mm)
1294{
1295        if (mm->context != 0) {
1296#ifdef DEBUG_CACHE
1297                printk("cmm[%d]", (int)mm->context);
1298#endif
1299                r4k_flush_cache_all_s16d16i16();
1300        }
1301}
1302
1303static void r4k_flush_cache_mm_s32d16i16(struct mm_struct *mm)
1304{
1305        if (mm->context != 0) {
1306#ifdef DEBUG_CACHE
1307                printk("cmm[%d]", (int)mm->context);
1308#endif
1309                r4k_flush_cache_all_s32d16i16();
1310        }
1311}
1312
1313static void r4k_flush_cache_mm_s64d16i16(struct mm_struct *mm)
1314{
1315        if (mm->context != 0) {
1316#ifdef DEBUG_CACHE
1317                printk("cmm[%d]", (int)mm->context);
1318#endif
1319                r4k_flush_cache_all_s64d16i16();
1320        }
1321}
1322
1323static void r4k_flush_cache_mm_s128d16i16(struct mm_struct *mm)
1324{
1325        if (mm->context != 0) {
1326#ifdef DEBUG_CACHE
1327                printk("cmm[%d]", (int)mm->context);
1328#endif
1329                r4k_flush_cache_all_s128d16i16();
1330        }
1331}
1332
1333static void r4k_flush_cache_mm_s32d32i32(struct mm_struct *mm)
1334{
1335        if (mm->context != 0) {
1336#ifdef DEBUG_CACHE
1337                printk("cmm[%d]", (int)mm->context);
1338#endif
1339                r4k_flush_cache_all_s32d32i32();
1340        }
1341}
1342
1343static void r4k_flush_cache_mm_s64d32i32(struct mm_struct *mm)
1344{
1345        if (mm->context != 0) {
1346#ifdef DEBUG_CACHE
1347                printk("cmm[%d]", (int)mm->context);
1348#endif
1349                r4k_flush_cache_all_s64d32i32();
1350        }
1351}
1352
1353static void r4k_flush_cache_mm_s128d32i32(struct mm_struct *mm)
1354{
1355        if (mm->context != 0) {
1356#ifdef DEBUG_CACHE
1357                printk("cmm[%d]", (int)mm->context);
1358#endif
1359                r4k_flush_cache_all_s128d32i32();
1360        }
1361}
1362
1363static void r4k_flush_cache_mm_d16i16(struct mm_struct *mm)
1364{
1365        if (mm->context != 0) {
1366#ifdef DEBUG_CACHE
1367                printk("cmm[%d]", (int)mm->context);
1368#endif
1369                r4k_flush_cache_all_d16i16();
1370        }
1371}
1372
1373static void r4k_flush_cache_mm_d32i32(struct mm_struct *mm)
1374{
1375        if (mm->context != 0) {
1376#ifdef DEBUG_CACHE
1377                printk("cmm[%d]", (int)mm->context);
1378#endif
1379                r4k_flush_cache_all_d32i32();
1380        }
1381}
1382
1383static void r4k_flush_cache_page_s16d16i16(struct vm_area_struct *vma,
1384                                           unsigned long page)
1385{
1386        struct mm_struct *mm = vma->vm_mm;
1387        unsigned long flags;
1388        pgd_t *pgdp;
1389        pmd_t *pmdp;
1390        pte_t *ptep;
1391
1392        /*
1393         * If ownes no valid ASID yet, cannot possibly have gotten
1394         * this page into the cache.
1395         */
1396        if (mm->context == 0)
1397                return;
1398
1399#ifdef DEBUG_CACHE
1400        printk("cpage[%d,%08lx]", (int)mm->context, page);
1401#endif
1402        local_irq_save(flags);
1403        page &= PAGE_MASK;
1404        pgdp = pgd_offset(mm, page);
1405        pmdp = pmd_offset(pgdp, page);
1406        ptep = pte_offset(pmdp, page);
1407
1408        /*
1409         * If the page isn't marked valid, the page cannot possibly be
1410         * in the cache.
1411         */
1412        if (!(pte_val(*ptep) & _PAGE_VALID))
1413                goto out;
1414
1415        /*
1416         * Doing flushes for another ASID than the current one is
1417         * too difficult since stupid R4k caches do a TLB translation
1418         * for every cache flush operation.  So we do indexed flushes
1419         * in that case, which doesn't overly flush the cache too much.
1420         */
1421        if (mm->context != current->active_mm->context) {
1422                /*
1423                 * Do indexed flush, too much work to get the (possible)
1424                 * tlb refills to work correctly.
1425                 */
1426                page = (KSEG0 + (page & (scache_size - 1)));
1427                blast_dcache16_page_indexed(page);
1428                blast_scache16_page_indexed(page);
1429        } else
1430                blast_scache16_page(page);
1431out:
1432        local_irq_restore(flags);
1433}
1434
1435static void r4k_flush_cache_page_s32d16i16(struct vm_area_struct *vma,
1436                                           unsigned long page)
1437{
1438        struct mm_struct *mm = vma->vm_mm;
1439        unsigned long flags;
1440        pgd_t *pgdp;
1441        pmd_t *pmdp;
1442        pte_t *ptep;
1443
1444        /*
1445         * If ownes no valid ASID yet, cannot possibly have gotten
1446         * this page into the cache.
1447         */
1448        if (mm->context == 0)
1449                return;
1450
1451#ifdef DEBUG_CACHE
1452        printk("cpage[%d,%08lx]", (int)mm->context, page);
1453#endif
1454        local_irq_save(flags);
1455        page &= PAGE_MASK;
1456        pgdp = pgd_offset(mm, page);
1457        pmdp = pmd_offset(pgdp, page);
1458        ptep = pte_offset(pmdp, page);
1459
1460        /* If the page isn't marked valid, the page cannot possibly be
1461         * in the cache.
1462         */
1463        if (!(pte_val(*ptep) & _PAGE_VALID))
1464                goto out;
1465
1466        /*
1467         * Doing flushes for another ASID than the current one is
1468         * too difficult since stupid R4k caches do a TLB translation
1469         * for every cache flush operation.  So we do indexed flushes
1470         * in that case, which doesn't overly flush the cache too much.
1471         */
1472        if (mm->context != current->active_mm->context) {
1473                /*
1474                 * Do indexed flush, too much work to get the (possible)
1475                 * tlb refills to work correctly.
1476                 */
1477                page = (KSEG0 + (page & (scache_size - 1)));
1478                blast_dcache16_page_indexed(page);
1479                blast_scache32_page_indexed(page);
1480        } else
1481                blast_scache32_page(page);
1482out:
1483        local_irq_restore(flags);
1484}
1485
1486static void r4k_flush_cache_page_s64d16i16(struct vm_area_struct *vma,
1487                                           unsigned long page)
1488{
1489        struct mm_struct *mm = vma->vm_mm;
1490        unsigned long flags;
1491        pgd_t *pgdp;
1492        pmd_t *pmdp;
1493        pte_t *ptep;
1494
1495        /*
1496         * If ownes no valid ASID yet, cannot possibly have gotten
1497         * this page into the cache.
1498         */
1499        if (mm->context == 0)
1500                return;
1501
1502#ifdef DEBUG_CACHE
1503        printk("cpage[%d,%08lx]", (int)mm->context, page);
1504#endif
1505        local_irq_save(flags);
1506        page &= PAGE_MASK;
1507        pgdp = pgd_offset(mm, page);
1508        pmdp = pmd_offset(pgdp, page);
1509        ptep = pte_offset(pmdp, page);
1510
1511        /* If the page isn't marked valid, the page cannot possibly be
1512         * in the cache.
1513         */
1514        if (!(pte_val(*ptep) & _PAGE_VALID))
1515                goto out;
1516
1517        /*
1518         * Doing flushes for another ASID than the current one is
1519         * too difficult since stupid R4k caches do a TLB translation
1520         * for every cache flush operation.  So we do indexed flushes
1521         * in that case, which doesn't overly flush the cache too much.
1522         */
1523        if (mm->context != current->active_mm->context) {
1524                /*
1525                 * Do indexed flush, too much work to get the (possible)
1526                 * tlb refills to work correctly.
1527                 */
1528                page = (KSEG0 + (page & (scache_size - 1)));
1529                blast_dcache16_page_indexed(page);
1530                blast_scache64_page_indexed(page);
1531        } else
1532                blast_scache64_page(page);
1533out:
1534        local_irq_restore(flags);
1535}
1536
1537static void r4k_flush_cache_page_s128d16i16(struct vm_area_struct *vma,
1538                                            unsigned long page)
1539{
1540        struct mm_struct *mm = vma->vm_mm;
1541        unsigned long flags;
1542        pgd_t *pgdp;
1543        pmd_t *pmdp;
1544        pte_t *ptep;
1545
1546        /*
1547         * If ownes no valid ASID yet, cannot possibly have gotten
1548         * this page into the cache.
1549         */
1550        if (mm->context == 0)
1551                return;
1552
1553#ifdef DEBUG_CACHE
1554        printk("cpage[%d,%08lx]", (int)mm->context, page);
1555#endif
1556        local_irq_save(flags);
1557        page &= PAGE_MASK;
1558        pgdp = pgd_offset(mm, page);
1559        pmdp = pmd_offset(pgdp, page);
1560        ptep = pte_offset(pmdp, page);
1561
1562        /*
1563         * If the page isn't marked valid, the page cannot possibly be
1564         * in the cache.
1565         */
1566        if (!(pte_val(*ptep) & _PAGE_VALID))
1567                goto out;
1568
1569        /*
1570         * Doing flushes for another ASID than the current one is
1571         * too difficult since stupid R4k caches do a TLB translation
1572         * for every cache flush operation.  So we do indexed flushes
1573         * in that case, which doesn't overly flush the cache too much.
1574         */
1575        if (mm->context != current->active_mm->context) {
1576                /*
1577                 * Do indexed flush, too much work to get the (possible)
1578                 * tlb refills to work correctly.
1579                 */
1580                page = (KSEG0 + (page & (scache_size - 1)));
1581                blast_dcache16_page_indexed(page);
1582                blast_scache128_page_indexed(page);
1583        } else
1584                blast_scache128_page(page);
1585out:
1586        local_irq_restore(flags);
1587}
1588
1589static void r4k_flush_cache_page_s32d32i32(struct vm_area_struct *vma,
1590                                           unsigned long page)
1591{
1592        struct mm_struct *mm = vma->vm_mm;
1593        unsigned long flags;
1594        pgd_t *pgdp;
1595        pmd_t *pmdp;
1596        pte_t *ptep;
1597
1598        /*
1599         * If ownes no valid ASID yet, cannot possibly have gotten
1600         * this page into the cache.
1601         */
1602        if (mm->context == 0)
1603                return;
1604
1605#ifdef DEBUG_CACHE
1606        printk("cpage[%d,%08lx]", (int)mm->context, page);
1607#endif
1608        local_irq_save(flags);
1609        page &= PAGE_MASK;
1610        pgdp = pgd_offset(mm, page);
1611        pmdp = pmd_offset(pgdp, page);
1612        ptep = pte_offset(pmdp, page);
1613
1614        /*
1615         * If the page isn't marked valid, the page cannot possibly be
1616         * in the cache.
1617         */
1618        if (!(pte_val(*ptep) & _PAGE_VALID))
1619                goto out;
1620
1621        /*
1622         * Doing flushes for another ASID than the current one is
1623         * too difficult since stupid R4k caches do a TLB translation
1624         * for every cache flush operation.  So we do indexed flushes
1625         * in that case, which doesn't overly flush the cache too much.
1626         */
1627        if (mm->context != current->active_mm->context) {
1628                /*
1629                 * Do indexed flush, too much work to get the (possible)
1630                 * tlb refills to work correctly.
1631                 */
1632                page = (KSEG0 + (page & (scache_size - 1)));
1633                blast_dcache32_page_indexed(page);
1634                blast_scache32_page_indexed(page);
1635        } else
1636                blast_scache32_page(page);
1637out:
1638        local_irq_restore(flags);
1639}
1640
1641static void r4k_flush_cache_page_s64d32i32(struct vm_area_struct *vma,
1642                                           unsigned long page)
1643{
1644        struct mm_struct *mm = vma->vm_mm;
1645        unsigned long flags;
1646        pgd_t *pgdp;
1647        pmd_t *pmdp;
1648        pte_t *ptep;
1649
1650        /*
1651         * If ownes no valid ASID yet, cannot possibly have gotten
1652         * this page into the cache.
1653         */
1654        if (mm->context == 0)
1655                return;
1656
1657#ifdef DEBUG_CACHE
1658        printk("cpage[%d,%08lx]", (int)mm->context, page);
1659#endif
1660        local_irq_save(flags);
1661        page &= PAGE_MASK;
1662        pgdp = pgd_offset(mm, page);
1663        pmdp = pmd_offset(pgdp, page);
1664        ptep = pte_offset(pmdp, page);
1665
1666        /*
1667         * If the page isn't marked valid, the page cannot possibly be
1668         * in the cache.
1669         */
1670        if (!(pte_val(*ptep) & _PAGE_VALID))
1671                goto out;
1672
1673        /*
1674         * Doing flushes for another ASID than the current one is
1675         * too difficult since stupid R4k caches do a TLB translation
1676         * for every cache flush operation.  So we do indexed flushes
1677         * in that case, which doesn't overly flush the cache too much.
1678         */
1679        if (mm->context != current->active_mm->context) {
1680                /*
1681                 * Do indexed flush, too much work to get the (possible)
1682                 * tlb refills to work correctly.
1683                 */
1684                page = (KSEG0 + (page & (scache_size - 1)));
1685                blast_dcache32_page_indexed(page);
1686                blast_scache64_page_indexed(page);
1687        } else
1688                blast_scache64_page(page);
1689out:
1690        local_irq_restore(flags);
1691}
1692
1693static void r4k_flush_cache_page_s128d32i32(struct vm_area_struct *vma,
1694                                            unsigned long page)
1695{
1696        struct mm_struct *mm = vma->vm_mm;
1697        unsigned long flags;
1698        pgd_t *pgdp;
1699        pmd_t *pmdp;
1700        pte_t *ptep;
1701
1702        /*
1703         * If ownes no valid ASID yet, cannot possibly have gotten
1704         * this page into the cache.
1705         */
1706        if (mm->context == 0)
1707                return;
1708
1709#ifdef DEBUG_CACHE
1710        printk("cpage[%d,%08lx]", (int)mm->context, page);
1711#endif
1712        local_irq_save(flags);
1713        page &= PAGE_MASK;
1714        pgdp = pgd_offset(mm, page);
1715        pmdp = pmd_offset(pgdp, page);
1716        ptep = pte_offset(pmdp, page);
1717
1718        /*
1719         * If the page isn't marked valid, the page cannot possibly be
1720         * in the cache.
1721         */
1722        if (!(pte_val(*ptep) & _PAGE_VALID))
1723                goto out;
1724
1725        /*
1726         * Doing flushes for another ASID than the current one is
1727         * too difficult since stupid R4k caches do a TLB translation
1728         * for every cache flush operation.  So we do indexed flushes
1729         * in that case, which doesn't overly flush the cache too much.
1730         */
1731        if (mm->context != current->active_mm->context) {
1732                /* Do indexed flush, too much work to get the (possible)
1733                 * tlb refills to work correctly.
1734                 */
1735                page = (KSEG0 + (page & (scache_size - 1)));
1736                blast_dcache32_page_indexed(page);
1737                blast_scache128_page_indexed(page);
1738        } else
1739                blast_scache128_page(page);
1740out:
1741        local_irq_restore(flags);
1742}
1743
1744static void r4k_flush_cache_page_d16i16(struct vm_area_struct *vma,
1745                                        unsigned long page)
1746{
1747        struct mm_struct *mm = vma->vm_mm;
1748        unsigned long flags;
1749        pgd_t *pgdp;
1750        pmd_t *pmdp;
1751        pte_t *ptep;
1752
1753        /*
1754         * If ownes no valid ASID yet, cannot possibly have gotten
1755         * this page into the cache.
1756         */
1757        if (mm->context == 0)
1758                return;
1759
1760#ifdef DEBUG_CACHE
1761        printk("cpage[%d,%08lx]", (int)mm->context, page);
1762#endif
1763        local_irq_save(flags);
1764        page &= PAGE_MASK;
1765        pgdp = pgd_offset(mm, page);
1766        pmdp = pmd_offset(pgdp, page);
1767        ptep = pte_offset(pmdp, page);
1768
1769        /*
1770         * If the page isn't marked valid, the page cannot possibly be
1771         * in the cache.
1772         */
1773        if (!(pte_val(*ptep) & _PAGE_VALID))
1774                goto out;
1775
1776        /*
1777         * Doing flushes for another ASID than the current one is
1778         * too difficult since stupid R4k caches do a TLB translation
1779         * for every cache flush operation.  So we do indexed flushes
1780         * in that case, which doesn't overly flush the cache too much.
1781         */
1782        if (mm == current->active_mm) {
1783                blast_dcache16_page(page);
1784        } else {
1785                /* Do indexed flush, too much work to get the (possible)
1786                 * tlb refills to work correctly.
1787                 */
1788                page = (KSEG0 + (page & (dcache_size - 1)));
1789                blast_dcache16_page_indexed(page);
1790        }
1791out:
1792        local_irq_restore(flags);
1793}
1794
1795static void r4k_flush_cache_page_d32i32(struct vm_area_struct *vma,
1796                                        unsigned long page)
1797{
1798        struct mm_struct *mm = vma->vm_mm;
1799        unsigned long flags;
1800        pgd_t *pgdp;
1801        pmd_t *pmdp;
1802        pte_t *ptep;
1803
1804        /*
1805         * If ownes no valid ASID yet, cannot possibly have gotten
1806         * this page into the cache.
1807         */
1808        if (mm->context == 0)
1809                return;
1810
1811#ifdef DEBUG_CACHE
1812        printk("cpage[%d,%08lx]", (int)mm->context, page);
1813#endif
1814        local_irq_save(flags);
1815        page &= PAGE_MASK;
1816        pgdp = pgd_offset(mm, page);
1817        pmdp = pmd_offset(pgdp, page);
1818        ptep = pte_offset(pmdp, page);
1819
1820        /*
1821         * If the page isn't marked valid, the page cannot possibly be
1822         * in the cache.
1823         */
1824        if (!(pte_val(*ptep) & _PAGE_PRESENT))
1825                goto out;
1826
1827        /*
1828         * Doing flushes for another ASID than the current one is
1829         * too difficult since stupid R4k caches do a TLB translation
1830         * for every cache flush operation.  So we do indexed flushes
1831         * in that case, which doesn't overly flush the cache too much.
1832         */
1833        if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) {
1834                blast_dcache32_page(page);
1835        } else {
1836                /*
1837                 * Do indexed flush, too much work to get the (possible)
1838                 * tlb refills to work correctly.
1839                 */
1840                page = (KSEG0 + (page & (dcache_size - 1)));
1841                blast_dcache32_page_indexed(page);
1842        }
1843out:
1844        local_irq_restore(flags);
1845}
1846
1847static void r4k_flush_cache_page_d32i32_r4600(struct vm_area_struct *vma,
1848                                              unsigned long page)
1849{
1850        struct mm_struct *mm = vma->vm_mm;
1851        unsigned long flags;
1852        pgd_t *pgdp;
1853        pmd_t *pmdp;
1854        pte_t *ptep;
1855
1856        /*
1857         * If ownes no valid ASID yet, cannot possibly have gotten
1858         * this page into the cache.
1859         */
1860        if (mm->context == 0)
1861                return;
1862
1863#ifdef DEBUG_CACHE
1864        printk("cpage[%d,%08lx]", (int)mm->context, page);
1865#endif
1866        local_irq_save(flags);
1867        page &= PAGE_MASK;
1868        pgdp = pgd_offset(mm, page);
1869        pmdp = pmd_offset(pgdp, page);
1870        ptep = pte_offset(pmdp, page);
1871
1872        /*
1873         * If the page isn't marked valid, the page cannot possibly be
1874         * in the cache.
1875         */
1876        if (!(pte_val(*ptep) & _PAGE_PRESENT))
1877                goto out;
1878
1879        /*
1880         * Doing flushes for another ASID than the current one is
1881         * too difficult since stupid R4k caches do a TLB translation
1882         * for every cache flush operation.  So we do indexed flushes
1883         * in that case, which doesn't overly flush the cache too much.
1884         */
1885        if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) {
1886                blast_dcache32_page(page);
1887        } else {
1888                /* Do indexed flush, too much work to get the (possible)
1889                 * tlb refills to work correctly.
1890                 */
1891                page = (KSEG0 + (page & (dcache_size - 1)));
1892                blast_dcache32_page_indexed(page);
1893                blast_dcache32_page_indexed(page ^ dcache_waybit);
1894        }
1895out:
1896        local_irq_restore(flags);
1897}
1898
1899/* If the addresses passed to these routines are valid, they are
1900 * either:
1901 *
1902 * 1) In KSEG0, so we can do a direct flush of the page.
1903 * 2) In KSEG2, and since every process can translate those
1904 *    addresses all the time in kernel mode we can do a direct
1905 *    flush.
1906 * 3) In KSEG1, no flush necessary.
1907 */
1908static void r4k_flush_page_to_ram_s16(struct page *page)
1909{
1910        blast_scache16_page((unsigned long)page_address(page));
1911}
1912
1913static void r4k_flush_page_to_ram_s32(struct page *page)
1914{
1915        blast_scache32_page((unsigned long)page_address(page));
1916}
1917
1918static void r4k_flush_page_to_ram_s64(struct page *page)
1919{
1920        blast_scache64_page((unsigned long)page_address(page));
1921}
1922
1923static void r4k_flush_page_to_ram_s128(struct page *page)
1924{
1925        blast_scache128_page((unsigned long)page_address(page));
1926}
1927
1928static void r4k_flush_page_to_ram_d16(struct page *page)
1929{
1930        blast_dcache16_page((unsigned long)page_address(page));
1931}
1932
1933static void r4k_flush_page_to_ram_d32(struct page *page)
1934{
1935        blast_dcache32_page((unsigned long)page_address(page));
1936}
1937
1938static void r4k_flush_page_to_ram_d32_r4600(struct page *page)
1939{
1940        unsigned long flags;
1941
1942        local_irq_save(flags);                  /* For R4600 v1.7 bug.  */
1943        blast_dcache32_page((unsigned long)page_address(page));
1944        local_irq_restore(flags);
1945}
1946
1947static void
1948r4k_flush_icache_page_s(struct vm_area_struct *vma, struct page *page)
1949{
1950        /*
1951         * We did an scache flush therefore PI is already clean.
1952         */
1953}
1954
1955static void
1956r4k_flush_icache_range(unsigned long start, unsigned long end)
1957{
1958        flush_cache_all();
1959}
1960
1961/*
1962 * Ok, this seriously sucks.  We use them to flush a user page but don't
1963 * know the virtual address, so we have to blast away the whole icache
1964 * which is significantly more expensive than the real thing.
1965 */
1966static void
1967r4k_flush_icache_page_p(struct vm_area_struct *vma, struct page *page)
1968{
1969        if (!(vma->vm_flags & VM_EXEC))
1970                return;
1971
1972        flush_cache_all();
1973}
1974
1975/*
1976 * Writeback and invalidate the primary cache dcache before DMA.
1977 *
1978 * R4600 v2.0 bug: "The CACHE instructions Hit_Writeback_Inv_D,
1979 * Hit_Writeback_D, Hit_Invalidate_D and Create_Dirty_Exclusive_D will only
1980 * operate correctly if the internal data cache refill buffer is empty.  These
1981 * CACHE instructions should be separated from any potential data cache miss
1982 * by a load instruction to an uncached address to empty the response buffer."
1983 * (Revision 2.0 device errata from IDT available on http://www.idt.com/
1984 * in .pdf format.)
1985 */
1986static void
1987r4k_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size)
1988{
1989        unsigned long end, a;
1990        unsigned int flags;
1991
1992        if (size >= dcache_size) {
1993                flush_cache_all();
1994        } else {
1995                /* Workaround for R4600 bug.  See comment above. */
1996                local_irq_save(flags);
1997                *(volatile unsigned long *)KSEG1;
1998
1999                a = addr & ~(dc_lsize - 1);
2000                end = (addr + size) & ~(dc_lsize - 1);
2001                while (1) {
2002                        flush_dcache_line(a); /* Hit_Writeback_Inv_D */
2003                        if (a == end) break;
2004                        a += dc_lsize;
2005                }
2006                local_irq_restore(flags);
2007        }
2008        bc_wback_inv(addr, size);
2009}
2010
2011static void
2012r4k_dma_cache_wback_inv_sc(unsigned long addr, unsigned long size)
2013{
2014        unsigned long end, a;
2015
2016        if (size >= scache_size) {
2017                flush_cache_all();
2018                return;
2019        }
2020
2021        a = addr & ~(sc_lsize - 1);
2022        end = (addr + size) & ~(sc_lsize - 1);
2023        while (1) {
2024                flush_scache_line(a);   /* Hit_Writeback_Inv_SD */
2025                if (a == end) break;
2026                a += sc_lsize;
2027        }
2028}
2029
2030static void
2031r4k_dma_cache_inv_pc(unsigned long addr, unsigned long size)
2032{
2033        unsigned long end, a;
2034        unsigned int flags;
2035
2036        if (size >= dcache_size) {
2037                flush_cache_all();
2038        } else {
2039                /* Workaround for R4600 bug.  See comment above. */
2040                local_irq_save(flags);
2041                *(volatile unsigned long *)KSEG1;
2042
2043                a = addr & ~(dc_lsize - 1);
2044                end = (addr + size) & ~(dc_lsize - 1);
2045                while (1) {
2046                        flush_dcache_line(a); /* Hit_Writeback_Inv_D */
2047                        if (a == end) break;
2048                        a += dc_lsize;
2049                }
2050                local_irq_restore(flags);
2051        }
2052
2053        bc_inv(addr, size);
2054}
2055
2056static void
2057r4k_dma_cache_inv_sc(unsigned long addr, unsigned long size)
2058{
2059        unsigned long end, a;
2060
2061        if (size >= scache_size) {
2062                flush_cache_all();
2063                return;
2064        }
2065
2066        a = addr & ~(sc_lsize - 1);
2067        end = (addr + size) & ~(sc_lsize - 1);
2068        while (1) {
2069                flush_scache_line(a); /* Hit_Writeback_Inv_SD */
2070                if (a == end) break;
2071                a += sc_lsize;
2072        }
2073}
2074
2075static void
2076r4k_dma_cache_wback(unsigned long addr, unsigned long size)
2077{
2078        panic("r4k_dma_cache called - should not happen.\n");
2079}
2080
2081/*
2082 * While we're protected against bad userland addresses we don't care
2083 * very much about what happens in that case.  Usually a segmentation
2084 * fault will dump the process later on anyway ...
2085 */
2086static void r4k_flush_cache_sigtramp(unsigned long addr)
2087{
2088        __asm__ __volatile__("nop;nop;nop;nop");        /* R4600 V1.7 */
2089        protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
2090        protected_flush_icache_line(addr & ~(ic_lsize - 1));
2091}
2092
2093static void r4600v20k_flush_cache_sigtramp(unsigned long addr)
2094{
2095        unsigned int flags;
2096
2097        local_irq_save(flags);
2098
2099        /* Clear internal cache refill buffer */
2100        *(volatile unsigned int *)KSEG1;
2101
2102        protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
2103        protected_flush_icache_line(addr & ~(ic_lsize - 1));
2104
2105        local_irq_restore(flags);
2106}
2107
2108#undef DEBUG_TLB
2109#undef DEBUG_TLBUPDATE
2110
2111void flush_tlb_all(void)
2112{
2113        unsigned long flags;
2114        unsigned long old_ctx;
2115        int entry;
2116
2117#ifdef DEBUG_TLB
2118        printk("[tlball]");
2119#endif
2120
2121        local_irq_save(flags);
2122        /* Save old context and create impossible VPN2 value */
2123        old_ctx = (get_entryhi() & 0xff);
2124        set_entryhi(KSEG0);
2125        set_entrylo0(0);
2126        set_entrylo1(0);
2127        BARRIER;
2128
2129        entry = get_wired();
2130
2131        /* Blast 'em all away. */
2132        while(entry < mips_cpu.tlbsize) {
2133                set_index(entry);
2134                BARRIER;
2135                tlb_write_indexed();
2136                BARRIER;
2137                entry++;
2138        }
2139        BARRIER;
2140        set_entryhi(old_ctx);
2141        local_irq_restore(flags);
2142}
2143
2144void flush_tlb_mm(struct mm_struct *mm)
2145{
2146        if (mm->context != 0) {
2147                unsigned long flags;
2148
2149#ifdef DEBUG_TLB
2150                printk("[tlbmm<%d>]", mm->context);
2151#endif
2152                local_irq_save(flags);
2153                get_new_mmu_context(mm, asid_cache);
2154                if (mm == current->active_mm)
2155                        set_entryhi(mm->context & 0xff);
2156                local_irq_restore(flags);
2157        }
2158}
2159
2160void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
2161                                unsigned long end)
2162{
2163        struct mm_struct *mm = vma->vm_mm;
2164
2165        if (mm->context != 0) {
2166                unsigned long flags;
2167                int size;
2168
2169#ifdef DEBUG_TLB
2170                printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff),
2171                       start, end);
2172#endif
2173                local_irq_save(flags);
2174                size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
2175                size = (size + 1) >> 1;
2176                if(size <= mips_cpu.tlbsize/2) {
2177                        int oldpid = (get_entryhi() & 0xff);
2178                        int newpid = (mm->context & 0xff);
2179
2180                        start &= (PAGE_MASK << 1);
2181                        end += ((PAGE_SIZE << 1) - 1);
2182                        end &= (PAGE_MASK << 1);
2183                        while(start < end) {
2184                                int idx;
2185
2186                                set_entryhi(start | newpid);
2187                                start += (PAGE_SIZE << 1);
2188                                BARRIER;
2189                                tlb_probe();
2190                                BARRIER;
2191                                idx = get_index();
2192                                set_entrylo0(0);
2193                                set_entrylo1(0);
2194                                set_entryhi(KSEG0);
2195                                BARRIER;
2196                                if(idx < 0)
2197                                        continue;
2198                                tlb_write_indexed();
2199                                BARRIER;
2200                        }
2201                        set_entryhi(oldpid);
2202                } else {
2203                        get_new_mmu_context(mm, asid_cache);
2204                        if (mm == current->active_mm)
2205                                set_entryhi(mm->context & 0xff);
2206                }
2207                local_irq_restore(flags);
2208        }
2209}
2210
2211void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
2212{
2213        if (vma->vm_mm->context != 0) {
2214                unsigned long flags;
2215                int oldpid, newpid, idx;
2216
2217#ifdef DEBUG_TLB
2218                printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page);
2219#endif
2220                newpid = (vma->vm_mm->context & 0xff);
2221                page &= (PAGE_MASK << 1);
2222                local_irq_save(flags);
2223                oldpid = (get_entryhi() & 0xff);
2224                set_entryhi(page | newpid);
2225                BARRIER;
2226                tlb_probe();
2227                BARRIER;
2228                idx = get_index();
2229                set_entrylo0(0);
2230                set_entrylo1(0);
2231                set_entryhi(KSEG0);
2232                if(idx < 0)
2233                        goto finish;
2234                BARRIER;
2235                tlb_write_indexed();
2236
2237        finish:
2238                BARRIER;
2239                set_entryhi(oldpid);
2240                local_irq_restore(flags);
2241        }
2242}
2243
2244void pgd_init(unsigned long page)
2245{
2246        unsigned long *p = (unsigned long *) page;
2247        int i;
2248
2249        for(i = 0; i < USER_PTRS_PER_PGD; i+=8) {
2250                p[i + 0] = (unsigned long) invalid_pte_table;
2251                p[i + 1] = (unsigned long) invalid_pte_table;
2252                p[i + 2] = (unsigned long) invalid_pte_table;
2253                p[i + 3] = (unsigned long) invalid_pte_table;
2254                p[i + 4] = (unsigned long) invalid_pte_table;
2255                p[i + 5] = (unsigned long) invalid_pte_table;
2256                p[i + 6] = (unsigned long) invalid_pte_table;
2257                p[i + 7] = (unsigned long) invalid_pte_table;
2258        }
2259}
2260
2261/* We will need multiple versions of update_mmu_cache(), one that just
2262 * updates the TLB with the new pte(s), and another which also checks
2263 * for the R4k "end of page" hardware bug and does the needy.
2264 */
2265void update_mmu_cache(struct vm_area_struct * vma,
2266                                 unsigned long address, pte_t pte)
2267{
2268        unsigned long flags;
2269        pgd_t *pgdp;
2270        pmd_t *pmdp;
2271        pte_t *ptep;
2272        int idx, pid;
2273
2274        /*
2275         * Handle debugger faulting in for debugee.
2276         */
2277        if (current->active_mm != vma->vm_mm)
2278                return;
2279
2280        pid = get_entryhi() & 0xff;
2281
2282#ifdef DEBUG_TLB
2283        if((pid != (vma->vm_mm->context & 0xff)) || (vma->vm_mm->context == 0)) {
2284                printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n",
2285                       (int) (vma->vm_mm->context & 0xff), pid);
2286        }
2287#endif
2288
2289        local_irq_save(flags);
2290        address &= (PAGE_MASK << 1);
2291        set_entryhi(address | (pid));
2292        pgdp = pgd_offset(vma->vm_mm, address);
2293        BARRIER;
2294        tlb_probe();
2295        BARRIER;
2296        pmdp = pmd_offset(pgdp, address);
2297        idx = get_index();
2298        ptep = pte_offset(pmdp, address);
2299        BARRIER;
2300        set_entrylo0(pte_val(*ptep++) >> 6);
2301        set_entrylo1(pte_val(*ptep) >> 6);
2302        set_entryhi(address | (pid));
2303        BARRIER;
2304        if(idx < 0) {
2305                tlb_write_random();
2306        } else {
2307                tlb_write_indexed();
2308        }
2309        BARRIER;
2310        set_entryhi(pid);
2311        BARRIER;
2312        local_irq_restore(flags);
2313}
2314
2315#if 0
2316static void r4k_update_mmu_cache_hwbug(struct vm_area_struct * vma,
2317                                       unsigned long address, pte_t pte)
2318{
2319        unsigned long flags;
2320        pgd_t *pgdp;
2321        pmd_t *pmdp;
2322        pte_t *ptep;
2323        int idx;
2324
2325        local_irq_save(flags);
2326        address &= (PAGE_MASK << 1);
2327        set_entryhi(address | (get_entryhi() & 0xff));
2328        pgdp = pgd_offset(vma->vm_mm, address);
2329        tlb_probe();
2330        pmdp = pmd_offset(pgdp, address);
2331        idx = get_index();
2332        ptep = pte_offset(pmdp, address);
2333        set_entrylo0(pte_val(*ptep++) >> 6);
2334        set_entrylo1(pte_val(*ptep) >> 6);
2335        BARRIER;
2336        if(idx < 0)
2337                tlb_write_random();
2338        else
2339                tlb_write_indexed();
2340        BARRIER;
2341        local_irq_restore(flags);
2342}
2343#endif
2344
2345void show_regs(struct pt_regs * regs)
2346{
2347        /* Saved main processor registers. */
2348        printk("$0 : %08lx %08lx %08lx %08lx\n",
2349               0UL, regs->regs[1], regs->regs[2], regs->regs[3]);
2350        printk("$4 : %08lx %08lx %08lx %08lx\n",
2351               regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
2352        printk("$8 : %08lx %08lx %08lx %08lx\n",
2353               regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11]);
2354        printk("$12: %08lx %08lx %08lx %08lx\n",
2355               regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]);
2356        printk("$16: %08lx %08lx %08lx %08lx\n",
2357               regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19]);
2358        printk("$20: %08lx %08lx %08lx %08lx\n",
2359               regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]);
2360        printk("$24: %08lx %08lx\n",
2361               regs->regs[24], regs->regs[25]);
2362        printk("$28: %08lx %08lx %08lx %08lx\n",
2363               regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]);
2364
2365        /* Saved cp0 registers. */
2366        printk("epc   : %08lx    %s\nStatus: %08lx\nCause : %08lx\n",
2367               regs->cp0_epc, print_tainted(), regs->cp0_status, regs->cp0_cause);
2368}
2369                        
2370void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
2371                                      unsigned long entryhi, unsigned long pagemask)
2372{
2373        unsigned long flags;
2374        unsigned long wired;
2375        unsigned long old_pagemask;
2376        unsigned long old_ctx;
2377
2378        local_irq_save(flags);
2379        /* Save old context and create impossible VPN2 value */
2380        old_ctx = (get_entryhi() & 0xff);
2381        old_pagemask = get_pagemask();
2382        wired = get_wired();
2383        set_wired (wired + 1);
2384        set_index (wired);
2385        BARRIER;    
2386        set_pagemask (pagemask);
2387        set_entryhi(entryhi);
2388        set_entrylo0(entrylo0);
2389        set_entrylo1(entrylo1);
2390        BARRIER;    
2391        tlb_write_indexed();
2392        BARRIER;    
2393    
2394        set_entryhi(old_ctx);
2395        BARRIER;    
2396        set_pagemask (old_pagemask);
2397        flush_tlb_all();    
2398        local_irq_restore(flags);
2399}
2400
2401/* Detect and size the various r4k caches. */
2402static void __init probe_icache(unsigned long config)
2403{
2404        switch (mips_cpu.cputype) {
2405        case CPU_VR41XX:
2406                icache_size = 1 << (10 + ((config >> 9) & 7));
2407                break;
2408        default:
2409                icache_size = 1 << (12 + ((config >> 9) & 7));
2410                break;
2411        }
2412        ic_lsize = 16 << ((config >> 5) & 1);
2413
2414        printk("Primary instruction cache %dkb, linesize %d bytes.\n",
2415               icache_size >> 10, ic_lsize);
2416}
2417
2418static void __init probe_dcache(unsigned long config)
2419{
2420        switch (mips_cpu.cputype) {
2421        case CPU_VR41XX:
2422                dcache_size = 1 << (10 + ((config >> 6) & 7));
2423                break;
2424        default:
2425                dcache_size = 1 << (12 + ((config >> 6) & 7));
2426                break;
2427        }
2428        dc_lsize = 16 << ((config >> 4) & 1);
2429
2430        printk("Primary data cache %dkb, linesize %d bytes.\n",
2431               dcache_size >> 10, dc_lsize);
2432}
2433
2434
2435/* If you even _breathe_ on this function, look at the gcc output
2436 * and make sure it does not pop things on and off the stack for
2437 * the cache sizing loop that executes in KSEG1 space or else
2438 * you will crash and burn badly.  You have been warned.
2439 */
2440static int __init probe_scache(unsigned long config)
2441{
2442        extern unsigned long stext;
2443        unsigned long flags, addr, begin, end, pow2;
2444        int tmp;
2445
2446        tmp = ((config >> 17) & 1);
2447        if(tmp)
2448                return 0;
2449        tmp = ((config >> 22) & 3);
2450        switch(tmp) {
2451        case 0:
2452                sc_lsize = 16;
2453                break;
2454        case 1:
2455                sc_lsize = 32;
2456                break;
2457        case 2:
2458                sc_lsize = 64;
2459                break;
2460        case 3:
2461                sc_lsize = 128;
2462                break;
2463        }
2464
2465        begin = (unsigned long) &stext;
2466        begin &= ~((4 * 1024 * 1024) - 1);
2467        end = begin + (4 * 1024 * 1024);
2468
2469        /* This is such a bitch, you'd think they would make it
2470         * easy to do this.  Away you daemons of stupidity!
2471         */
2472        local_irq_save(flags);
2473
2474        /* Fill each size-multiple cache line with a valid tag. */
2475        pow2 = (64 * 1024);
2476        for(addr = begin; addr < end; addr = (begin + pow2)) {
2477                unsigned long *p = (unsigned long *) addr;
2478                __asm__ __volatile__("nop" : : "r" (*p)); /* whee... */
2479                pow2 <<= 1;
2480        }
2481
2482        /* Load first line with zero (therefore invalid) tag. */
2483        set_taglo(0);
2484        set_taghi(0);
2485        __asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */
2486        __asm__ __volatile__("\n\t.set noreorder\n\t"
2487                             ".set mips3\n\t"
2488                             "cache 8, (%0)\n\t"
2489                             ".set mips0\n\t"
2490                             ".set reorder\n\t" : : "r" (begin));
2491        __asm__ __volatile__("\n\t.set noreorder\n\t"
2492                             ".set mips3\n\t"
2493                             "cache 9, (%0)\n\t"
2494                             ".set mips0\n\t"
2495                             ".set reorder\n\t" : : "r" (begin));
2496        __asm__ __volatile__("\n\t.set noreorder\n\t"
2497                             ".set mips3\n\t"
2498                             "cache 11, (%0)\n\t"
2499                             ".set mips0\n\t"
2500                             ".set reorder\n\t" : : "r" (begin));
2501
2502        /* Now search for the wrap around point. */
2503        pow2 = (128 * 1024);
2504        tmp = 0;
2505        for(addr = (begin + (128 * 1024)); addr < (end); addr = (begin + pow2)) {
2506                __asm__ __volatile__("\n\t.set noreorder\n\t"
2507                                     ".set mips3\n\t"
2508                                     "cache 7, (%0)\n\t"
2509                                     ".set mips0\n\t"
2510                                     ".set reorder\n\t" : : "r" (addr));
2511                __asm__ __volatile__("nop; nop; nop; nop;"); /* hazard... */
2512                if(!get_taglo())
2513                        break;
2514                pow2 <<= 1;
2515        }
2516        local_irq_restore(flags);
2517        addr -= begin;
2518        printk("Secondary cache sized at %dK linesize %d bytes.\n",
2519               (int) (addr >> 10), sc_lsize);
2520        scache_size = addr;
2521        return 1;
2522}
2523
2524static void __init setup_noscache_funcs(void)
2525{
2526        unsigned int prid;
2527
2528        switch(dc_lsize) {
2529        case 16:
2530                _clear_page = r4k_clear_page_d16;
2531                _copy_page = r4k_copy_page_d16;
2532                _flush_cache_all = r4k_flush_cache_all_d16i16;
2533                _flush_cache_mm = r4k_flush_cache_mm_d16i16;
2534                _flush_cache_range = r4k_flush_cache_range_d16i16;
2535                _flush_cache_page = r4k_flush_cache_page_d16i16;
2536                _flush_page_to_ram = r4k_flush_page_to_ram_d16;
2537                break;
2538        case 32:
2539                prid = read_32bit_cp0_register(CP0_PRID) & 0xfff0;
2540                if (prid == 0x2010) {                   /* R4600 V1.7 */
2541                        _clear_page = r4k_clear_page_r4600_v1;
2542                        _copy_page = r4k_copy_page_r4600_v1;
2543                        _flush_page_to_ram = r4k_flush_page_to_ram_d32_r4600;
2544                } else if (prid == 0x2020) {            /* R4600 V2.0 */
2545                        _clear_page = r4k_clear_page_r4600_v2;
2546                        _copy_page = r4k_copy_page_r4600_v2;
2547                        _flush_page_to_ram = r4k_flush_page_to_ram_d32;
2548                } else {
2549                        _clear_page = r4k_clear_page_d32;
2550                        _copy_page = r4k_copy_page_d32;
2551                        _flush_page_to_ram = r4k_flush_page_to_ram_d32;
2552                }
2553                _flush_cache_all = r4k_flush_cache_all_d32i32;
2554                _flush_cache_mm = r4k_flush_cache_mm_d32i32;
2555                _flush_cache_range = r4k_flush_cache_range_d32i32;
2556                _flush_cache_page = r4k_flush_cache_page_d32i32;
2557                break;
2558        }
2559        ___flush_cache_all = _flush_cache_all;
2560
2561        _flush_icache_page = r4k_flush_icache_page_p;
2562
2563        _dma_cache_wback_inv = r4k_dma_cache_wback_inv_pc;
2564        _dma_cache_wback = r4k_dma_cache_wback;
2565        _dma_cache_inv = r4k_dma_cache_inv_pc;
2566}
2567
2568static void __init setup_scache_funcs(void)
2569{
2570        switch(sc_lsize) {
2571        case 16:
2572                switch(dc_lsize) {
2573                case 16:
2574                        _flush_cache_all = r4k_flush_cache_all_s16d16i16;
2575                        _flush_cache_mm = r4k_flush_cache_mm_s16d16i16;
2576                        _flush_cache_range = r4k_flush_cache_range_s16d16i16;
2577                        _flush_cache_page = r4k_flush_cache_page_s16d16i16;
2578                        break;
2579                case 32:
2580                        panic("Invalid cache configuration detected");
2581                };
2582                _flush_page_to_ram = r4k_flush_page_to_ram_s16;
2583                _clear_page = r4k_clear_page_s16;
2584                _copy_page = r4k_copy_page_s16;
2585                break;
2586        case 32:
2587                switch(dc_lsize) {
2588                case 16:
2589                        _flush_cache_all = r4k_flush_cache_all_s32d16i16;
2590                        _flush_cache_mm = r4k_flush_cache_mm_s32d16i16;
2591                        _flush_cache_range = r4k_flush_cache_range_s32d16i16;
2592                        _flush_cache_page = r4k_flush_cache_page_s32d16i16;
2593                        break;
2594                case 32:
2595                        _flush_cache_all = r4k_flush_cache_all_s32d32i32;
2596                        _flush_cache_mm = r4k_flush_cache_mm_s32d32i32;
2597                        _flush_cache_range = r4k_flush_cache_range_s32d32i32;
2598                        _flush_cache_page = r4k_flush_cache_page_s32d32i32;
2599                        break;
2600                };
2601                _flush_page_to_ram = r4k_flush_page_to_ram_s32;
2602                _clear_page = r4k_clear_page_s32;
2603                _copy_page = r4k_copy_page_s32;
2604                break;
2605        case 64:
2606                switch(dc_lsize) {
2607                case 16:
2608                        _flush_cache_all = r4k_flush_cache_all_s64d16i16;
2609                        _flush_cache_mm = r4k_flush_cache_mm_s64d16i16;
2610                        _flush_cache_range = r4k_flush_cache_range_s64d16i16;
2611                        _flush_cache_page = r4k_flush_cache_page_s64d16i16;
2612                        break;
2613                case 32:
2614                        _flush_cache_all = r4k_flush_cache_all_s64d32i32;
2615                        _flush_cache_mm = r4k_flush_cache_mm_s64d32i32;
2616                        _flush_cache_range = r4k_flush_cache_range_s64d32i32;
2617                        _flush_cache_page = r4k_flush_cache_page_s64d32i32;
2618                        break;
2619                };
2620                _flush_page_to_ram = r4k_flush_page_to_ram_s64;
2621                _clear_page = r4k_clear_page_s64;
2622                _copy_page = r4k_copy_page_s64;
2623                break;
2624        case 128:
2625                switch(dc_lsize) {
2626                case 16:
2627                        _flush_cache_all = r4k_flush_cache_all_s128d16i16;
2628                        _flush_cache_mm = r4k_flush_cache_mm_s128d16i16;
2629                        _flush_cache_range = r4k_flush_cache_range_s128d16i16;
2630                        _flush_cache_page = r4k_flush_cache_page_s128d16i16;
2631                        break;
2632                case 32:
2633                        _flush_cache_all = r4k_flush_cache_all_s128d32i32;
2634                        _flush_cache_mm = r4k_flush_cache_mm_s128d32i32;
2635                        _flush_cache_range = r4k_flush_cache_range_s128d32i32;
2636                        _flush_cache_page = r4k_flush_cache_page_s128d32i32;
2637                        break;
2638                };
2639                _flush_page_to_ram = r4k_flush_page_to_ram_s128;
2640                _clear_page = r4k_clear_page_s128;
2641                _copy_page = r4k_copy_page_s128;
2642                break;
2643        }
2644        ___flush_cache_all = _flush_cache_all;
2645        _flush_icache_page = r4k_flush_icache_page_s;
2646        _dma_cache_wback_inv = r4k_dma_cache_wback_inv_sc;
2647        _dma_cache_wback = r4k_dma_cache_wback;
2648        _dma_cache_inv = r4k_dma_cache_inv_sc;
2649}
2650
2651typedef int (*probe_func_t)(unsigned long);
2652
2653static inline void __init setup_scache(unsigned int config)
2654{
2655        probe_func_t probe_scache_kseg1;
2656        int sc_present = 0;
2657
2658        /* Maybe the cpu knows about a l2 cache? */
2659        probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache));
2660        sc_present = probe_scache_kseg1(config);
2661
2662        if (sc_present) {
2663                setup_scache_funcs();
2664                return;
2665        }
2666
2667        setup_noscache_funcs();
2668}
2669
2670void __init ld_mmu_r4xx0(void)
2671{
2672        unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
2673
2674        printk("CPU revision is: %08x\n", read_32bit_cp0_register(CP0_PRID));
2675
2676#ifdef CONFIG_MIPS_UNCACHED
2677        change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
2678#else
2679        change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);
2680#endif
2681
2682        probe_icache(config);
2683        probe_dcache(config);
2684        setup_scache(config);
2685
2686        switch(mips_cpu.cputype) {
2687        case CPU_R4600:                 /* QED style two way caches? */
2688        case CPU_R4700:
2689        case CPU_R5000:
2690        case CPU_NEVADA:
2691                _flush_cache_page = r4k_flush_cache_page_d32i32_r4600;
2692        }
2693
2694        _flush_cache_sigtramp = r4k_flush_cache_sigtramp;
2695        _flush_icache_range = r4k_flush_icache_range;   /* Ouch */
2696        if ((read_32bit_cp0_register(CP0_PRID) & 0xfff0) == 0x2020) {
2697                _flush_cache_sigtramp = r4600v20k_flush_cache_sigtramp;
2698        }
2699
2700        __flush_cache_all();
2701        write_32bit_cp0_register(CP0_WIRED, 0);
2702
2703        /*
2704         * You should never change this register:
2705         *   - On R4600 1.7 the tlbp never hits for pages smaller than
2706         *     the value in the c0_pagemask register.
2707         *   - The entire mm handling assumes the c0_pagemask register to
2708         *     be set for 4kb pages.
2709         */
2710        set_pagemask(PM_4K);
2711        flush_tlb_all();
2712}
2713
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.