123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- /* SPDX-License-Identifier: GPL-2.0-only */
- /*
- * Copyright (C) 2020 Synopsys, Inc. (www.synopsys.com)
- *
- * Author: Eugeniy Paltsev <[email protected]>
- */
- #ifndef __ASM_ARC_DSP_IMPL_H
- #define __ASM_ARC_DSP_IMPL_H
- #include <asm/dsp.h>
- #define DSP_CTRL_DISABLED_ALL 0
- #ifdef __ASSEMBLY__
- /* clobbers r5 register */
- .macro DSP_EARLY_INIT
- #ifdef CONFIG_ISA_ARCV2
- lr r5, [ARC_AUX_DSP_BUILD]
- bmsk r5, r5, 7
- breq r5, 0, 1f
- mov r5, DSP_CTRL_DISABLED_ALL
- sr r5, [ARC_AUX_DSP_CTRL]
- 1:
- #endif
- .endm
- /* clobbers r10, r11 registers pair */
- .macro DSP_SAVE_REGFILE_IRQ
- #if defined(CONFIG_ARC_DSP_KERNEL)
- /*
- * Drop any changes to DSP_CTRL made by userspace so userspace won't be
- * able to break kernel - reset it to DSP_CTRL_DISABLED_ALL value
- */
- mov r10, DSP_CTRL_DISABLED_ALL
- sr r10, [ARC_AUX_DSP_CTRL]
- #elif defined(CONFIG_ARC_DSP_SAVE_RESTORE_REGS)
- /*
- * Save DSP_CTRL register and reset it to value suitable for kernel
- * (DSP_CTRL_DISABLED_ALL)
- */
- mov r10, DSP_CTRL_DISABLED_ALL
- aex r10, [ARC_AUX_DSP_CTRL]
- st r10, [sp, PT_DSP_CTRL]
- #endif
- .endm
- /* clobbers r10, r11 registers pair */
- .macro DSP_RESTORE_REGFILE_IRQ
- #if defined(CONFIG_ARC_DSP_SAVE_RESTORE_REGS)
- ld r10, [sp, PT_DSP_CTRL]
- sr r10, [ARC_AUX_DSP_CTRL]
- #endif
- .endm
- #else /* __ASEMBLY__ */
- #include <linux/sched.h>
- #include <asm/asserts.h>
- #include <asm/switch_to.h>
- #ifdef CONFIG_ARC_DSP_SAVE_RESTORE_REGS
- /*
- * As we save new and restore old AUX register value in the same place we
- * can optimize a bit and use AEX instruction (swap contents of an auxiliary
- * register with a core register) instead of LR + SR pair.
- */
- #define AUX_SAVE_RESTORE(_saveto, _readfrom, _offt, _aux) \
- do { \
- long unsigned int _scratch; \
- \
- __asm__ __volatile__( \
- "ld %0, [%2, %4] \n" \
- "aex %0, [%3] \n" \
- "st %0, [%1, %4] \n" \
- : \
- "=&r" (_scratch) /* must be early clobber */ \
- : \
- "r" (_saveto), \
- "r" (_readfrom), \
- "Ir" (_aux), \
- "Ir" (_offt) \
- : \
- "memory" \
- ); \
- } while (0)
- #define DSP_AUX_SAVE_RESTORE(_saveto, _readfrom, _aux) \
- AUX_SAVE_RESTORE(_saveto, _readfrom, \
- offsetof(struct dsp_callee_regs, _aux), \
- ARC_AUX_##_aux)
- static inline void dsp_save_restore(struct task_struct *prev,
- struct task_struct *next)
- {
- long unsigned int *saveto = &prev->thread.dsp.ACC0_GLO;
- long unsigned int *readfrom = &next->thread.dsp.ACC0_GLO;
- DSP_AUX_SAVE_RESTORE(saveto, readfrom, ACC0_GLO);
- DSP_AUX_SAVE_RESTORE(saveto, readfrom, ACC0_GHI);
- DSP_AUX_SAVE_RESTORE(saveto, readfrom, DSP_BFLY0);
- DSP_AUX_SAVE_RESTORE(saveto, readfrom, DSP_FFT_CTRL);
- #ifdef CONFIG_ARC_DSP_AGU_USERSPACE
- DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP0);
- DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP1);
- DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP2);
- DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP3);
- DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_OS0);
- DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_OS1);
- DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD0);
- DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD1);
- DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD2);
- DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD3);
- #endif /* CONFIG_ARC_DSP_AGU_USERSPACE */
- }
- #else /* !CONFIG_ARC_DSP_SAVE_RESTORE_REGS */
- #define dsp_save_restore(p, n)
- #endif /* CONFIG_ARC_DSP_SAVE_RESTORE_REGS */
- static inline bool dsp_exist(void)
- {
- struct bcr_generic bcr;
- READ_BCR(ARC_AUX_DSP_BUILD, bcr);
- return !!bcr.ver;
- }
- static inline bool agu_exist(void)
- {
- struct bcr_generic bcr;
- READ_BCR(ARC_AUX_AGU_BUILD, bcr);
- return !!bcr.ver;
- }
- static inline void dsp_config_check(void)
- {
- CHK_OPT_STRICT(CONFIG_ARC_DSP_HANDLED, dsp_exist());
- CHK_OPT_WEAK(CONFIG_ARC_DSP_AGU_USERSPACE, agu_exist());
- }
- #endif /* __ASEMBLY__ */
- #endif /* __ASM_ARC_DSP_IMPL_H */
|