ARC: handle DSP presence in HW
authorEugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
Thu, 5 Mar 2020 20:02:50 +0000 (23:02 +0300)
committerVineet Gupta <vgupta@synopsys.com>
Mon, 16 Mar 2020 17:23:44 +0000 (10:23 -0700)
When DSP extensions are present, some of the regular integer instructions
such as DIV, MACD etc are executed in the DSP unit with semantics alterable
by flags in DSP_CTRL aux register. This register is writable by userspace
and thus can potentially affect corresponding instructions in kernel code,
intentionally or otherwise. So safegaurd kernel by effectively disabling
DSP_CTRL upon bootup and every entry to kernel.

Do note that for this config we simply zero out the DSP_CTRL reg assuming
userspace doesn't really care about DSP. The next patch caters to the DSP
aware userspace where this reg is saved/restored upon kernel entry/exit.

Reviewed-by: Vineet Gupta <vgupta@synopsys.com>
Signed-off-by: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
arch/arc/Kconfig
arch/arc/include/asm/arcregs.h
arch/arc/include/asm/dsp-impl.h [new file with mode: 0644]
arch/arc/include/asm/entry-arcv2.h
arch/arc/kernel/head.S
arch/arc/kernel/setup.c

index 7124ab8..55432a8 100644 (file)
@@ -401,13 +401,40 @@ config ARC_HAS_DIV_REM
        default y
 
 config ARC_HAS_ACCL_REGS
-       bool "Reg Pair ACCL:ACCH (FPU and/or MPY > 6)"
+       bool "Reg Pair ACCL:ACCH (FPU and/or MPY > 6 and/or DSP)"
        default y
        help
          Depending on the configuration, CPU can contain accumulator reg-pair
          (also referred to as r58:r59). These can also be used by gcc as GPR so
          kernel needs to save/restore per process
 
+config ARC_DSP_HANDLED
+       def_bool n
+
+choice
+       prompt "DSP support"
+       default ARC_DSP_NONE
+       help
+         Depending on the configuration, CPU can contain DSP registers
+         (ACC0_GLO, ACC0_GHI, DSP_BFLY0, DSP_CTRL, DSP_FFT_CTRL).
+         Bellow is options describing how to handle these registers in
+         interrupt entry / exit and in context switch.
+
+config ARC_DSP_NONE
+       bool "No DSP extension presence in HW"
+       help
+         No DSP extension presence in HW
+
+config ARC_DSP_KERNEL
+       bool "DSP extension in HW, no support for userspace"
+       select ARC_HAS_ACCL_REGS
+       select ARC_DSP_HANDLED
+       help
+         DSP extension presence in HW, no support for DSP-enabled userspace
+         applications. We don't save / restore DSP registers and only do
+         some minimal preparations so userspace won't be able to break kernel
+endchoice
+
 config ARC_IRQ_NO_AUTOSAVE
        bool "Disable hardware autosave regfile on interrupts"
        default n
index f7e4324..135f6ec 100644 (file)
 #define ARC_AUX_DPFP_2H         0x304
 #define ARC_AUX_DPFP_STAT       0x305
 
+/*
+ * DSP-related registers
+ */
+#define ARC_AUX_DSP_BUILD      0x7A
+#define ARC_AUX_ACC0_LO                0x580
+#define ARC_AUX_ACC0_GLO       0x581
+#define ARC_AUX_ACC0_HI                0x582
+#define ARC_AUX_ACC0_GHI       0x583
+#define ARC_AUX_DSP_BFLY0      0x598
+#define ARC_AUX_DSP_CTRL       0x59F
+#define ARC_AUX_DSP_FFT_CTRL   0x59E
+
 #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
new file mode 100644 (file)
index 0000000..6066203
--- /dev/null
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2020 Synopsys, Inc. (www.synopsys.com)
+ *
+ * Author: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
+ */
+#ifndef __ASM_ARC_DSP_IMPL_H
+#define __ASM_ARC_DSP_IMPL_H
+
+#define DSP_CTRL_DISABLED_ALL          0
+
+#ifdef __ASSEMBLY__
+
+/* clobbers r5 register */
+.macro DSP_EARLY_INIT
+       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:
+.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]
+#endif /* ARC_DSP_KERNEL */
+.endm
+
+#else /* __ASEMBLY__ */
+
+#include <asm/asserts.h>
+
+static inline bool dsp_exist(void)
+{
+       struct bcr_generic bcr;
+
+       READ_BCR(ARC_AUX_DSP_BUILD, bcr);
+       return !!bcr.ver;
+}
+
+static inline void dsp_config_check(void)
+{
+       CHK_OPT_STRICT(CONFIG_ARC_DSP_HANDLED, dsp_exist());
+}
+
+#endif /* __ASEMBLY__ */
+#endif /* __ASM_ARC_DSP_IMPL_H */
index 0b8b63d..dd6aa18 100644 (file)
@@ -4,6 +4,7 @@
 #define __ASM_ARC_ENTRY_ARCV2_H
 
 #include <asm/asm-offsets.h>
+#include <asm/dsp-impl.h>
 #include <asm/irqflags-arcv2.h>
 #include <asm/thread_info.h>   /* For THREAD_SIZE */
 
        ST2     r58, r59, PT_r58
 #endif
 
+       /* clobbers r10, r11 registers pair */
+       DSP_SAVE_REGFILE_IRQ
 .endm
 
 /*------------------------------------------------------------------------*/
index 6f41265..6eb23f1 100644 (file)
@@ -14,6 +14,7 @@
 #include <asm/entry.h>
 #include <asm/arcregs.h>
 #include <asm/cache.h>
+#include <asm/dsp-impl.h>
 #include <asm/irqflags.h>
 
 .macro CPU_EARLY_SETUP
@@ -59,6 +60,9 @@
 #endif
        kflag   r5
 #endif
+       ; Config DSP_CTRL properly, so kernel may use integer multiply,
+       ; multiply-accumulate, and divide operations
+       DSP_EARLY_INIT
 .endm
 
        .section .init.text, "ax",@progbits
index 820c0cf..1ed1528 100644 (file)
@@ -27,6 +27,7 @@
 #include <asm/unwind.h>
 #include <asm/mach_desc.h>
 #include <asm/smp.h>
+#include <asm/dsp-impl.h>
 
 #define FIX_PTR(x)  __asm__ __volatile__(";" : "+r"(x))
 
@@ -440,6 +441,8 @@ static void arc_chk_core_config(void)
                /* Accumulator Low:High pair (r58:59) present if DSP MPY or FPU */
                present = cpu->extn_mpy.dsp | cpu->extn.fpu_sp | cpu->extn.fpu_dp;
                CHK_OPT_STRICT(CONFIG_ARC_HAS_ACCL_REGS, present);
+
+               dsp_config_check();
        }
 }