18a23fdecSChristophe Leroy /* SPDX-License-Identifier: GPL-2.0 */ 28a23fdecSChristophe Leroy #ifndef __HEAD_32_H__ 38a23fdecSChristophe Leroy #define __HEAD_32_H__ 48a23fdecSChristophe Leroy 58a23fdecSChristophe Leroy #include <asm/ptrace.h> /* for STACK_FRAME_REGS_MARKER */ 68a23fdecSChristophe Leroy 78a23fdecSChristophe Leroy /* 88a23fdecSChristophe Leroy * Exception entry code. This code runs with address translation 98a23fdecSChristophe Leroy * turned off, i.e. using physical addresses. 108a23fdecSChristophe Leroy * We assume sprg3 has the physical address of the current 118a23fdecSChristophe Leroy * task's thread_struct. 128a23fdecSChristophe Leroy */ 13719e7e21SChristophe Leroy .macro EXCEPTION_PROLOG trapno name handle_dar_dsisr=0 1402847487SChristophe Leroy EXCEPTION_PROLOG_0 handle_dar_dsisr=\handle_dar_dsisr 151f1c4d01SChristophe Leroy EXCEPTION_PROLOG_1 16719e7e21SChristophe Leroy EXCEPTION_PROLOG_2 \trapno \name handle_dar_dsisr=\handle_dar_dsisr 171f1c4d01SChristophe Leroy .endm 181f1c4d01SChristophe Leroy 1902847487SChristophe Leroy .macro EXCEPTION_PROLOG_0 handle_dar_dsisr=0 208a23fdecSChristophe Leroy mtspr SPRN_SPRG_SCRATCH0,r10 218a23fdecSChristophe Leroy mtspr SPRN_SPRG_SCRATCH1,r11 2202847487SChristophe Leroy mfspr r10, SPRN_SPRG_THREAD 2302847487SChristophe Leroy .if \handle_dar_dsisr 2402847487SChristophe Leroy mfspr r11, SPRN_DAR 2502847487SChristophe Leroy stw r11, DAR(r10) 2602847487SChristophe Leroy mfspr r11, SPRN_DSISR 2702847487SChristophe Leroy stw r11, DSISR(r10) 2802847487SChristophe Leroy .endif 2902847487SChristophe Leroy mfspr r11, SPRN_SRR0 3002847487SChristophe Leroy stw r11, SRR0(r10) 315ae8fabcSChristophe Leroy mfspr r11, SPRN_SRR1 /* check whether user or kernel */ 3202847487SChristophe Leroy stw r11, SRR1(r10) 338a23fdecSChristophe Leroy mfcr r10 345ae8fabcSChristophe Leroy andi. r11, r11, MSR_PR 358a23fdecSChristophe Leroy .endm 368a23fdecSChristophe Leroy 377aa8dd67SChristophe Leroy .macro EXCEPTION_PROLOG_1 38d2e00603SChristophe Leroy mtspr SPRN_SPRG_SCRATCH2,r1 39da7bb43aSChristophe Leroy subi r1, r1, INT_FRAME_SIZE /* use r1 if kernel */ 40da7bb43aSChristophe Leroy beq 1f 41da7bb43aSChristophe Leroy mfspr r1,SPRN_SPRG_THREAD 42da7bb43aSChristophe Leroy lwz r1,TASK_STACK-THREAD(r1) 43da7bb43aSChristophe Leroy addi r1, r1, THREAD_SIZE - INT_FRAME_SIZE 446285f9cfSChristophe Leroy 1: 457aa8dd67SChristophe Leroy #ifdef CONFIG_VMAP_STACK 463642eb21SChristophe Leroy mtcrf 0x3f, r1 475b5e5bc5SChristophe Leroy bt 32 - THREAD_ALIGN_SHIFT, vmap_stack_overflow 483978eb78SChristophe Leroy #endif 498a23fdecSChristophe Leroy .endm 508a23fdecSChristophe Leroy 51719e7e21SChristophe Leroy .macro EXCEPTION_PROLOG_2 trapno name handle_dar_dsisr=0 525b1c9a0dSChristophe Leroy #ifdef CONFIG_PPC_8xx 535b1c9a0dSChristophe Leroy .if \handle_dar_dsisr 545b1c9a0dSChristophe Leroy li r11, RPN_PATTERN 555b1c9a0dSChristophe Leroy mtspr SPRN_DAR, r11 /* Tag DAR, to be used in DTLB Error */ 565b1c9a0dSChristophe Leroy .endif 575b1c9a0dSChristophe Leroy #endif 589b6150fbSChristophe Leroy LOAD_REG_IMMEDIATE(r11, MSR_KERNEL & ~MSR_RI) /* re-enable MMU */ 599b6150fbSChristophe Leroy mtspr SPRN_SRR1, r11 609b6150fbSChristophe Leroy lis r11, 1f@h 619b6150fbSChristophe Leroy ori r11, r11, 1f@l 629b6150fbSChristophe Leroy mtspr SPRN_SRR0, r11 63d2e00603SChristophe Leroy mfspr r11, SPRN_SPRG_SCRATCH2 649b6150fbSChristophe Leroy rfi 65dc13b889SChristophe Leroy 66dc13b889SChristophe Leroy .text 678f844c06SChristophe Leroy \name\()_virt: 689b6150fbSChristophe Leroy 1: 69da7bb43aSChristophe Leroy stw r11,GPR1(r1) 70da7bb43aSChristophe Leroy stw r11,0(r1) 71da7bb43aSChristophe Leroy mr r11, r1 72d2e00603SChristophe Leroy stw r10,_CCR(r11) /* save registers */ 738a23fdecSChristophe Leroy stw r12,GPR12(r11) 748a23fdecSChristophe Leroy stw r9,GPR9(r11) 75d2e00603SChristophe Leroy mfspr r10,SPRN_SPRG_SCRATCH0 768a23fdecSChristophe Leroy mfspr r12,SPRN_SPRG_SCRATCH1 77d2e00603SChristophe Leroy stw r10,GPR10(r11) 788a23fdecSChristophe Leroy stw r12,GPR11(r11) 798a23fdecSChristophe Leroy mflr r10 808a23fdecSChristophe Leroy stw r10,_LINK(r11) 8102847487SChristophe Leroy mfspr r12, SPRN_SPRG_THREAD 8202847487SChristophe Leroy tovirt(r12, r12) 8302847487SChristophe Leroy .if \handle_dar_dsisr 8402847487SChristophe Leroy lwz r10, DAR(r12) 8502847487SChristophe Leroy stw r10, _DAR(r11) 8602847487SChristophe Leroy lwz r10, DSISR(r12) 8702847487SChristophe Leroy stw r10, _DSISR(r11) 8802847487SChristophe Leroy .endif 8902847487SChristophe Leroy lwz r9, SRR1(r12) 9002847487SChristophe Leroy lwz r12, SRR0(r12) 91*732b32daSChristophe Leroy #ifdef CONFIG_PPC_8xx 92e464d92bSChristophe Leroy mtspr SPRN_EID, r2 /* Set MSR_RI */ 9390f204b9SChristophe Leroy #else 949b6150fbSChristophe Leroy li r10, MSR_KERNEL /* can take exceptions */ 9539bccfd1SChristophe Leroy mtmsr r10 /* (except for mach check in rtas) */ 9690f204b9SChristophe Leroy #endif 97a3055978SChristophe Leroy COMMON_EXCEPTION_PROLOG_END \trapno 98a3055978SChristophe Leroy _ASM_NOKPROBE_SYMBOL(\name\()_virt) 99a3055978SChristophe Leroy .endm 100a3055978SChristophe Leroy 101a3055978SChristophe Leroy .macro COMMON_EXCEPTION_PROLOG_END trapno 102a3055978SChristophe Leroy stw r0,GPR0(r1) 1038a23fdecSChristophe Leroy lis r10,STACK_FRAME_REGS_MARKER@ha /* exception frame marker */ 1048a23fdecSChristophe Leroy addi r10,r10,STACK_FRAME_REGS_MARKER@l 105d2e8ff9fSNicholas Piggin stw r10,STACK_INT_FRAME_MARKER(r1) 106719e7e21SChristophe Leroy li r10, \trapno 107a3055978SChristophe Leroy stw r10,_TRAP(r1) 108aebd1fb4SNicholas Piggin SAVE_GPRS(3, 8, r1) 10916db5436SChristophe Leroy SAVE_NVGPRS(r1) 11016db5436SChristophe Leroy stw r2,GPR2(r1) 11116db5436SChristophe Leroy stw r12,_NIP(r1) 11216db5436SChristophe Leroy stw r9,_MSR(r1) 11316db5436SChristophe Leroy mfctr r10 11416db5436SChristophe Leroy mfspr r2,SPRN_SPRG_THREAD 11516db5436SChristophe Leroy stw r10,_CTR(r1) 11616db5436SChristophe Leroy tovirt(r2, r2) 11716db5436SChristophe Leroy mfspr r10,SPRN_XER 11816db5436SChristophe Leroy addi r2, r2, -THREAD 11916db5436SChristophe Leroy stw r10,_XER(r1) 120c03be0a3SNicholas Piggin addi r3,r1,STACK_INT_FRAME_REGS 1218a23fdecSChristophe Leroy .endm 1228a23fdecSChristophe Leroy 123bce4c26aSChristophe Leroy .macro prepare_transfer_to_handler 124a2b3e09aSChristophe Leroy #ifdef CONFIG_PPC_BOOK3S_32 125b5efec00SChristophe Leroy andi. r12,r9,MSR_PR 126b5efec00SChristophe Leroy bne 777f 127bce4c26aSChristophe Leroy bl prepare_transfer_to_handler 128526d4a4cSChristophe Leroy #ifdef CONFIG_PPC_KUEP 129526d4a4cSChristophe Leroy b 778f 130526d4a4cSChristophe Leroy 777: 131526d4a4cSChristophe Leroy bl __kuep_lock 132526d4a4cSChristophe Leroy 778: 133526d4a4cSChristophe Leroy #endif 134b5efec00SChristophe Leroy 777: 135a2b3e09aSChristophe Leroy #endif 136bce4c26aSChristophe Leroy .endm 137bce4c26aSChristophe Leroy 138b86fb888SChristophe Leroy .macro SYSCALL_ENTRY trapno 1399e270862SChristophe Leroy mfspr r9, SPRN_SRR1 14010e9252fSChristophe Leroy mfspr r12, SPRN_SRR0 1412c59e510SChristophe Leroy LOAD_REG_IMMEDIATE(r11, MSR_KERNEL) /* can take exceptions */ 14210e9252fSChristophe Leroy lis r10, 1f@h 14310e9252fSChristophe Leroy ori r10, r10, 1f@l 1442c59e510SChristophe Leroy mtspr SPRN_SRR1, r11 14510e9252fSChristophe Leroy mtspr SPRN_SRR0, r10 14610e9252fSChristophe Leroy mfspr r10,SPRN_SPRG_THREAD 147d5c24398SChristophe Leroy mr r11, r1 14810e9252fSChristophe Leroy lwz r1,TASK_STACK-THREAD(r10) 14910e9252fSChristophe Leroy tovirt(r10, r10) 150d5c24398SChristophe Leroy addi r1, r1, THREAD_SIZE - INT_FRAME_SIZE 15176249ddcSChristophe Leroy rfi 15276249ddcSChristophe Leroy 1: 153275dcf24SChristophe Leroy stw r12,_NIP(r1) 15410e9252fSChristophe Leroy mfcr r12 15510e9252fSChristophe Leroy rlwinm r12,r12,0,4,2 /* Clear SO bit in CR */ 156275dcf24SChristophe Leroy stw r12,_CCR(r1) 15776249ddcSChristophe Leroy b transfer_to_syscall /* jump to handler */ 158b86fb888SChristophe Leroy .endm 159b86fb888SChristophe Leroy 1608a23fdecSChristophe Leroy /* 1618a23fdecSChristophe Leroy * Note: code which follows this uses cr0.eq (set if from kernel), 1628a23fdecSChristophe Leroy * r11, r12 (SRR0), and r9 (SRR1). 1638a23fdecSChristophe Leroy * 1648a23fdecSChristophe Leroy * Note2: once we have set r1 we are in a position to take exceptions 1658a23fdecSChristophe Leroy * again, and we could thus set MSR:RI at that point. 1668a23fdecSChristophe Leroy */ 1678a23fdecSChristophe Leroy 1688a23fdecSChristophe Leroy /* 1698a23fdecSChristophe Leroy * Exception vectors. 1708a23fdecSChristophe Leroy */ 1718a23fdecSChristophe Leroy #ifdef CONFIG_PPC_BOOK3S 1728a23fdecSChristophe Leroy #define START_EXCEPTION(n, label) \ 173dc13b889SChristophe Leroy __HEAD; \ 1748a23fdecSChristophe Leroy . = n; \ 1758a23fdecSChristophe Leroy DO_KVM n; \ 1768a23fdecSChristophe Leroy label: 1778a23fdecSChristophe Leroy 1788a23fdecSChristophe Leroy #else 1798a23fdecSChristophe Leroy #define START_EXCEPTION(n, label) \ 180dc13b889SChristophe Leroy __HEAD; \ 1818a23fdecSChristophe Leroy . = n; \ 1828a23fdecSChristophe Leroy label: 1838a23fdecSChristophe Leroy 1848a23fdecSChristophe Leroy #endif 1858a23fdecSChristophe Leroy 186acc142b6SChristophe Leroy #define EXCEPTION(n, label, hdlr) \ 1878a23fdecSChristophe Leroy START_EXCEPTION(n, label) \ 188719e7e21SChristophe Leroy EXCEPTION_PROLOG n label; \ 1894c0104a8SChristophe Leroy prepare_transfer_to_handler; \ 1900f2793e3SChristophe Leroy bl hdlr; \ 1914c0104a8SChristophe Leroy b interrupt_return 1928a23fdecSChristophe Leroy 1933978eb78SChristophe Leroy .macro vmap_stack_overflow_exception 194dc13b889SChristophe Leroy __HEAD 1955b5e5bc5SChristophe Leroy vmap_stack_overflow: 1963978eb78SChristophe Leroy #ifdef CONFIG_SMP 197da7bb43aSChristophe Leroy mfspr r1, SPRN_SPRG_THREAD 198da7bb43aSChristophe Leroy lwz r1, TASK_CPU - THREAD(r1) 199da7bb43aSChristophe Leroy slwi r1, r1, 3 2005bb60ea6SChristophe Leroy addis r1, r1, emergency_ctx-PAGE_OFFSET@ha 2013978eb78SChristophe Leroy #else 2025bb60ea6SChristophe Leroy lis r1, emergency_ctx-PAGE_OFFSET@ha 2033978eb78SChristophe Leroy #endif 2045bb60ea6SChristophe Leroy lwz r1, emergency_ctx-PAGE_OFFSET@l(r1) 205a4719f5bSChristophe Leroy addi r1, r1, THREAD_SIZE - INT_FRAME_SIZE 206719e7e21SChristophe Leroy EXCEPTION_PROLOG_2 0 vmap_stack_overflow 2074c0104a8SChristophe Leroy prepare_transfer_to_handler 2084c0104a8SChristophe Leroy bl stack_overflow_exception 2094c0104a8SChristophe Leroy b interrupt_return 2103978eb78SChristophe Leroy .endm 2113978eb78SChristophe Leroy 2128a23fdecSChristophe Leroy #endif /* __HEAD_32_H__ */ 213