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 41 /** 42 * LDIMM - load immediate value 43 * STI - enable interruption 44 * CLI - disable interruption 45 */ 46 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 */ 231