1/* 2 * Kernel execution entry point code. 3 * 4 * Copyright (c) 1995-1996 Gary Thomas <gdt@linuxppc.org> 5 * Initial PowerPC version. 6 * Copyright (c) 1996 Cort Dougan <cort@cs.nmt.edu> 7 * Rewritten for PReP 8 * Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au> 9 * Low-level exception handers, MMU support, and rewrite. 10 * Copyright (c) 1997 Dan Malek <dmalek@jlc.net> 11 * PowerPC 8xx modifications. 12 * Copyright (c) 1998-1999 TiVo, Inc. 13 * PowerPC 403GCX modifications. 14 * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> 15 * PowerPC 403GCX/405GP modifications. 16 * Copyright 2000 MontaVista Software Inc. 17 * PPC405 modifications 18 * PowerPC 403GCX/405GP modifications. 19 * Author: MontaVista Software, Inc. 20 * frank_rowand@mvista.com or source@mvista.com 21 * debbie_chu@mvista.com 22 * Copyright 2002-2005 MontaVista Software, Inc. 23 * PowerPC 44x support, Matt Porter <mporter@kernel.crashing.org> 24 * 25 * This program is free software; you can redistribute it and/or modify it 26 * under the terms of the GNU General Public License as published by the 27 * Free Software Foundation; either version 2 of the License, or (at your 28 * option) any later version. 29 */ 30 31#include <linux/init.h> 32#include <asm/processor.h> 33#include <asm/page.h> 34#include <asm/mmu.h> 35#include <asm/pgtable.h> 36#include <asm/cputable.h> 37#include <asm/thread_info.h> 38#include <asm/ppc_asm.h> 39#include <asm/asm-offsets.h> 40#include <asm/ptrace.h> 41#include <asm/synch.h> 42#include "head_booke.h" 43 44 45/* As with the other PowerPC ports, it is expected that when code 46 * execution begins here, the following registers contain valid, yet 47 * optional, information: 48 * 49 * r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.) 50 * r4 - Starting address of the init RAM disk 51 * r5 - Ending address of the init RAM disk 52 * r6 - Start of kernel command line string (e.g. "mem=128") 53 * r7 - End of kernel command line string 54 * 55 */ 56 __HEAD 57_ENTRY(_stext); 58_ENTRY(_start); 59 /* 60 * Reserve a word at a fixed location to store the address 61 * of abatron_pteptrs 62 */ 63 nop 64/* 65 * Save parameters we are passed 66 */ 67 mr r31,r3 68 mr r30,r4 69 mr r29,r5 70 mr r28,r6 71 mr r27,r7 72 li r24,0 /* CPU number */ 73 74 bl init_cpu_state 75 76 /* 77 * This is where the main kernel code starts. 78 */ 79 80 /* ptr to current */ 81 lis r2,init_task@h 82 ori r2,r2,init_task@l 83 84 /* ptr to current thread */ 85 addi r4,r2,THREAD /* init task's THREAD */ 86 mtspr SPRN_SPRG_THREAD,r4 87 88 /* stack */ 89 lis r1,init_thread_union@h 90 ori r1,r1,init_thread_union@l 91 li r0,0 92 stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1) 93 94 bl early_init 95 96/* 97 * Decide what sort of machine this is and initialize the MMU. 98 */ 99 mr r3,r31 100 mr r4,r30 101 mr r5,r29 102 mr r6,r28 103 mr r7,r27 104 bl machine_init 105 bl MMU_init 106 107 /* Setup PTE pointers for the Abatron bdiGDB */ 108 lis r6, swapper_pg_dir@h 109 ori r6, r6, swapper_pg_dir@l 110 lis r5, abatron_pteptrs@h 111 ori r5, r5, abatron_pteptrs@l 112 lis r4, KERNELBASE@h 113 ori r4, r4, KERNELBASE@l 114 stw r5, 0(r4) /* Save abatron_pteptrs at a fixed location */ 115 stw r6, 0(r5) 116 117 /* Clear the Machine Check Syndrome Register */ 118 li r0,0 119 mtspr SPRN_MCSR,r0 120 121 /* Let's move on */ 122 lis r4,start_kernel@h 123 ori r4,r4,start_kernel@l 124 lis r3,MSR_KERNEL@h 125 ori r3,r3,MSR_KERNEL@l 126 mtspr SPRN_SRR0,r4 127 mtspr SPRN_SRR1,r3 128 rfi /* change context and jump to start_kernel */ 129 130/* 131 * Interrupt vector entry code 132 * 133 * The Book E MMUs are always on so we don't need to handle 134 * interrupts in real mode as with previous PPC processors. In 135 * this case we handle interrupts in the kernel virtual address 136 * space. 137 * 138 * Interrupt vectors are dynamically placed relative to the 139 * interrupt prefix as determined by the address of interrupt_base. 140 * The interrupt vectors offsets are programmed using the labels 141 * for each interrupt vector entry. 142 * 143 * Interrupt vectors must be aligned on a 16 byte boundary. 144 * We align on a 32 byte cache line boundary for good measure. 145 */ 146 147interrupt_base: 148 /* Critical Input Interrupt */ 149 CRITICAL_EXCEPTION(0x0100, CriticalInput, unknown_exception) 150 151 /* Machine Check Interrupt */ 152 CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception) 153 MCHECK_EXCEPTION(0x0210, MachineCheckA, machine_check_exception) 154 155 /* Data Storage Interrupt */ 156 DATA_STORAGE_EXCEPTION 157 158 /* Instruction Storage Interrupt */ 159 INSTRUCTION_STORAGE_EXCEPTION 160 161 /* External Input Interrupt */ 162 EXCEPTION(0x0500, ExternalInput, do_IRQ, EXC_XFER_LITE) 163 164 /* Alignment Interrupt */ 165 ALIGNMENT_EXCEPTION 166 167 /* Program Interrupt */ 168 PROGRAM_EXCEPTION 169 170 /* Floating Point Unavailable Interrupt */ 171#ifdef CONFIG_PPC_FPU 172 FP_UNAVAILABLE_EXCEPTION 173#else 174 EXCEPTION(0x2010, FloatingPointUnavailable, unknown_exception, EXC_XFER_EE) 175#endif 176 /* System Call Interrupt */ 177 START_EXCEPTION(SystemCall) 178 NORMAL_EXCEPTION_PROLOG 179 EXC_XFER_EE_LITE(0x0c00, DoSyscall) 180 181 /* Auxillary Processor Unavailable Interrupt */ 182 EXCEPTION(0x2020, AuxillaryProcessorUnavailable, unknown_exception, EXC_XFER_EE) 183 184 /* Decrementer Interrupt */ 185 DECREMENTER_EXCEPTION 186 187 /* Fixed Internal Timer Interrupt */ 188 /* TODO: Add FIT support */ 189 EXCEPTION(0x1010, FixedIntervalTimer, unknown_exception, EXC_XFER_EE) 190 191 /* Watchdog Timer Interrupt */ 192 /* TODO: Add watchdog support */ 193#ifdef CONFIG_BOOKE_WDT 194 CRITICAL_EXCEPTION(0x1020, WatchdogTimer, WatchdogException) 195#else 196 CRITICAL_EXCEPTION(0x1020, WatchdogTimer, unknown_exception) 197#endif 198 199 /* Data TLB Error Interrupt */ 200 START_EXCEPTION(DataTLBError44x) 201 mtspr SPRN_SPRG_WSCRATCH0, r10 /* Save some working registers */ 202 mtspr SPRN_SPRG_WSCRATCH1, r11 203 mtspr SPRN_SPRG_WSCRATCH2, r12 204 mtspr SPRN_SPRG_WSCRATCH3, r13 205 mfcr r11 206 mtspr SPRN_SPRG_WSCRATCH4, r11 207 mfspr r10, SPRN_DEAR /* Get faulting address */ 208 209 /* If we are faulting a kernel address, we have to use the 210 * kernel page tables. 211 */ 212 lis r11, PAGE_OFFSET@h 213 cmplw r10, r11 214 blt+ 3f 215 lis r11, swapper_pg_dir@h 216 ori r11, r11, swapper_pg_dir@l 217 218 mfspr r12,SPRN_MMUCR 219 rlwinm r12,r12,0,0,23 /* Clear TID */ 220 221 b 4f 222 223 /* Get the PGD for the current thread */ 2243: 225 mfspr r11,SPRN_SPRG_THREAD 226 lwz r11,PGDIR(r11) 227 228 /* Load PID into MMUCR TID */ 229 mfspr r12,SPRN_MMUCR 230 mfspr r13,SPRN_PID /* Get PID */ 231 rlwimi r12,r13,0,24,31 /* Set TID */ 232 2334: 234 mtspr SPRN_MMUCR,r12 235 236 /* Mask of required permission bits. Note that while we 237 * do copy ESR:ST to _PAGE_RW position as trying to write 238 * to an RO page is pretty common, we don't do it with 239 * _PAGE_DIRTY. We could do it, but it's a fairly rare 240 * event so I'd rather take the overhead when it happens 241 * rather than adding an instruction here. We should measure 242 * whether the whole thing is worth it in the first place 243 * as we could avoid loading SPRN_ESR completely in the first 244 * place... 245 * 246 * TODO: Is it worth doing that mfspr & rlwimi in the first 247 * place or can we save a couple of instructions here ? 248 */ 249 mfspr r12,SPRN_ESR 250 li r13,_PAGE_PRESENT|_PAGE_ACCESSED 251 rlwimi r13,r12,10,30,30 252 253 /* Load the PTE */ 254 /* Compute pgdir/pmd offset */ 255 rlwinm r12, r10, PPC44x_PGD_OFF_SHIFT, PPC44x_PGD_OFF_MASK_BIT, 29 256 lwzx r11, r12, r11 /* Get pgd/pmd entry */ 257 rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */ 258 beq 2f /* Bail if no table */ 259 260 /* Compute pte address */ 261 rlwimi r12, r10, PPC44x_PTE_ADD_SHIFT, PPC44x_PTE_ADD_MASK_BIT, 28 262 lwz r11, 0(r12) /* Get high word of pte entry */ 263 lwz r12, 4(r12) /* Get low word of pte entry */ 264 265 lis r10,tlb_44x_index@ha 266 267 andc. r13,r13,r12 /* Check permission */ 268 269 /* Load the next available TLB index */ 270 lwz r13,tlb_44x_index@l(r10) 271 272 bne 2f /* Bail if permission mismach */ 273 274 /* Increment, rollover, and store TLB index */ 275 addi r13,r13,1 276 277 /* Compare with watermark (instruction gets patched) */ 278 .globl tlb_44x_patch_hwater_D 279tlb_44x_patch_hwater_D: 280 cmpwi 0,r13,1 /* reserve entries */ 281 ble 5f 282 li r13,0 2835: 284 /* Store the next available TLB index */ 285 stw r13,tlb_44x_index@l(r10) 286 287 /* Re-load the faulting address */ 288 mfspr r10,SPRN_DEAR 289 290 /* Jump to common tlb load */ 291 b finish_tlb_load_44x 292 2932: 294 /* The bailout. Restore registers to pre-exception conditions 295 * and call the heavyweights to help us out. 296 */ 297 mfspr r11, SPRN_SPRG_RSCRATCH4 298 mtcr r11 299 mfspr r13, SPRN_SPRG_RSCRATCH3 300 mfspr r12, SPRN_SPRG_RSCRATCH2 301 mfspr r11, SPRN_SPRG_RSCRATCH1 302 mfspr r10, SPRN_SPRG_RSCRATCH0 303 b DataStorage 304 305 /* Instruction TLB Error Interrupt */ 306 /* 307 * Nearly the same as above, except we get our 308 * information from different registers and bailout 309 * to a different point. 310 */ 311 START_EXCEPTION(InstructionTLBError44x) 312 mtspr SPRN_SPRG_WSCRATCH0, r10 /* Save some working registers */ 313 mtspr SPRN_SPRG_WSCRATCH1, r11 314 mtspr SPRN_SPRG_WSCRATCH2, r12 315 mtspr SPRN_SPRG_WSCRATCH3, r13 316 mfcr r11 317 mtspr SPRN_SPRG_WSCRATCH4, r11 318 mfspr r10, SPRN_SRR0 /* Get faulting address */ 319 320 /* If we are faulting a kernel address, we have to use the 321 * kernel page tables. 322 */ 323 lis r11, PAGE_OFFSET@h 324 cmplw r10, r11 325 blt+ 3f 326 lis r11, swapper_pg_dir@h 327 ori r11, r11, swapper_pg_dir@l 328 329 mfspr r12,SPRN_MMUCR 330 rlwinm r12,r12,0,0,23 /* Clear TID */ 331 332 b 4f 333 334 /* Get the PGD for the current thread */ 3353: 336 mfspr r11,SPRN_SPRG_THREAD 337 lwz r11,PGDIR(r11) 338 339 /* Load PID into MMUCR TID */ 340 mfspr r12,SPRN_MMUCR 341 mfspr r13,SPRN_PID /* Get PID */ 342 rlwimi r12,r13,0,24,31 /* Set TID */ 343 3444: 345 mtspr SPRN_MMUCR,r12 346 347 /* Make up the required permissions */ 348 li r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC 349 350 /* Compute pgdir/pmd offset */ 351 rlwinm r12, r10, PPC44x_PGD_OFF_SHIFT, PPC44x_PGD_OFF_MASK_BIT, 29 352 lwzx r11, r12, r11 /* Get pgd/pmd entry */ 353 rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */ 354 beq 2f /* Bail if no table */ 355 356 /* Compute pte address */ 357 rlwimi r12, r10, PPC44x_PTE_ADD_SHIFT, PPC44x_PTE_ADD_MASK_BIT, 28 358 lwz r11, 0(r12) /* Get high word of pte entry */ 359 lwz r12, 4(r12) /* Get low word of pte entry */ 360 361 lis r10,tlb_44x_index@ha 362 363 andc. r13,r13,r12 /* Check permission */ 364 365 /* Load the next available TLB index */ 366 lwz r13,tlb_44x_index@l(r10) 367 368 bne 2f /* Bail if permission mismach */ 369 370 /* Increment, rollover, and store TLB index */ 371 addi r13,r13,1 372 373 /* Compare with watermark (instruction gets patched) */ 374 .globl tlb_44x_patch_hwater_I 375tlb_44x_patch_hwater_I: 376 cmpwi 0,r13,1 /* reserve entries */ 377 ble 5f 378 li r13,0 3795: 380 /* Store the next available TLB index */ 381 stw r13,tlb_44x_index@l(r10) 382 383 /* Re-load the faulting address */ 384 mfspr r10,SPRN_SRR0 385 386 /* Jump to common TLB load point */ 387 b finish_tlb_load_44x 388 3892: 390 /* The bailout. Restore registers to pre-exception conditions 391 * and call the heavyweights to help us out. 392 */ 393 mfspr r11, SPRN_SPRG_RSCRATCH4 394 mtcr r11 395 mfspr r13, SPRN_SPRG_RSCRATCH3 396 mfspr r12, SPRN_SPRG_RSCRATCH2 397 mfspr r11, SPRN_SPRG_RSCRATCH1 398 mfspr r10, SPRN_SPRG_RSCRATCH0 399 b InstructionStorage 400 401/* 402 * Both the instruction and data TLB miss get to this 403 * point to load the TLB. 404 * r10 - EA of fault 405 * r11 - PTE high word value 406 * r12 - PTE low word value 407 * r13 - TLB index 408 * MMUCR - loaded with proper value when we get here 409 * Upon exit, we reload everything and RFI. 410 */ 411finish_tlb_load_44x: 412 /* Combine RPN & ERPN an write WS 0 */ 413 rlwimi r11,r12,0,0,31-PAGE_SHIFT 414 tlbwe r11,r13,PPC44x_TLB_XLAT 415 416 /* 417 * Create WS1. This is the faulting address (EPN), 418 * page size, and valid flag. 419 */ 420 li r11,PPC44x_TLB_VALID | PPC44x_TLBE_SIZE 421 /* Insert valid and page size */ 422 rlwimi r10,r11,0,PPC44x_PTE_ADD_MASK_BIT,31 423 tlbwe r10,r13,PPC44x_TLB_PAGEID /* Write PAGEID */ 424 425 /* And WS 2 */ 426 li r10,0xf85 /* Mask to apply from PTE */ 427 rlwimi r10,r12,29,30,30 /* DIRTY -> SW position */ 428 and r11,r12,r10 /* Mask PTE bits to keep */ 429 andi. r10,r12,_PAGE_USER /* User page ? */ 430 beq 1f /* nope, leave U bits empty */ 431 rlwimi r11,r11,3,26,28 /* yes, copy S bits to U */ 4321: tlbwe r11,r13,PPC44x_TLB_ATTRIB /* Write ATTRIB */ 433 434 /* Done...restore registers and get out of here. 435 */ 436 mfspr r11, SPRN_SPRG_RSCRATCH4 437 mtcr r11 438 mfspr r13, SPRN_SPRG_RSCRATCH3 439 mfspr r12, SPRN_SPRG_RSCRATCH2 440 mfspr r11, SPRN_SPRG_RSCRATCH1 441 mfspr r10, SPRN_SPRG_RSCRATCH0 442 rfi /* Force context change */ 443 444/* TLB error interrupts for 476 445 */ 446#ifdef CONFIG_PPC_47x 447 START_EXCEPTION(DataTLBError47x) 448 mtspr SPRN_SPRG_WSCRATCH0,r10 /* Save some working registers */ 449 mtspr SPRN_SPRG_WSCRATCH1,r11 450 mtspr SPRN_SPRG_WSCRATCH2,r12 451 mtspr SPRN_SPRG_WSCRATCH3,r13 452 mfcr r11 453 mtspr SPRN_SPRG_WSCRATCH4,r11 454 mfspr r10,SPRN_DEAR /* Get faulting address */ 455 456 /* If we are faulting a kernel address, we have to use the 457 * kernel page tables. 458 */ 459 lis r11,PAGE_OFFSET@h 460 cmplw cr0,r10,r11 461 blt+ 3f 462 lis r11,swapper_pg_dir@h 463 ori r11,r11, swapper_pg_dir@l 464 li r12,0 /* MMUCR = 0 */ 465 b 4f 466 467 /* Get the PGD for the current thread and setup MMUCR */ 4683: mfspr r11,SPRN_SPRG3 469 lwz r11,PGDIR(r11) 470 mfspr r12,SPRN_PID /* Get PID */ 4714: mtspr SPRN_MMUCR,r12 /* Set MMUCR */ 472 473 /* Mask of required permission bits. Note that while we 474 * do copy ESR:ST to _PAGE_RW position as trying to write 475 * to an RO page is pretty common, we don't do it with 476 * _PAGE_DIRTY. We could do it, but it's a fairly rare 477 * event so I'd rather take the overhead when it happens 478 * rather than adding an instruction here. We should measure 479 * whether the whole thing is worth it in the first place 480 * as we could avoid loading SPRN_ESR completely in the first 481 * place... 482 * 483 * TODO: Is it worth doing that mfspr & rlwimi in the first 484 * place or can we save a couple of instructions here ? 485 */ 486 mfspr r12,SPRN_ESR 487 li r13,_PAGE_PRESENT|_PAGE_ACCESSED 488 rlwimi r13,r12,10,30,30 489 490 /* Load the PTE */ 491 /* Compute pgdir/pmd offset */ 492 rlwinm r12,r10,PPC44x_PGD_OFF_SHIFT,PPC44x_PGD_OFF_MASK_BIT,29 493 lwzx r11,r12,r11 /* Get pgd/pmd entry */ 494 495 /* Word 0 is EPN,V,TS,DSIZ */ 496 li r12,PPC47x_TLB0_VALID | PPC47x_TLBE_SIZE 497 rlwimi r10,r12,0,32-PAGE_SHIFT,31 /* Insert valid and page size*/ 498 li r12,0 499 tlbwe r10,r12,0 500 501 /* XXX can we do better ? Need to make sure tlbwe has established 502 * latch V bit in MMUCR0 before the PTE is loaded further down */ 503#ifdef CONFIG_SMP 504 isync 505#endif 506 507 rlwinm. r12,r11,0,0,20 /* Extract pt base address */ 508 /* Compute pte address */ 509 rlwimi r12,r10,PPC44x_PTE_ADD_SHIFT,PPC44x_PTE_ADD_MASK_BIT,28 510 beq 2f /* Bail if no table */ 511 lwz r11,0(r12) /* Get high word of pte entry */ 512 513 /* XXX can we do better ? maybe insert a known 0 bit from r11 into the 514 * bottom of r12 to create a data dependency... We can also use r10 515 * as destination nowadays 516 */ 517#ifdef CONFIG_SMP 518 lwsync 519#endif 520 lwz r12,4(r12) /* Get low word of pte entry */ 521 522 andc. r13,r13,r12 /* Check permission */ 523 524 /* Jump to common tlb load */ 525 beq finish_tlb_load_47x 526 5272: /* The bailout. Restore registers to pre-exception conditions 528 * and call the heavyweights to help us out. 529 */ 530 mfspr r11,SPRN_SPRG_RSCRATCH4 531 mtcr r11 532 mfspr r13,SPRN_SPRG_RSCRATCH3 533 mfspr r12,SPRN_SPRG_RSCRATCH2 534 mfspr r11,SPRN_SPRG_RSCRATCH1 535 mfspr r10,SPRN_SPRG_RSCRATCH0 536 b DataStorage 537 538 /* Instruction TLB Error Interrupt */ 539 /* 540 * Nearly the same as above, except we get our 541 * information from different registers and bailout 542 * to a different point. 543 */ 544 START_EXCEPTION(InstructionTLBError47x) 545 mtspr SPRN_SPRG_WSCRATCH0,r10 /* Save some working registers */ 546 mtspr SPRN_SPRG_WSCRATCH1,r11 547 mtspr SPRN_SPRG_WSCRATCH2,r12 548 mtspr SPRN_SPRG_WSCRATCH3,r13 549 mfcr r11 550 mtspr SPRN_SPRG_WSCRATCH4,r11 551 mfspr r10,SPRN_SRR0 /* Get faulting address */ 552 553 /* If we are faulting a kernel address, we have to use the 554 * kernel page tables. 555 */ 556 lis r11,PAGE_OFFSET@h 557 cmplw cr0,r10,r11 558 blt+ 3f 559 lis r11,swapper_pg_dir@h 560 ori r11,r11, swapper_pg_dir@l 561 li r12,0 /* MMUCR = 0 */ 562 b 4f 563 564 /* Get the PGD for the current thread and setup MMUCR */ 5653: mfspr r11,SPRN_SPRG_THREAD 566 lwz r11,PGDIR(r11) 567 mfspr r12,SPRN_PID /* Get PID */ 5684: mtspr SPRN_MMUCR,r12 /* Set MMUCR */ 569 570 /* Make up the required permissions */ 571 li r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC 572 573 /* Load PTE */ 574 /* Compute pgdir/pmd offset */ 575 rlwinm r12,r10,PPC44x_PGD_OFF_SHIFT,PPC44x_PGD_OFF_MASK_BIT,29 576 lwzx r11,r12,r11 /* Get pgd/pmd entry */ 577 578 /* Word 0 is EPN,V,TS,DSIZ */ 579 li r12,PPC47x_TLB0_VALID | PPC47x_TLBE_SIZE 580 rlwimi r10,r12,0,32-PAGE_SHIFT,31 /* Insert valid and page size*/ 581 li r12,0 582 tlbwe r10,r12,0 583 584 /* XXX can we do better ? Need to make sure tlbwe has established 585 * latch V bit in MMUCR0 before the PTE is loaded further down */ 586#ifdef CONFIG_SMP 587 isync 588#endif 589 590 rlwinm. r12,r11,0,0,20 /* Extract pt base address */ 591 /* Compute pte address */ 592 rlwimi r12,r10,PPC44x_PTE_ADD_SHIFT,PPC44x_PTE_ADD_MASK_BIT,28 593 beq 2f /* Bail if no table */ 594 595 lwz r11,0(r12) /* Get high word of pte entry */ 596 /* XXX can we do better ? maybe insert a known 0 bit from r11 into the 597 * bottom of r12 to create a data dependency... We can also use r10 598 * as destination nowadays 599 */ 600#ifdef CONFIG_SMP 601 lwsync 602#endif 603 lwz r12,4(r12) /* Get low word of pte entry */ 604 605 andc. r13,r13,r12 /* Check permission */ 606 607 /* Jump to common TLB load point */ 608 beq finish_tlb_load_47x 609 6102: /* The bailout. Restore registers to pre-exception conditions 611 * and call the heavyweights to help us out. 612 */ 613 mfspr r11, SPRN_SPRG_RSCRATCH4 614 mtcr r11 615 mfspr r13, SPRN_SPRG_RSCRATCH3 616 mfspr r12, SPRN_SPRG_RSCRATCH2 617 mfspr r11, SPRN_SPRG_RSCRATCH1 618 mfspr r10, SPRN_SPRG_RSCRATCH0 619 b InstructionStorage 620 621/* 622 * Both the instruction and data TLB miss get to this 623 * point to load the TLB. 624 * r10 - free to use 625 * r11 - PTE high word value 626 * r12 - PTE low word value 627 * r13 - free to use 628 * MMUCR - loaded with proper value when we get here 629 * Upon exit, we reload everything and RFI. 630 */ 631finish_tlb_load_47x: 632 /* Combine RPN & ERPN an write WS 1 */ 633 rlwimi r11,r12,0,0,31-PAGE_SHIFT 634 tlbwe r11,r13,1 635 636 /* And make up word 2 */ 637 li r10,0xf85 /* Mask to apply from PTE */ 638 rlwimi r10,r12,29,30,30 /* DIRTY -> SW position */ 639 and r11,r12,r10 /* Mask PTE bits to keep */ 640 andi. r10,r12,_PAGE_USER /* User page ? */ 641 beq 1f /* nope, leave U bits empty */ 642 rlwimi r11,r11,3,26,28 /* yes, copy S bits to U */ 6431: tlbwe r11,r13,2 644 645 /* Done...restore registers and get out of here. 646 */ 647 mfspr r11, SPRN_SPRG_RSCRATCH4 648 mtcr r11 649 mfspr r13, SPRN_SPRG_RSCRATCH3 650 mfspr r12, SPRN_SPRG_RSCRATCH2 651 mfspr r11, SPRN_SPRG_RSCRATCH1 652 mfspr r10, SPRN_SPRG_RSCRATCH0 653 rfi 654 655#endif /* CONFIG_PPC_47x */ 656 657 /* Debug Interrupt */ 658 /* 659 * This statement needs to exist at the end of the IVPR 660 * definition just in case you end up taking a debug 661 * exception within another exception. 662 */ 663 DEBUG_CRIT_EXCEPTION 664 665/* 666 * Global functions 667 */ 668 669/* 670 * Adjust the machine check IVOR on 440A cores 671 */ 672_GLOBAL(__fixup_440A_mcheck) 673 li r3,MachineCheckA@l 674 mtspr SPRN_IVOR1,r3 675 sync 676 blr 677 678/* 679 * extern void giveup_altivec(struct task_struct *prev) 680 * 681 * The 44x core does not have an AltiVec unit. 682 */ 683_GLOBAL(giveup_altivec) 684 blr 685 686/* 687 * extern void giveup_fpu(struct task_struct *prev) 688 * 689 * The 44x core does not have an FPU. 690 */ 691#ifndef CONFIG_PPC_FPU 692_GLOBAL(giveup_fpu) 693 blr 694#endif 695 696_GLOBAL(set_context) 697 698#ifdef CONFIG_BDI_SWITCH 699 /* Context switch the PTE pointer for the Abatron BDI2000. 700 * The PGDIR is the second parameter. 701 */ 702 lis r5, abatron_pteptrs@h 703 ori r5, r5, abatron_pteptrs@l 704 stw r4, 0x4(r5) 705#endif 706 mtspr SPRN_PID,r3 707 isync /* Force context change */ 708 blr 709 710/* 711 * Init CPU state. This is called at boot time or for secondary CPUs 712 * to setup initial TLB entries, setup IVORs, etc... 713 * 714 */ 715_GLOBAL(init_cpu_state) 716 mflr r22 717#ifdef CONFIG_PPC_47x 718 /* We use the PVR to differenciate 44x cores from 476 */ 719 mfspr r3,SPRN_PVR 720 srwi r3,r3,16 721 cmplwi cr0,r3,PVR_476@h 722 beq head_start_47x 723 cmplwi cr0,r3,PVR_476_ISS@h 724 beq head_start_47x 725#endif /* CONFIG_PPC_47x */ 726 727/* 728 * In case the firmware didn't do it, we apply some workarounds 729 * that are good for all 440 core variants here 730 */ 731 mfspr r3,SPRN_CCR0 732 rlwinm r3,r3,0,0,27 /* disable icache prefetch */ 733 isync 734 mtspr SPRN_CCR0,r3 735 isync 736 sync 737 738/* 739 * Set up the initial MMU state for 44x 740 * 741 * We are still executing code at the virtual address 742 * mappings set by the firmware for the base of RAM. 743 * 744 * We first invalidate all TLB entries but the one 745 * we are running from. We then load the KERNELBASE 746 * mappings so we can begin to use kernel addresses 747 * natively and so the interrupt vector locations are 748 * permanently pinned (necessary since Book E 749 * implementations always have translation enabled). 750 * 751 * TODO: Use the known TLB entry we are running from to 752 * determine which physical region we are located 753 * in. This can be used to determine where in RAM 754 * (on a shared CPU system) or PCI memory space 755 * (on a DRAMless system) we are located. 756 * For now, we assume a perfect world which means 757 * we are located at the base of DRAM (physical 0). 758 */ 759 760/* 761 * Search TLB for entry that we are currently using. 762 * Invalidate all entries but the one we are using. 763 */ 764 /* Load our current PID->MMUCR TID and MSR IS->MMUCR STS */ 765 mfspr r3,SPRN_PID /* Get PID */ 766 mfmsr r4 /* Get MSR */ 767 andi. r4,r4,MSR_IS@l /* TS=1? */ 768 beq wmmucr /* If not, leave STS=0 */ 769 oris r3,r3,PPC44x_MMUCR_STS@h /* Set STS=1 */ 770wmmucr: mtspr SPRN_MMUCR,r3 /* Put MMUCR */ 771 sync 772 773 bl invstr /* Find our address */ 774invstr: mflr r5 /* Make it accessible */ 775 tlbsx r23,0,r5 /* Find entry we are in */ 776 li r4,0 /* Start at TLB entry 0 */ 777 li r3,0 /* Set PAGEID inval value */ 7781: cmpw r23,r4 /* Is this our entry? */ 779 beq skpinv /* If so, skip the inval */ 780 tlbwe r3,r4,PPC44x_TLB_PAGEID /* If not, inval the entry */ 781skpinv: addi r4,r4,1 /* Increment */ 782 cmpwi r4,64 /* Are we done? */ 783 bne 1b /* If not, repeat */ 784 isync /* If so, context change */ 785 786/* 787 * Configure and load pinned entry into TLB slot 63. 788 */ 789 790 lis r3,PAGE_OFFSET@h 791 ori r3,r3,PAGE_OFFSET@l 792 793 /* Kernel is at the base of RAM */ 794 li r4, 0 /* Load the kernel physical address */ 795 796 /* Load the kernel PID = 0 */ 797 li r0,0 798 mtspr SPRN_PID,r0 799 sync 800 801 /* Initialize MMUCR */ 802 li r5,0 803 mtspr SPRN_MMUCR,r5 804 sync 805 806 /* pageid fields */ 807 clrrwi r3,r3,10 /* Mask off the effective page number */ 808 ori r3,r3,PPC44x_TLB_VALID | PPC44x_TLB_256M 809 810 /* xlat fields */ 811 clrrwi r4,r4,10 /* Mask off the real page number */ 812 /* ERPN is 0 for first 4GB page */ 813 814 /* attrib fields */ 815 /* Added guarded bit to protect against speculative loads/stores */ 816 li r5,0 817 ori r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G) 818 819 li r0,63 /* TLB slot 63 */ 820 821 tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */ 822 tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */ 823 tlbwe r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */ 824 825 /* Force context change */ 826 mfmsr r0 827 mtspr SPRN_SRR1, r0 828 lis r0,3f@h 829 ori r0,r0,3f@l 830 mtspr SPRN_SRR0,r0 831 sync 832 rfi 833 834 /* If necessary, invalidate original entry we used */ 8353: cmpwi r23,63 836 beq 4f 837 li r6,0 838 tlbwe r6,r23,PPC44x_TLB_PAGEID 839 isync 840 8414: 842#ifdef CONFIG_PPC_EARLY_DEBUG_44x 843 /* Add UART mapping for early debug. */ 844 845 /* pageid fields */ 846 lis r3,PPC44x_EARLY_DEBUG_VIRTADDR@h 847 ori r3,r3,PPC44x_TLB_VALID|PPC44x_TLB_TS|PPC44x_TLB_64K 848 849 /* xlat fields */ 850 lis r4,CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW@h 851 ori r4,r4,CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH 852 853 /* attrib fields */ 854 li r5,(PPC44x_TLB_SW|PPC44x_TLB_SR|PPC44x_TLB_I|PPC44x_TLB_G) 855 li r0,62 /* TLB slot 0 */ 856 857 tlbwe r3,r0,PPC44x_TLB_PAGEID 858 tlbwe r4,r0,PPC44x_TLB_XLAT 859 tlbwe r5,r0,PPC44x_TLB_ATTRIB 860 861 /* Force context change */ 862 isync 863#endif /* CONFIG_PPC_EARLY_DEBUG_44x */ 864 865 /* Establish the interrupt vector offsets */ 866 SET_IVOR(0, CriticalInput); 867 SET_IVOR(1, MachineCheck); 868 SET_IVOR(2, DataStorage); 869 SET_IVOR(3, InstructionStorage); 870 SET_IVOR(4, ExternalInput); 871 SET_IVOR(5, Alignment); 872 SET_IVOR(6, Program); 873 SET_IVOR(7, FloatingPointUnavailable); 874 SET_IVOR(8, SystemCall); 875 SET_IVOR(9, AuxillaryProcessorUnavailable); 876 SET_IVOR(10, Decrementer); 877 SET_IVOR(11, FixedIntervalTimer); 878 SET_IVOR(12, WatchdogTimer); 879 SET_IVOR(13, DataTLBError44x); 880 SET_IVOR(14, InstructionTLBError44x); 881 SET_IVOR(15, DebugCrit); 882 883 b head_start_common 884 885 886#ifdef CONFIG_PPC_47x 887 888#ifdef CONFIG_SMP 889 890/* Entry point for secondary 47x processors */ 891_GLOBAL(start_secondary_47x) 892 mr r24,r3 /* CPU number */ 893 894 bl init_cpu_state 895 896 /* Now we need to bolt the rest of kernel memory which 897 * is done in C code. We must be careful because our task 898 * struct or our stack can (and will probably) be out 899 * of reach of the initial 256M TLB entry, so we use a 900 * small temporary stack in .bss for that. This works 901 * because only one CPU at a time can be in this code 902 */ 903 lis r1,temp_boot_stack@h 904 ori r1,r1,temp_boot_stack@l 905 addi r1,r1,1024-STACK_FRAME_OVERHEAD 906 li r0,0 907 stw r0,0(r1) 908 bl mmu_init_secondary 909 910 /* Now we can get our task struct and real stack pointer */ 911 912 /* Get current_thread_info and current */ 913 lis r1,secondary_ti@ha 914 lwz r1,secondary_ti@l(r1) 915 lwz r2,TI_TASK(r1) 916 917 /* Current stack pointer */ 918 addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD 919 li r0,0 920 stw r0,0(r1) 921 922 /* Kernel stack for exception entry in SPRG3 */ 923 addi r4,r2,THREAD /* init task's THREAD */ 924 mtspr SPRN_SPRG3,r4 925 926 b start_secondary 927 928#endif /* CONFIG_SMP */ 929 930/* 931 * Set up the initial MMU state for 44x 932 * 933 * We are still executing code at the virtual address 934 * mappings set by the firmware for the base of RAM. 935 */ 936 937head_start_47x: 938 /* Load our current PID->MMUCR TID and MSR IS->MMUCR STS */ 939 mfspr r3,SPRN_PID /* Get PID */ 940 mfmsr r4 /* Get MSR */ 941 andi. r4,r4,MSR_IS@l /* TS=1? */ 942 beq 1f /* If not, leave STS=0 */ 943 oris r3,r3,PPC47x_MMUCR_STS@h /* Set STS=1 */ 9441: mtspr SPRN_MMUCR,r3 /* Put MMUCR */ 945 sync 946 947 /* Find the entry we are running from */ 948 bl 1f 9491: mflr r23 950 tlbsx r23,0,r23 951 tlbre r24,r23,0 952 tlbre r25,r23,1 953 tlbre r26,r23,2 954 955/* 956 * Cleanup time 957 */ 958 959 /* Initialize MMUCR */ 960 li r5,0 961 mtspr SPRN_MMUCR,r5 962 sync 963 964clear_all_utlb_entries: 965 966 #; Set initial values. 967 968 addis r3,0,0x8000 969 addi r4,0,0 970 addi r5,0,0 971 b clear_utlb_entry 972 973 #; Align the loop to speed things up. 974 975 .align 6 976 977clear_utlb_entry: 978 979 tlbwe r4,r3,0 980 tlbwe r5,r3,1 981 tlbwe r5,r3,2 982 addis r3,r3,0x2000 983 cmpwi r3,0 984 bne clear_utlb_entry 985 addis r3,0,0x8000 986 addis r4,r4,0x100 987 cmpwi r4,0 988 bne clear_utlb_entry 989 990 #; Restore original entry. 991 992 oris r23,r23,0x8000 /* specify the way */ 993 tlbwe r24,r23,0 994 tlbwe r25,r23,1 995 tlbwe r26,r23,2 996 997/* 998 * Configure and load pinned entry into TLB for the kernel core 999 */ 1000 1001 lis r3,PAGE_OFFSET@h 1002 ori r3,r3,PAGE_OFFSET@l 1003 1004 /* Kernel is at the base of RAM */ 1005 li r4, 0 /* Load the kernel physical address */ 1006 1007 /* Load the kernel PID = 0 */ 1008 li r0,0 1009 mtspr SPRN_PID,r0 1010 sync 1011 1012 /* Word 0 */ 1013 clrrwi r3,r3,12 /* Mask off the effective page number */ 1014 ori r3,r3,PPC47x_TLB0_VALID | PPC47x_TLB0_256M 1015 1016 /* Word 1 */ 1017 clrrwi r4,r4,12 /* Mask off the real page number */ 1018 /* ERPN is 0 for first 4GB page */ 1019 /* Word 2 */ 1020 li r5,0 1021 ori r5,r5,PPC47x_TLB2_S_RWX 1022#ifdef CONFIG_SMP 1023 ori r5,r5,PPC47x_TLB2_M 1024#endif 1025 1026 /* We write to way 0 and bolted 0 */ 1027 lis r0,0x8800 1028 tlbwe r3,r0,0 1029 tlbwe r4,r0,1 1030 tlbwe r5,r0,2 1031 1032/* 1033 * Configure SSPCR, ISPCR and USPCR for now to search everything, we can fix 1034 * them up later 1035 */ 1036 LOAD_REG_IMMEDIATE(r3, 0x9abcdef0) 1037 mtspr SPRN_SSPCR,r3 1038 mtspr SPRN_USPCR,r3 1039 LOAD_REG_IMMEDIATE(r3, 0x12345670) 1040 mtspr SPRN_ISPCR,r3 1041 1042 /* Force context change */ 1043 mfmsr r0 1044 mtspr SPRN_SRR1, r0 1045 lis r0,3f@h 1046 ori r0,r0,3f@l 1047 mtspr SPRN_SRR0,r0 1048 sync 1049 rfi 1050 1051 /* Invalidate original entry we used */ 10523: 1053 rlwinm r24,r24,0,21,19 /* clear the "valid" bit */ 1054 tlbwe r24,r23,0 1055 addi r24,0,0 1056 tlbwe r24,r23,1 1057 tlbwe r24,r23,2 1058 isync /* Clear out the shadow TLB entries */ 1059 1060#ifdef CONFIG_PPC_EARLY_DEBUG_44x 1061 /* Add UART mapping for early debug. */ 1062 1063 /* Word 0 */ 1064 lis r3,PPC44x_EARLY_DEBUG_VIRTADDR@h 1065 ori r3,r3,PPC47x_TLB0_VALID | PPC47x_TLB0_TS | PPC47x_TLB0_1M 1066 1067 /* Word 1 */ 1068 lis r4,CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW@h 1069 ori r4,r4,CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH 1070 1071 /* Word 2 */ 1072 li r5,(PPC47x_TLB2_S_RW | PPC47x_TLB2_IMG) 1073 1074 /* Bolted in way 0, bolt slot 5, we -hope- we don't hit the same 1075 * congruence class as the kernel, we need to make sure of it at 1076 * some point 1077 */ 1078 lis r0,0x8d00 1079 tlbwe r3,r0,0 1080 tlbwe r4,r0,1 1081 tlbwe r5,r0,2 1082 1083 /* Force context change */ 1084 isync 1085#endif /* CONFIG_PPC_EARLY_DEBUG_44x */ 1086 1087 /* Establish the interrupt vector offsets */ 1088 SET_IVOR(0, CriticalInput); 1089 SET_IVOR(1, MachineCheckA); 1090 SET_IVOR(2, DataStorage); 1091 SET_IVOR(3, InstructionStorage); 1092 SET_IVOR(4, ExternalInput); 1093 SET_IVOR(5, Alignment); 1094 SET_IVOR(6, Program); 1095 SET_IVOR(7, FloatingPointUnavailable); 1096 SET_IVOR(8, SystemCall); 1097 SET_IVOR(9, AuxillaryProcessorUnavailable); 1098 SET_IVOR(10, Decrementer); 1099 SET_IVOR(11, FixedIntervalTimer); 1100 SET_IVOR(12, WatchdogTimer); 1101 SET_IVOR(13, DataTLBError47x); 1102 SET_IVOR(14, InstructionTLBError47x); 1103 SET_IVOR(15, DebugCrit); 1104 1105 /* We configure icbi to invalidate 128 bytes at a time since the 1106 * current 32-bit kernel code isn't too happy with icache != dcache 1107 * block size 1108 */ 1109 mfspr r3,SPRN_CCR0 1110 oris r3,r3,0x0020 1111 mtspr SPRN_CCR0,r3 1112 isync 1113 1114#endif /* CONFIG_PPC_47x */ 1115 1116/* 1117 * Here we are back to code that is common between 44x and 47x 1118 * 1119 * We proceed to further kernel initialization and return to the 1120 * main kernel entry 1121 */ 1122head_start_common: 1123 /* Establish the interrupt vector base */ 1124 lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */ 1125 mtspr SPRN_IVPR,r4 1126 1127 addis r22,r22,KERNELBASE@h 1128 mtlr r22 1129 isync 1130 blr 1131 1132/* 1133 * We put a few things here that have to be page-aligned. This stuff 1134 * goes at the beginning of the data segment, which is page-aligned. 1135 */ 1136 .data 1137 .align PAGE_SHIFT 1138 .globl sdata 1139sdata: 1140 .globl empty_zero_page 1141empty_zero_page: 1142 .space PAGE_SIZE 1143 1144/* 1145 * To support >32-bit physical addresses, we use an 8KB pgdir. 1146 */ 1147 .globl swapper_pg_dir 1148swapper_pg_dir: 1149 .space PGD_TABLE_SIZE 1150 1151/* 1152 * Room for two PTE pointers, usually the kernel and current user pointers 1153 * to their respective root page table. 1154 */ 1155abatron_pteptrs: 1156 .space 8 1157 1158#ifdef CONFIG_SMP 1159 .align 12 1160temp_boot_stack: 1161 .space 1024 1162#endif /* CONFIG_SMP */ 1163