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