You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
231 lines
4.2 KiB
231 lines
4.2 KiB
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef _ASM_M32R_ASSEMBLER_H
|
|
#define _ASM_M32R_ASSEMBLER_H
|
|
|
|
/*
|
|
* linux/asm-m32r/assembler.h
|
|
*
|
|
* Copyright (C) 2004 Hirokazu Takata <takata at linux-m32r.org>
|
|
*
|
|
* This file contains M32R architecture specific macro definitions.
|
|
*/
|
|
|
|
#include <linux/stringify.h>
|
|
|
|
#undef __STR
|
|
|
|
#ifdef __ASSEMBLY__
|
|
#define __STR(x) x
|
|
#else
|
|
#define __STR(x) __stringify(x)
|
|
#endif
|
|
|
|
#ifdef CONFIG_SMP
|
|
#define M32R_LOCK __STR(lock)
|
|
#define M32R_UNLOCK __STR(unlock)
|
|
#else
|
|
#define M32R_LOCK __STR(ld)
|
|
#define M32R_UNLOCK __STR(st)
|
|
#endif
|
|
|
|
#ifdef __ASSEMBLY__
|
|
#undef ENTRY
|
|
#define ENTRY(name) ENTRY_M name
|
|
.macro ENTRY_M name
|
|
.global \name
|
|
ALIGN
|
|
\name:
|
|
.endm
|
|
#endif
|
|
|
|
|
|
/**
|
|
* LDIMM - load immediate value
|
|
* STI - enable interruption
|
|
* CLI - disable interruption
|
|
*/
|
|
|
|
#ifdef __ASSEMBLY__
|
|
|
|
#define LDIMM(reg,x) LDIMM reg x
|
|
.macro LDIMM reg x
|
|
seth \reg, #high(\x)
|
|
or3 \reg, \reg, #low(\x)
|
|
.endm
|
|
|
|
#if !(defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_M32104))
|
|
#define ENABLE_INTERRUPTS(reg) ENABLE_INTERRUPTS reg
|
|
.macro ENABLE_INTERRUPTS reg
|
|
setpsw #0x40 -> nop
|
|
; WORKAROUND: "-> nop" is a workaround for the M32700(TS1).
|
|
.endm
|
|
|
|
#define DISABLE_INTERRUPTS(reg) DISABLE_INTERRUPTS reg
|
|
.macro DISABLE_INTERRUPTS reg
|
|
clrpsw #0x40 -> nop
|
|
; WORKAROUND: "-> nop" is a workaround for the M32700(TS1).
|
|
.endm
|
|
#else /* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
|
|
#define ENABLE_INTERRUPTS(reg) ENABLE_INTERRUPTS reg
|
|
.macro ENABLE_INTERRUPTS reg
|
|
mvfc \reg, psw
|
|
or3 \reg, \reg, #0x0040
|
|
mvtc \reg, psw
|
|
.endm
|
|
|
|
#define DISABLE_INTERRUPTS(reg) DISABLE_INTERRUPTS reg
|
|
.macro DISABLE_INTERRUPTS reg
|
|
mvfc \reg, psw
|
|
and3 \reg, \reg, #0xffbf
|
|
mvtc \reg, psw
|
|
.endm
|
|
#endif /* CONFIG_CHIP_M32102 */
|
|
|
|
.macro SAVE_ALL
|
|
push r0 ; orig_r0
|
|
push sp ; spi (r15)
|
|
push lr ; r14
|
|
push r13
|
|
mvfc r13, cr3 ; spu
|
|
push r13
|
|
mvfc r13, bbpc
|
|
push r13
|
|
mvfc r13, bbpsw
|
|
push r13
|
|
mvfc r13, bpc
|
|
push r13
|
|
mvfc r13, psw
|
|
push r13
|
|
#if defined(CONFIG_ISA_M32R2) && defined(CONFIG_ISA_DSP_LEVEL2)
|
|
mvfaclo r13, a1
|
|
push r13
|
|
mvfachi r13, a1
|
|
push r13
|
|
mvfaclo r13, a0
|
|
push r13
|
|
mvfachi r13, a0
|
|
push r13
|
|
#elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R)
|
|
mvfaclo r13
|
|
push r13
|
|
mvfachi r13
|
|
push r13
|
|
ldi r13, #0
|
|
push r13 ; dummy push acc1h
|
|
push r13 ; dummy push acc1l
|
|
#else
|
|
#error unknown isa configuration
|
|
#endif
|
|
ldi r13, #-1
|
|
push r13 ; syscall_nr (default: -1)
|
|
push r12
|
|
push r11
|
|
push r10
|
|
push r9
|
|
push r8
|
|
push r7
|
|
push r3
|
|
push r2
|
|
push r1
|
|
push r0
|
|
addi sp, #-4 ; room for implicit pt_regs parameter
|
|
push r6
|
|
push r5
|
|
push r4
|
|
.endm
|
|
|
|
.macro RESTORE_ALL
|
|
pop r4
|
|
pop r5
|
|
pop r6
|
|
addi sp, #4
|
|
pop r0
|
|
pop r1
|
|
pop r2
|
|
pop r3
|
|
pop r7
|
|
pop r8
|
|
pop r9
|
|
pop r10
|
|
pop r11
|
|
pop r12
|
|
addi r15, #4 ; Skip syscall number
|
|
#if defined(CONFIG_ISA_M32R2) && defined(CONFIG_ISA_DSP_LEVEL2)
|
|
pop r13
|
|
mvtachi r13, a0
|
|
pop r13
|
|
mvtaclo r13, a0
|
|
pop r13
|
|
mvtachi r13, a1
|
|
pop r13
|
|
mvtaclo r13, a1
|
|
#elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R)
|
|
pop r13 ; dummy pop acc1h
|
|
pop r13 ; dummy pop acc1l
|
|
pop r13
|
|
mvtachi r13
|
|
pop r13
|
|
mvtaclo r13
|
|
#else
|
|
#error unknown isa configuration
|
|
#endif
|
|
pop r14
|
|
mvtc r14, psw
|
|
pop r14
|
|
mvtc r14, bpc
|
|
addi sp, #8 ; Skip bbpsw, bbpc
|
|
pop r14
|
|
mvtc r14, cr3 ; spu
|
|
pop r13
|
|
pop lr ; r14
|
|
pop sp ; spi (r15)
|
|
addi sp, #4 ; Skip orig_r0
|
|
.fillinsn
|
|
1: rte
|
|
.section .fixup,"ax"
|
|
2: bl do_exit
|
|
.previous
|
|
.section __ex_table,"a"
|
|
ALIGN
|
|
.long 1b, 2b
|
|
.previous
|
|
.endm
|
|
|
|
#define GET_CURRENT(reg) get_current reg
|
|
.macro get_current reg
|
|
ldi \reg, #-8192
|
|
and \reg, sp
|
|
.endm
|
|
|
|
#if !(defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_M32104))
|
|
.macro SWITCH_TO_KERNEL_STACK
|
|
; switch to kernel stack (spi)
|
|
clrpsw #0x80 -> nop
|
|
.endm
|
|
#else /* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
|
|
.macro SWITCH_TO_KERNEL_STACK
|
|
push r0 ; save r0 for working
|
|
mvfc r0, psw
|
|
and3 r0, r0, #0x00ff7f
|
|
mvtc r0, psw
|
|
slli r0, #16
|
|
bltz r0, 1f ; check BSM-bit
|
|
;
|
|
;; called from kernel context: previous stack = spi
|
|
pop r0 ; retrieve r0
|
|
bra 2f
|
|
.fillinsn
|
|
1:
|
|
;; called from user context: previous stack = spu
|
|
mvfc r0, cr3 ; spu
|
|
addi r0, #4
|
|
mvtc r0, cr3 ; spu
|
|
ld r0, @(-4,r0) ; retrieve r0
|
|
.fillinsn
|
|
2:
|
|
.endm
|
|
#endif /* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
|
|
|
|
#endif /* __ASSEMBLY__ */
|
|
|
|
#endif /* _ASM_M32R_ASSEMBLER_H */
|
|
|