Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef __HEAD_32_H__
0003 #define __HEAD_32_H__
0004 
0005 #include <asm/ptrace.h> /* for STACK_FRAME_REGS_MARKER */
0006 
0007 /*
0008  * Exception entry code.  This code runs with address translation
0009  * turned off, i.e. using physical addresses.
0010  * We assume sprg3 has the physical address of the current
0011  * task's thread_struct.
0012  */
0013 .macro EXCEPTION_PROLOG     trapno name handle_dar_dsisr=0
0014     EXCEPTION_PROLOG_0  handle_dar_dsisr=\handle_dar_dsisr
0015     EXCEPTION_PROLOG_1
0016     EXCEPTION_PROLOG_2  \trapno \name handle_dar_dsisr=\handle_dar_dsisr
0017 .endm
0018 
0019 .macro EXCEPTION_PROLOG_0 handle_dar_dsisr=0
0020     mtspr   SPRN_SPRG_SCRATCH0,r10
0021     mtspr   SPRN_SPRG_SCRATCH1,r11
0022     mfspr   r10, SPRN_SPRG_THREAD
0023     .if \handle_dar_dsisr
0024 #ifdef CONFIG_40x
0025     mfspr   r11, SPRN_DEAR
0026 #else
0027     mfspr   r11, SPRN_DAR
0028 #endif
0029     stw r11, DAR(r10)
0030 #ifdef CONFIG_40x
0031     mfspr   r11, SPRN_ESR
0032 #else
0033     mfspr   r11, SPRN_DSISR
0034 #endif
0035     stw r11, DSISR(r10)
0036     .endif
0037     mfspr   r11, SPRN_SRR0
0038     stw r11, SRR0(r10)
0039     mfspr   r11, SPRN_SRR1      /* check whether user or kernel */
0040     stw r11, SRR1(r10)
0041     mfcr    r10
0042     andi.   r11, r11, MSR_PR
0043 .endm
0044 
0045 .macro EXCEPTION_PROLOG_1
0046     mtspr   SPRN_SPRG_SCRATCH2,r1
0047     subi    r1, r1, INT_FRAME_SIZE      /* use r1 if kernel */
0048     beq 1f
0049     mfspr   r1,SPRN_SPRG_THREAD
0050     lwz r1,TASK_STACK-THREAD(r1)
0051     addi    r1, r1, THREAD_SIZE - INT_FRAME_SIZE
0052 1:
0053 #ifdef CONFIG_VMAP_STACK
0054     mtcrf   0x3f, r1
0055     bt  32 - THREAD_ALIGN_SHIFT, vmap_stack_overflow
0056 #endif
0057 .endm
0058 
0059 .macro EXCEPTION_PROLOG_2 trapno name handle_dar_dsisr=0
0060 #ifdef CONFIG_PPC_8xx
0061     .if \handle_dar_dsisr
0062     li  r11, RPN_PATTERN
0063     mtspr   SPRN_DAR, r11   /* Tag DAR, to be used in DTLB Error */
0064     .endif
0065 #endif
0066     LOAD_REG_IMMEDIATE(r11, MSR_KERNEL & ~MSR_RI) /* re-enable MMU */
0067     mtspr   SPRN_SRR1, r11
0068     lis r11, 1f@h
0069     ori r11, r11, 1f@l
0070     mtspr   SPRN_SRR0, r11
0071     mfspr   r11, SPRN_SPRG_SCRATCH2
0072     rfi
0073 
0074     .text
0075 \name\()_virt:
0076 1:
0077     stw r11,GPR1(r1)
0078     stw r11,0(r1)
0079     mr  r11, r1
0080     stw r10,_CCR(r11)       /* save registers */
0081     stw r12,GPR12(r11)
0082     stw r9,GPR9(r11)
0083     mfspr   r10,SPRN_SPRG_SCRATCH0
0084     mfspr   r12,SPRN_SPRG_SCRATCH1
0085     stw r10,GPR10(r11)
0086     stw r12,GPR11(r11)
0087     mflr    r10
0088     stw r10,_LINK(r11)
0089     mfspr   r12, SPRN_SPRG_THREAD
0090     tovirt(r12, r12)
0091     .if \handle_dar_dsisr
0092     lwz r10, DAR(r12)
0093     stw r10, _DAR(r11)
0094     lwz r10, DSISR(r12)
0095     stw r10, _DSISR(r11)
0096     .endif
0097     lwz r9, SRR1(r12)
0098     lwz r12, SRR0(r12)
0099 #ifdef CONFIG_40x
0100     rlwinm  r9,r9,0,14,12       /* clear MSR_WE (necessary?) */
0101 #elif defined(CONFIG_PPC_8xx)
0102     mtspr   SPRN_EID, r2        /* Set MSR_RI */
0103 #else
0104     li  r10, MSR_KERNEL     /* can take exceptions */
0105     mtmsr   r10         /* (except for mach check in rtas) */
0106 #endif
0107     COMMON_EXCEPTION_PROLOG_END \trapno
0108 _ASM_NOKPROBE_SYMBOL(\name\()_virt)
0109 .endm
0110 
0111 .macro COMMON_EXCEPTION_PROLOG_END trapno
0112     stw r0,GPR0(r1)
0113     lis r10,STACK_FRAME_REGS_MARKER@ha /* exception frame marker */
0114     addi    r10,r10,STACK_FRAME_REGS_MARKER@l
0115     stw r10,8(r1)
0116     li  r10, \trapno
0117     stw r10,_TRAP(r1)
0118     SAVE_GPRS(3, 8, r1)
0119     SAVE_NVGPRS(r1)
0120     stw r2,GPR2(r1)
0121     stw r12,_NIP(r1)
0122     stw r9,_MSR(r1)
0123     mfctr   r10
0124     mfspr   r2,SPRN_SPRG_THREAD
0125     stw r10,_CTR(r1)
0126     tovirt(r2, r2)
0127     mfspr   r10,SPRN_XER
0128     addi    r2, r2, -THREAD
0129     stw r10,_XER(r1)
0130     addi    r3,r1,STACK_FRAME_OVERHEAD
0131 .endm
0132 
0133 .macro prepare_transfer_to_handler
0134 #ifdef CONFIG_PPC_BOOK3S_32
0135     andi.   r12,r9,MSR_PR
0136     bne 777f
0137     bl  prepare_transfer_to_handler
0138 #ifdef CONFIG_PPC_KUEP
0139     b   778f
0140 777:
0141     bl  __kuep_lock
0142 778:
0143 #endif
0144 777:
0145 #endif
0146 .endm
0147 
0148 .macro SYSCALL_ENTRY trapno
0149     mfspr   r9, SPRN_SRR1
0150     mfspr   r12, SPRN_SRR0
0151     LOAD_REG_IMMEDIATE(r11, MSR_KERNEL)     /* can take exceptions */
0152     lis r10, 1f@h
0153     ori r10, r10, 1f@l
0154     mtspr   SPRN_SRR1, r11
0155     mtspr   SPRN_SRR0, r10
0156     mfspr   r10,SPRN_SPRG_THREAD
0157     mr  r11, r1
0158     lwz r1,TASK_STACK-THREAD(r10)
0159     tovirt(r10, r10)
0160     addi    r1, r1, THREAD_SIZE - INT_FRAME_SIZE
0161     rfi
0162 1:
0163     stw r12,_NIP(r1)
0164     mfcr    r12
0165     rlwinm  r12,r12,0,4,2   /* Clear SO bit in CR */
0166     stw r12,_CCR(r1)
0167     b   transfer_to_syscall     /* jump to handler */
0168 .endm
0169 
0170 /*
0171  * Note: code which follows this uses cr0.eq (set if from kernel),
0172  * r11, r12 (SRR0), and r9 (SRR1).
0173  *
0174  * Note2: once we have set r1 we are in a position to take exceptions
0175  * again, and we could thus set MSR:RI at that point.
0176  */
0177 
0178 /*
0179  * Exception vectors.
0180  */
0181 #ifdef CONFIG_PPC_BOOK3S
0182 #define START_EXCEPTION(n, label)       \
0183     __HEAD;                 \
0184     . = n;                  \
0185     DO_KVM n;               \
0186 label:
0187 
0188 #else
0189 #define START_EXCEPTION(n, label)       \
0190     __HEAD;                 \
0191     . = n;                  \
0192 label:
0193 
0194 #endif
0195 
0196 #define EXCEPTION(n, label, hdlr)       \
0197     START_EXCEPTION(n, label)       \
0198     EXCEPTION_PROLOG n label;       \
0199     prepare_transfer_to_handler;        \
0200     bl  hdlr;               \
0201     b   interrupt_return
0202 
0203 .macro vmap_stack_overflow_exception
0204     __HEAD
0205 vmap_stack_overflow:
0206 #ifdef CONFIG_SMP
0207     mfspr   r1, SPRN_SPRG_THREAD
0208     lwz r1, TASK_CPU - THREAD(r1)
0209     slwi    r1, r1, 3
0210     addis   r1, r1, emergency_ctx-PAGE_OFFSET@ha
0211 #else
0212     lis r1, emergency_ctx-PAGE_OFFSET@ha
0213 #endif
0214     lwz r1, emergency_ctx-PAGE_OFFSET@l(r1)
0215     addi    r1, r1, THREAD_SIZE - INT_FRAME_SIZE
0216     EXCEPTION_PROLOG_2 0 vmap_stack_overflow
0217     prepare_transfer_to_handler
0218     bl  stack_overflow_exception
0219     b   interrupt_return
0220 .endm
0221 
0222 #endif /* __HEAD_32_H__ */