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 <asm/processor.h> 32#include <asm/page.h> 33#include <asm/mmu.h> 34#include <asm/pgtable.h> 35#include <asm/cputable.h> 36#include <asm/thread_info.h> 37#include <asm/ppc_asm.h> 38#include <asm/asm-offsets.h> 39#include "head_booke.h" 40 41 42/* As with the other PowerPC ports, it is expected that when code 43 * execution begins here, the following registers contain valid, yet 44 * optional, information: 45 * 46 * r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.) 47 * r4 - Starting address of the init RAM disk 48 * r5 - Ending address of the init RAM disk 49 * r6 - Start of kernel command line string (e.g. "mem=128") 50 * r7 - End of kernel command line string 51 * 52 */ 53 .section .text.head, "ax" 54_ENTRY(_stext); 55_ENTRY(_start); 56 /* 57 * Reserve a word at a fixed location to store the address 58 * of abatron_pteptrs 59 */ 60 nop 61/* 62 * Save parameters we are passed 63 */ 64 mr r31,r3 65 mr r30,r4 66 mr r29,r5 67 mr r28,r6 68 mr r27,r7 69 li r24,0 /* CPU number */ 70 71/* 72 * Set up the initial MMU state 73 * 74 * We are still executing code at the virtual address 75 * mappings set by the firmware for the base of RAM. 76 * 77 * We first invalidate all TLB entries but the one 78 * we are running from. We then load the KERNELBASE 79 * mappings so we can begin to use kernel addresses 80 * natively and so the interrupt vector locations are 81 * permanently pinned (necessary since Book E 82 * implementations always have translation enabled). 83 * 84 * TODO: Use the known TLB entry we are running from to 85 * determine which physical region we are located 86 * in. This can be used to determine where in RAM 87 * (on a shared CPU system) or PCI memory space 88 * (on a DRAMless system) we are located. 89 * For now, we assume a perfect world which means 90 * we are located at the base of DRAM (physical 0). 91 */ 92 93/* 94 * Search TLB for entry that we are currently using. 95 * Invalidate all entries but the one we are using. 96 */ 97 /* Load our current PID->MMUCR TID and MSR IS->MMUCR STS */ 98 mfspr r3,SPRN_PID /* Get PID */ 99 mfmsr r4 /* Get MSR */ 100 andi. r4,r4,MSR_IS@l /* TS=1? */ 101 beq wmmucr /* If not, leave STS=0 */ 102 oris r3,r3,PPC44x_MMUCR_STS@h /* Set STS=1 */ 103wmmucr: mtspr SPRN_MMUCR,r3 /* Put MMUCR */ 104 sync 105 106 bl invstr /* Find our address */ 107invstr: mflr r5 /* Make it accessible */ 108 tlbsx r23,0,r5 /* Find entry we are in */ 109 li r4,0 /* Start at TLB entry 0 */ 110 li r3,0 /* Set PAGEID inval value */ 1111: cmpw r23,r4 /* Is this our entry? */ 112 beq skpinv /* If so, skip the inval */ 113 tlbwe r3,r4,PPC44x_TLB_PAGEID /* If not, inval the entry */ 114skpinv: addi r4,r4,1 /* Increment */ 115 cmpwi r4,64 /* Are we done? */ 116 bne 1b /* If not, repeat */ 117 isync /* If so, context change */ 118 119/* 120 * Configure and load pinned entry into TLB slot 63. 121 */ 122 123 lis r3,PAGE_OFFSET@h 124 ori r3,r3,PAGE_OFFSET@l 125 126 /* Kernel is at the base of RAM */ 127 li r4, 0 /* Load the kernel physical address */ 128 129 /* Load the kernel PID = 0 */ 130 li r0,0 131 mtspr SPRN_PID,r0 132 sync 133 134 /* Initialize MMUCR */ 135 li r5,0 136 mtspr SPRN_MMUCR,r5 137 sync 138 139 /* pageid fields */ 140 clrrwi r3,r3,10 /* Mask off the effective page number */ 141 ori r3,r3,PPC44x_TLB_VALID | PPC44x_TLB_256M 142 143 /* xlat fields */ 144 clrrwi r4,r4,10 /* Mask off the real page number */ 145 /* ERPN is 0 for first 4GB page */ 146 147 /* attrib fields */ 148 /* Added guarded bit to protect against speculative loads/stores */ 149 li r5,0 150 ori r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G) 151 152 li r0,63 /* TLB slot 63 */ 153 154 tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */ 155 tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */ 156 tlbwe r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */ 157 158 /* Force context change */ 159 mfmsr r0 160 mtspr SPRN_SRR1, r0 161 lis r0,3f@h 162 ori r0,r0,3f@l 163 mtspr SPRN_SRR0,r0 164 sync 165 rfi 166 167 /* If necessary, invalidate original entry we used */ 1683: cmpwi r23,63 169 beq 4f 170 li r6,0 171 tlbwe r6,r23,PPC44x_TLB_PAGEID 172 isync 173 1744: 175#ifdef CONFIG_PPC_EARLY_DEBUG_44x 176 /* Add UART mapping for early debug. */ 177 178 /* pageid fields */ 179 lis r3,PPC44x_EARLY_DEBUG_VIRTADDR@h 180 ori r3,r3,PPC44x_TLB_VALID|PPC44x_TLB_TS|PPC44x_TLB_64K 181 182 /* xlat fields */ 183 lis r4,CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW@h 184 ori r4,r4,CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH 185 186 /* attrib fields */ 187 li r5,(PPC44x_TLB_SW|PPC44x_TLB_SR|PPC44x_TLB_I|PPC44x_TLB_G) 188 li r0,62 /* TLB slot 0 */ 189 190 tlbwe r3,r0,PPC44x_TLB_PAGEID 191 tlbwe r4,r0,PPC44x_TLB_XLAT 192 tlbwe r5,r0,PPC44x_TLB_ATTRIB 193 194 /* Force context change */ 195 isync 196#endif /* CONFIG_PPC_EARLY_DEBUG_44x */ 197 198 /* Establish the interrupt vector offsets */ 199 SET_IVOR(0, CriticalInput); 200 SET_IVOR(1, MachineCheck); 201 SET_IVOR(2, DataStorage); 202 SET_IVOR(3, InstructionStorage); 203 SET_IVOR(4, ExternalInput); 204 SET_IVOR(5, Alignment); 205 SET_IVOR(6, Program); 206 SET_IVOR(7, FloatingPointUnavailable); 207 SET_IVOR(8, SystemCall); 208 SET_IVOR(9, AuxillaryProcessorUnavailable); 209 SET_IVOR(10, Decrementer); 210 SET_IVOR(11, FixedIntervalTimer); 211 SET_IVOR(12, WatchdogTimer); 212 SET_IVOR(13, DataTLBError); 213 SET_IVOR(14, InstructionTLBError); 214 SET_IVOR(15, DebugCrit); 215 216 /* Establish the interrupt vector base */ 217 lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */ 218 mtspr SPRN_IVPR,r4 219 220 /* 221 * This is where the main kernel code starts. 222 */ 223 224 /* ptr to current */ 225 lis r2,init_task@h 226 ori r2,r2,init_task@l 227 228 /* ptr to current thread */ 229 addi r4,r2,THREAD /* init task's THREAD */ 230 mtspr SPRN_SPRG3,r4 231 232 /* stack */ 233 lis r1,init_thread_union@h 234 ori r1,r1,init_thread_union@l 235 li r0,0 236 stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1) 237 238 bl early_init 239 240/* 241 * Decide what sort of machine this is and initialize the MMU. 242 */ 243 mr r3,r31 244 mr r4,r30 245 mr r5,r29 246 mr r6,r28 247 mr r7,r27 248 bl machine_init 249 bl MMU_init 250 251 /* Setup PTE pointers for the Abatron bdiGDB */ 252 lis r6, swapper_pg_dir@h 253 ori r6, r6, swapper_pg_dir@l 254 lis r5, abatron_pteptrs@h 255 ori r5, r5, abatron_pteptrs@l 256 lis r4, KERNELBASE@h 257 ori r4, r4, KERNELBASE@l 258 stw r5, 0(r4) /* Save abatron_pteptrs at a fixed location */ 259 stw r6, 0(r5) 260 261 /* Let's move on */ 262 lis r4,start_kernel@h 263 ori r4,r4,start_kernel@l 264 lis r3,MSR_KERNEL@h 265 ori r3,r3,MSR_KERNEL@l 266 mtspr SPRN_SRR0,r4 267 mtspr SPRN_SRR1,r3 268 rfi /* change context and jump to start_kernel */ 269 270/* 271 * Interrupt vector entry code 272 * 273 * The Book E MMUs are always on so we don't need to handle 274 * interrupts in real mode as with previous PPC processors. In 275 * this case we handle interrupts in the kernel virtual address 276 * space. 277 * 278 * Interrupt vectors are dynamically placed relative to the 279 * interrupt prefix as determined by the address of interrupt_base. 280 * The interrupt vectors offsets are programmed using the labels 281 * for each interrupt vector entry. 282 * 283 * Interrupt vectors must be aligned on a 16 byte boundary. 284 * We align on a 32 byte cache line boundary for good measure. 285 */ 286 287interrupt_base: 288 /* Critical Input Interrupt */ 289 CRITICAL_EXCEPTION(0x0100, CriticalInput, unknown_exception) 290 291 /* Machine Check Interrupt */ 292 CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception) 293 MCHECK_EXCEPTION(0x0210, MachineCheckA, machine_check_exception) 294 295 /* Data Storage Interrupt */ 296 DATA_STORAGE_EXCEPTION 297 298 /* Instruction Storage Interrupt */ 299 INSTRUCTION_STORAGE_EXCEPTION 300 301 /* External Input Interrupt */ 302 EXCEPTION(0x0500, ExternalInput, do_IRQ, EXC_XFER_LITE) 303 304 /* Alignment Interrupt */ 305 ALIGNMENT_EXCEPTION 306 307 /* Program Interrupt */ 308 PROGRAM_EXCEPTION 309 310 /* Floating Point Unavailable Interrupt */ 311#ifdef CONFIG_PPC_FPU 312 FP_UNAVAILABLE_EXCEPTION 313#else 314 EXCEPTION(0x2010, FloatingPointUnavailable, unknown_exception, EXC_XFER_EE) 315#endif 316 /* System Call Interrupt */ 317 START_EXCEPTION(SystemCall) 318 NORMAL_EXCEPTION_PROLOG 319 EXC_XFER_EE_LITE(0x0c00, DoSyscall) 320 321 /* Auxillary Processor Unavailable Interrupt */ 322 EXCEPTION(0x2020, AuxillaryProcessorUnavailable, unknown_exception, EXC_XFER_EE) 323 324 /* Decrementer Interrupt */ 325 DECREMENTER_EXCEPTION 326 327 /* Fixed Internal Timer Interrupt */ 328 /* TODO: Add FIT support */ 329 EXCEPTION(0x1010, FixedIntervalTimer, unknown_exception, EXC_XFER_EE) 330 331 /* Watchdog Timer Interrupt */ 332 /* TODO: Add watchdog support */ 333#ifdef CONFIG_BOOKE_WDT 334 CRITICAL_EXCEPTION(0x1020, WatchdogTimer, WatchdogException) 335#else 336 CRITICAL_EXCEPTION(0x1020, WatchdogTimer, unknown_exception) 337#endif 338 339 /* Data TLB Error Interrupt */ 340 START_EXCEPTION(DataTLBError) 341 mtspr SPRN_SPRG0, r10 /* Save some working registers */ 342 mtspr SPRN_SPRG1, r11 343 mtspr SPRN_SPRG4W, r12 344 mtspr SPRN_SPRG5W, r13 345 mfcr r11 346 mtspr SPRN_SPRG7W, r11 347 mfspr r10, SPRN_DEAR /* Get faulting address */ 348 349 /* If we are faulting a kernel address, we have to use the 350 * kernel page tables. 351 */ 352 lis r11, PAGE_OFFSET@h 353 cmplw r10, r11 354 blt+ 3f 355 lis r11, swapper_pg_dir@h 356 ori r11, r11, swapper_pg_dir@l 357 358 mfspr r12,SPRN_MMUCR 359 rlwinm r12,r12,0,0,23 /* Clear TID */ 360 361 b 4f 362 363 /* Get the PGD for the current thread */ 3643: 365 mfspr r11,SPRN_SPRG3 366 lwz r11,PGDIR(r11) 367 368 /* Load PID into MMUCR TID */ 369 mfspr r12,SPRN_MMUCR 370 mfspr r13,SPRN_PID /* Get PID */ 371 rlwimi r12,r13,0,24,31 /* Set TID */ 372 3734: 374 mtspr SPRN_MMUCR,r12 375 376 /* Mask of required permission bits. Note that while we 377 * do copy ESR:ST to _PAGE_RW position as trying to write 378 * to an RO page is pretty common, we don't do it with 379 * _PAGE_DIRTY. We could do it, but it's a fairly rare 380 * event so I'd rather take the overhead when it happens 381 * rather than adding an instruction here. We should measure 382 * whether the whole thing is worth it in the first place 383 * as we could avoid loading SPRN_ESR completely in the first 384 * place... 385 * 386 * TODO: Is it worth doing that mfspr & rlwimi in the first 387 * place or can we save a couple of instructions here ? 388 */ 389 mfspr r12,SPRN_ESR 390 li r13,_PAGE_PRESENT|_PAGE_ACCESSED 391 rlwimi r13,r12,10,30,30 392 393 /* Load the PTE */ 394 rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */ 395 lwzx r11, r12, r11 /* Get pgd/pmd entry */ 396 rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */ 397 beq 2f /* Bail if no table */ 398 399 rlwimi r12, r10, 23, 20, 28 /* Compute pte address */ 400 lwz r11, 0(r12) /* Get high word of pte entry */ 401 lwz r12, 4(r12) /* Get low word of pte entry */ 402 403 lis r10,tlb_44x_index@ha 404 405 andc. r13,r13,r12 /* Check permission */ 406 407 /* Load the next available TLB index */ 408 lwz r13,tlb_44x_index@l(r10) 409 410 bne 2f /* Bail if permission mismach */ 411 412 /* Increment, rollover, and store TLB index */ 413 addi r13,r13,1 414 415 /* Compare with watermark (instruction gets patched) */ 416 .globl tlb_44x_patch_hwater_D 417tlb_44x_patch_hwater_D: 418 cmpwi 0,r13,1 /* reserve entries */ 419 ble 5f 420 li r13,0 4215: 422 /* Store the next available TLB index */ 423 stw r13,tlb_44x_index@l(r10) 424 425 /* Re-load the faulting address */ 426 mfspr r10,SPRN_DEAR 427 428 /* Jump to common tlb load */ 429 b finish_tlb_load 430 4312: 432 /* The bailout. Restore registers to pre-exception conditions 433 * and call the heavyweights to help us out. 434 */ 435 mfspr r11, SPRN_SPRG7R 436 mtcr r11 437 mfspr r13, SPRN_SPRG5R 438 mfspr r12, SPRN_SPRG4R 439 mfspr r11, SPRN_SPRG1 440 mfspr r10, SPRN_SPRG0 441 b DataStorage 442 443 /* Instruction TLB Error Interrupt */ 444 /* 445 * Nearly the same as above, except we get our 446 * information from different registers and bailout 447 * to a different point. 448 */ 449 START_EXCEPTION(InstructionTLBError) 450 mtspr SPRN_SPRG0, r10 /* Save some working registers */ 451 mtspr SPRN_SPRG1, r11 452 mtspr SPRN_SPRG4W, r12 453 mtspr SPRN_SPRG5W, r13 454 mfcr r11 455 mtspr SPRN_SPRG7W, r11 456 mfspr r10, SPRN_SRR0 /* Get faulting address */ 457 458 /* If we are faulting a kernel address, we have to use the 459 * kernel page tables. 460 */ 461 lis r11, PAGE_OFFSET@h 462 cmplw r10, r11 463 blt+ 3f 464 lis r11, swapper_pg_dir@h 465 ori r11, r11, swapper_pg_dir@l 466 467 mfspr r12,SPRN_MMUCR 468 rlwinm r12,r12,0,0,23 /* Clear TID */ 469 470 b 4f 471 472 /* Get the PGD for the current thread */ 4733: 474 mfspr r11,SPRN_SPRG3 475 lwz r11,PGDIR(r11) 476 477 /* Load PID into MMUCR TID */ 478 mfspr r12,SPRN_MMUCR 479 mfspr r13,SPRN_PID /* Get PID */ 480 rlwimi r12,r13,0,24,31 /* Set TID */ 481 4824: 483 mtspr SPRN_MMUCR,r12 484 485 /* Make up the required permissions */ 486 li r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_HWEXEC 487 488 rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */ 489 lwzx r11, r12, r11 /* Get pgd/pmd entry */ 490 rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */ 491 beq 2f /* Bail if no table */ 492 493 rlwimi r12, r10, 23, 20, 28 /* Compute pte address */ 494 lwz r11, 0(r12) /* Get high word of pte entry */ 495 lwz r12, 4(r12) /* Get low word of pte entry */ 496 497 lis r10,tlb_44x_index@ha 498 499 andc. r13,r13,r12 /* Check permission */ 500 501 /* Load the next available TLB index */ 502 lwz r13,tlb_44x_index@l(r10) 503 504 bne 2f /* Bail if permission mismach */ 505 506 /* Increment, rollover, and store TLB index */ 507 addi r13,r13,1 508 509 /* Compare with watermark (instruction gets patched) */ 510 .globl tlb_44x_patch_hwater_I 511tlb_44x_patch_hwater_I: 512 cmpwi 0,r13,1 /* reserve entries */ 513 ble 5f 514 li r13,0 5155: 516 /* Store the next available TLB index */ 517 stw r13,tlb_44x_index@l(r10) 518 519 /* Re-load the faulting address */ 520 mfspr r10,SPRN_SRR0 521 522 /* Jump to common TLB load point */ 523 b finish_tlb_load 524 5252: 526 /* The bailout. Restore registers to pre-exception conditions 527 * and call the heavyweights to help us out. 528 */ 529 mfspr r11, SPRN_SPRG7R 530 mtcr r11 531 mfspr r13, SPRN_SPRG5R 532 mfspr r12, SPRN_SPRG4R 533 mfspr r11, SPRN_SPRG1 534 mfspr r10, SPRN_SPRG0 535 b InstructionStorage 536 537 /* Debug Interrupt */ 538 DEBUG_CRIT_EXCEPTION 539 540/* 541 * Local functions 542 */ 543 544/* 545 546 * Both the instruction and data TLB miss get to this 547 * point to load the TLB. 548 * r10 - EA of fault 549 * r11 - PTE high word value 550 * r12 - PTE low word value 551 * r13 - TLB index 552 * MMUCR - loaded with proper value when we get here 553 * Upon exit, we reload everything and RFI. 554 */ 555finish_tlb_load: 556 /* Combine RPN & ERPN an write WS 0 */ 557 rlwimi r11,r12,0,0,19 558 tlbwe r11,r13,PPC44x_TLB_XLAT 559 560 /* 561 * Create WS1. This is the faulting address (EPN), 562 * page size, and valid flag. 563 */ 564 li r11,PPC44x_TLB_VALID | PPC44x_TLB_4K 565 rlwimi r10,r11,0,20,31 /* Insert valid and page size*/ 566 tlbwe r10,r13,PPC44x_TLB_PAGEID /* Write PAGEID */ 567 568 /* And WS 2 */ 569 li r10,0xf85 /* Mask to apply from PTE */ 570 rlwimi r10,r12,29,30,30 /* DIRTY -> SW position */ 571 and r11,r12,r10 /* Mask PTE bits to keep */ 572 andi. r10,r12,_PAGE_USER /* User page ? */ 573 beq 1f /* nope, leave U bits empty */ 574 rlwimi r11,r11,3,26,28 /* yes, copy S bits to U */ 5751: tlbwe r11,r13,PPC44x_TLB_ATTRIB /* Write ATTRIB */ 576 577 /* Done...restore registers and get out of here. 578 */ 579 mfspr r11, SPRN_SPRG7R 580 mtcr r11 581 mfspr r13, SPRN_SPRG5R 582 mfspr r12, SPRN_SPRG4R 583 mfspr r11, SPRN_SPRG1 584 mfspr r10, SPRN_SPRG0 585 rfi /* Force context change */ 586 587/* 588 * Global functions 589 */ 590 591/* 592 * Adjust the machine check IVOR on 440A cores 593 */ 594_GLOBAL(__fixup_440A_mcheck) 595 li r3,MachineCheckA@l 596 mtspr SPRN_IVOR1,r3 597 sync 598 blr 599 600/* 601 * extern void giveup_altivec(struct task_struct *prev) 602 * 603 * The 44x core does not have an AltiVec unit. 604 */ 605_GLOBAL(giveup_altivec) 606 blr 607 608/* 609 * extern void giveup_fpu(struct task_struct *prev) 610 * 611 * The 44x core does not have an FPU. 612 */ 613#ifndef CONFIG_PPC_FPU 614_GLOBAL(giveup_fpu) 615 blr 616#endif 617 618_GLOBAL(set_context) 619 620#ifdef CONFIG_BDI_SWITCH 621 /* Context switch the PTE pointer for the Abatron BDI2000. 622 * The PGDIR is the second parameter. 623 */ 624 lis r5, abatron_pteptrs@h 625 ori r5, r5, abatron_pteptrs@l 626 stw r4, 0x4(r5) 627#endif 628 mtspr SPRN_PID,r3 629 isync /* Force context change */ 630 blr 631 632/* 633 * We put a few things here that have to be page-aligned. This stuff 634 * goes at the beginning of the data segment, which is page-aligned. 635 */ 636 .data 637 .align 12 638 .globl sdata 639sdata: 640 .globl empty_zero_page 641empty_zero_page: 642 .space 4096 643 644/* 645 * To support >32-bit physical addresses, we use an 8KB pgdir. 646 */ 647 .globl swapper_pg_dir 648swapper_pg_dir: 649 .space PGD_TABLE_SIZE 650 651/* 652 * Room for two PTE pointers, usually the kernel and current user pointers 653 * to their respective root page table. 654 */ 655abatron_pteptrs: 656 .space 8 657