Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Copyright (C) 2020 Synopsys, Inc. (www.synopsys.com)
4 *
5 * Author: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
6 */
7#ifndef __ASM_ARC_DSP_IMPL_H
8#define __ASM_ARC_DSP_IMPL_H
9
10#include <asm/dsp.h>
11
12#define DSP_CTRL_DISABLED_ALL 0
13
14#ifdef __ASSEMBLY__
15
16/* clobbers r5 register */
17.macro DSP_EARLY_INIT
18 lr r5, [ARC_AUX_DSP_BUILD]
19 bmsk r5, r5, 7
20 breq r5, 0, 1f
21 mov r5, DSP_CTRL_DISABLED_ALL
22 sr r5, [ARC_AUX_DSP_CTRL]
231:
24.endm
25
26/* clobbers r10, r11 registers pair */
27.macro DSP_SAVE_REGFILE_IRQ
28#if defined(CONFIG_ARC_DSP_KERNEL)
29 /*
30 * Drop any changes to DSP_CTRL made by userspace so userspace won't be
31 * able to break kernel - reset it to DSP_CTRL_DISABLED_ALL value
32 */
33 mov r10, DSP_CTRL_DISABLED_ALL
34 sr r10, [ARC_AUX_DSP_CTRL]
35
36#elif defined(CONFIG_ARC_DSP_SAVE_RESTORE_REGS)
37 /*
38 * Save DSP_CTRL register and reset it to value suitable for kernel
39 * (DSP_CTRL_DISABLED_ALL)
40 */
41 mov r10, DSP_CTRL_DISABLED_ALL
42 aex r10, [ARC_AUX_DSP_CTRL]
43 st r10, [sp, PT_DSP_CTRL]
44
45#endif
46.endm
47
48/* clobbers r10, r11 registers pair */
49.macro DSP_RESTORE_REGFILE_IRQ
50#if defined(CONFIG_ARC_DSP_SAVE_RESTORE_REGS)
51 ld r10, [sp, PT_DSP_CTRL]
52 sr r10, [ARC_AUX_DSP_CTRL]
53
54#endif
55.endm
56
57#else /* __ASEMBLY__ */
58
59#include <linux/sched.h>
60#include <asm/asserts.h>
61#include <asm/switch_to.h>
62
63#ifdef CONFIG_ARC_DSP_SAVE_RESTORE_REGS
64
65/*
66 * As we save new and restore old AUX register value in the same place we
67 * can optimize a bit and use AEX instruction (swap contents of an auxiliary
68 * register with a core register) instead of LR + SR pair.
69 */
70#define AUX_SAVE_RESTORE(_saveto, _readfrom, _offt, _aux) \
71do { \
72 long unsigned int _scratch; \
73 \
74 __asm__ __volatile__( \
75 "ld %0, [%2, %4] \n" \
76 "aex %0, [%3] \n" \
77 "st %0, [%1, %4] \n" \
78 : \
79 "=&r" (_scratch) /* must be early clobber */ \
80 : \
81 "r" (_saveto), \
82 "r" (_readfrom), \
83 "Ir" (_aux), \
84 "Ir" (_offt) \
85 : \
86 "memory" \
87 ); \
88} while (0)
89
90#define DSP_AUX_SAVE_RESTORE(_saveto, _readfrom, _aux) \
91 AUX_SAVE_RESTORE(_saveto, _readfrom, \
92 offsetof(struct dsp_callee_regs, _aux), \
93 ARC_AUX_##_aux)
94
95static inline void dsp_save_restore(struct task_struct *prev,
96 struct task_struct *next)
97{
98 long unsigned int *saveto = &prev->thread.dsp.ACC0_GLO;
99 long unsigned int *readfrom = &next->thread.dsp.ACC0_GLO;
100
101 DSP_AUX_SAVE_RESTORE(saveto, readfrom, ACC0_GLO);
102 DSP_AUX_SAVE_RESTORE(saveto, readfrom, ACC0_GHI);
103
104 DSP_AUX_SAVE_RESTORE(saveto, readfrom, DSP_BFLY0);
105 DSP_AUX_SAVE_RESTORE(saveto, readfrom, DSP_FFT_CTRL);
106
107#ifdef CONFIG_ARC_DSP_AGU_USERSPACE
108 DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP0);
109 DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP1);
110 DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP2);
111 DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP3);
112
113 DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_OS0);
114 DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_OS1);
115
116 DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD0);
117 DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD1);
118 DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD2);
119 DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD3);
120#endif /* CONFIG_ARC_DSP_AGU_USERSPACE */
121}
122
123#else /* !CONFIG_ARC_DSP_SAVE_RESTORE_REGS */
124#define dsp_save_restore(p, n)
125#endif /* CONFIG_ARC_DSP_SAVE_RESTORE_REGS */
126
127static inline bool dsp_exist(void)
128{
129 struct bcr_generic bcr;
130
131 READ_BCR(ARC_AUX_DSP_BUILD, bcr);
132 return !!bcr.ver;
133}
134
135static inline bool agu_exist(void)
136{
137 struct bcr_generic bcr;
138
139 READ_BCR(ARC_AUX_AGU_BUILD, bcr);
140 return !!bcr.ver;
141}
142
143static inline void dsp_config_check(void)
144{
145 CHK_OPT_STRICT(CONFIG_ARC_DSP_HANDLED, dsp_exist());
146 CHK_OPT_WEAK(CONFIG_ARC_DSP_AGU_USERSPACE, agu_exist());
147}
148
149#endif /* __ASEMBLY__ */
150#endif /* __ASM_ARC_DSP_IMPL_H */