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 /* 837737a2aSChristophe Leroy * MSR_KERNEL is > 0x8000 on 4xx/Book-E since it include MSR_CE. 937737a2aSChristophe Leroy */ 1037737a2aSChristophe Leroy .macro __LOAD_MSR_KERNEL r, x 1137737a2aSChristophe Leroy .if \x >= 0x8000 1237737a2aSChristophe Leroy lis \r, (\x)@h 1337737a2aSChristophe Leroy ori \r, \r, (\x)@l 1437737a2aSChristophe Leroy .else 1537737a2aSChristophe Leroy li \r, (\x) 1637737a2aSChristophe Leroy .endif 1737737a2aSChristophe Leroy .endm 1837737a2aSChristophe Leroy #define LOAD_MSR_KERNEL(r, x) __LOAD_MSR_KERNEL r, x 1937737a2aSChristophe Leroy 2037737a2aSChristophe Leroy /* 218a23fdecSChristophe Leroy * Exception entry code. This code runs with address translation 228a23fdecSChristophe Leroy * turned off, i.e. using physical addresses. 238a23fdecSChristophe Leroy * We assume sprg3 has the physical address of the current 248a23fdecSChristophe Leroy * task's thread_struct. 258a23fdecSChristophe Leroy */ 268a23fdecSChristophe Leroy 278a23fdecSChristophe Leroy .macro EXCEPTION_PROLOG 288a23fdecSChristophe Leroy mtspr SPRN_SPRG_SCRATCH0,r10 298a23fdecSChristophe Leroy mtspr SPRN_SPRG_SCRATCH1,r11 308a23fdecSChristophe Leroy mfcr r10 318a23fdecSChristophe Leroy EXCEPTION_PROLOG_1 328a23fdecSChristophe Leroy EXCEPTION_PROLOG_2 338a23fdecSChristophe Leroy .endm 348a23fdecSChristophe Leroy 358a23fdecSChristophe Leroy .macro EXCEPTION_PROLOG_1 368a23fdecSChristophe Leroy mfspr r11,SPRN_SRR1 /* check whether user or kernel */ 378a23fdecSChristophe Leroy andi. r11,r11,MSR_PR 388a23fdecSChristophe Leroy tophys(r11,r1) /* use tophys(r1) if kernel */ 398a23fdecSChristophe Leroy beq 1f 408a23fdecSChristophe Leroy mfspr r11,SPRN_SPRG_THREAD 418a23fdecSChristophe Leroy lwz r11,TASK_STACK-THREAD(r11) 428a23fdecSChristophe Leroy addi r11,r11,THREAD_SIZE 438a23fdecSChristophe Leroy tophys(r11,r11) 448a23fdecSChristophe Leroy 1: subi r11,r11,INT_FRAME_SIZE /* alloc exc. frame */ 458a23fdecSChristophe Leroy .endm 468a23fdecSChristophe Leroy 478a23fdecSChristophe Leroy .macro EXCEPTION_PROLOG_2 488a23fdecSChristophe Leroy stw r10,_CCR(r11) /* save registers */ 498a23fdecSChristophe Leroy stw r12,GPR12(r11) 508a23fdecSChristophe Leroy stw r9,GPR9(r11) 518a23fdecSChristophe Leroy mfspr r10,SPRN_SPRG_SCRATCH0 528a23fdecSChristophe Leroy stw r10,GPR10(r11) 538a23fdecSChristophe Leroy mfspr r12,SPRN_SPRG_SCRATCH1 548a23fdecSChristophe Leroy stw r12,GPR11(r11) 558a23fdecSChristophe Leroy mflr r10 568a23fdecSChristophe Leroy stw r10,_LINK(r11) 578a23fdecSChristophe Leroy mfspr r12,SPRN_SRR0 588a23fdecSChristophe Leroy mfspr r9,SPRN_SRR1 598a23fdecSChristophe Leroy stw r1,GPR1(r11) 608a23fdecSChristophe Leroy stw r1,0(r11) 618a23fdecSChristophe Leroy tovirt(r1,r11) /* set new kernel sp */ 62*90f204b9SChristophe Leroy #ifdef CONFIG_40x 63*90f204b9SChristophe Leroy rlwinm r9,r9,0,14,12 /* clear MSR_WE (necessary?) */ 64*90f204b9SChristophe Leroy #else 658a23fdecSChristophe Leroy li r10,MSR_KERNEL & ~(MSR_IR|MSR_DR) /* can take exceptions */ 668a23fdecSChristophe Leroy MTMSRD(r10) /* (except for mach check in rtas) */ 67*90f204b9SChristophe Leroy #endif 688a23fdecSChristophe Leroy stw r0,GPR0(r11) 698a23fdecSChristophe Leroy lis r10,STACK_FRAME_REGS_MARKER@ha /* exception frame marker */ 708a23fdecSChristophe Leroy addi r10,r10,STACK_FRAME_REGS_MARKER@l 718a23fdecSChristophe Leroy stw r10,8(r11) 728a23fdecSChristophe Leroy SAVE_4GPRS(3, r11) 738a23fdecSChristophe Leroy SAVE_2GPRS(7, r11) 748a23fdecSChristophe Leroy .endm 758a23fdecSChristophe Leroy 768a23fdecSChristophe Leroy /* 778a23fdecSChristophe Leroy * Note: code which follows this uses cr0.eq (set if from kernel), 788a23fdecSChristophe Leroy * r11, r12 (SRR0), and r9 (SRR1). 798a23fdecSChristophe Leroy * 808a23fdecSChristophe Leroy * Note2: once we have set r1 we are in a position to take exceptions 818a23fdecSChristophe Leroy * again, and we could thus set MSR:RI at that point. 828a23fdecSChristophe Leroy */ 838a23fdecSChristophe Leroy 848a23fdecSChristophe Leroy /* 858a23fdecSChristophe Leroy * Exception vectors. 868a23fdecSChristophe Leroy */ 878a23fdecSChristophe Leroy #ifdef CONFIG_PPC_BOOK3S 888a23fdecSChristophe Leroy #define START_EXCEPTION(n, label) \ 898a23fdecSChristophe Leroy . = n; \ 908a23fdecSChristophe Leroy DO_KVM n; \ 918a23fdecSChristophe Leroy label: 928a23fdecSChristophe Leroy 938a23fdecSChristophe Leroy #else 948a23fdecSChristophe Leroy #define START_EXCEPTION(n, label) \ 958a23fdecSChristophe Leroy . = n; \ 968a23fdecSChristophe Leroy label: 978a23fdecSChristophe Leroy 988a23fdecSChristophe Leroy #endif 998a23fdecSChristophe Leroy 1008a23fdecSChristophe Leroy #define EXCEPTION(n, label, hdlr, xfer) \ 1018a23fdecSChristophe Leroy START_EXCEPTION(n, label) \ 1028a23fdecSChristophe Leroy EXCEPTION_PROLOG; \ 1038a23fdecSChristophe Leroy addi r3,r1,STACK_FRAME_OVERHEAD; \ 1048a23fdecSChristophe Leroy xfer(n, hdlr) 1058a23fdecSChristophe Leroy 1061d3034aeSChristophe Leroy #define EXC_XFER_TEMPLATE(hdlr, trap, msr, copyee, tfer, ret) \ 1078a23fdecSChristophe Leroy li r10,trap; \ 1088a23fdecSChristophe Leroy stw r10,_TRAP(r11); \ 1091d3034aeSChristophe Leroy LOAD_MSR_KERNEL(r10, msr); \ 1108a23fdecSChristophe Leroy copyee(r10, r9); \ 1118a23fdecSChristophe Leroy bl tfer; \ 1128a23fdecSChristophe Leroy .long hdlr; \ 1138a23fdecSChristophe Leroy .long ret 1148a23fdecSChristophe Leroy 1158a23fdecSChristophe Leroy #define COPY_EE(d, s) rlwimi d,s,0,MSR_EE 1168a23fdecSChristophe Leroy #define NOCOPY(d, s) 1178a23fdecSChristophe Leroy 1188a23fdecSChristophe Leroy #define EXC_XFER_STD(n, hdlr) \ 1191d3034aeSChristophe Leroy EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, NOCOPY, transfer_to_handler_full, \ 1208a23fdecSChristophe Leroy ret_from_except_full) 1218a23fdecSChristophe Leroy 1228a23fdecSChristophe Leroy #define EXC_XFER_LITE(n, hdlr) \ 1231d3034aeSChristophe Leroy EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, NOCOPY, transfer_to_handler, \ 1248a23fdecSChristophe Leroy ret_from_except) 1258a23fdecSChristophe Leroy 1268a23fdecSChristophe Leroy #define EXC_XFER_EE(n, hdlr) \ 1271d3034aeSChristophe Leroy EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, COPY_EE, transfer_to_handler_full, \ 1288a23fdecSChristophe Leroy ret_from_except_full) 1298a23fdecSChristophe Leroy 1308a23fdecSChristophe Leroy #define EXC_XFER_EE_LITE(n, hdlr) \ 1311d3034aeSChristophe Leroy EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, COPY_EE, transfer_to_handler, \ 1328a23fdecSChristophe Leroy ret_from_except) 1338a23fdecSChristophe Leroy 1348a23fdecSChristophe Leroy #endif /* __HEAD_32_H__ */ 135