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 */ 230