mirror of https://github.com/Qortal/Brooklyn
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.
152 lines
3.8 KiB
152 lines
3.8 KiB
/* 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 */
|
|
|