[PATCH 5/5] ARC: allow userspace DSP applications to use AGU extensions

From: Eugeniy Paltsev
Date: Fri Dec 27 2019 - 13:04:12 EST


To be able to run DSP-enabled userspace applications with AGU
(address generation unit) extensions we additionally need to
save and restore following registers at context switch:
* AGU_AP*
* AGU_OS*
* AGU_MOD*

Signed-off-by: Eugeniy Paltsev <Eugeniy.Paltsev@xxxxxxxxxxxx>
---
arch/arc/Kconfig | 7 +++++++
arch/arc/include/asm/arcregs.h | 12 ++++++++++++
arch/arc/include/asm/dsp-impl.h | 23 +++++++++++++++++++++++
arch/arc/include/asm/dsp.h | 12 ++++++++++--
arch/arc/kernel/setup.c | 14 ++++++++++++++
5 files changed, 66 insertions(+), 2 deletions(-)

diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index c3210754a3d2..c27bb7900ebd 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -439,6 +439,13 @@ config ARC_DSP_USERSPACE
help
DSP extension presence in HW, support save / restore DSP registers to
run DSP-enabled userspace applications
+
+config ARC_DSP_AGU_USERSPACE
+ bool "Support DSP with AGU for userspace apps"
+ select ARC_HAS_ACCL_REGS
+ help
+ DSP and AGU extensions presence in HW, support save / restore DSP
+ and AGU registers to run DSP-enabled userspace applications
endchoice

config ARC_IRQ_NO_AUTOSAVE
diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h
index a713819cab3c..9f6abed8a336 100644
--- a/arch/arc/include/asm/arcregs.h
+++ b/arch/arc/include/asm/arcregs.h
@@ -130,6 +130,18 @@
#define ARC_AUX_DSP_CTRL 0x59F
#define ARC_AUX_DSP_FFT_CTRL 0x59E

+#define ARC_AUX_AGU_BUILD 0xCC
+#define ARC_AUX_AGU_AP0 0x5C0
+#define ARC_AUX_AGU_AP1 0x5C1
+#define ARC_AUX_AGU_AP2 0x5C2
+#define ARC_AUX_AGU_AP3 0x5C3
+#define ARC_AUX_AGU_OS0 0x5D0
+#define ARC_AUX_AGU_OS1 0x5D1
+#define ARC_AUX_AGU_MOD0 0x5E0
+#define ARC_AUX_AGU_MOD1 0x5E1
+#define ARC_AUX_AGU_MOD2 0x5E2
+#define ARC_AUX_AGU_MOD3 0x5E3
+
#ifndef __ASSEMBLY__

#include <soc/arc/aux.h>
diff --git a/arch/arc/include/asm/dsp-impl.h b/arch/arc/include/asm/dsp-impl.h
index 7b640a680dfc..d352be2d9f07 100644
--- a/arch/arc/include/asm/dsp-impl.h
+++ b/arch/arc/include/asm/dsp-impl.h
@@ -100,6 +100,21 @@ static inline void arc_dsp_save_restore(struct task_struct *prev,

DSP_AUX_SAVE_RESTORE(saveto, readfrom, DSP_BFLY0, zero);
DSP_AUX_SAVE_RESTORE(saveto, readfrom, DSP_FFT_CTRL, zero);
+
+#ifdef CONFIG_ARC_DSP_AGU_USERSPACE
+ DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP0, zero);
+ DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP1, zero);
+ DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP2, zero);
+ DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP3, zero);
+
+ DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_OS0, zero);
+ DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_OS1, zero);
+
+ DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD0, zero);
+ DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD1, zero);
+ DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD2, zero);
+ DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD3, zero);
+#endif /* CONFIG_ARC_DSP_AGU_USERSPACE */
}

#else /* !ARC_DSP_SAVE_RESTORE_REGS */
@@ -114,5 +129,13 @@ static inline bool dsp_exist(void)
return !!bcr.ver;
}

