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