blob: 4a692553651f0cc1d708b1e46b533cac701a4e57 [file] [log] [blame]
Christophe Leroy8a23fdec2019-04-30 12:38:50 +00001/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef __HEAD_32_H__
3#define __HEAD_32_H__
4
5#include <asm/ptrace.h> /* for STACK_FRAME_REGS_MARKER */
6
7/*
Christophe Leroy37737a22019-04-30 12:38:51 +00008 * MSR_KERNEL is > 0x8000 on 4xx/Book-E since it include MSR_CE.
9 */
10.macro __LOAD_MSR_KERNEL r, x
11.if \x >= 0x8000
12 lis \r, (\x)@h
13 ori \r, \r, (\x)@l
14.else
15 li \r, (\x)
16.endif
17.endm
18#define LOAD_MSR_KERNEL(r, x) __LOAD_MSR_KERNEL r, x
19
20/*
Christophe Leroy8a23fdec2019-04-30 12:38:50 +000021 * Exception entry code. This code runs with address translation
22 * turned off, i.e. using physical addresses.
23 * We assume sprg3 has the physical address of the current
24 * task's thread_struct.
25 */
26
27.macro EXCEPTION_PROLOG
28 mtspr SPRN_SPRG_SCRATCH0,r10
29 mtspr SPRN_SPRG_SCRATCH1,r11
30 mfcr r10
31 EXCEPTION_PROLOG_1
32 EXCEPTION_PROLOG_2
33.endm
34
35.macro EXCEPTION_PROLOG_1
36 mfspr r11,SPRN_SRR1 /* check whether user or kernel */
37 andi. r11,r11,MSR_PR
38 tophys(r11,r1) /* use tophys(r1) if kernel */
39 beq 1f
40 mfspr r11,SPRN_SPRG_THREAD
41 lwz r11,TASK_STACK-THREAD(r11)
42 addi r11,r11,THREAD_SIZE
43 tophys(r11,r11)
441: subi r11,r11,INT_FRAME_SIZE /* alloc exc. frame */
45.endm
46
47.macro EXCEPTION_PROLOG_2
48 stw r10,_CCR(r11) /* save registers */
49 stw r12,GPR12(r11)
50 stw r9,GPR9(r11)
51 mfspr r10,SPRN_SPRG_SCRATCH0
52 stw r10,GPR10(r11)
53 mfspr r12,SPRN_SPRG_SCRATCH1
54 stw r12,GPR11(r11)
55 mflr r10
56 stw r10,_LINK(r11)
57 mfspr r12,SPRN_SRR0
58 mfspr r9,SPRN_SRR1
59 stw r1,GPR1(r11)
60 stw r1,0(r11)
61 tovirt(r1,r11) /* set new kernel sp */
Christophe Leroy90f204b2019-04-30 12:38:56 +000062#ifdef CONFIG_40x
63 rlwinm r9,r9,0,14,12 /* clear MSR_WE (necessary?) */
64#else
Christophe Leroy8a23fdec2019-04-30 12:38:50 +000065 li r10,MSR_KERNEL & ~(MSR_IR|MSR_DR) /* can take exceptions */
66 MTMSRD(r10) /* (except for mach check in rtas) */
Christophe Leroy90f204b2019-04-30 12:38:56 +000067#endif
Christophe Leroy8a23fdec2019-04-30 12:38:50 +000068 stw r0,GPR0(r11)
69 lis r10,STACK_FRAME_REGS_MARKER@ha /* exception frame marker */
70 addi r10,r10,STACK_FRAME_REGS_MARKER@l
71 stw r10,8(r11)
72 SAVE_4GPRS(3, r11)
73 SAVE_2GPRS(7, r11)
74.endm
75
Christophe Leroyb86fb882019-04-30 12:39:02 +000076.macro SYSCALL_ENTRY trapno
77 mfspr r12,SPRN_SPRG_THREAD
78 mfcr r10
79 lwz r11,TASK_STACK-THREAD(r12)
80 mflr r9
81 addi r11,r11,THREAD_SIZE - INT_FRAME_SIZE
82 rlwinm r10,r10,0,4,2 /* Clear SO bit in CR */
83 tophys(r11,r11)
84 stw r10,_CCR(r11) /* save registers */
85 mfspr r10,SPRN_SRR0
86 stw r9,_LINK(r11)
87 mfspr r9,SPRN_SRR1
88 stw r1,GPR1(r11)
89 stw r1,0(r11)
90 tovirt(r1,r11) /* set new kernel sp */
91 stw r10,_NIP(r11)
92#ifdef CONFIG_40x
93 rlwinm r9,r9,0,14,12 /* clear MSR_WE (necessary?) */
94#else
95 LOAD_MSR_KERNEL(r10, MSR_KERNEL & ~(MSR_IR|MSR_DR)) /* can take exceptions */
96 MTMSRD(r10) /* (except for mach check in rtas) */
97#endif
98 lis r10,STACK_FRAME_REGS_MARKER@ha /* exception frame marker */
99 stw r2,GPR2(r11)
100 addi r10,r10,STACK_FRAME_REGS_MARKER@l
101 stw r9,_MSR(r11)
102 li r2, \trapno + 1
103 stw r10,8(r11)
104 stw r2,_TRAP(r11)
105 SAVE_GPR(0, r11)
106 SAVE_4GPRS(3, r11)
107 SAVE_2GPRS(7, r11)
108 addi r11,r1,STACK_FRAME_OVERHEAD
109 addi r2,r12,-THREAD
110 stw r11,PT_REGS(r12)
111#if defined(CONFIG_40x)
112 /* Check to see if the dbcr0 register is set up to debug. Use the
113 internal debug mode bit to do this. */
114 lwz r12,THREAD_DBCR0(r12)
115 andis. r12,r12,DBCR0_IDM@h
116#endif
117 ACCOUNT_CPU_USER_ENTRY(r2, r11, r12)
118#if defined(CONFIG_40x)
119 beq+ 3f
120 /* From user and task is ptraced - load up global dbcr0 */
121 li r12,-1 /* clear all pending debug events */
122 mtspr SPRN_DBSR,r12
123 lis r11,global_dbcr0@ha
124 tophys(r11,r11)
125 addi r11,r11,global_dbcr0@l
126 lwz r12,0(r11)
127 mtspr SPRN_DBCR0,r12
128 lwz r12,4(r11)
129 addi r12,r12,-1
130 stw r12,4(r11)
131#endif
132
1333:
134 tovirt(r2, r2) /* set r2 to current */
135 lis r11, transfer_to_syscall@h
136 ori r11, r11, transfer_to_syscall@l
137#ifdef CONFIG_TRACE_IRQFLAGS
138 /*
139 * If MSR is changing we need to keep interrupts disabled at this point
140 * otherwise we might risk taking an interrupt before we tell lockdep
141 * they are enabled.
142 */
143 LOAD_MSR_KERNEL(r10, MSR_KERNEL)
144 rlwimi r10, r9, 0, MSR_EE
145#else
146 LOAD_MSR_KERNEL(r10, MSR_KERNEL | MSR_EE)
147#endif
148#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PERF_EVENTS)
149 mtspr SPRN_NRI, r0
150#endif
151 mtspr SPRN_SRR1,r10
152 mtspr SPRN_SRR0,r11
153 SYNC
154 RFI /* jump to handler, enable MMU */
155.endm
156
Christophe Leroy8a23fdec2019-04-30 12:38:50 +0000157/*
158 * Note: code which follows this uses cr0.eq (set if from kernel),
159 * r11, r12 (SRR0), and r9 (SRR1).
160 *
161 * Note2: once we have set r1 we are in a position to take exceptions
162 * again, and we could thus set MSR:RI at that point.
163 */
164
165/*
166 * Exception vectors.
167 */
168#ifdef CONFIG_PPC_BOOK3S
169#define START_EXCEPTION(n, label) \
170 . = n; \
171 DO_KVM n; \
172label:
173
174#else
175#define START_EXCEPTION(n, label) \
176 . = n; \
177label:
178
179#endif
180
181#define EXCEPTION(n, label, hdlr, xfer) \
182 START_EXCEPTION(n, label) \
183 EXCEPTION_PROLOG; \
184 addi r3,r1,STACK_FRAME_OVERHEAD; \
185 xfer(n, hdlr)
186
Christophe Leroy1ae99b42019-04-30 12:39:00 +0000187#define EXC_XFER_TEMPLATE(hdlr, trap, msr, tfer, ret) \
Christophe Leroy8a23fdec2019-04-30 12:38:50 +0000188 li r10,trap; \
189 stw r10,_TRAP(r11); \
Christophe Leroy1d3034a2019-04-30 12:38:52 +0000190 LOAD_MSR_KERNEL(r10, msr); \
Christophe Leroy8a23fdec2019-04-30 12:38:50 +0000191 bl tfer; \
Christophe Leroy8a23fdec2019-04-30 12:38:50 +0000192 .long hdlr; \
193 .long ret
194
Christophe Leroy8a23fdec2019-04-30 12:38:50 +0000195#define EXC_XFER_STD(n, hdlr) \
Christophe Leroy1ae99b42019-04-30 12:39:00 +0000196 EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, transfer_to_handler_full, \
Christophe Leroy8a23fdec2019-04-30 12:38:50 +0000197 ret_from_except_full)
198
199#define EXC_XFER_LITE(n, hdlr) \
Christophe Leroy1ae99b42019-04-30 12:39:00 +0000200 EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, transfer_to_handler, \
Christophe Leroy8a23fdec2019-04-30 12:38:50 +0000201 ret_from_except)
202
Christophe Leroy8a23fdec2019-04-30 12:38:50 +0000203#endif /* __HEAD_32_H__ */