+static inline bool agu_exist(void)
+{
+ struct bcr_generic bcr;
+
+ READ_BCR(ARC_AUX_AGU_BUILD, bcr);
+ return !!bcr.ver;
+}
+
#endif /* __ASEMBLY__ */
#endif /* __ASM_ARC_DSP_IMPL_H */
diff --git a/arch/arc/include/asm/dsp.h b/arch/arc/include/asm/dsp.h
index 68507f04dea4..1619cf9c6d28 100644
--- a/arch/arc/include/asm/dsp.h
+++ b/arch/arc/include/asm/dsp.h
@@ -7,7 +7,7 @@
#ifndef __ASM_ARC_DSP_H
#define __ASM_ARC_DSP_H

-#if defined(CONFIG_ARC_DSP_USERSPACE)
+#if defined(CONFIG_ARC_DSP_USERSPACE) || defined(CONFIG_ARC_DSP_AGU_USERSPACE)
#define ARC_DSP_SAVE_RESTORE_REGS 1
#endif

@@ -15,7 +15,8 @@

/* some defines to simplify config sanitize in kernel/setup.c */
#if defined(CONFIG_ARC_DSP_KERNEL) || \
- defined(CONFIG_ARC_DSP_USERSPACE)
+ defined(CONFIG_ARC_DSP_USERSPACE) || \
+ defined(CONFIG_ARC_DSP_AGU_USERSPACE)
#define ARC_DSP_HANDLED 1
#else
#define ARC_DSP_HANDLED 0
@@ -23,6 +24,8 @@

#if defined(CONFIG_ARC_DSP_USERSPACE)
#define ARC_DSP_OPT_NAME "CONFIG_ARC_DSP_USERSPACE"
+#elif defined(CONFIG_ARC_DSP_AGU_USERSPACE)
+#define ARC_DSP_OPT_NAME "CONFIG_ARC_DSP_AGU_USERSPACE"
#else
#define ARC_DSP_OPT_NAME "CONFIG_ARC_DSP_KERNEL"
#endif
@@ -35,6 +38,11 @@
*/
struct dsp_callee_regs {
unsigned long DSP_BFLY0, DSP_FFT_CTRL;
+#ifdef CONFIG_ARC_DSP_AGU_USERSPACE
+ unsigned long AGU_AP0, AGU_AP1, AGU_AP2, AGU_AP3;
+ unsigned long AGU_OS0, AGU_OS1;
+ unsigned long AGU_MOD0, AGU_MOD1, AGU_MOD2, AGU_MOD3;
+#endif
};

#endif /* !__ASSEMBLY__ */
diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c
index 30d31579c51d..17d58ec69113 100644
--- a/arch/arc/kernel/setup.c
+++ b/arch/arc/kernel/setup.c
@@ -398,11 +398,22 @@ static void chk_opt_strict(char *opt_name, bool hw_exists, bool opt_ena)
panic("Disable %s, hardware NOT present\n", opt_name);
}

+static void chk_opt_weak(char *opt_name, bool hw_exists, bool opt_ena)
+{
+ if (!hw_exists && opt_ena)
+ panic("Disable %s, hardware NOT present\n", opt_name);
+}
+
#define CHK_OPT_STRICT(opt_name, hw_exists) \
({ \
chk_opt_strict(#opt_name, hw_exists, IS_ENABLED(opt_name)); \
})

+#define CHK_OPT_WEAK(opt_name, hw_exists) \
+({ \
+ chk_opt_weak(#opt_name, hw_exists, IS_ENABLED(opt_name)); \
+})
+
static void arc_chk_core_config(void)
{
struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
@@ -448,6 +459,9 @@ static void arc_chk_core_config(void)

present = dsp_exist();
chk_opt_strict(ARC_DSP_OPT_NAME, present, ARC_DSP_HANDLED);
+
+ present = agu_exist();
+ CHK_OPT_WEAK(CONFIG_ARC_DSP_AGU_USERSPACE, present);
}
}

--
2.21.0