1*8a23fdecSChristophe Leroy /* SPDX-License-Identifier: GPL-2.0 */ 2*8a23fdecSChristophe Leroy #ifndef __HEAD_32_H__ 3*8a23fdecSChristophe Leroy #define __HEAD_32_H__ 4*8a23fdecSChristophe Leroy 5*8a23fdecSChristophe Leroy #include <asm/ptrace.h> /* for STACK_FRAME_REGS_MARKER */ 6*8a23fdecSChristophe Leroy 7*8a23fdecSChristophe Leroy /* 8*8a23fdecSChristophe Leroy * Exception entry code. This code runs with address translation 9*8a23fdecSChristophe Leroy * turned off, i.e. using physical addresses. 10*8a23fdecSChristophe Leroy * We assume sprg3 has the physical address of the current 11*8a23fdecSChristophe Leroy * task's thread_struct. 12*8a23fdecSChristophe Leroy */ 13*8a23fdecSChristophe Leroy 14*8a23fdecSChristophe Leroy .macro EXCEPTION_PROLOG 15*8a23fdecSChristophe Leroy mtspr SPRN_SPRG_SCRATCH0,r10 16*8a23fdecSChristophe Leroy mtspr SPRN_SPRG_SCRATCH1,r11 17*8a23fdecSChristophe Leroy mfcr r10 18*8a23fdecSChristophe Leroy EXCEPTION_PROLOG_1 19*8a23fdecSChristophe Leroy EXCEPTION_PROLOG_2 20*8a23fdecSChristophe Leroy .endm 21*8a23fdecSChristophe Leroy 22*8a23fdecSChristophe Leroy .macro EXCEPTION_PROLOG_1 23*8a23fdecSChristophe Leroy mfspr r11,SPRN_SRR1 /* check whether user or kernel */ 24*8a23fdecSChristophe Leroy andi. r11,r11,MSR_PR 25*8a23fdecSChristophe Leroy tophys(r11,r1) /* use tophys(r1) if kernel */ 26*8a23fdecSChristophe Leroy beq 1f 27*8a23fdecSChristophe Leroy mfspr r11,SPRN_SPRG_THREAD 28*8a23fdecSChristophe Leroy lwz r11,TASK_STACK-THREAD(r11) 29*8a23fdecSChristophe Leroy addi r11,r11,THREAD_SIZE 30*8a23fdecSChristophe Leroy tophys(r11,r11) 31*8a23fdecSChristophe Leroy 1: subi r11,r11,INT_FRAME_SIZE /* alloc exc. frame */ 32*8a23fdecSChristophe Leroy .endm 33*8a23fdecSChristophe Leroy 34*8a23fdecSChristophe Leroy .macro EXCEPTION_PROLOG_2 35*8a23fdecSChristophe Leroy stw r10,_CCR(r11) /* save registers */ 36*8a23fdecSChristophe Leroy stw r12,GPR12(r11) 37*8a23fdecSChristophe Leroy stw r9,GPR9(r11) 38*8a23fdecSChristophe Leroy mfspr r10,SPRN_SPRG_SCRATCH0 39*8a23fdecSChristophe Leroy stw r10,GPR10(r11) 40*8a23fdecSChristophe Leroy mfspr r12,SPRN_SPRG_SCRATCH1 41*8a23fdecSChristophe Leroy stw r12,GPR11(r11) 42*8a23fdecSChristophe Leroy mflr r10 43*8a23fdecSChristophe Leroy stw r10,_LINK(r11) 44*8a23fdecSChristophe Leroy mfspr r12,SPRN_SRR0 45*8a23fdecSChristophe Leroy mfspr r9,SPRN_SRR1 46*8a23fdecSChristophe Leroy stw r1,GPR1(r11) 47*8a23fdecSChristophe Leroy stw r1,0(r11) 48*8a23fdecSChristophe Leroy tovirt(r1,r11) /* set new kernel sp */ 49*8a23fdecSChristophe Leroy li r10,MSR_KERNEL & ~(MSR_IR|MSR_DR) /* can take exceptions */ 50*8a23fdecSChristophe Leroy MTMSRD(r10) /* (except for mach check in rtas) */ 51*8a23fdecSChristophe Leroy stw r0,GPR0(r11) 52*8a23fdecSChristophe Leroy lis r10,STACK_FRAME_REGS_MARKER@ha /* exception frame marker */ 53*8a23fdecSChristophe Leroy addi r10,r10,STACK_FRAME_REGS_MARKER@l 54*8a23fdecSChristophe Leroy stw r10,8(r11) 55*8a23fdecSChristophe Leroy SAVE_4GPRS(3, r11) 56*8a23fdecSChristophe Leroy SAVE_2GPRS(7, r11) 57*8a23fdecSChristophe Leroy .endm 58*8a23fdecSChristophe Leroy 59*8a23fdecSChristophe Leroy /* 60*8a23fdecSChristophe Leroy * Note: code which follows this uses cr0.eq (set if from kernel), 61*8a23fdecSChristophe Leroy * r11, r12 (SRR0), and r9 (SRR1). 62*8a23fdecSChristophe Leroy * 63*8a23fdecSChristophe Leroy * Note2: once we have set r1 we are in a position to take exceptions 64*8a23fdecSChristophe Leroy * again, and we could thus set MSR:RI at that point. 65*8a23fdecSChristophe Leroy */ 66*8a23fdecSChristophe Leroy 67*8a23fdecSChristophe Leroy /* 68*8a23fdecSChristophe Leroy * Exception vectors. 69*8a23fdecSChristophe Leroy */ 70*8a23fdecSChristophe Leroy #ifdef CONFIG_PPC_BOOK3S 71*8a23fdecSChristophe Leroy #define START_EXCEPTION(n, label) \ 72*8a23fdecSChristophe Leroy . = n; \ 73*8a23fdecSChristophe Leroy DO_KVM n; \ 74*8a23fdecSChristophe Leroy label: 75*8a23fdecSChristophe Leroy 76*8a23fdecSChristophe Leroy #else 77*8a23fdecSChristophe Leroy #define START_EXCEPTION(n, label) \ 78*8a23fdecSChristophe Leroy . = n; \ 79*8a23fdecSChristophe Leroy label: 80*8a23fdecSChristophe Leroy 81*8a23fdecSChristophe Leroy #endif 82*8a23fdecSChristophe Leroy 83*8a23fdecSChristophe Leroy #define EXCEPTION(n, label, hdlr, xfer) \ 84*8a23fdecSChristophe Leroy START_EXCEPTION(n, label) \ 85*8a23fdecSChristophe Leroy EXCEPTION_PROLOG; \ 86*8a23fdecSChristophe Leroy addi r3,r1,STACK_FRAME_OVERHEAD; \ 87*8a23fdecSChristophe Leroy xfer(n, hdlr) 88*8a23fdecSChristophe Leroy 89*8a23fdecSChristophe Leroy #define EXC_XFER_TEMPLATE(n, hdlr, trap, copyee, tfer, ret) \ 90*8a23fdecSChristophe Leroy li r10,trap; \ 91*8a23fdecSChristophe Leroy stw r10,_TRAP(r11); \ 92*8a23fdecSChristophe Leroy li r10,MSR_KERNEL; \ 93*8a23fdecSChristophe Leroy copyee(r10, r9); \ 94*8a23fdecSChristophe Leroy bl tfer; \ 95*8a23fdecSChristophe Leroy i##n: \ 96*8a23fdecSChristophe Leroy .long hdlr; \ 97*8a23fdecSChristophe Leroy .long ret 98*8a23fdecSChristophe Leroy 99*8a23fdecSChristophe Leroy #define COPY_EE(d, s) rlwimi d,s,0,MSR_EE 100*8a23fdecSChristophe Leroy #define NOCOPY(d, s) 101*8a23fdecSChristophe Leroy 102*8a23fdecSChristophe Leroy #define EXC_XFER_STD(n, hdlr) \ 103*8a23fdecSChristophe Leroy EXC_XFER_TEMPLATE(n, hdlr, n, NOCOPY, transfer_to_handler_full, \ 104*8a23fdecSChristophe Leroy ret_from_except_full) 105*8a23fdecSChristophe Leroy 106*8a23fdecSChristophe Leroy #define EXC_XFER_LITE(n, hdlr) \ 107*8a23fdecSChristophe Leroy EXC_XFER_TEMPLATE(n, hdlr, n+1, NOCOPY, transfer_to_handler, \ 108*8a23fdecSChristophe Leroy ret_from_except) 109*8a23fdecSChristophe Leroy 110*8a23fdecSChristophe Leroy #define EXC_XFER_EE(n, hdlr) \ 111*8a23fdecSChristophe Leroy EXC_XFER_TEMPLATE(n, hdlr, n, COPY_EE, transfer_to_handler_full, \ 112*8a23fdecSChristophe Leroy ret_from_except_full) 113*8a23fdecSChristophe Leroy 114*8a23fdecSChristophe Leroy #define EXC_XFER_EE_LITE(n, hdlr) \ 115*8a23fdecSChristophe Leroy EXC_XFER_TEMPLATE(n, hdlr, n+1, COPY_EE, transfer_to_handler, \ 116*8a23fdecSChristophe Leroy ret_from_except) 117*8a23fdecSChristophe Leroy 118*8a23fdecSChristophe Leroy #endif /* __HEAD_32_H__ */ 119