• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _ASM_M32R_ASSEMBLER_H
3 #define _ASM_M32R_ASSEMBLER_H
4 
5 /*
6  * linux/asm-m32r/assembler.h
7  *
8  * Copyright (C) 2004  Hirokazu Takata <takata at linux-m32r.org>
9  *
10  * This file contains M32R architecture specific macro definitions.
11  */
12 
13 #include <linux/stringify.h>
14 
15 #undef __STR
16 
17 #ifdef __ASSEMBLY__
18 #define __STR(x) x
19 #else
20 #define __STR(x) __stringify(x)
21 #endif
22 
23 #ifdef CONFIG_SMP
24 #define M32R_LOCK	__STR(lock)
25 #define M32R_UNLOCK	__STR(unlock)
26 #else
27 #define M32R_LOCK	__STR(ld)
28 #define M32R_UNLOCK	__STR(st)
29 #endif
30 
31 #ifdef __ASSEMBLY__
32 #undef ENTRY
33 #define ENTRY(name) ENTRY_M name
34 	.macro  ENTRY_M name
35 	.global \name
36 	ALIGN
37 \name:
38 	.endm
39 #endif
40 
41 
42 /**
43  * LDIMM - load immediate value
44  * STI - enable interruption
45  * CLI - disable interruption
46  */
47 
48 #ifdef __ASSEMBLY__
49 
50 #define LDIMM(reg,x) LDIMM reg x
51 	.macro LDIMM reg x
52 	seth	\reg, #high(\x)
53 	or3	\reg, \reg, #low(\x)
54 	.endm
55 
56 #if !(defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_M32104))
57 #define ENABLE_INTERRUPTS(reg) ENABLE_INTERRUPTS reg
58 	.macro ENABLE_INTERRUPTS reg
59 	setpsw  #0x40	    ->	nop
60 	; WORKAROUND: "-> nop" is a workaround for the M32700(TS1).
61 	.endm
62 
63 #define DISABLE_INTERRUPTS(reg) DISABLE_INTERRUPTS reg
64 	.macro DISABLE_INTERRUPTS reg
65 	clrpsw  #0x40	    ->	nop
66 	; WORKAROUND: "-> nop" is a workaround for the M32700(TS1).
67 	.endm
68 #else	/* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
69 #define ENABLE_INTERRUPTS(reg) ENABLE_INTERRUPTS reg
70 	.macro ENABLE_INTERRUPTS reg
71 	mvfc	\reg, psw
72 	or3	\reg, \reg, #0x0040
73 	mvtc	\reg, psw
74 	.endm
75 
76 #define DISABLE_INTERRUPTS(reg) DISABLE_INTERRUPTS reg
77 	.macro DISABLE_INTERRUPTS reg
78 	mvfc	\reg, psw
79 	and3	\reg, \reg, #0xffbf
80 	mvtc	\reg, psw
81 	.endm
82 #endif	/* CONFIG_CHIP_M32102 */
83 
84 	.macro	SAVE_ALL
85 	push	r0		; orig_r0
86 	push	sp		; spi (r15)
87 	push	lr		; r14
88 	push	r13
89 	mvfc	r13, cr3	; spu
90 	push	r13
91 	mvfc	r13, bbpc
92 	push	r13
93 	mvfc	r13, bbpsw
94 	push	r13
95 	mvfc	r13, bpc
96 	push	r13
97 	mvfc	r13, psw
98 	push	r13
99 #if defined(CONFIG_ISA_M32R2) && defined(CONFIG_ISA_DSP_LEVEL2)
100 	mvfaclo	r13, a1
101 	push	r13
102 	mvfachi r13, a1
103 	push	r13
104 	mvfaclo	r13, a0
105 	push	r13
106 	mvfachi	r13, a0
107 	push	r13
108 #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R)
109 	mvfaclo	r13
110 	push	r13
111 	mvfachi	r13
112 	push	r13
113 	ldi	r13, #0
114 	push	r13		; dummy push acc1h
115 	push	r13		; dummy push acc1l
116 #else
117 #error unknown isa configuration
118 #endif
119 	ldi	r13, #-1
120 	push	r13		; syscall_nr (default: -1)
121 	push	r12
122 	push	r11
123 	push	r10
124 	push	r9
125 	push	r8
126 	push	r7
127 	push	r3
128 	push	r2
129 	push	r1
130 	push	r0
131 	addi	sp, #-4		; room for implicit pt_regs parameter
132 	push	r6
133 	push	r5
134 	push	r4
135 	.endm
136 
137 	.macro	RESTORE_ALL
138 	pop	r4
139 	pop	r5
140 	pop	r6
141 	addi	sp, #4
142 	pop	r0
143 	pop	r1
144 	pop	r2
145 	pop	r3
146 	pop	r7
147 	pop	r8
148 	pop	r9
149 	pop	r10
150 	pop	r11
151 	pop	r12
152 	addi	r15, #4		; Skip syscall number
153 #if defined(CONFIG_ISA_M32R2) && defined(CONFIG_ISA_DSP_LEVEL2)
154 	pop	r13
155 	mvtachi	r13, a0
156 	pop	r13
157 	mvtaclo	r13, a0
158 	pop	r13
159 	mvtachi	r13, a1
160 	pop	r13
161 	mvtaclo	r13, a1
162 #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R)
163 	pop	r13		; dummy pop acc1h
164 	pop	r13		; dummy pop acc1l
165 	pop	r13
166 	mvtachi	r13
167 	pop	r13
168 	mvtaclo	r13
169 #else
170 #error unknown isa configuration
171 #endif
172 	pop	r14
173 	mvtc	r14, psw
174 	pop	r14
175 	mvtc	r14, bpc
176 	addi	sp, #8		; Skip bbpsw, bbpc
177 	pop	r14
178 	mvtc	r14, cr3	; spu
179 	pop	r13
180 	pop	lr		; r14
181 	pop	sp		; spi (r15)
182 	addi	sp, #4		; Skip orig_r0
183 	.fillinsn
184 1:	rte
185 	.section .fixup,"ax"
186 2:	bl	do_exit
187 	.previous
188 	.section __ex_table,"a"
189 	ALIGN
190 	.long	1b, 2b
191 	.previous
192 	.endm
193 
194 #define GET_CURRENT(reg)  get_current reg
195 	.macro get_current reg
196 	ldi  \reg, #-8192
197 	and  \reg, sp
198 	.endm
199 
200 #if !(defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_M32104))
201 	.macro	SWITCH_TO_KERNEL_STACK
202 	; switch to kernel stack (spi)
203 	clrpsw	#0x80	    ->	nop
204 	.endm
205 #else	/* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
206 	.macro	SWITCH_TO_KERNEL_STACK
207 	push	r0		; save r0 for working
208 	mvfc	r0, psw
209 	and3	r0, r0, #0x00ff7f
210 	mvtc	r0, psw
211 	slli	r0, #16
212 	bltz	r0, 1f		; check BSM-bit
213 ;
214 	;; called from kernel context: previous stack = spi
215 	pop	r0		; retrieve r0
216 	bra	2f
217 	.fillinsn
218 1:
219 	;; called from user context: previous stack = spu
220 	mvfc	r0, cr3		; spu
221 	addi	r0, #4
222 	mvtc	r0, cr3		; spu
223 	ld	r0, @(-4,r0)	; retrieve r0
224 	.fillinsn
225 2:
226 	.endm
227 #endif	/* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
228 
229 #endif	/* __ASSEMBLY__ */
230 
231 #endif	/* _ASM_M32R_ASSEMBLER_H */
232