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 */ 1302847487SChristophe Leroy .macro EXCEPTION_PROLOG handle_dar_dsisr=0 1402847487SChristophe Leroy EXCEPTION_PROLOG_0 handle_dar_dsisr=\handle_dar_dsisr 151f1c4d01SChristophe Leroy EXCEPTION_PROLOG_1 1602847487SChristophe Leroy EXCEPTION_PROLOG_2 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 240512aaddSChristophe Leroy #ifdef CONFIG_40x 250512aaddSChristophe Leroy mfspr r11, SPRN_DEAR 260512aaddSChristophe Leroy #else 2702847487SChristophe Leroy mfspr r11, SPRN_DAR 280512aaddSChristophe Leroy #endif 2902847487SChristophe Leroy stw r11, DAR(r10) 300512aaddSChristophe Leroy #ifdef CONFIG_40x 310512aaddSChristophe Leroy mfspr r11, SPRN_ESR 320512aaddSChristophe Leroy #else 3302847487SChristophe Leroy mfspr r11, SPRN_DSISR 340512aaddSChristophe Leroy #endif 3502847487SChristophe Leroy stw r11, DSISR(r10) 3602847487SChristophe Leroy .endif 3702847487SChristophe Leroy mfspr r11, SPRN_SRR0 3802847487SChristophe Leroy stw r11, SRR0(r10) 395ae8fabcSChristophe Leroy mfspr r11, SPRN_SRR1 /* check whether user or kernel */ 4002847487SChristophe Leroy stw r11, SRR1(r10) 418a23fdecSChristophe Leroy mfcr r10 425ae8fabcSChristophe Leroy andi. r11, r11, MSR_PR 438a23fdecSChristophe Leroy .endm 448a23fdecSChristophe Leroy 457aa8dd67SChristophe Leroy .macro EXCEPTION_PROLOG_1 46d2e00603SChristophe Leroy mtspr SPRN_SPRG_SCRATCH2,r1 47da7bb43aSChristophe Leroy subi r1, r1, INT_FRAME_SIZE /* use r1 if kernel */ 48da7bb43aSChristophe Leroy beq 1f 49da7bb43aSChristophe Leroy mfspr r1,SPRN_SPRG_THREAD 50da7bb43aSChristophe Leroy lwz r1,TASK_STACK-THREAD(r1) 51da7bb43aSChristophe Leroy addi r1, r1, THREAD_SIZE - INT_FRAME_SIZE 526285f9cfSChristophe Leroy 1: 537aa8dd67SChristophe Leroy #ifdef CONFIG_VMAP_STACK 543642eb21SChristophe Leroy mtcrf 0x3f, r1 556285f9cfSChristophe Leroy bt 32 - THREAD_ALIGN_SHIFT, stack_overflow 563978eb78SChristophe Leroy #endif 578a23fdecSChristophe Leroy .endm 588a23fdecSChristophe Leroy 5902847487SChristophe Leroy .macro EXCEPTION_PROLOG_2 handle_dar_dsisr=0 60*5b1c9a0dSChristophe Leroy #ifdef CONFIG_PPC_8xx 61*5b1c9a0dSChristophe Leroy .if \handle_dar_dsisr 62*5b1c9a0dSChristophe Leroy li r11, RPN_PATTERN 63*5b1c9a0dSChristophe Leroy mtspr SPRN_DAR, r11 /* Tag DAR, to be used in DTLB Error */ 64*5b1c9a0dSChristophe Leroy .endif 65*5b1c9a0dSChristophe Leroy #endif 660512aaddSChristophe Leroy LOAD_REG_IMMEDIATE(r11, MSR_KERNEL & ~(MSR_IR | MSR_RI)) /* can take DTLB miss */ 67d2e00603SChristophe Leroy mtmsr r11 68c118c730SChristophe Leroy isync 69d2e00603SChristophe Leroy mfspr r11, SPRN_SPRG_SCRATCH2 70da7bb43aSChristophe Leroy stw r11,GPR1(r1) 71da7bb43aSChristophe Leroy stw r11,0(r1) 72da7bb43aSChristophe Leroy mr r11, r1 73d2e00603SChristophe Leroy stw r10,_CCR(r11) /* save registers */ 748a23fdecSChristophe Leroy stw r12,GPR12(r11) 758a23fdecSChristophe Leroy stw r9,GPR9(r11) 76d2e00603SChristophe Leroy mfspr r10,SPRN_SPRG_SCRATCH0 778a23fdecSChristophe Leroy mfspr r12,SPRN_SPRG_SCRATCH1 78d2e00603SChristophe Leroy stw r10,GPR10(r11) 798a23fdecSChristophe Leroy stw r12,GPR11(r11) 808a23fdecSChristophe Leroy mflr r10 818a23fdecSChristophe Leroy stw r10,_LINK(r11) 8202847487SChristophe Leroy mfspr r12, SPRN_SPRG_THREAD 8302847487SChristophe Leroy tovirt(r12, r12) 8402847487SChristophe Leroy .if \handle_dar_dsisr 8502847487SChristophe Leroy lwz r10, DAR(r12) 8602847487SChristophe Leroy stw r10, _DAR(r11) 8702847487SChristophe Leroy lwz r10, DSISR(r12) 8802847487SChristophe Leroy stw r10, _DSISR(r11) 8902847487SChristophe Leroy .endif 9002847487SChristophe Leroy lwz r9, SRR1(r12) 9102847487SChristophe Leroy lwz r12, SRR0(r12) 9290f204b9SChristophe Leroy #ifdef CONFIG_40x 9390f204b9SChristophe Leroy rlwinm r9,r9,0,14,12 /* clear MSR_WE (necessary?) */ 94e464d92bSChristophe Leroy #elif defined(CONFIG_PPC_8xx) 95e464d92bSChristophe Leroy mtspr SPRN_EID, r2 /* Set MSR_RI */ 9690f204b9SChristophe Leroy #else 9702847487SChristophe Leroy li r10, MSR_KERNEL & ~MSR_IR /* can take exceptions */ 9839bccfd1SChristophe Leroy mtmsr r10 /* (except for mach check in rtas) */ 9990f204b9SChristophe Leroy #endif 1008a23fdecSChristophe Leroy stw r0,GPR0(r11) 1018a23fdecSChristophe Leroy lis r10,STACK_FRAME_REGS_MARKER@ha /* exception frame marker */ 1028a23fdecSChristophe Leroy addi r10,r10,STACK_FRAME_REGS_MARKER@l 1038a23fdecSChristophe Leroy stw r10,8(r11) 1048a23fdecSChristophe Leroy SAVE_4GPRS(3, r11) 1058a23fdecSChristophe Leroy SAVE_2GPRS(7, r11) 1068a23fdecSChristophe Leroy .endm 1078a23fdecSChristophe Leroy 108b86fb888SChristophe Leroy .macro SYSCALL_ENTRY trapno 1099e270862SChristophe Leroy mfspr r9, SPRN_SRR1 1102c59e510SChristophe Leroy mfspr r10, SPRN_SRR0 1112c59e510SChristophe Leroy LOAD_REG_IMMEDIATE(r11, MSR_KERNEL) /* can take exceptions */ 1122c59e510SChristophe Leroy lis r12, 1f@h 1132c59e510SChristophe Leroy ori r12, r12, 1f@l 1142c59e510SChristophe Leroy mtspr SPRN_SRR1, r11 1152c59e510SChristophe Leroy mtspr SPRN_SRR0, r12 1162c59e510SChristophe Leroy mfspr r12,SPRN_SPRG_THREAD 117d5c24398SChristophe Leroy mr r11, r1 118d5c24398SChristophe Leroy lwz r1,TASK_STACK-THREAD(r12) 1192c59e510SChristophe Leroy tovirt(r12, r12) 120d5c24398SChristophe Leroy addi r1, r1, THREAD_SIZE - INT_FRAME_SIZE 12176249ddcSChristophe Leroy rfi 12276249ddcSChristophe Leroy 1: 123d5c24398SChristophe Leroy stw r11,GPR1(r1) 124d5c24398SChristophe Leroy stw r11,0(r1) 125d5c24398SChristophe Leroy mr r11, r1 1262c59e510SChristophe Leroy stw r10,_NIP(r11) 1279e270862SChristophe Leroy mflr r10 1289e270862SChristophe Leroy stw r10, _LINK(r11) 129c06f0affSChristophe Leroy mfcr r10 130c06f0affSChristophe Leroy rlwinm r10,r10,0,4,2 /* Clear SO bit in CR */ 131c06f0affSChristophe Leroy stw r10,_CCR(r11) /* save registers */ 132b86fb888SChristophe Leroy #ifdef CONFIG_40x 133b86fb888SChristophe Leroy rlwinm r9,r9,0,14,12 /* clear MSR_WE (necessary?) */ 134b86fb888SChristophe Leroy #endif 135b86fb888SChristophe Leroy lis r10,STACK_FRAME_REGS_MARKER@ha /* exception frame marker */ 136b86fb888SChristophe Leroy stw r2,GPR2(r11) 137b86fb888SChristophe Leroy addi r10,r10,STACK_FRAME_REGS_MARKER@l 138b86fb888SChristophe Leroy stw r9,_MSR(r11) 139fbcee2ebSChristophe Leroy li r2, \trapno 140b86fb888SChristophe Leroy stw r10,8(r11) 141b86fb888SChristophe Leroy stw r2,_TRAP(r11) 142b86fb888SChristophe Leroy SAVE_GPR(0, r11) 143b86fb888SChristophe Leroy SAVE_4GPRS(3, r11) 144b86fb888SChristophe Leroy SAVE_2GPRS(7, r11) 145b86fb888SChristophe Leroy addi r2,r12,-THREAD 14676249ddcSChristophe Leroy b transfer_to_syscall /* jump to handler */ 147b86fb888SChristophe Leroy .endm 148b86fb888SChristophe Leroy 1498a23fdecSChristophe Leroy /* 1508a23fdecSChristophe Leroy * Note: code which follows this uses cr0.eq (set if from kernel), 1518a23fdecSChristophe Leroy * r11, r12 (SRR0), and r9 (SRR1). 1528a23fdecSChristophe Leroy * 1538a23fdecSChristophe Leroy * Note2: once we have set r1 we are in a position to take exceptions 1548a23fdecSChristophe Leroy * again, and we could thus set MSR:RI at that point. 1558a23fdecSChristophe Leroy */ 1568a23fdecSChristophe Leroy 1578a23fdecSChristophe Leroy /* 1588a23fdecSChristophe Leroy * Exception vectors. 1598a23fdecSChristophe Leroy */ 1608a23fdecSChristophe Leroy #ifdef CONFIG_PPC_BOOK3S 1618a23fdecSChristophe Leroy #define START_EXCEPTION(n, label) \ 1628a23fdecSChristophe Leroy . = n; \ 1638a23fdecSChristophe Leroy DO_KVM n; \ 1648a23fdecSChristophe Leroy label: 1658a23fdecSChristophe Leroy 1668a23fdecSChristophe Leroy #else 1678a23fdecSChristophe Leroy #define START_EXCEPTION(n, label) \ 1688a23fdecSChristophe Leroy . = n; \ 1698a23fdecSChristophe Leroy label: 1708a23fdecSChristophe Leroy 1718a23fdecSChristophe Leroy #endif 1728a23fdecSChristophe Leroy 1738a23fdecSChristophe Leroy #define EXCEPTION(n, label, hdlr, xfer) \ 1748a23fdecSChristophe Leroy START_EXCEPTION(n, label) \ 1758a23fdecSChristophe Leroy EXCEPTION_PROLOG; \ 1768a23fdecSChristophe Leroy addi r3,r1,STACK_FRAME_OVERHEAD; \ 1778a23fdecSChristophe Leroy xfer(n, hdlr) 1788a23fdecSChristophe Leroy 1791ae99b4bSChristophe Leroy #define EXC_XFER_TEMPLATE(hdlr, trap, msr, tfer, ret) \ 1808a23fdecSChristophe Leroy li r10,trap; \ 1818a23fdecSChristophe Leroy stw r10,_TRAP(r11); \ 182ba18025fSChristophe Leroy LOAD_REG_IMMEDIATE(r10, msr); \ 1838a23fdecSChristophe Leroy bl tfer; \ 1848a23fdecSChristophe Leroy .long hdlr; \ 1858a23fdecSChristophe Leroy .long ret 1868a23fdecSChristophe Leroy 1878a23fdecSChristophe Leroy #define EXC_XFER_STD(n, hdlr) \ 1881ae99b4bSChristophe Leroy EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, transfer_to_handler_full, \ 1898a23fdecSChristophe Leroy ret_from_except_full) 1908a23fdecSChristophe Leroy 1918a23fdecSChristophe Leroy #define EXC_XFER_LITE(n, hdlr) \ 1921ae99b4bSChristophe Leroy EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, transfer_to_handler, \ 1938a23fdecSChristophe Leroy ret_from_except) 1948a23fdecSChristophe Leroy 1953978eb78SChristophe Leroy .macro vmap_stack_overflow_exception 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 200da7bb43aSChristophe Leroy addis r1, r1, emergency_ctx@ha 2013978eb78SChristophe Leroy #else 202da7bb43aSChristophe Leroy lis r1, emergency_ctx@ha 2033978eb78SChristophe Leroy #endif 204da7bb43aSChristophe Leroy lwz r1, emergency_ctx@l(r1) 205da7bb43aSChristophe Leroy cmpwi cr1, r1, 0 2063978eb78SChristophe Leroy bne cr1, 1f 207da7bb43aSChristophe Leroy lis r1, init_thread_union@ha 208da7bb43aSChristophe Leroy addi r1, r1, init_thread_union@l 209da7bb43aSChristophe Leroy 1: addi r1, r1, THREAD_SIZE - INT_FRAME_SIZE 2103978eb78SChristophe Leroy EXCEPTION_PROLOG_2 2113978eb78SChristophe Leroy SAVE_NVGPRS(r11) 2123978eb78SChristophe Leroy addi r3, r1, STACK_FRAME_OVERHEAD 2133978eb78SChristophe Leroy EXC_XFER_STD(0, stack_overflow_exception) 2143978eb78SChristophe Leroy .endm 2153978eb78SChristophe Leroy 2168a23fdecSChristophe Leroy #endif /* __HEAD_32_H__ */ 217