ARCv2: entry: save Accumulator register pair (r58:59) if present
authorVineet Gupta <vgupta@synopsys.com>
Thu, 20 Apr 2017 22:36:51 +0000 (15:36 -0700)
committerVineet Gupta <vgupta@synopsys.com>
Thu, 20 Apr 2017 22:37:49 +0000 (15:37 -0700)
Accumulator is present in configs with FPU and/or DSP MPY (mpy > 6)

Instead of doing this in pt_regs (and thus every kernel entry/exit),
this could have been done in context switch (and for user task only) as
currently kernel doesn't clobber these registers for its own accord.
However we will soon start using 64-bit multiply instructions for kernel
which can clobber these. Also gcc folks also plan to start using these
as GPRs, hence better to always save/restore them

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
arch/arc/Kconfig
arch/arc/include/asm/entry-arcv2.h
arch/arc/include/asm/ptrace.h
arch/arc/kernel/setup.c

index c9f30f4763abce5ca1ffda1817e87bb5de410861..5d7fb3e7cb97159012d49e6cee745ada293949a6 100644 (file)
@@ -406,6 +406,14 @@ config ARC_HAS_DIV_REM
        bool "Insn: div, divu, rem, remu"
        default y
 
+config ARC_HAS_ACCL_REGS
+       bool "Reg Pair ACCL:ACCH (FPU and/or MPY > 6)"
+       default n
+       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
+
 endif  # ISA_ARCV2
 
 endmenu   # "ARC CPU Configuration"
index aee1a77934cf694e37ae579347a37bc167e43762..ac85380d14a4bb364bb9077e8c8b329f862845b8 100644 (file)
        ;
        ; Now manually save: r12, sp, fp, gp, r25
 
+#ifdef CONFIG_ARC_HAS_ACCL_REGS
+       PUSH    r59
+       PUSH    r58
+#endif
+
        PUSH    r30
        PUSH    r12
 
        POP     r12
        POP     r30
 
+#ifdef CONFIG_ARC_HAS_ACCL_REGS
+       POP     r58
+       POP     r59
+#endif
+
 .endm
 
 /*------------------------------------------------------------------------*/
index 47111d565a959d117ab9e2c7c9eea3b852137971..5297faa8a37803fd702da4270a7e23f5d6ba4f2b 100644 (file)
@@ -86,6 +86,10 @@ struct pt_regs {
 
        unsigned long r12, r30;
 
+#ifdef CONFIG_ARC_HAS_ACCL_REGS
+       unsigned long r58, r59; /* ACCL/ACCH used by FPU / DSP MPY */
+#endif
+
        /*------- Below list auto saved by h/w -----------*/
        unsigned long r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11;
 
index fa62404ba58f77ab9fc24489b35c15132d03d720..fc8211f338ad33cab4036a09693cb77e1ea62a98 100644 (file)
@@ -319,7 +319,8 @@ static char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len)
 static void arc_chk_core_config(void)
 {
        struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
-       int fpu_enabled;
+       int saved = 0, present = 0;
+       char *opt_nm = NULL;;
 
        if (!cpu->extn.timer0)
                panic("Timer0 is not present!\n");
@@ -346,17 +347,28 @@ static void arc_chk_core_config(void)
 
        /*
         * FP hardware/software config sanity
-        * -If hardware contains DPFP, kernel needs to save/restore FPU state
+        * -If hardware present, kernel needs to save/restore FPU state
         * -If not, it will crash trying to save/restore the non-existant regs
-        *
-        * (only DPDP checked since SP has no arch visible regs)
         */
-       fpu_enabled = IS_ENABLED(CONFIG_ARC_FPU_SAVE_RESTORE);
 
-       if (cpu->extn.fpu_dp && !fpu_enabled)
-               pr_warn("CONFIG_ARC_FPU_SAVE_RESTORE needed for working apps\n");
-       else if (!cpu->extn.fpu_dp && fpu_enabled)
-               panic("FPU non-existent, disable CONFIG_ARC_FPU_SAVE_RESTORE\n");
+       if (is_isa_arcompact()) {
+               opt_nm = "CONFIG_ARC_FPU_SAVE_RESTORE";
+               saved = IS_ENABLED(CONFIG_ARC_FPU_SAVE_RESTORE);
+
+               /* only DPDP checked since SP has no arch visible regs */
+               present = cpu->extn.fpu_dp;
+       } else {
+               opt_nm = "CONFIG_ARC_HAS_ACCL_REGS";
+               saved = IS_ENABLED(CONFIG_ARC_HAS_ACCL_REGS);
+
+               /* 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;
+       }
+
+       if (present && !saved)
+               pr_warn("Enable %s for working apps\n", opt_nm);
+       else if (!present && saved)
+               panic("Disable %s, hardware NOT present\n", opt_nm);
 }
 
 /*