diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arc/Kconfig | 8 | ||||
-rw-r--r-- | arch/arc/include/asm/atomic.h | 3 | ||||
-rw-r--r-- | arch/arc/include/asm/entry-arcv2.h | 10 | ||||
-rw-r--r-- | arch/arc/include/asm/ptrace.h | 4 | ||||
-rw-r--r-- | arch/arc/kernel/setup.c | 30 |
5 files changed, 45 insertions, 10 deletions
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index c9f30f4763ab..5d7fb3e7cb97 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -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" diff --git a/arch/arc/include/asm/atomic.h b/arch/arc/include/asm/atomic.h index b65930a49589..54b54da6384c 100644 --- a/arch/arc/include/asm/atomic.h +++ b/arch/arc/include/asm/atomic.h @@ -17,10 +17,11 @@ #include <asm/barrier.h> #include <asm/smp.h> +#define ATOMIC_INIT(i) { (i) } + #ifndef CONFIG_ARC_PLAT_EZNPS #define atomic_read(v) READ_ONCE((v)->counter) -#define ATOMIC_INIT(i) { (i) } #ifdef CONFIG_ARC_HAS_LLSC diff --git a/arch/arc/include/asm/entry-arcv2.h b/arch/arc/include/asm/entry-arcv2.h index aee1a77934cf..ac85380d14a4 100644 --- a/arch/arc/include/asm/entry-arcv2.h +++ b/arch/arc/include/asm/entry-arcv2.h @@ -16,6 +16,11 @@ ; ; Now manually save: r12, sp, fp, gp, r25 +#ifdef CONFIG_ARC_HAS_ACCL_REGS + PUSH r59 + PUSH r58 +#endif + PUSH r30 PUSH r12 @@ -75,6 +80,11 @@ POP r12 POP r30 +#ifdef CONFIG_ARC_HAS_ACCL_REGS + POP r58 + POP r59 +#endif + .endm /*------------------------------------------------------------------------*/ diff --git a/arch/arc/include/asm/ptrace.h b/arch/arc/include/asm/ptrace.h index 47111d565a95..5297faa8a378 100644 --- a/arch/arc/include/asm/ptrace.h +++ b/arch/arc/include/asm/ptrace.h @@ -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; diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c index fa62404ba58f..fc8211f338ad 100644 --- a/arch/arc/kernel/setup.c +++ b/arch/arc/kernel/setup.c @@ -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); } /* |