.. | .. |
---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-or-later */ |
---|
1 | 2 | /* |
---|
2 | 3 | * Kernel execution entry point code. |
---|
3 | 4 | * |
---|
.. | .. |
---|
23 | 24 | * PowerPC 44x support, Matt Porter <mporter@kernel.crashing.org> |
---|
24 | 25 | * Copyright 2004 Freescale Semiconductor, Inc |
---|
25 | 26 | * PowerPC e500 modifications, Kumar Gala <galak@kernel.crashing.org> |
---|
26 | | - * |
---|
27 | | - * This program is free software; you can redistribute it and/or modify it |
---|
28 | | - * under the terms of the GNU General Public License as published by the |
---|
29 | | - * Free Software Foundation; either version 2 of the License, or (at your |
---|
30 | | - * option) any later version. |
---|
31 | 27 | */ |
---|
32 | 28 | |
---|
33 | 29 | #include <linux/init.h> |
---|
34 | 30 | #include <linux/threads.h> |
---|
| 31 | +#include <linux/pgtable.h> |
---|
35 | 32 | #include <asm/processor.h> |
---|
36 | 33 | #include <asm/page.h> |
---|
37 | 34 | #include <asm/mmu.h> |
---|
38 | | -#include <asm/pgtable.h> |
---|
39 | 35 | #include <asm/cputable.h> |
---|
40 | 36 | #include <asm/thread_info.h> |
---|
41 | 37 | #include <asm/ppc_asm.h> |
---|
.. | .. |
---|
159 | 155 | */ |
---|
160 | 156 | |
---|
161 | 157 | _ENTRY(__early_start) |
---|
| 158 | + LOAD_REG_ADDR_PIC(r20, kernstart_virt_addr) |
---|
| 159 | + lwz r20,0(r20) |
---|
162 | 160 | |
---|
163 | 161 | #define ENTRY_MAPPING_BOOT_SETUP |
---|
164 | 162 | #include "fsl_booke_entry_mapping.S" |
---|
.. | .. |
---|
193 | 191 | oris r2,r2,MAS4_TLBSELD(1)@h |
---|
194 | 192 | #endif |
---|
195 | 193 | mtspr SPRN_MAS4, r2 |
---|
196 | | - |
---|
197 | | -#if 0 |
---|
198 | | - /* Enable DOZE */ |
---|
199 | | - mfspr r2,SPRN_HID0 |
---|
200 | | - oris r2,r2,HID0_DOZE@h |
---|
201 | | - mtspr SPRN_HID0, r2 |
---|
202 | | -#endif |
---|
203 | 194 | |
---|
204 | 195 | #if !defined(CONFIG_BDI_SWITCH) |
---|
205 | 196 | /* |
---|
.. | .. |
---|
243 | 234 | li r0,0 |
---|
244 | 235 | stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1) |
---|
245 | 236 | |
---|
246 | | - CURRENT_THREAD_INFO(r22, r1) |
---|
247 | | - stw r24, TI_CPU(r22) |
---|
| 237 | +#ifdef CONFIG_SMP |
---|
| 238 | + stw r24, TASK_CPU(r2) |
---|
| 239 | +#endif |
---|
248 | 240 | |
---|
249 | 241 | bl early_init |
---|
250 | 242 | |
---|
| 243 | +#ifdef CONFIG_KASAN |
---|
| 244 | + bl kasan_early_init |
---|
| 245 | +#endif |
---|
251 | 246 | #ifdef CONFIG_RELOCATABLE |
---|
252 | 247 | mr r3,r30 |
---|
253 | 248 | mr r4,r31 |
---|
.. | .. |
---|
284 | 279 | ori r6, r6, swapper_pg_dir@l |
---|
285 | 280 | lis r5, abatron_pteptrs@h |
---|
286 | 281 | ori r5, r5, abatron_pteptrs@l |
---|
287 | | - lis r4, KERNELBASE@h |
---|
288 | | - ori r4, r4, KERNELBASE@l |
---|
| 282 | + lis r3, kernstart_virt_addr@ha |
---|
| 283 | + lwz r4, kernstart_virt_addr@l(r3) |
---|
289 | 284 | stw r5, 0(r4) /* Save abatron_pteptrs at a fixed location */ |
---|
290 | 285 | stw r6, 0(r5) |
---|
291 | 286 | |
---|
.. | .. |
---|
383 | 378 | mfspr r4,SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */ |
---|
384 | 379 | andis. r10,r5,(ESR_ILK|ESR_DLK)@h |
---|
385 | 380 | bne 1f |
---|
| 381 | + stw r4, _DEAR(r11) |
---|
386 | 382 | EXC_XFER_LITE(0x0300, handle_page_fault) |
---|
387 | 383 | 1: |
---|
388 | 384 | addi r3,r1,STACK_FRAME_OVERHEAD |
---|
389 | | - EXC_XFER_EE_LITE(0x0300, CacheLockingException) |
---|
| 385 | + EXC_XFER_LITE(0x0300, CacheLockingException) |
---|
390 | 386 | |
---|
391 | 387 | /* Instruction Storage Interrupt */ |
---|
392 | 388 | INSTRUCTION_STORAGE_EXCEPTION |
---|
.. | .. |
---|
407 | 403 | #ifdef CONFIG_E200 |
---|
408 | 404 | /* E200 treats 'normal' floating point instructions as FP Unavail exception */ |
---|
409 | 405 | EXCEPTION(0x0800, FP_UNAVAIL, FloatingPointUnavailable, \ |
---|
410 | | - program_check_exception, EXC_XFER_EE) |
---|
| 406 | + program_check_exception, EXC_XFER_STD) |
---|
411 | 407 | #else |
---|
412 | 408 | EXCEPTION(0x0800, FP_UNAVAIL, FloatingPointUnavailable, \ |
---|
413 | | - unknown_exception, EXC_XFER_EE) |
---|
| 409 | + unknown_exception, EXC_XFER_STD) |
---|
414 | 410 | #endif |
---|
415 | 411 | #endif |
---|
416 | 412 | |
---|
417 | 413 | /* System Call Interrupt */ |
---|
418 | 414 | START_EXCEPTION(SystemCall) |
---|
419 | | - NORMAL_EXCEPTION_PROLOG(SYSCALL) |
---|
420 | | - EXC_XFER_EE_LITE(0x0c00, DoSyscall) |
---|
| 415 | + SYSCALL_ENTRY 0xc00 BOOKE_INTERRUPT_SYSCALL SPRN_SRR1 |
---|
421 | 416 | |
---|
422 | 417 | /* Auxiliary Processor Unavailable Interrupt */ |
---|
423 | 418 | EXCEPTION(0x2900, AP_UNAVAIL, AuxillaryProcessorUnavailable, \ |
---|
424 | | - unknown_exception, EXC_XFER_EE) |
---|
| 419 | + unknown_exception, EXC_XFER_STD) |
---|
425 | 420 | |
---|
426 | 421 | /* Decrementer Interrupt */ |
---|
427 | 422 | DECREMENTER_EXCEPTION |
---|
.. | .. |
---|
429 | 424 | /* Fixed Internal Timer Interrupt */ |
---|
430 | 425 | /* TODO: Add FIT support */ |
---|
431 | 426 | EXCEPTION(0x3100, FIT, FixedIntervalTimer, \ |
---|
432 | | - unknown_exception, EXC_XFER_EE) |
---|
| 427 | + unknown_exception, EXC_XFER_STD) |
---|
433 | 428 | |
---|
434 | 429 | /* Watchdog Timer Interrupt */ |
---|
435 | 430 | #ifdef CONFIG_BOOKE_WDT |
---|
.. | .. |
---|
639 | 634 | bl load_up_spe |
---|
640 | 635 | b fast_exception_return |
---|
641 | 636 | 1: addi r3,r1,STACK_FRAME_OVERHEAD |
---|
642 | | - EXC_XFER_EE_LITE(0x2010, KernelSPE) |
---|
| 637 | + EXC_XFER_LITE(0x2010, KernelSPE) |
---|
643 | 638 | #elif defined(CONFIG_SPE_POSSIBLE) |
---|
644 | 639 | EXCEPTION(0x2020, SPE_UNAVAIL, SPEUnavailable, \ |
---|
645 | | - unknown_exception, EXC_XFER_EE) |
---|
| 640 | + unknown_exception, EXC_XFER_STD) |
---|
646 | 641 | #endif /* CONFIG_SPE_POSSIBLE */ |
---|
647 | 642 | |
---|
648 | 643 | /* SPE Floating Point Data */ |
---|
649 | 644 | #ifdef CONFIG_SPE |
---|
650 | 645 | EXCEPTION(0x2030, SPE_FP_DATA, SPEFloatingPointData, |
---|
651 | | - SPEFloatingPointException, EXC_XFER_EE) |
---|
| 646 | + SPEFloatingPointException, EXC_XFER_STD) |
---|
652 | 647 | |
---|
653 | 648 | /* SPE Floating Point Round */ |
---|
654 | 649 | EXCEPTION(0x2050, SPE_FP_ROUND, SPEFloatingPointRound, \ |
---|
655 | | - SPEFloatingPointRoundException, EXC_XFER_EE) |
---|
| 650 | + SPEFloatingPointRoundException, EXC_XFER_STD) |
---|
656 | 651 | #elif defined(CONFIG_SPE_POSSIBLE) |
---|
657 | 652 | EXCEPTION(0x2040, SPE_FP_DATA, SPEFloatingPointData, |
---|
658 | | - unknown_exception, EXC_XFER_EE) |
---|
| 653 | + unknown_exception, EXC_XFER_STD) |
---|
659 | 654 | EXCEPTION(0x2050, SPE_FP_ROUND, SPEFloatingPointRound, \ |
---|
660 | | - unknown_exception, EXC_XFER_EE) |
---|
| 655 | + unknown_exception, EXC_XFER_STD) |
---|
661 | 656 | #endif /* CONFIG_SPE_POSSIBLE */ |
---|
662 | 657 | |
---|
663 | 658 | |
---|
.. | .. |
---|
680 | 675 | unknown_exception) |
---|
681 | 676 | |
---|
682 | 677 | /* Hypercall */ |
---|
683 | | - EXCEPTION(0, HV_SYSCALL, Hypercall, unknown_exception, EXC_XFER_EE) |
---|
| 678 | + EXCEPTION(0, HV_SYSCALL, Hypercall, unknown_exception, EXC_XFER_STD) |
---|
684 | 679 | |
---|
685 | 680 | /* Embedded Hypervisor Privilege */ |
---|
686 | | - EXCEPTION(0, HV_PRIV, Ehvpriv, unknown_exception, EXC_XFER_EE) |
---|
| 681 | + EXCEPTION(0, HV_PRIV, Ehvpriv, unknown_exception, EXC_XFER_STD) |
---|
687 | 682 | |
---|
688 | 683 | interrupt_end: |
---|
689 | 684 | |
---|
.. | .. |
---|
717 | 712 | |
---|
718 | 713 | /* Get the next_tlbcam_idx percpu var */ |
---|
719 | 714 | #ifdef CONFIG_SMP |
---|
720 | | - lwz r12, THREAD_INFO-THREAD(r12) |
---|
721 | | - lwz r15, TI_CPU(r12) |
---|
| 715 | + lwz r15, TASK_CPU-THREAD(r12) |
---|
722 | 716 | lis r14, __per_cpu_offset@h |
---|
723 | 717 | ori r14, r14, __per_cpu_offset@l |
---|
724 | 718 | rlwinm r15, r15, 2, 0, 29 |
---|
.. | .. |
---|
1076 | 1070 | mr r5,r25 /* phys kernel start */ |
---|
1077 | 1071 | rlwinm r5,r5,0,~0x3ffffff /* aligned 64M */ |
---|
1078 | 1072 | subf r4,r5,r4 /* memstart_addr - phys kernel start */ |
---|
1079 | | - li r5,0 /* no device tree */ |
---|
| 1073 | + lis r7,KERNELBASE@h |
---|
| 1074 | + ori r7,r7,KERNELBASE@l |
---|
| 1075 | + cmpw r20,r7 /* if kernstart_virt_addr != KERNELBASE, randomized */ |
---|
| 1076 | + beq 2f |
---|
| 1077 | + li r4,0 |
---|
| 1078 | +2: li r5,0 /* no device tree */ |
---|
1080 | 1079 | li r6,0 /* not boot cpu */ |
---|
1081 | 1080 | bl restore_to_as0 |
---|
1082 | 1081 | |
---|
.. | .. |
---|
1089 | 1088 | mr r4,r24 /* Why? */ |
---|
1090 | 1089 | bl call_setup_cpu |
---|
1091 | 1090 | |
---|
1092 | | - /* get current_thread_info and current */ |
---|
1093 | | - lis r1,secondary_ti@ha |
---|
1094 | | - lwz r1,secondary_ti@l(r1) |
---|
1095 | | - lwz r2,TI_TASK(r1) |
---|
| 1091 | + /* get current's stack and current */ |
---|
| 1092 | + lis r2,secondary_current@ha |
---|
| 1093 | + lwz r2,secondary_current@l(r2) |
---|
| 1094 | + lwz r1,TASK_STACK(r2) |
---|
1096 | 1095 | |
---|
1097 | 1096 | /* stack */ |
---|
1098 | 1097 | addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD |
---|
.. | .. |
---|
1124 | 1123 | #endif |
---|
1125 | 1124 | |
---|
1126 | 1125 | /* |
---|
| 1126 | + * Create a 64M tlb by address and entry |
---|
| 1127 | + * r3 - entry |
---|
| 1128 | + * r4 - virtual address |
---|
| 1129 | + * r5/r6 - physical address |
---|
| 1130 | + */ |
---|
| 1131 | +_GLOBAL(create_kaslr_tlb_entry) |
---|
| 1132 | + lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ |
---|
| 1133 | + rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r6) */ |
---|
| 1134 | + mtspr SPRN_MAS0,r7 /* Write MAS0 */ |
---|
| 1135 | + |
---|
| 1136 | + lis r3,(MAS1_VALID|MAS1_IPROT)@h |
---|
| 1137 | + ori r3,r3,(MAS1_TSIZE(BOOK3E_PAGESZ_64M))@l |
---|
| 1138 | + mtspr SPRN_MAS1,r3 /* Write MAS1 */ |
---|
| 1139 | + |
---|
| 1140 | + lis r3,MAS2_EPN_MASK(BOOK3E_PAGESZ_64M)@h |
---|
| 1141 | + ori r3,r3,MAS2_EPN_MASK(BOOK3E_PAGESZ_64M)@l |
---|
| 1142 | + and r3,r3,r4 |
---|
| 1143 | + ori r3,r3,MAS2_M_IF_NEEDED@l |
---|
| 1144 | + mtspr SPRN_MAS2,r3 /* Write MAS2(EPN) */ |
---|
| 1145 | + |
---|
| 1146 | +#ifdef CONFIG_PHYS_64BIT |
---|
| 1147 | + ori r8,r6,(MAS3_SW|MAS3_SR|MAS3_SX) |
---|
| 1148 | + mtspr SPRN_MAS3,r8 /* Write MAS3(RPN) */ |
---|
| 1149 | + mtspr SPRN_MAS7,r5 |
---|
| 1150 | +#else |
---|
| 1151 | + ori r8,r5,(MAS3_SW|MAS3_SR|MAS3_SX) |
---|
| 1152 | + mtspr SPRN_MAS3,r8 /* Write MAS3(RPN) */ |
---|
| 1153 | +#endif |
---|
| 1154 | + |
---|
| 1155 | + tlbwe /* Write TLB */ |
---|
| 1156 | + isync |
---|
| 1157 | + sync |
---|
| 1158 | + blr |
---|
| 1159 | + |
---|
| 1160 | +/* |
---|
| 1161 | + * Return to the start of the relocated kernel and run again |
---|
| 1162 | + * r3 - virtual address of fdt |
---|
| 1163 | + * r4 - entry of the kernel |
---|
| 1164 | + */ |
---|
| 1165 | +_GLOBAL(reloc_kernel_entry) |
---|
| 1166 | + mfmsr r7 |
---|
| 1167 | + rlwinm r7, r7, 0, ~(MSR_IS | MSR_DS) |
---|
| 1168 | + |
---|
| 1169 | + mtspr SPRN_SRR0,r4 |
---|
| 1170 | + mtspr SPRN_SRR1,r7 |
---|
| 1171 | + rfi |
---|
| 1172 | + |
---|
| 1173 | +/* |
---|
1127 | 1174 | * Create a tlb entry with the same effective and physical address as |
---|
1128 | 1175 | * the tlb entry used by the current running code. But set the TS to 1. |
---|
1129 | 1176 | * Then switch to the address space 1. It will return with the r3 set to |
---|