0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #include <linux/init.h>
0029 #include <linux/pgtable.h>
0030 #include <linux/sizes.h>
0031 #include <asm/processor.h>
0032 #include <asm/page.h>
0033 #include <asm/mmu.h>
0034 #include <asm/cputable.h>
0035 #include <asm/thread_info.h>
0036 #include <asm/ppc_asm.h>
0037 #include <asm/asm-offsets.h>
0038 #include <asm/ptrace.h>
0039 #include <asm/export.h>
0040
0041 #include "head_32.h"
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055 __HEAD
0056 _GLOBAL(_stext);
0057 _GLOBAL(_start);
0058
0059 mr r31,r3
0060
0061
0062
0063
0064 bl initial_mmu
0065
0066
0067
0068
0069 turn_on_mmu:
0070 lis r0,MSR_KERNEL@h
0071 ori r0,r0,MSR_KERNEL@l
0072 mtspr SPRN_SRR1,r0
0073 lis r0,start_here@h
0074 ori r0,r0,start_here@l
0075 mtspr SPRN_SRR0,r0
0076 rfi
0077 b .
0078
0079
0080
0081
0082
0083 . = 0xc0
0084 crit_save:
0085 _GLOBAL(crit_r10)
0086 .space 4
0087 _GLOBAL(crit_r11)
0088 .space 4
0089 _GLOBAL(crit_srr0)
0090 .space 4
0091 _GLOBAL(crit_srr1)
0092 .space 4
0093 _GLOBAL(crit_r1)
0094 .space 4
0095 _GLOBAL(crit_dear)
0096 .space 4
0097 _GLOBAL(crit_esr)
0098 .space 4
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108 .macro CRITICAL_EXCEPTION_PROLOG trapno name
0109 stw r10,crit_r10@l(0)
0110 stw r11,crit_r11@l(0)
0111 mfspr r10,SPRN_SRR0
0112 mfspr r11,SPRN_SRR1
0113 stw r10,crit_srr0@l(0)
0114 stw r11,crit_srr1@l(0)
0115 mfspr r10,SPRN_DEAR
0116 mfspr r11,SPRN_ESR
0117 stw r10,crit_dear@l(0)
0118 stw r11,crit_esr@l(0)
0119 mfcr r10
0120 mfspr r11,SPRN_SRR3
0121 andi. r11,r11,MSR_PR
0122 lis r11,(critirq_ctx-PAGE_OFFSET)@ha
0123 lwz r11,(critirq_ctx-PAGE_OFFSET)@l(r11)
0124 beq 1f
0125
0126 mfspr r11,SPRN_SPRG_THREAD
0127 lwz r11,TASK_STACK-THREAD(r11)
0128 1: stw r1,crit_r1@l(0)
0129 addi r1,r11,THREAD_SIZE-INT_FRAME_SIZE
0130 LOAD_REG_IMMEDIATE(r11, MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE))
0131 mtspr SPRN_SRR1, r11
0132 lis r11, 1f@h
0133 ori r11, r11, 1f@l
0134 mtspr SPRN_SRR0, r11
0135 rfi
0136
0137 .text
0138 1:
0139 \name\()_virt:
0140 lwz r11,crit_r1@l(0)
0141 stw r11,GPR1(r1)
0142 stw r11,0(r1)
0143 mr r11,r1
0144 stw r10,_CCR(r11)
0145 stw r12,GPR12(r11)
0146 stw r9,GPR9(r11)
0147 mflr r10
0148 stw r10,_LINK(r11)
0149 lis r9,PAGE_OFFSET@ha
0150 lwz r10,crit_r10@l(r9)
0151 lwz r12,crit_r11@l(r9)
0152 stw r10,GPR10(r11)
0153 stw r12,GPR11(r11)
0154 lwz r12,crit_dear@l(r9)
0155 lwz r9,crit_esr@l(r9)
0156 stw r12,_DEAR(r11)
0157 stw r9,_ESR(r11)
0158 mfspr r12,SPRN_SRR2
0159 mfspr r9,SPRN_SRR3
0160 rlwinm r9,r9,0,14,12
0161 COMMON_EXCEPTION_PROLOG_END \trapno + 2
0162 _ASM_NOKPROBE_SYMBOL(\name\()_virt)
0163 .endm
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181 #define CRITICAL_EXCEPTION(n, label, hdlr) \
0182 START_EXCEPTION(n, label); \
0183 CRITICAL_EXCEPTION_PROLOG n label; \
0184 prepare_transfer_to_handler; \
0185 bl hdlr; \
0186 b ret_from_crit_exc
0187
0188
0189
0190
0191 CRITICAL_EXCEPTION(0x0100, CriticalInterrupt, unknown_exception)
0192
0193
0194
0195
0196 CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
0197
0198
0199
0200
0201
0202
0203
0204
0205 START_EXCEPTION(0x0300, DataStorage)
0206 EXCEPTION_PROLOG 0x300 DataStorage handle_dar_dsisr=1
0207 prepare_transfer_to_handler
0208 bl do_page_fault
0209 b interrupt_return
0210
0211
0212
0213
0214
0215 START_EXCEPTION(0x0400, InstructionAccess)
0216 EXCEPTION_PROLOG 0x400 InstructionAccess
0217 li r5,0
0218 stw r5, _ESR(r11)
0219 stw r12, _DEAR(r11)
0220 prepare_transfer_to_handler
0221 bl do_page_fault
0222 b interrupt_return
0223
0224
0225 EXCEPTION(0x0500, HardwareInterrupt, do_IRQ)
0226
0227
0228 START_EXCEPTION(0x0600, Alignment)
0229 EXCEPTION_PROLOG 0x600 Alignment handle_dar_dsisr=1
0230 prepare_transfer_to_handler
0231 bl alignment_exception
0232 REST_NVGPRS(r1)
0233 b interrupt_return
0234
0235
0236 START_EXCEPTION(0x0700, ProgramCheck)
0237 EXCEPTION_PROLOG 0x700 ProgramCheck handle_dar_dsisr=1
0238 prepare_transfer_to_handler
0239 bl program_check_exception
0240 REST_NVGPRS(r1)
0241 b interrupt_return
0242
0243 EXCEPTION(0x0800, Trap_08, unknown_exception)
0244 EXCEPTION(0x0900, Trap_09, unknown_exception)
0245 EXCEPTION(0x0A00, Trap_0A, unknown_exception)
0246 EXCEPTION(0x0B00, Trap_0B, unknown_exception)
0247
0248
0249 START_EXCEPTION(0x0C00, SystemCall)
0250 SYSCALL_ENTRY 0xc00
0251
0252
0253
0254 EXCEPTION(0x0E00, Trap_0E, unknown_exception)
0255 EXCEPTION(0x0F00, Trap_0F, unknown_exception)
0256
0257
0258 START_EXCEPTION(0x1000, DecrementerTrap)
0259 b Decrementer
0260
0261
0262 START_EXCEPTION(0x1010, FITExceptionTrap)
0263 b FITException
0264
0265
0266 START_EXCEPTION(0x1020, WDTExceptionTrap)
0267 b WDTException
0268
0269
0270
0271
0272
0273
0274 START_EXCEPTION(0x1100, DTLBMiss)
0275 mtspr SPRN_SPRG_SCRATCH5, r10
0276 mtspr SPRN_SPRG_SCRATCH6, r11
0277 mtspr SPRN_SPRG_SCRATCH3, r12
0278 mtspr SPRN_SPRG_SCRATCH4, r9
0279 mfcr r12
0280 mfspr r9, SPRN_PID
0281 rlwimi r12, r9, 0, 0xff
0282 mfspr r10, SPRN_DEAR
0283
0284
0285
0286
0287 lis r11, PAGE_OFFSET@h
0288 cmplw r10, r11
0289 blt+ 3f
0290 lis r11, swapper_pg_dir@h
0291 ori r11, r11, swapper_pg_dir@l
0292 li r9, 0
0293 mtspr SPRN_PID, r9
0294 b 4f
0295
0296
0297
0298 3:
0299 mfspr r11,SPRN_SPRG_THREAD
0300 lwz r11,PGDIR(r11)
0301 #ifdef CONFIG_PPC_KUAP
0302 rlwinm. r9, r9, 0, 0xff
0303 beq 5f
0304 #endif
0305 4:
0306 tophys(r11, r11)
0307 rlwimi r11, r10, 12, 20, 29
0308 lwz r11, 0(r11)
0309 andi. r9, r11, _PMD_PRESENT
0310 beq 2f
0311
0312 rlwimi r11, r10, 22, 20, 29
0313 lwz r11, 0(r11)
0314 li r9, _PAGE_PRESENT | _PAGE_ACCESSED
0315 andc. r9, r9, r11
0316 bne 5f
0317
0318 rlwinm r9, r11, 1, _PAGE_RW
0319 and r9, r9, r11
0320 rlwimi r11, r9, 0, _PAGE_RW
0321
0322
0323
0324
0325 li r9, 0x00c0
0326 rlwimi r10, r9, 0, 20, 31
0327
0328 b finish_tlb_load
0329
0330 2:
0331 rlwinm. r9, r11, 2, 22, 24
0332 beq 5f
0333
0334
0335
0336
0337 ori r9, r9, 0x40
0338 rlwimi r10, r9, 0, 20, 31
0339
0340 b finish_tlb_load
0341
0342 5:
0343
0344
0345
0346 mtspr SPRN_PID, r12
0347 mtcrf 0x80, r12
0348 mfspr r9, SPRN_SPRG_SCRATCH4
0349 mfspr r12, SPRN_SPRG_SCRATCH3
0350 mfspr r11, SPRN_SPRG_SCRATCH6
0351 mfspr r10, SPRN_SPRG_SCRATCH5
0352 b DataStorage
0353
0354
0355
0356
0357
0358 START_EXCEPTION(0x1200, ITLBMiss)
0359 mtspr SPRN_SPRG_SCRATCH5, r10
0360 mtspr SPRN_SPRG_SCRATCH6, r11
0361 mtspr SPRN_SPRG_SCRATCH3, r12
0362 mtspr SPRN_SPRG_SCRATCH4, r9
0363 mfcr r12
0364 mfspr r9, SPRN_PID
0365 rlwimi r12, r9, 0, 0xff
0366 mfspr r10, SPRN_SRR0
0367
0368
0369
0370
0371 lis r11, PAGE_OFFSET@h
0372 cmplw r10, r11
0373 blt+ 3f
0374 lis r11, swapper_pg_dir@h
0375 ori r11, r11, swapper_pg_dir@l
0376 li r9, 0
0377 mtspr SPRN_PID, r9
0378 b 4f
0379
0380
0381
0382 3:
0383 mfspr r11,SPRN_SPRG_THREAD
0384 lwz r11,PGDIR(r11)
0385 #ifdef CONFIG_PPC_KUAP
0386 rlwinm. r9, r9, 0, 0xff
0387 beq 5f
0388 #endif
0389 4:
0390 tophys(r11, r11)
0391 rlwimi r11, r10, 12, 20, 29
0392 lwz r11, 0(r11)
0393 andi. r9, r11, _PMD_PRESENT
0394 beq 2f
0395
0396 rlwimi r11, r10, 22, 20, 29
0397 lwz r11, 0(r11)
0398 li r9, _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
0399 andc. r9, r9, r11
0400 bne 5f
0401
0402 rlwinm r9, r11, 1, _PAGE_RW
0403 and r9, r9, r11
0404 rlwimi r11, r9, 0, _PAGE_RW
0405
0406
0407
0408
0409 li r9, 0x00c0
0410 rlwimi r10, r9, 0, 20, 31
0411
0412 b finish_tlb_load
0413
0414 2:
0415 rlwinm. r9, r11, 2, 22, 24
0416 beq 5f
0417
0418
0419
0420
0421 ori r9, r9, 0x40
0422 rlwimi r10, r9, 0, 20, 31
0423
0424 b finish_tlb_load
0425
0426 5:
0427
0428
0429
0430 mtspr SPRN_PID, r12
0431 mtcrf 0x80, r12
0432 mfspr r9, SPRN_SPRG_SCRATCH4
0433 mfspr r12, SPRN_SPRG_SCRATCH3
0434 mfspr r11, SPRN_SPRG_SCRATCH6
0435 mfspr r10, SPRN_SPRG_SCRATCH5
0436 b InstructionAccess
0437
0438 EXCEPTION(0x1300, Trap_13, unknown_exception)
0439 EXCEPTION(0x1400, Trap_14, unknown_exception)
0440 EXCEPTION(0x1500, Trap_15, unknown_exception)
0441 EXCEPTION(0x1600, Trap_16, unknown_exception)
0442 EXCEPTION(0x1700, Trap_17, unknown_exception)
0443 EXCEPTION(0x1800, Trap_18, unknown_exception)
0444 EXCEPTION(0x1900, Trap_19, unknown_exception)
0445 EXCEPTION(0x1A00, Trap_1A, unknown_exception)
0446 EXCEPTION(0x1B00, Trap_1B, unknown_exception)
0447 EXCEPTION(0x1C00, Trap_1C, unknown_exception)
0448 EXCEPTION(0x1D00, Trap_1D, unknown_exception)
0449 EXCEPTION(0x1E00, Trap_1E, unknown_exception)
0450 EXCEPTION(0x1F00, Trap_1F, unknown_exception)
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466 START_EXCEPTION(0x2000, DebugTrap)
0467 CRITICAL_EXCEPTION_PROLOG 0x2000 DebugTrap
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477 mfspr r10,SPRN_DBSR
0478 andis. r10,r10,DBSR_IC@h
0479 beq+ 2f
0480
0481 andi. r10,r9,MSR_IR|MSR_PR
0482 beq 1f
0483
0484 mfspr r10,SPRN_SRR2
0485 cmplwi r10,0x2100
0486 bgt+ 2f
0487
0488
0489 1: rlwinm r9,r9,0,~MSR_DE
0490 lis r10,DBSR_IC@h
0491 mtspr SPRN_DBSR,r10
0492
0493 lwz r10,_CCR(r11)
0494 lwz r0,GPR0(r11)
0495 lwz r1,GPR1(r11)
0496 mtcrf 0x80,r10
0497 mtspr SPRN_SRR2,r12
0498 mtspr SPRN_SRR3,r9
0499 lwz r9,GPR9(r11)
0500 lwz r12,GPR12(r11)
0501 lwz r10,crit_r10@l(0)
0502 lwz r11,crit_r11@l(0)
0503 rfci
0504 b .
0505
0506
0507 2: mfspr r4,SPRN_DBSR
0508 stw r4,_ESR(r11)
0509 prepare_transfer_to_handler
0510 bl DebugException
0511 b ret_from_crit_exc
0512
0513
0514 __HEAD
0515 Decrementer:
0516 EXCEPTION_PROLOG 0x1000 Decrementer
0517 lis r0,TSR_PIS@h
0518 mtspr SPRN_TSR,r0
0519 prepare_transfer_to_handler
0520 bl timer_interrupt
0521 b interrupt_return
0522
0523
0524 __HEAD
0525 FITException:
0526 EXCEPTION_PROLOG 0x1010 FITException
0527 prepare_transfer_to_handler
0528 bl unknown_exception
0529 b interrupt_return
0530
0531
0532 __HEAD
0533 WDTException:
0534 CRITICAL_EXCEPTION_PROLOG 0x1020 WDTException
0535 prepare_transfer_to_handler
0536 bl WatchdogException
0537 b ret_from_crit_exc
0538
0539
0540
0541
0542
0543
0544
0545 __HEAD
0546
0547
0548
0549
0550
0551
0552
0553
0554
0555
0556
0557 tlb_4xx_index:
0558 .long 0
0559 finish_tlb_load:
0560
0561
0562
0563
0564
0565 li r9, 0x0ce2
0566 andc r11, r11, r9
0567
0568
0569 lwz r9, tlb_4xx_index@l(0)
0570 addi r9, r9, 1
0571 andi. r9, r9, PPC40X_TLB_SIZE - 1
0572 stw r9, tlb_4xx_index@l(0)
0573
0574 tlbwe r11, r9, TLB_DATA
0575 tlbwe r10, r9, TLB_TAG
0576
0577
0578
0579 mtspr SPRN_PID, r12
0580 mtcrf 0x80, r12
0581 mfspr r9, SPRN_SPRG_SCRATCH4
0582 mfspr r12, SPRN_SPRG_SCRATCH3
0583 mfspr r11, SPRN_SPRG_SCRATCH6
0584 mfspr r10, SPRN_SPRG_SCRATCH5
0585 rfi
0586 b .
0587
0588
0589
0590 start_here:
0591
0592
0593 lis r2,init_task@h
0594 ori r2,r2,init_task@l
0595
0596
0597 tophys(r4,r2)
0598 addi r4,r4,THREAD
0599 mtspr SPRN_SPRG_THREAD,r4
0600
0601
0602 lis r1,init_thread_union@ha
0603 addi r1,r1,init_thread_union@l
0604 li r0,0
0605 stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
0606
0607 bl early_init
0608
0609
0610
0611
0612 #ifdef CONFIG_KASAN
0613 bl kasan_early_init
0614 #endif
0615 li r3,0
0616 mr r4,r31
0617 bl machine_init
0618 bl MMU_init
0619
0620
0621
0622
0623
0624
0625 lis r4,2f@h
0626 ori r4,r4,2f@l
0627 tophys(r4,r4)
0628 lis r3,(MSR_KERNEL & ~(MSR_IR|MSR_DR))@h
0629 ori r3,r3,(MSR_KERNEL & ~(MSR_IR|MSR_DR))@l
0630 mtspr SPRN_SRR0,r4
0631 mtspr SPRN_SRR1,r3
0632 rfi
0633 b .
0634
0635
0636 2:
0637 sync
0638 tlbia
0639 isync
0640
0641
0642
0643 lis r6, swapper_pg_dir@h
0644 ori r6, r6, swapper_pg_dir@l
0645 lis r5, abatron_pteptrs@h
0646 ori r5, r5, abatron_pteptrs@l
0647 stw r5, 0xf0(0)
0648 tophys(r5,r5)
0649 stw r6, 0(r5)
0650
0651
0652 lis r4,MSR_KERNEL@h
0653 ori r4,r4,MSR_KERNEL@l
0654 lis r3,start_kernel@h
0655 ori r3,r3,start_kernel@l
0656 mtspr SPRN_SRR0,r3
0657 mtspr SPRN_SRR1,r4
0658 rfi
0659 b .
0660
0661
0662
0663
0664
0665 initial_mmu:
0666 tlbia
0667 isync
0668
0669
0670
0671
0672
0673
0674
0675 lis r3,KERNELBASE@h
0676 ori r3,r3,KERNELBASE@l
0677 tophys(r4,r3)
0678
0679 iccci r0,r3
0680
0681
0682
0683 li r0,0
0684 mtspr SPRN_PID,r0
0685 sync
0686
0687
0688 clrrwi r4,r4,10
0689 ori r4,r4,(TLB_WR | TLB_EX)
0690
0691 clrrwi r3,r3,10
0692 ori r3,r3,(TLB_VALID | TLB_PAGESZ(PAGESZ_16M))
0693
0694 li r0,63
0695
0696 tlbwe r4,r0,TLB_DATA
0697 tlbwe r3,r0,TLB_TAG
0698
0699 li r0,62
0700 addis r4,r4,SZ_16M@h
0701 addis r3,r3,SZ_16M@h
0702 tlbwe r4,r0,TLB_DATA
0703 tlbwe r3,r0,TLB_TAG
0704
0705 isync
0706
0707
0708
0709 lis r4,KERNELBASE@h
0710 tophys(r0,r4)
0711 mtspr SPRN_EVPR,r0
0712
0713 blr
0714
0715 _GLOBAL(abort)
0716 mfspr r13,SPRN_DBCR0
0717 oris r13,r13,DBCR0_RST_SYSTEM@h
0718 mtspr SPRN_DBCR0,r13