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 #ifdef CONFIG_VMAP_STACK 2302847487SChristophe Leroy mfspr r10, SPRN_SPRG_THREAD 2402847487SChristophe Leroy .if \handle_dar_dsisr 25*0512aaddSChristophe Leroy #ifdef CONFIG_40x 26*0512aaddSChristophe Leroy mfspr r11, SPRN_DEAR 27*0512aaddSChristophe Leroy #else 2802847487SChristophe Leroy mfspr r11, SPRN_DAR 29*0512aaddSChristophe Leroy #endif 3002847487SChristophe Leroy stw r11, DAR(r10) 31*0512aaddSChristophe Leroy #ifdef CONFIG_40x 32*0512aaddSChristophe Leroy mfspr r11, SPRN_ESR 33*0512aaddSChristophe Leroy #else 3402847487SChristophe Leroy mfspr r11, SPRN_DSISR 35*0512aaddSChristophe Leroy #endif 3602847487SChristophe Leroy stw r11, DSISR(r10) 3702847487SChristophe Leroy .endif 3802847487SChristophe Leroy mfspr r11, SPRN_SRR0 3902847487SChristophe Leroy stw r11, SRR0(r10) 4002847487SChristophe Leroy #endif 415ae8fabcSChristophe Leroy mfspr r11, SPRN_SRR1 /* check whether user or kernel */ 4202847487SChristophe Leroy #ifdef CONFIG_VMAP_STACK 4302847487SChristophe Leroy stw r11, SRR1(r10) 4402847487SChristophe Leroy #endif 458a23fdecSChristophe Leroy mfcr r10 465ae8fabcSChristophe Leroy andi. r11, r11, MSR_PR 478a23fdecSChristophe Leroy .endm 488a23fdecSChristophe Leroy 49cd08f109SChristophe Leroy .macro EXCEPTION_PROLOG_1 for_rtas=0 50da7bb43aSChristophe Leroy #ifdef CONFIG_VMAP_STACK 51d2e00603SChristophe Leroy mtspr SPRN_SPRG_SCRATCH2,r1 52da7bb43aSChristophe Leroy subi r1, r1, INT_FRAME_SIZE /* use r1 if kernel */ 53da7bb43aSChristophe Leroy beq 1f 54da7bb43aSChristophe Leroy mfspr r1,SPRN_SPRG_THREAD 55da7bb43aSChristophe Leroy lwz r1,TASK_STACK-THREAD(r1) 56da7bb43aSChristophe Leroy addi r1, r1, THREAD_SIZE - INT_FRAME_SIZE 576285f9cfSChristophe Leroy 1: 583642eb21SChristophe Leroy mtcrf 0x3f, r1 596285f9cfSChristophe Leroy bt 32 - THREAD_ALIGN_SHIFT, stack_overflow 60da7bb43aSChristophe Leroy #else 6102847487SChristophe Leroy subi r11, r1, INT_FRAME_SIZE /* use r1 if kernel */ 628a23fdecSChristophe Leroy beq 1f 638a23fdecSChristophe Leroy mfspr r11,SPRN_SPRG_THREAD 648a23fdecSChristophe Leroy lwz r11,TASK_STACK-THREAD(r11) 6502847487SChristophe Leroy addi r11, r11, THREAD_SIZE - INT_FRAME_SIZE 666285f9cfSChristophe Leroy 1: tophys(r11, r11) 673978eb78SChristophe Leroy #endif 688a23fdecSChristophe Leroy .endm 698a23fdecSChristophe Leroy 7002847487SChristophe Leroy .macro EXCEPTION_PROLOG_2 handle_dar_dsisr=0 71c118c730SChristophe Leroy #ifdef CONFIG_VMAP_STACK 72*0512aaddSChristophe Leroy LOAD_REG_IMMEDIATE(r11, MSR_KERNEL & ~(MSR_IR | MSR_RI)) /* can take DTLB miss */ 73d2e00603SChristophe Leroy mtmsr r11 74c118c730SChristophe Leroy isync 75d2e00603SChristophe Leroy mfspr r11, SPRN_SPRG_SCRATCH2 76da7bb43aSChristophe Leroy stw r11,GPR1(r1) 77da7bb43aSChristophe Leroy stw r11,0(r1) 78da7bb43aSChristophe Leroy mr r11, r1 79da7bb43aSChristophe Leroy #else 80da7bb43aSChristophe Leroy stw r1,GPR1(r11) 81da7bb43aSChristophe Leroy stw r1,0(r11) 82da7bb43aSChristophe Leroy tovirt(r1, r11) /* set new kernel sp */ 83da7bb43aSChristophe Leroy #endif 84d2e00603SChristophe Leroy stw r10,_CCR(r11) /* save registers */ 858a23fdecSChristophe Leroy stw r12,GPR12(r11) 868a23fdecSChristophe Leroy stw r9,GPR9(r11) 87d2e00603SChristophe Leroy mfspr r10,SPRN_SPRG_SCRATCH0 888a23fdecSChristophe Leroy mfspr r12,SPRN_SPRG_SCRATCH1 89d2e00603SChristophe Leroy stw r10,GPR10(r11) 908a23fdecSChristophe Leroy stw r12,GPR11(r11) 918a23fdecSChristophe Leroy mflr r10 928a23fdecSChristophe Leroy stw r10,_LINK(r11) 9302847487SChristophe Leroy #ifdef CONFIG_VMAP_STACK 9402847487SChristophe Leroy mfspr r12, SPRN_SPRG_THREAD 9502847487SChristophe Leroy tovirt(r12, r12) 9602847487SChristophe Leroy .if \handle_dar_dsisr 9702847487SChristophe Leroy lwz r10, DAR(r12) 9802847487SChristophe Leroy stw r10, _DAR(r11) 9902847487SChristophe Leroy lwz r10, DSISR(r12) 10002847487SChristophe Leroy stw r10, _DSISR(r11) 10102847487SChristophe Leroy .endif 10202847487SChristophe Leroy lwz r9, SRR1(r12) 10302847487SChristophe Leroy lwz r12, SRR0(r12) 10402847487SChristophe Leroy #else 1058a23fdecSChristophe Leroy mfspr r12,SPRN_SRR0 1068a23fdecSChristophe Leroy mfspr r9,SPRN_SRR1 10702847487SChristophe Leroy #endif 10890f204b9SChristophe Leroy #ifdef CONFIG_40x 10990f204b9SChristophe Leroy rlwinm r9,r9,0,14,12 /* clear MSR_WE (necessary?) */ 11090f204b9SChristophe Leroy #else 11102847487SChristophe Leroy #ifdef CONFIG_VMAP_STACK 11202847487SChristophe Leroy li r10, MSR_KERNEL & ~MSR_IR /* can take exceptions */ 11302847487SChristophe Leroy #else 1148a23fdecSChristophe Leroy li r10,MSR_KERNEL & ~(MSR_IR|MSR_DR) /* can take exceptions */ 11502847487SChristophe Leroy #endif 11639bccfd1SChristophe Leroy mtmsr r10 /* (except for mach check in rtas) */ 11790f204b9SChristophe Leroy #endif 1188a23fdecSChristophe Leroy stw r0,GPR0(r11) 1198a23fdecSChristophe Leroy lis r10,STACK_FRAME_REGS_MARKER@ha /* exception frame marker */ 1208a23fdecSChristophe Leroy addi r10,r10,STACK_FRAME_REGS_MARKER@l 1218a23fdecSChristophe Leroy stw r10,8(r11) 1228a23fdecSChristophe Leroy SAVE_4GPRS(3, r11) 1238a23fdecSChristophe Leroy SAVE_2GPRS(7, r11) 1248a23fdecSChristophe Leroy .endm 1258a23fdecSChristophe Leroy 126b86fb888SChristophe Leroy .macro SYSCALL_ENTRY trapno 1279e270862SChristophe Leroy mfspr r9, SPRN_SRR1 1282c59e510SChristophe Leroy mfspr r10, SPRN_SRR0 1292c59e510SChristophe Leroy LOAD_REG_IMMEDIATE(r11, MSR_KERNEL) /* can take exceptions */ 1302c59e510SChristophe Leroy lis r12, 1f@h 1312c59e510SChristophe Leroy ori r12, r12, 1f@l 1322c59e510SChristophe Leroy mtspr SPRN_SRR1, r11 1332c59e510SChristophe Leroy mtspr SPRN_SRR0, r12 1342c59e510SChristophe Leroy mfspr r12,SPRN_SPRG_THREAD 135d5c24398SChristophe Leroy mr r11, r1 136d5c24398SChristophe Leroy lwz r1,TASK_STACK-THREAD(r12) 1372c59e510SChristophe Leroy tovirt(r12, r12) 138d5c24398SChristophe Leroy addi r1, r1, THREAD_SIZE - INT_FRAME_SIZE 13976249ddcSChristophe Leroy rfi 14076249ddcSChristophe Leroy 1: 141d5c24398SChristophe Leroy stw r11,GPR1(r1) 142d5c24398SChristophe Leroy stw r11,0(r1) 143d5c24398SChristophe Leroy mr r11, r1 1442c59e510SChristophe Leroy stw r10,_NIP(r11) 1459e270862SChristophe Leroy mflr r10 1469e270862SChristophe Leroy stw r10, _LINK(r11) 147c06f0affSChristophe Leroy mfcr r10 148c06f0affSChristophe Leroy rlwinm r10,r10,0,4,2 /* Clear SO bit in CR */ 149c06f0affSChristophe Leroy stw r10,_CCR(r11) /* save registers */ 150b86fb888SChristophe Leroy #ifdef CONFIG_40x 151b86fb888SChristophe Leroy rlwinm r9,r9,0,14,12 /* clear MSR_WE (necessary?) */ 152b86fb888SChristophe Leroy #endif 153b86fb888SChristophe Leroy lis r10,STACK_FRAME_REGS_MARKER@ha /* exception frame marker */ 154b86fb888SChristophe Leroy stw r2,GPR2(r11) 155b86fb888SChristophe Leroy addi r10,r10,STACK_FRAME_REGS_MARKER@l 156b86fb888SChristophe Leroy stw r9,_MSR(r11) 157fbcee2ebSChristophe Leroy li r2, \trapno 158b86fb888SChristophe Leroy stw r10,8(r11) 159b86fb888SChristophe Leroy stw r2,_TRAP(r11) 160b86fb888SChristophe Leroy SAVE_GPR(0, r11) 161b86fb888SChristophe Leroy SAVE_4GPRS(3, r11) 162b86fb888SChristophe Leroy SAVE_2GPRS(7, r11) 163b86fb888SChristophe Leroy addi r2,r12,-THREAD 16476249ddcSChristophe Leroy b transfer_to_syscall /* jump to handler */ 165b86fb888SChristophe Leroy .endm 166b86fb888SChristophe Leroy 167c9c84fd9SChristophe Leroy .macro save_dar_dsisr_on_stack reg1, reg2, sp 16802847487SChristophe Leroy #ifndef CONFIG_VMAP_STACK 169*0512aaddSChristophe Leroy #ifdef CONFIG_40x 170*0512aaddSChristophe Leroy mfspr \reg1, SPRN_DEAR 171*0512aaddSChristophe Leroy mfspr \reg2, SPRN_ESR 172*0512aaddSChristophe Leroy #else 173c9c84fd9SChristophe Leroy mfspr \reg1, SPRN_DAR 174c9c84fd9SChristophe Leroy mfspr \reg2, SPRN_DSISR 175*0512aaddSChristophe Leroy #endif 176c9c84fd9SChristophe Leroy stw \reg1, _DAR(\sp) 177c9c84fd9SChristophe Leroy stw \reg2, _DSISR(\sp) 17802847487SChristophe Leroy #endif 179c9c84fd9SChristophe Leroy .endm 180c9c84fd9SChristophe Leroy 181c9c84fd9SChristophe Leroy .macro get_and_save_dar_dsisr_on_stack reg1, reg2, sp 18202847487SChristophe Leroy #ifdef CONFIG_VMAP_STACK 18302847487SChristophe Leroy lwz \reg1, _DAR(\sp) 18402847487SChristophe Leroy lwz \reg2, _DSISR(\sp) 18502847487SChristophe Leroy #else 186c9c84fd9SChristophe Leroy save_dar_dsisr_on_stack \reg1, \reg2, \sp 18702847487SChristophe Leroy #endif 18802847487SChristophe Leroy .endm 18902847487SChristophe Leroy 19002847487SChristophe Leroy .macro tovirt_vmstack dst, src 19102847487SChristophe Leroy #ifdef CONFIG_VMAP_STACK 19202847487SChristophe Leroy tovirt(\dst, \src) 19302847487SChristophe Leroy #else 19402847487SChristophe Leroy .ifnc \dst, \src 19502847487SChristophe Leroy mr \dst, \src 19602847487SChristophe Leroy .endif 19702847487SChristophe Leroy #endif 19802847487SChristophe Leroy .endm 19902847487SChristophe Leroy 20002847487SChristophe Leroy .macro tovirt_novmstack dst, src 20102847487SChristophe Leroy #ifndef CONFIG_VMAP_STACK 20202847487SChristophe Leroy tovirt(\dst, \src) 20302847487SChristophe Leroy #else 20402847487SChristophe Leroy .ifnc \dst, \src 20502847487SChristophe Leroy mr \dst, \src 20602847487SChristophe Leroy .endif 20702847487SChristophe Leroy #endif 20802847487SChristophe Leroy .endm 20902847487SChristophe Leroy 21002847487SChristophe Leroy .macro tophys_novmstack dst, src 21102847487SChristophe Leroy #ifndef CONFIG_VMAP_STACK 21202847487SChristophe Leroy tophys(\dst, \src) 21302847487SChristophe Leroy #else 21402847487SChristophe Leroy .ifnc \dst, \src 21502847487SChristophe Leroy mr \dst, \src 21602847487SChristophe Leroy .endif 21702847487SChristophe Leroy #endif 218c9c84fd9SChristophe Leroy .endm 219c9c84fd9SChristophe Leroy 2208a23fdecSChristophe Leroy /* 2218a23fdecSChristophe Leroy * Note: code which follows this uses cr0.eq (set if from kernel), 2228a23fdecSChristophe Leroy * r11, r12 (SRR0), and r9 (SRR1). 2238a23fdecSChristophe Leroy * 2248a23fdecSChristophe Leroy * Note2: once we have set r1 we are in a position to take exceptions 2258a23fdecSChristophe Leroy * again, and we could thus set MSR:RI at that point. 2268a23fdecSChristophe Leroy */ 2278a23fdecSChristophe Leroy 2288a23fdecSChristophe Leroy /* 2298a23fdecSChristophe Leroy * Exception vectors. 2308a23fdecSChristophe Leroy */ 2318a23fdecSChristophe Leroy #ifdef CONFIG_PPC_BOOK3S 2328a23fdecSChristophe Leroy #define START_EXCEPTION(n, label) \ 2338a23fdecSChristophe Leroy . = n; \ 2348a23fdecSChristophe Leroy DO_KVM n; \ 2358a23fdecSChristophe Leroy label: 2368a23fdecSChristophe Leroy 2378a23fdecSChristophe Leroy #else 2388a23fdecSChristophe Leroy #define START_EXCEPTION(n, label) \ 2398a23fdecSChristophe Leroy . = n; \ 2408a23fdecSChristophe Leroy label: 2418a23fdecSChristophe Leroy 2428a23fdecSChristophe Leroy #endif 2438a23fdecSChristophe Leroy 2448a23fdecSChristophe Leroy #define EXCEPTION(n, label, hdlr, xfer) \ 2458a23fdecSChristophe Leroy START_EXCEPTION(n, label) \ 2468a23fdecSChristophe Leroy EXCEPTION_PROLOG; \ 2478a23fdecSChristophe Leroy addi r3,r1,STACK_FRAME_OVERHEAD; \ 2488a23fdecSChristophe Leroy xfer(n, hdlr) 2498a23fdecSChristophe Leroy 2501ae99b4bSChristophe Leroy #define EXC_XFER_TEMPLATE(hdlr, trap, msr, tfer, ret) \ 2518a23fdecSChristophe Leroy li r10,trap; \ 2528a23fdecSChristophe Leroy stw r10,_TRAP(r11); \ 253ba18025fSChristophe Leroy LOAD_REG_IMMEDIATE(r10, msr); \ 2548a23fdecSChristophe Leroy bl tfer; \ 2558a23fdecSChristophe Leroy .long hdlr; \ 2568a23fdecSChristophe Leroy .long ret 2578a23fdecSChristophe Leroy 2588a23fdecSChristophe Leroy #define EXC_XFER_STD(n, hdlr) \ 2591ae99b4bSChristophe Leroy EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, transfer_to_handler_full, \ 2608a23fdecSChristophe Leroy ret_from_except_full) 2618a23fdecSChristophe Leroy 2628a23fdecSChristophe Leroy #define EXC_XFER_LITE(n, hdlr) \ 2631ae99b4bSChristophe Leroy EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, transfer_to_handler, \ 2648a23fdecSChristophe Leroy ret_from_except) 2658a23fdecSChristophe Leroy 2663978eb78SChristophe Leroy .macro vmap_stack_overflow_exception 2673978eb78SChristophe Leroy #ifdef CONFIG_VMAP_STACK 2683978eb78SChristophe Leroy #ifdef CONFIG_SMP 269da7bb43aSChristophe Leroy mfspr r1, SPRN_SPRG_THREAD 270da7bb43aSChristophe Leroy lwz r1, TASK_CPU - THREAD(r1) 271da7bb43aSChristophe Leroy slwi r1, r1, 3 272da7bb43aSChristophe Leroy addis r1, r1, emergency_ctx@ha 2733978eb78SChristophe Leroy #else 274da7bb43aSChristophe Leroy lis r1, emergency_ctx@ha 2753978eb78SChristophe Leroy #endif 276da7bb43aSChristophe Leroy lwz r1, emergency_ctx@l(r1) 277da7bb43aSChristophe Leroy cmpwi cr1, r1, 0 2783978eb78SChristophe Leroy bne cr1, 1f 279da7bb43aSChristophe Leroy lis r1, init_thread_union@ha 280da7bb43aSChristophe Leroy addi r1, r1, init_thread_union@l 281da7bb43aSChristophe Leroy 1: addi r1, r1, THREAD_SIZE - INT_FRAME_SIZE 2823978eb78SChristophe Leroy EXCEPTION_PROLOG_2 2833978eb78SChristophe Leroy SAVE_NVGPRS(r11) 2843978eb78SChristophe Leroy addi r3, r1, STACK_FRAME_OVERHEAD 2853978eb78SChristophe Leroy EXC_XFER_STD(0, stack_overflow_exception) 2863978eb78SChristophe Leroy #endif 2873978eb78SChristophe Leroy .endm 2883978eb78SChristophe Leroy 2898a23fdecSChristophe Leroy #endif /* __HEAD_32_H__ */ 290