linux/arch/powerpc/kernel/head_8xx.S
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-or-later */
   2/*
   3 *  PowerPC version
   4 *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
   5 *  Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
   6 *    Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
   7 *  Low-level exception handlers and MMU support
   8 *  rewritten by Paul Mackerras.
   9 *    Copyright (C) 1996 Paul Mackerras.
  10 *  MPC8xx modifications by Dan Malek
  11 *    Copyright (C) 1997 Dan Malek (dmalek@jlc.net).
  12 *
  13 *  This file contains low-level support and setup for PowerPC 8xx
  14 *  embedded processors, including trap and interrupt dispatch.
  15 */
  16
  17#include <linux/init.h>
  18#include <asm/processor.h>
  19#include <asm/page.h>
  20#include <asm/mmu.h>
  21#include <asm/cache.h>
  22#include <asm/pgtable.h>
  23#include <asm/cputable.h>
  24#include <asm/thread_info.h>
  25#include <asm/ppc_asm.h>
  26#include <asm/asm-offsets.h>
  27#include <asm/ptrace.h>
  28#include <asm/export.h>
  29#include <asm/code-patching-asm.h>
  30
  31#include "head_32.h"
  32
  33#if CONFIG_TASK_SIZE <= 0x80000000 && CONFIG_PAGE_OFFSET >= 0x80000000
  34/* By simply checking Address >= 0x80000000, we know if its a kernel address */
  35#define SIMPLE_KERNEL_ADDRESS           1
  36#endif
  37
  38/*
  39 * We need an ITLB miss handler for kernel addresses if:
  40 * - Either we have modules
  41 * - Or we have not pinned the first 8M
  42 */
  43#if defined(CONFIG_MODULES) || !defined(CONFIG_PIN_TLB_TEXT) || \
  44    defined(CONFIG_DEBUG_PAGEALLOC)
  45#define ITLB_MISS_KERNEL        1
  46#endif
  47
  48/*
  49 * Value for the bits that have fixed value in RPN entries.
  50 * Also used for tagging DAR for DTLBerror.
  51 */
  52#define RPN_PATTERN     0x00f0
  53
  54#define PAGE_SHIFT_512K         19
  55#define PAGE_SHIFT_8M           23
  56
  57        __HEAD
  58_ENTRY(_stext);
  59_ENTRY(_start);
  60
  61/* MPC8xx
  62 * This port was done on an MBX board with an 860.  Right now I only
  63 * support an ELF compressed (zImage) boot from EPPC-Bug because the
  64 * code there loads up some registers before calling us:
  65 *   r3: ptr to board info data
  66 *   r4: initrd_start or if no initrd then 0
  67 *   r5: initrd_end - unused if r4 is 0
  68 *   r6: Start of command line string
  69 *   r7: End of command line string
  70 *
  71 * I decided to use conditional compilation instead of checking PVR and
  72 * adding more processor specific branches around code I don't need.
  73 * Since this is an embedded processor, I also appreciate any memory
  74 * savings I can get.
  75 *
  76 * The MPC8xx does not have any BATs, but it supports large page sizes.
  77 * We first initialize the MMU to support 8M byte pages, then load one
  78 * entry into each of the instruction and data TLBs to map the first
  79 * 8M 1:1.  I also mapped an additional I/O space 1:1 so we can get to
  80 * the "internal" processor registers before MMU_init is called.
  81 *
  82 *      -- Dan
  83 */
  84        .globl  __start
  85__start:
  86        mr      r31,r3                  /* save device tree ptr */
  87
  88        /* We have to turn on the MMU right away so we get cache modes
  89         * set correctly.
  90         */
  91        bl      initial_mmu
  92
  93/* We now have the lower 8 Meg mapped into TLB entries, and the caches
  94 * ready to work.
  95 */
  96
  97turn_on_mmu:
  98        mfmsr   r0
  99        ori     r0,r0,MSR_DR|MSR_IR
 100        mtspr   SPRN_SRR1,r0
 101        lis     r0,start_here@h
 102        ori     r0,r0,start_here@l
 103        mtspr   SPRN_SRR0,r0
 104        rfi                             /* enables MMU */
 105
 106
 107#ifdef CONFIG_PERF_EVENTS
 108        .align  4
 109
 110        .globl  itlb_miss_counter
 111itlb_miss_counter:
 112        .space  4
 113
 114        .globl  dtlb_miss_counter
 115dtlb_miss_counter:
 116        .space  4
 117
 118        .globl  instruction_counter
 119instruction_counter:
 120        .space  4
 121#endif
 122
 123/* System reset */
 124        EXCEPTION(0x100, Reset, system_reset_exception, EXC_XFER_STD)
 125
 126/* Machine check */
 127        . = 0x200
 128MachineCheck:
 129        EXCEPTION_PROLOG
 130        mfspr r4,SPRN_DAR
 131        stw r4,_DAR(r11)
 132        li r5,RPN_PATTERN
 133        mtspr SPRN_DAR,r5       /* Tag DAR, to be used in DTLB Error */
 134        mfspr r5,SPRN_DSISR
 135        stw r5,_DSISR(r11)
 136        addi r3,r1,STACK_FRAME_OVERHEAD
 137        EXC_XFER_STD(0x200, machine_check_exception)
 138
 139/* Data access exception.
 140 * This is "never generated" by the MPC8xx.
 141 */
 142        . = 0x300
 143DataAccess:
 144
 145/* Instruction access exception.
 146 * This is "never generated" by the MPC8xx.
 147 */
 148        . = 0x400
 149InstructionAccess:
 150
 151/* External interrupt */
 152        EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
 153
 154/* Alignment exception */
 155        . = 0x600
 156Alignment:
 157        EXCEPTION_PROLOG
 158        mfspr   r4,SPRN_DAR
 159        stw     r4,_DAR(r11)
 160        li      r5,RPN_PATTERN
 161        mtspr   SPRN_DAR,r5     /* Tag DAR, to be used in DTLB Error */
 162        mfspr   r5,SPRN_DSISR
 163        stw     r5,_DSISR(r11)
 164        addi    r3,r1,STACK_FRAME_OVERHEAD
 165        EXC_XFER_STD(0x600, alignment_exception)
 166
 167/* Program check exception */
 168        EXCEPTION(0x700, ProgramCheck, program_check_exception, EXC_XFER_STD)
 169
 170/* No FPU on MPC8xx.  This exception is not supposed to happen.
 171*/
 172        EXCEPTION(0x800, FPUnavailable, unknown_exception, EXC_XFER_STD)
 173
 174/* Decrementer */
 175        EXCEPTION(0x900, Decrementer, timer_interrupt, EXC_XFER_LITE)
 176
 177        EXCEPTION(0xa00, Trap_0a, unknown_exception, EXC_XFER_STD)
 178        EXCEPTION(0xb00, Trap_0b, unknown_exception, EXC_XFER_STD)
 179
 180/* System call */
 181        . = 0xc00
 182SystemCall:
 183        SYSCALL_ENTRY   0xc00
 184
 185/* Single step - not used on 601 */
 186        EXCEPTION(0xd00, SingleStep, single_step_exception, EXC_XFER_STD)
 187        EXCEPTION(0xe00, Trap_0e, unknown_exception, EXC_XFER_STD)
 188        EXCEPTION(0xf00, Trap_0f, unknown_exception, EXC_XFER_STD)
 189
 190/* On the MPC8xx, this is a software emulation interrupt.  It occurs
 191 * for all unimplemented and illegal instructions.
 192 */
 193        EXCEPTION(0x1000, SoftEmu, program_check_exception, EXC_XFER_STD)
 194
 195/* Called from DataStoreTLBMiss when perf TLB misses events are activated */
 196#ifdef CONFIG_PERF_EVENTS
 197        patch_site      0f, patch__dtlbmiss_perf
 1980:      lwz     r10, (dtlb_miss_counter - PAGE_OFFSET)@l(0)
 199        addi    r10, r10, 1
 200        stw     r10, (dtlb_miss_counter - PAGE_OFFSET)@l(0)
 201        mfspr   r10, SPRN_SPRG_SCRATCH0
 202        mfspr   r11, SPRN_SPRG_SCRATCH1
 203        rfi
 204#endif
 205
 206        . = 0x1100
 207/*
 208 * For the MPC8xx, this is a software tablewalk to load the instruction
 209 * TLB.  The task switch loads the M_TWB register with the pointer to the first
 210 * level table.
 211 * If we discover there is no second level table (value is zero) or if there
 212 * is an invalid pte, we load that into the TLB, which causes another fault
 213 * into the TLB Error interrupt where we can handle such problems.
 214 * We have to use the MD_xxx registers for the tablewalk because the
 215 * equivalent MI_xxx registers only perform the attribute functions.
 216 */
 217
 218#ifdef CONFIG_8xx_CPU15
 219#define INVALIDATE_ADJACENT_PAGES_CPU15(addr)   \
 220        addi    addr, addr, PAGE_SIZE;  \
 221        tlbie   addr;                   \
 222        addi    addr, addr, -(PAGE_SIZE << 1);  \
 223        tlbie   addr;                   \
 224        addi    addr, addr, PAGE_SIZE
 225#else
 226#define INVALIDATE_ADJACENT_PAGES_CPU15(addr)
 227#endif
 228
 229InstructionTLBMiss:
 230        mtspr   SPRN_SPRG_SCRATCH0, r10
 231#if defined(ITLB_MISS_KERNEL) || defined(CONFIG_SWAP)
 232        mtspr   SPRN_SPRG_SCRATCH1, r11
 233#endif
 234
 235        /* If we are faulting a kernel address, we have to use the
 236         * kernel page tables.
 237         */
 238        mfspr   r10, SPRN_SRR0  /* Get effective address of fault */
 239        INVALIDATE_ADJACENT_PAGES_CPU15(r10)
 240        mtspr   SPRN_MD_EPN, r10
 241        /* Only modules will cause ITLB Misses as we always
 242         * pin the first 8MB of kernel memory */
 243#ifdef ITLB_MISS_KERNEL
 244        mfcr    r11
 245#if defined(SIMPLE_KERNEL_ADDRESS) && defined(CONFIG_PIN_TLB_TEXT)
 246        cmpi    cr0, r10, 0     /* Address >= 0x80000000 */
 247#else
 248        rlwinm  r10, r10, 16, 0xfff8
 249        cmpli   cr0, r10, PAGE_OFFSET@h
 250#ifndef CONFIG_PIN_TLB_TEXT
 251        /* It is assumed that kernel code fits into the first 32M */
 2520:      cmpli   cr7, r10, (PAGE_OFFSET + 0x2000000)@h
 253        patch_site      0b, patch__itlbmiss_linmem_top
 254#endif
 255#endif
 256#endif
 257        mfspr   r10, SPRN_M_TWB /* Get level 1 table */
 258#ifdef ITLB_MISS_KERNEL
 259#if defined(SIMPLE_KERNEL_ADDRESS) && defined(CONFIG_PIN_TLB_TEXT)
 260        bge+    3f
 261#else
 262        blt+    3f
 263#endif
 264#ifndef CONFIG_PIN_TLB_TEXT
 265        blt     cr7, ITLBMissLinear
 266#endif
 267        rlwinm  r10, r10, 0, 20, 31
 268        oris    r10, r10, (swapper_pg_dir - PAGE_OFFSET)@ha
 2693:
 270#endif
 271        lwz     r10, (swapper_pg_dir-PAGE_OFFSET)@l(r10)        /* Get level 1 entry */
 272        mtspr   SPRN_MI_TWC, r10        /* Set segment attributes */
 273
 274        mtspr   SPRN_MD_TWC, r10
 275        mfspr   r10, SPRN_MD_TWC
 276        lwz     r10, 0(r10)     /* Get the pte */
 277#ifdef ITLB_MISS_KERNEL
 278        mtcr    r11
 279#endif
 280#ifdef CONFIG_SWAP
 281        rlwinm  r11, r10, 32-5, _PAGE_PRESENT
 282        and     r11, r11, r10
 283        rlwimi  r10, r11, 0, _PAGE_PRESENT
 284#endif
 285        /* The Linux PTE won't go exactly into the MMU TLB.
 286         * Software indicator bits 20 and 23 must be clear.
 287         * Software indicator bits 22, 24, 25, 26, and 27 must be
 288         * set.  All other Linux PTE bits control the behavior
 289         * of the MMU.
 290         */
 291        rlwimi  r10, r10, 0, 0x0f00     /* Clear bits 20-23 */
 292        rlwimi  r10, r10, 4, 0x0400     /* Copy _PAGE_EXEC into bit 21 */
 293        ori     r10, r10, RPN_PATTERN | 0x200 /* Set 22 and 24-27 */
 294        mtspr   SPRN_MI_RPN, r10        /* Update TLB entry */
 295
 296        /* Restore registers */
 2970:      mfspr   r10, SPRN_SPRG_SCRATCH0
 298#if defined(ITLB_MISS_KERNEL) || defined(CONFIG_SWAP)
 299        mfspr   r11, SPRN_SPRG_SCRATCH1
 300#endif
 301        rfi
 302        patch_site      0b, patch__itlbmiss_exit_1
 303
 304#ifdef CONFIG_PERF_EVENTS
 305        patch_site      0f, patch__itlbmiss_perf
 3060:      lwz     r10, (itlb_miss_counter - PAGE_OFFSET)@l(0)
 307        addi    r10, r10, 1
 308        stw     r10, (itlb_miss_counter - PAGE_OFFSET)@l(0)
 309        mfspr   r10, SPRN_SPRG_SCRATCH0
 310#if defined(ITLB_MISS_KERNEL) || defined(CONFIG_SWAP)
 311        mfspr   r11, SPRN_SPRG_SCRATCH1
 312#endif
 313        rfi
 314#endif
 315
 316#ifndef CONFIG_PIN_TLB_TEXT
 317ITLBMissLinear:
 318        mtcr    r11
 319#if defined(CONFIG_STRICT_KERNEL_RWX) && CONFIG_ETEXT_SHIFT < 23
 320        patch_site      0f, patch__itlbmiss_linmem_top8
 321
 322        mfspr   r10, SPRN_SRR0
 3230:      subis   r11, r10, (PAGE_OFFSET - 0x80000000)@ha
 324        rlwinm  r11, r11, 4, MI_PS8MEG ^ MI_PS512K
 325        ori     r11, r11, MI_PS512K | MI_SVALID
 326        rlwinm  r10, r10, 0, 0x0ff80000 /* 8xx supports max 256Mb RAM */
 327#else
 328        /* Set 8M byte page and mark it valid */
 329        li      r11, MI_PS8MEG | MI_SVALID
 330        rlwinm  r10, r10, 20, 0x0f800000        /* 8xx supports max 256Mb RAM */
 331#endif
 332        mtspr   SPRN_MI_TWC, r11
 333        ori     r10, r10, 0xf0 | MI_SPS16K | _PAGE_SH | _PAGE_DIRTY | \
 334                          _PAGE_PRESENT
 335        mtspr   SPRN_MI_RPN, r10        /* Update TLB entry */
 336
 3370:      mfspr   r10, SPRN_SPRG_SCRATCH0
 338        mfspr   r11, SPRN_SPRG_SCRATCH1
 339        rfi
 340        patch_site      0b, patch__itlbmiss_exit_2
 341#endif
 342
 343        . = 0x1200
 344DataStoreTLBMiss:
 345        mtspr   SPRN_SPRG_SCRATCH0, r10
 346        mtspr   SPRN_SPRG_SCRATCH1, r11
 347        mfcr    r11
 348
 349        /* If we are faulting a kernel address, we have to use the
 350         * kernel page tables.
 351         */
 352        mfspr   r10, SPRN_MD_EPN
 353        rlwinm  r10, r10, 16, 0xfff8
 354        cmpli   cr0, r10, PAGE_OFFSET@h
 355#ifndef CONFIG_PIN_TLB_IMMR
 356        cmpli   cr6, r10, VIRT_IMMR_BASE@h
 357#endif
 3580:      cmpli   cr7, r10, (PAGE_OFFSET + 0x2000000)@h
 359        patch_site      0b, patch__dtlbmiss_linmem_top
 360
 361        mfspr   r10, SPRN_M_TWB /* Get level 1 table */
 362        blt+    3f
 363#ifndef CONFIG_PIN_TLB_IMMR
 3640:      beq-    cr6, DTLBMissIMMR
 365        patch_site      0b, patch__dtlbmiss_immr_jmp
 366#endif
 367        blt     cr7, DTLBMissLinear
 368        rlwinm  r10, r10, 0, 20, 31
 369        oris    r10, r10, (swapper_pg_dir - PAGE_OFFSET)@ha
 3703:
 371        mtcr    r11
 372        lwz     r11, (swapper_pg_dir-PAGE_OFFSET)@l(r10)        /* Get level 1 entry */
 373
 374        mtspr   SPRN_MD_TWC, r11
 375        mfspr   r10, SPRN_MD_TWC
 376        lwz     r10, 0(r10)     /* Get the pte */
 377
 378        /* Insert the Guarded flag into the TWC from the Linux PTE.
 379         * It is bit 27 of both the Linux PTE and the TWC (at least
 380         * I got that right :-).  It will be better when we can put
 381         * this into the Linux pgd/pmd and load it in the operation
 382         * above.
 383         */
 384        rlwimi  r11, r10, 0, _PAGE_GUARDED
 385        mtspr   SPRN_MD_TWC, r11
 386
 387        /* Both _PAGE_ACCESSED and _PAGE_PRESENT has to be set.
 388         * We also need to know if the insn is a load/store, so:
 389         * Clear _PAGE_PRESENT and load that which will
 390         * trap into DTLB Error with store bit set accordinly.
 391         */
 392        /* PRESENT=0x1, ACCESSED=0x20
 393         * r11 = ((r10 & PRESENT) & ((r10 & ACCESSED) >> 5));
 394         * r10 = (r10 & ~PRESENT) | r11;
 395         */
 396#ifdef CONFIG_SWAP
 397        rlwinm  r11, r10, 32-5, _PAGE_PRESENT
 398        and     r11, r11, r10
 399        rlwimi  r10, r11, 0, _PAGE_PRESENT
 400#endif
 401        /* The Linux PTE won't go exactly into the MMU TLB.
 402         * Software indicator bits 24, 25, 26, and 27 must be
 403         * set.  All other Linux PTE bits control the behavior
 404         * of the MMU.
 405         */
 406        li      r11, RPN_PATTERN
 407        rlwimi  r10, r11, 0, 24, 27     /* Set 24-27 */
 408        mtspr   SPRN_MD_RPN, r10        /* Update TLB entry */
 409
 410        /* Restore registers */
 411        mtspr   SPRN_DAR, r11   /* Tag DAR */
 412
 4130:      mfspr   r10, SPRN_SPRG_SCRATCH0
 414        mfspr   r11, SPRN_SPRG_SCRATCH1
 415        rfi
 416        patch_site      0b, patch__dtlbmiss_exit_1
 417
 418DTLBMissIMMR:
 419        mtcr    r11
 420        /* Set 512k byte guarded page and mark it valid */
 421        li      r10, MD_PS512K | MD_GUARDED | MD_SVALID
 422        mtspr   SPRN_MD_TWC, r10
 423        mfspr   r10, SPRN_IMMR                  /* Get current IMMR */
 424        rlwinm  r10, r10, 0, 0xfff80000         /* Get 512 kbytes boundary */
 425        ori     r10, r10, 0xf0 | MD_SPS16K | _PAGE_SH | _PAGE_DIRTY | \
 426                          _PAGE_PRESENT | _PAGE_NO_CACHE
 427        mtspr   SPRN_MD_RPN, r10        /* Update TLB entry */
 428
 429        li      r11, RPN_PATTERN
 430        mtspr   SPRN_DAR, r11   /* Tag DAR */
 431
 4320:      mfspr   r10, SPRN_SPRG_SCRATCH0
 433        mfspr   r11, SPRN_SPRG_SCRATCH1
 434        rfi
 435        patch_site      0b, patch__dtlbmiss_exit_2
 436
 437DTLBMissLinear:
 438        mtcr    r11
 439        rlwinm  r10, r10, 20, 0x0f800000        /* 8xx supports max 256Mb RAM */
 440#if defined(CONFIG_STRICT_KERNEL_RWX) && CONFIG_DATA_SHIFT < 23
 441        patch_site      0f, patch__dtlbmiss_romem_top8
 442
 4430:      subis   r11, r10, (PAGE_OFFSET - 0x80000000)@ha
 444        rlwinm  r11, r11, 0, 0xff800000
 445        neg     r10, r11
 446        or      r11, r11, r10
 447        rlwinm  r11, r11, 4, MI_PS8MEG ^ MI_PS512K
 448        ori     r11, r11, MI_PS512K | MI_SVALID
 449        mfspr   r10, SPRN_MD_EPN
 450        rlwinm  r10, r10, 0, 0x0ff80000 /* 8xx supports max 256Mb RAM */
 451#else
 452        /* Set 8M byte page and mark it valid */
 453        li      r11, MD_PS8MEG | MD_SVALID
 454#endif
 455        mtspr   SPRN_MD_TWC, r11
 456#ifdef CONFIG_STRICT_KERNEL_RWX
 457        patch_site      0f, patch__dtlbmiss_romem_top
 458
 4590:      subis   r11, r10, 0
 460        rlwimi  r10, r11, 11, _PAGE_RO
 461#endif
 462        ori     r10, r10, 0xf0 | MD_SPS16K | _PAGE_SH | _PAGE_DIRTY | \
 463                          _PAGE_PRESENT
 464        mtspr   SPRN_MD_RPN, r10        /* Update TLB entry */
 465
 466        li      r11, RPN_PATTERN
 467        mtspr   SPRN_DAR, r11   /* Tag DAR */
 468
 4690:      mfspr   r10, SPRN_SPRG_SCRATCH0
 470        mfspr   r11, SPRN_SPRG_SCRATCH1
 471        rfi
 472        patch_site      0b, patch__dtlbmiss_exit_3
 473
 474/* This is an instruction TLB error on the MPC8xx.  This could be due
 475 * to many reasons, such as executing guarded memory or illegal instruction
 476 * addresses.  There is nothing to do but handle a big time error fault.
 477 */
 478        . = 0x1300
 479InstructionTLBError:
 480        EXCEPTION_PROLOG
 481        mr      r4,r12
 482        andis.  r5,r9,DSISR_SRR1_MATCH_32S@h /* Filter relevant SRR1 bits */
 483        andis.  r10,r9,SRR1_ISI_NOPT@h
 484        beq+    .Litlbie
 485        tlbie   r4
 486        /* 0x400 is InstructionAccess exception, needed by bad_page_fault() */
 487.Litlbie:
 488        EXC_XFER_LITE(0x400, handle_page_fault)
 489
 490/* This is the data TLB error on the MPC8xx.  This could be due to
 491 * many reasons, including a dirty update to a pte.  We bail out to
 492 * a higher level function that can handle it.
 493 */
 494        . = 0x1400
 495DataTLBError:
 496        mtspr   SPRN_SPRG_SCRATCH0, r10
 497        mtspr   SPRN_SPRG_SCRATCH1, r11
 498        mfcr    r10
 499
 500        mfspr   r11, SPRN_DAR
 501        cmpwi   cr0, r11, RPN_PATTERN
 502        beq-    FixupDAR        /* must be a buggy dcbX, icbi insn. */
 503DARFixed:/* Return from dcbx instruction bug workaround */
 504        EXCEPTION_PROLOG_1
 505        EXCEPTION_PROLOG_2
 506        mfspr   r5,SPRN_DSISR
 507        stw     r5,_DSISR(r11)
 508        mfspr   r4,SPRN_DAR
 509        andis.  r10,r5,DSISR_NOHPTE@h
 510        beq+    .Ldtlbie
 511        tlbie   r4
 512.Ldtlbie:
 513        li      r10,RPN_PATTERN
 514        mtspr   SPRN_DAR,r10    /* Tag DAR, to be used in DTLB Error */
 515        /* 0x300 is DataAccess exception, needed by bad_page_fault() */
 516        EXC_XFER_LITE(0x300, handle_page_fault)
 517
 518        EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_STD)
 519        EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_STD)
 520        EXCEPTION(0x1700, Trap_17, unknown_exception, EXC_XFER_STD)
 521        EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_STD)
 522        EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_STD)
 523        EXCEPTION(0x1a00, Trap_1a, unknown_exception, EXC_XFER_STD)
 524        EXCEPTION(0x1b00, Trap_1b, unknown_exception, EXC_XFER_STD)
 525
 526/* On the MPC8xx, these next four traps are used for development
 527 * support of breakpoints and such.  Someday I will get around to
 528 * using them.
 529 */
 530        . = 0x1c00
 531DataBreakpoint:
 532        mtspr   SPRN_SPRG_SCRATCH0, r10
 533        mtspr   SPRN_SPRG_SCRATCH1, r11
 534        mfcr    r10
 535        mfspr   r11, SPRN_SRR0
 536        cmplwi  cr0, r11, (.Ldtlbie - PAGE_OFFSET)@l
 537        cmplwi  cr7, r11, (.Litlbie - PAGE_OFFSET)@l
 538        beq-    cr0, 11f
 539        beq-    cr7, 11f
 540        EXCEPTION_PROLOG_1
 541        EXCEPTION_PROLOG_2
 542        addi    r3,r1,STACK_FRAME_OVERHEAD
 543        mfspr   r4,SPRN_BAR
 544        stw     r4,_DAR(r11)
 545        mfspr   r5,SPRN_DSISR
 546        EXC_XFER_STD(0x1c00, do_break)
 54711:
 548        mtcr    r10
 549        mfspr   r10, SPRN_SPRG_SCRATCH0
 550        mfspr   r11, SPRN_SPRG_SCRATCH1
 551        rfi
 552
 553#ifdef CONFIG_PERF_EVENTS
 554        . = 0x1d00
 555InstructionBreakpoint:
 556        mtspr   SPRN_SPRG_SCRATCH0, r10
 557        lwz     r10, (instruction_counter - PAGE_OFFSET)@l(0)
 558        addi    r10, r10, -1
 559        stw     r10, (instruction_counter - PAGE_OFFSET)@l(0)
 560        lis     r10, 0xffff
 561        ori     r10, r10, 0x01
 562        mtspr   SPRN_COUNTA, r10
 563        mfspr   r10, SPRN_SPRG_SCRATCH0
 564        rfi
 565#else
 566        EXCEPTION(0x1d00, Trap_1d, unknown_exception, EXC_XFER_STD)
 567#endif
 568        EXCEPTION(0x1e00, Trap_1e, unknown_exception, EXC_XFER_STD)
 569        EXCEPTION(0x1f00, Trap_1f, unknown_exception, EXC_XFER_STD)
 570
 571        . = 0x2000
 572
 573/* This is the procedure to calculate the data EA for buggy dcbx,dcbi instructions
 574 * by decoding the registers used by the dcbx instruction and adding them.
 575 * DAR is set to the calculated address.
 576 */
 577 /* define if you don't want to use self modifying code */
 578#define NO_SELF_MODIFYING_CODE
 579FixupDAR:/* Entry point for dcbx workaround. */
 580        mtspr   SPRN_M_TW, r10
 581        /* fetch instruction from memory. */
 582        mfspr   r10, SPRN_SRR0
 583        mtspr   SPRN_MD_EPN, r10
 584        rlwinm  r11, r10, 16, 0xfff8
 585        cmpli   cr0, r11, PAGE_OFFSET@h
 586        mfspr   r11, SPRN_M_TWB /* Get level 1 table */
 587        blt+    3f
 588        rlwinm  r11, r10, 16, 0xfff8
 589
 5900:      cmpli   cr7, r11, (PAGE_OFFSET + 0x1800000)@h
 591        patch_site      0b, patch__fixupdar_linmem_top
 592
 593        /* create physical page address from effective address */
 594        tophys(r11, r10)
 595        blt-    cr7, 201f
 596        mfspr   r11, SPRN_M_TWB /* Get level 1 table */
 597        rlwinm  r11, r11, 0, 20, 31
 598        oris    r11, r11, (swapper_pg_dir - PAGE_OFFSET)@ha
 5993:
 600        lwz     r11, (swapper_pg_dir-PAGE_OFFSET)@l(r11)        /* Get the level 1 entry */
 601        mtspr   SPRN_MD_TWC, r11
 602        mtcr    r11
 603        mfspr   r11, SPRN_MD_TWC
 604        lwz     r11, 0(r11)     /* Get the pte */
 605        bt      28,200f         /* bit 28 = Large page (8M) */
 606        bt      29,202f         /* bit 29 = Large page (8M or 512K) */
 607        /* concat physical page address(r11) and page offset(r10) */
 608        rlwimi  r11, r10, 0, 32 - PAGE_SHIFT, 31
 609201:    lwz     r11,0(r11)
 610/* Check if it really is a dcbx instruction. */
 611/* dcbt and dcbtst does not generate DTLB Misses/Errors,
 612 * no need to include them here */
 613        xoris   r10, r11, 0x7c00        /* check if major OP code is 31 */
 614        rlwinm  r10, r10, 0, 21, 5
 615        cmpwi   cr0, r10, 2028  /* Is dcbz? */
 616        beq+    142f
 617        cmpwi   cr0, r10, 940   /* Is dcbi? */
 618        beq+    142f
 619        cmpwi   cr0, r10, 108   /* Is dcbst? */
 620        beq+    144f            /* Fix up store bit! */
 621        cmpwi   cr0, r10, 172   /* Is dcbf? */
 622        beq+    142f
 623        cmpwi   cr0, r10, 1964  /* Is icbi? */
 624        beq+    142f
 625141:    mfspr   r10,SPRN_M_TW
 626        b       DARFixed        /* Nope, go back to normal TLB processing */
 627
 628200:
 629        /* concat physical page address(r11) and page offset(r10) */
 630        rlwimi  r11, r10, 0, 32 - PAGE_SHIFT_8M, 31
 631        b       201b
 632
 633202:
 634        /* concat physical page address(r11) and page offset(r10) */
 635        rlwimi  r11, r10, 0, 32 - PAGE_SHIFT_512K, 31
 636        b       201b
 637
 638144:    mfspr   r10, SPRN_DSISR
 639        rlwinm  r10, r10,0,7,5  /* Clear store bit for buggy dcbst insn */
 640        mtspr   SPRN_DSISR, r10
 641142:    /* continue, it was a dcbx, dcbi instruction. */
 642#ifndef NO_SELF_MODIFYING_CODE
 643        andis.  r10,r11,0x1f    /* test if reg RA is r0 */
 644        li      r10,modified_instr@l
 645        dcbtst  r0,r10          /* touch for store */
 646        rlwinm  r11,r11,0,0,20  /* Zero lower 10 bits */
 647        oris    r11,r11,640     /* Transform instr. to a "add r10,RA,RB" */
 648        ori     r11,r11,532
 649        stw     r11,0(r10)      /* store add/and instruction */
 650        dcbf    0,r10           /* flush new instr. to memory. */
 651        icbi    0,r10           /* invalidate instr. cache line */
 652        mfspr   r11, SPRN_SPRG_SCRATCH1 /* restore r11 */
 653        mfspr   r10, SPRN_SPRG_SCRATCH0 /* restore r10 */
 654        isync                   /* Wait until new instr is loaded from memory */
 655modified_instr:
 656        .space  4               /* this is where the add instr. is stored */
 657        bne+    143f
 658        subf    r10,r0,r10      /* r10=r10-r0, only if reg RA is r0 */
 659143:    mtdar   r10             /* store faulting EA in DAR */
 660        mfspr   r10,SPRN_M_TW
 661        b       DARFixed        /* Go back to normal TLB handling */
 662#else
 663        mfctr   r10
 664        mtdar   r10                     /* save ctr reg in DAR */
 665        rlwinm  r10, r11, 24, 24, 28    /* offset into jump table for reg RB */
 666        addi    r10, r10, 150f@l        /* add start of table */
 667        mtctr   r10                     /* load ctr with jump address */
 668        xor     r10, r10, r10           /* sum starts at zero */
 669        bctr                            /* jump into table */
 670150:
 671        add     r10, r10, r0    ;b      151f
 672        add     r10, r10, r1    ;b      151f
 673        add     r10, r10, r2    ;b      151f
 674        add     r10, r10, r3    ;b      151f
 675        add     r10, r10, r4    ;b      151f
 676        add     r10, r10, r5    ;b      151f
 677        add     r10, r10, r6    ;b      151f
 678        add     r10, r10, r7    ;b      151f
 679        add     r10, r10, r8    ;b      151f
 680        add     r10, r10, r9    ;b      151f
 681        mtctr   r11     ;b      154f    /* r10 needs special handling */
 682        mtctr   r11     ;b      153f    /* r11 needs special handling */
 683        add     r10, r10, r12   ;b      151f
 684        add     r10, r10, r13   ;b      151f
 685        add     r10, r10, r14   ;b      151f
 686        add     r10, r10, r15   ;b      151f
 687        add     r10, r10, r16   ;b      151f
 688        add     r10, r10, r17   ;b      151f
 689        add     r10, r10, r18   ;b      151f
 690        add     r10, r10, r19   ;b      151f
 691        add     r10, r10, r20   ;b      151f
 692        add     r10, r10, r21   ;b      151f
 693        add     r10, r10, r22   ;b      151f
 694        add     r10, r10, r23   ;b      151f
 695        add     r10, r10, r24   ;b      151f
 696        add     r10, r10, r25   ;b      151f
 697        add     r10, r10, r26   ;b      151f
 698        add     r10, r10, r27   ;b      151f
 699        add     r10, r10, r28   ;b      151f
 700        add     r10, r10, r29   ;b      151f
 701        add     r10, r10, r30   ;b      151f
 702        add     r10, r10, r31
 703151:
 704        rlwinm. r11,r11,19,24,28        /* offset into jump table for reg RA */
 705        beq     152f                    /* if reg RA is zero, don't add it */
 706        addi    r11, r11, 150b@l        /* add start of table */
 707        mtctr   r11                     /* load ctr with jump address */
 708        rlwinm  r11,r11,0,16,10         /* make sure we don't execute this more than once */
 709        bctr                            /* jump into table */
 710152:
 711        mfdar   r11
 712        mtctr   r11                     /* restore ctr reg from DAR */
 713        mtdar   r10                     /* save fault EA to DAR */
 714        mfspr   r10,SPRN_M_TW
 715        b       DARFixed                /* Go back to normal TLB handling */
 716
 717        /* special handling for r10,r11 since these are modified already */
 718153:    mfspr   r11, SPRN_SPRG_SCRATCH1 /* load r11 from SPRN_SPRG_SCRATCH1 */
 719        add     r10, r10, r11   /* add it */
 720        mfctr   r11             /* restore r11 */
 721        b       151b
 722154:    mfspr   r11, SPRN_SPRG_SCRATCH0 /* load r10 from SPRN_SPRG_SCRATCH0 */
 723        add     r10, r10, r11   /* add it */
 724        mfctr   r11             /* restore r11 */
 725        b       151b
 726#endif
 727
 728/*
 729 * This is where the main kernel code starts.
 730 */
 731start_here:
 732        /* ptr to current */
 733        lis     r2,init_task@h
 734        ori     r2,r2,init_task@l
 735
 736        /* ptr to phys current thread */
 737        tophys(r4,r2)
 738        addi    r4,r4,THREAD    /* init task's THREAD */
 739        mtspr   SPRN_SPRG_THREAD,r4
 740
 741        /* stack */
 742        lis     r1,init_thread_union@ha
 743        addi    r1,r1,init_thread_union@l
 744        li      r0,0
 745        stwu    r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
 746
 747        lis     r6, swapper_pg_dir@ha
 748        tophys(r6,r6)
 749        mtspr   SPRN_M_TWB, r6
 750
 751        bl      early_init      /* We have to do this with MMU on */
 752
 753/*
 754 * Decide what sort of machine this is and initialize the MMU.
 755 */
 756#ifdef CONFIG_KASAN
 757        bl      kasan_early_init
 758#endif
 759        li      r3,0
 760        mr      r4,r31
 761        bl      machine_init
 762        bl      MMU_init
 763
 764/*
 765 * Go back to running unmapped so we can load up new values
 766 * and change to using our exception vectors.
 767 * On the 8xx, all we have to do is invalidate the TLB to clear
 768 * the old 8M byte TLB mappings and load the page table base register.
 769 */
 770        /* The right way to do this would be to track it down through
 771         * init's THREAD like the context switch code does, but this is
 772         * easier......until someone changes init's static structures.
 773         */
 774        lis     r4,2f@h
 775        ori     r4,r4,2f@l
 776        tophys(r4,r4)
 777        li      r3,MSR_KERNEL & ~(MSR_IR|MSR_DR)
 778        mtspr   SPRN_SRR0,r4
 779        mtspr   SPRN_SRR1,r3
 780        rfi
 781/* Load up the kernel context */
 7822:
 783        tlbia                   /* Clear all TLB entries */
 784        sync                    /* wait for tlbia/tlbie to finish */
 785
 786        /* set up the PTE pointers for the Abatron bdiGDB.
 787        */
 788        lis     r5, abatron_pteptrs@h
 789        ori     r5, r5, abatron_pteptrs@l
 790        stw     r5, 0xf0(0)     /* Must match your Abatron config file */
 791        tophys(r5,r5)
 792        lis     r6, swapper_pg_dir@h
 793        ori     r6, r6, swapper_pg_dir@l
 794        stw     r6, 0(r5)
 795
 796/* Now turn on the MMU for real! */
 797        li      r4,MSR_KERNEL
 798        lis     r3,start_kernel@h
 799        ori     r3,r3,start_kernel@l
 800        mtspr   SPRN_SRR0,r3
 801        mtspr   SPRN_SRR1,r4
 802        rfi                     /* enable MMU and jump to start_kernel */
 803
 804/* Set up the initial MMU state so we can do the first level of
 805 * kernel initialization.  This maps the first 8 MBytes of memory 1:1
 806 * virtual to physical.  Also, set the cache mode since that is defined
 807 * by TLB entries and perform any additional mapping (like of the IMMR).
 808 * If configured to pin some TLBs, we pin the first 8 Mbytes of kernel,
 809 * 24 Mbytes of data, and the 512k IMMR space.  Anything not covered by
 810 * these mappings is mapped by page tables.
 811 */
 812initial_mmu:
 813        li      r8, 0
 814        mtspr   SPRN_MI_CTR, r8         /* remove PINNED ITLB entries */
 815        lis     r10, MD_RESETVAL@h
 816#ifndef CONFIG_8xx_COPYBACK
 817        oris    r10, r10, MD_WTDEF@h
 818#endif
 819        mtspr   SPRN_MD_CTR, r10        /* remove PINNED DTLB entries */
 820
 821        tlbia                   /* Invalidate all TLB entries */
 822#ifdef CONFIG_PIN_TLB_DATA
 823        oris    r10, r10, MD_RSV4I@h
 824        mtspr   SPRN_MD_CTR, r10        /* Set data TLB control */
 825#endif
 826
 827        lis     r8, MI_APG_INIT@h       /* Set protection modes */
 828        ori     r8, r8, MI_APG_INIT@l
 829        mtspr   SPRN_MI_AP, r8
 830        lis     r8, MD_APG_INIT@h
 831        ori     r8, r8, MD_APG_INIT@l
 832        mtspr   SPRN_MD_AP, r8
 833
 834        /* Map a 512k page for the IMMR to get the processor
 835         * internal registers (among other things).
 836         */
 837#ifdef CONFIG_PIN_TLB_IMMR
 838        oris    r10, r10, MD_RSV4I@h
 839        ori     r10, r10, 0x1c00
 840        mtspr   SPRN_MD_CTR, r10
 841
 842        mfspr   r9, 638                 /* Get current IMMR */
 843        andis.  r9, r9, 0xfff8          /* Get 512 kbytes boundary */
 844
 845        lis     r8, VIRT_IMMR_BASE@h    /* Create vaddr for TLB */
 846        ori     r8, r8, MD_EVALID       /* Mark it valid */
 847        mtspr   SPRN_MD_EPN, r8
 848        li      r8, MD_PS512K | MD_GUARDED      /* Set 512k byte page */
 849        ori     r8, r8, MD_SVALID       /* Make it valid */
 850        mtspr   SPRN_MD_TWC, r8
 851        mr      r8, r9                  /* Create paddr for TLB */
 852        ori     r8, r8, MI_BOOTINIT|0x2 /* Inhibit cache -- Cort */
 853        mtspr   SPRN_MD_RPN, r8
 854#endif
 855
 856        /* Now map the lower RAM (up to 32 Mbytes) into the ITLB. */
 857#ifdef CONFIG_PIN_TLB_TEXT
 858        lis     r8, MI_RSV4I@h
 859        ori     r8, r8, 0x1c00
 860#endif
 861        li      r9, 4                           /* up to 4 pages of 8M */
 862        mtctr   r9
 863        lis     r9, KERNELBASE@h                /* Create vaddr for TLB */
 864        li      r10, MI_PS8MEG | MI_SVALID      /* Set 8M byte page */
 865        li      r11, MI_BOOTINIT                /* Create RPN for address 0 */
 866        lis     r12, _einittext@h
 867        ori     r12, r12, _einittext@l
 8681:
 869#ifdef CONFIG_PIN_TLB_TEXT
 870        mtspr   SPRN_MI_CTR, r8 /* Set instruction MMU control */
 871        addi    r8, r8, 0x100
 872#endif
 873
 874        ori     r0, r9, MI_EVALID               /* Mark it valid */
 875        mtspr   SPRN_MI_EPN, r0
 876        mtspr   SPRN_MI_TWC, r10
 877        mtspr   SPRN_MI_RPN, r11                /* Store TLB entry */
 878        addis   r9, r9, 0x80
 879        addis   r11, r11, 0x80
 880
 881        cmpl    cr0, r9, r12
 882        bdnzf   gt, 1b
 883
 884        /* Since the cache is enabled according to the information we
 885         * just loaded into the TLB, invalidate and enable the caches here.
 886         * We should probably check/set other modes....later.
 887         */
 888        lis     r8, IDC_INVALL@h
 889        mtspr   SPRN_IC_CST, r8
 890        mtspr   SPRN_DC_CST, r8
 891        lis     r8, IDC_ENABLE@h
 892        mtspr   SPRN_IC_CST, r8
 893#ifdef CONFIG_8xx_COPYBACK
 894        mtspr   SPRN_DC_CST, r8
 895#else
 896        /* For a debug option, I left this here to easily enable
 897         * the write through cache mode
 898         */
 899        lis     r8, DC_SFWT@h
 900        mtspr   SPRN_DC_CST, r8
 901        lis     r8, IDC_ENABLE@h
 902        mtspr   SPRN_DC_CST, r8
 903#endif
 904        /* Disable debug mode entry on breakpoints */
 905        mfspr   r8, SPRN_DER
 906#ifdef CONFIG_PERF_EVENTS
 907        rlwinm  r8, r8, 0, ~0xc
 908#else
 909        rlwinm  r8, r8, 0, ~0x8
 910#endif
 911        mtspr   SPRN_DER, r8
 912        blr
 913
 914
 915/*
 916 * We put a few things here that have to be page-aligned.
 917 * This stuff goes at the beginning of the data segment,
 918 * which is page-aligned.
 919 */
 920        .data
 921        .globl  sdata
 922sdata:
 923        .globl  empty_zero_page
 924        .align  PAGE_SHIFT
 925empty_zero_page:
 926        .space  PAGE_SIZE
 927EXPORT_SYMBOL(empty_zero_page)
 928
 929        .globl  swapper_pg_dir
 930swapper_pg_dir:
 931        .space  PGD_TABLE_SIZE
 932
 933/* Room for two PTE table poiners, usually the kernel and current user
 934 * pointer to their respective root page table (pgdir).
 935 */
 936        .globl  abatron_pteptrs
 937abatron_pteptrs:
 938        .space  8
 939