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