You've already forked linux-rockchip
mirror of
https://github.com/armbian/linux-rockchip.git
synced 2026-01-06 11:08:10 -08:00
sh: SH-2A FPU support.
Signed-off-by: Kieran Bingham <kbingham@mpc-data.co.uk> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
This commit is contained in:
@@ -161,6 +161,7 @@ config CPU_SUBTYPE_SH7619
|
||||
config CPU_SUBTYPE_SH7203
|
||||
bool "Support SH7203 processor"
|
||||
select CPU_SH2A
|
||||
select CPU_HAS_FPU
|
||||
|
||||
config CPU_SUBTYPE_SH7206
|
||||
bool "Support SH7206 processor"
|
||||
@@ -169,6 +170,7 @@ config CPU_SUBTYPE_SH7206
|
||||
config CPU_SUBTYPE_SH7263
|
||||
bool "Support SH7263 processor"
|
||||
select CPU_SH2A
|
||||
select CPU_HAS_FPU
|
||||
|
||||
# SH-3 Processor Support
|
||||
|
||||
|
||||
@@ -20,10 +20,6 @@ isa-$(CONFIG_CPU_SH4AL_DSP) := sh4al
|
||||
isa-$(CONFIG_CPU_SH5) := shmedia
|
||||
isa-$(CONFIG_SH_DSP) := $(isa-y)-dsp
|
||||
|
||||
ifndef CONFIG_MMU
|
||||
isa-y := $(isa-y)-nommu
|
||||
endif
|
||||
|
||||
ifndef CONFIG_SH_DSP
|
||||
ifndef CONFIG_SH_FPU
|
||||
isa-y := $(isa-y)-nofpu
|
||||
|
||||
@@ -149,6 +149,14 @@ ENTRY(exception_handler)
|
||||
mov #32,r8
|
||||
cmp/hs r8,r9
|
||||
bt trap_entry ! 64 > vec >= 32 is trap
|
||||
|
||||
#if defined(CONFIG_SH_FPU)
|
||||
mov #13,r8
|
||||
cmp/eq r8,r9
|
||||
bt 10f ! fpu
|
||||
nop
|
||||
#endif
|
||||
|
||||
mov.l 4f,r8
|
||||
mov r9,r4
|
||||
shll2 r9
|
||||
@@ -158,6 +166,10 @@ ENTRY(exception_handler)
|
||||
cmp/eq r9,r8
|
||||
bf 3f
|
||||
mov.l 8f,r8 ! unhandled exception
|
||||
#if defined(CONFIG_SH_FPU)
|
||||
10:
|
||||
mov.l 9f, r8 ! unhandled exception
|
||||
#endif
|
||||
3:
|
||||
mov.l 5f,r10
|
||||
jmp @r8
|
||||
@@ -177,7 +189,10 @@ interrupt_entry:
|
||||
6: .long ret_from_irq
|
||||
7: .long do_IRQ
|
||||
8: .long do_exception_error
|
||||
|
||||
#ifdef CONFIG_SH_FPU
|
||||
9: .long fpu_error_trap_handler
|
||||
#endif
|
||||
|
||||
trap_entry:
|
||||
mov #0x30,r8
|
||||
cmp/ge r8,r9 ! vector 0x20-0x2f is systemcall
|
||||
|
||||
@@ -6,6 +6,8 @@ obj-y := common.o probe.o opcode_helper.o
|
||||
|
||||
common-y += $(addprefix ../sh2/, ex.o entry.o)
|
||||
|
||||
obj-$(CONFIG_SH_FPU) += fpu.o
|
||||
|
||||
obj-$(CONFIG_CPU_SUBTYPE_SH7206) += setup-sh7206.o clock-sh7206.o
|
||||
obj-$(CONFIG_CPU_SUBTYPE_SH7203) += setup-sh7203.o clock-sh7203.o
|
||||
obj-$(CONFIG_CPU_SUBTYPE_SH7263) += setup-sh7203.o clock-sh7203.o
|
||||
|
||||
633
arch/sh/kernel/cpu/sh2a/fpu.c
Normal file
633
arch/sh/kernel/cpu/sh2a/fpu.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -36,7 +36,7 @@ ENTRY(exception_handling_table)
|
||||
.long exception_error ! address error store /* 100 */
|
||||
#endif
|
||||
#if defined(CONFIG_SH_FPU)
|
||||
.long do_fpu_error /* 120 */
|
||||
.long fpu_error_trap_handler /* 120 */
|
||||
#else
|
||||
.long exception_error /* 120 */
|
||||
#endif
|
||||
|
||||
@@ -82,8 +82,8 @@ save_fpu(struct task_struct *tsk, struct pt_regs *regs)
|
||||
"r" (FPSCR_INIT)
|
||||
: "memory");
|
||||
|
||||
disable_fpu();
|
||||
release_fpu(regs);
|
||||
disable_fpu();
|
||||
release_fpu(regs);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -91,7 +91,7 @@ restore_fpu(struct task_struct *tsk)
|
||||
{
|
||||
unsigned long dummy;
|
||||
|
||||
enable_fpu();
|
||||
enable_fpu();
|
||||
asm volatile("lds %2, fpscr\n\t"
|
||||
"fmov.s @%0+, fr0\n\t"
|
||||
"fmov.s @%0+, fr1\n\t"
|
||||
@@ -138,7 +138,7 @@ restore_fpu(struct task_struct *tsk)
|
||||
/*
|
||||
* Load the FPU with signalling NANS. This bit pattern we're using
|
||||
* has the property that no matter wether considered as single or as
|
||||
* double precision represents signaling NANS.
|
||||
* double precision represents signaling NANS.
|
||||
*/
|
||||
|
||||
static void
|
||||
@@ -184,7 +184,7 @@ fpu_init(void)
|
||||
"lds %2, fpscr\n\t"
|
||||
: /* no output */
|
||||
: "r" (0), "r" (FPSCR_RCHG), "r" (FPSCR_INIT));
|
||||
disable_fpu();
|
||||
disable_fpu();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -238,7 +238,6 @@ ieee_fpe_handler (struct pt_regs *regs)
|
||||
if (nib[0] == 0xb ||
|
||||
(nib[0] == 0x4 && nib[2] == 0x0 && nib[3] == 0xb)) /* bsr & jsr */
|
||||
regs->pr = regs->pc + 4;
|
||||
|
||||
if (nib[0] == 0xa || nib[0] == 0xb) { /* bra & bsr */
|
||||
nextpc = regs->pc + 4 + ((short) ((insn & 0xfff) << 4) >> 3);
|
||||
finsn = *(unsigned short *) (regs->pc + 2);
|
||||
@@ -293,12 +292,10 @@ ieee_fpe_handler (struct pt_regs *regs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
asmlinkage void
|
||||
do_fpu_error(unsigned long r4, unsigned long r5, unsigned long r6,
|
||||
unsigned long r7, struct pt_regs __regs)
|
||||
BUILD_TRAP_HANDLER(fpu_error)
|
||||
{
|
||||
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
|
||||
struct task_struct *tsk = current;
|
||||
TRAP_HANDLER_DECL;
|
||||
|
||||
if (ieee_fpe_handler(regs))
|
||||
return;
|
||||
@@ -308,12 +305,10 @@ do_fpu_error(unsigned long r4, unsigned long r5, unsigned long r6,
|
||||
force_sig(SIGFPE, tsk);
|
||||
}
|
||||
|
||||
asmlinkage void
|
||||
do_fpu_state_restore(unsigned long r4, unsigned long r5, unsigned long r6,
|
||||
unsigned long r7, struct pt_regs __regs)
|
||||
BUILD_TRAP_HANDLER(fpu_state_restore)
|
||||
{
|
||||
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
|
||||
struct task_struct *tsk = current;
|
||||
TRAP_HANDLER_DECL;
|
||||
|
||||
grab_fpu(regs);
|
||||
if (!user_mode(regs)) {
|
||||
|
||||
@@ -662,11 +662,6 @@ asmlinkage void do_divide_error(unsigned long r4, unsigned long r5,
|
||||
}
|
||||
#endif
|
||||
|
||||
/* arch/sh/kernel/cpu/sh4/fpu.c */
|
||||
extern int do_fpu_inst(unsigned short, struct pt_regs *);
|
||||
extern asmlinkage void do_fpu_state_restore(unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, unsigned long r7, struct pt_regs __regs);
|
||||
|
||||
asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, unsigned long r7,
|
||||
struct pt_regs __regs)
|
||||
@@ -853,11 +848,11 @@ void __init trap_init(void)
|
||||
set_exception_table_evt(0x820, do_illegal_slot_inst);
|
||||
#elif defined(CONFIG_SH_FPU)
|
||||
#ifdef CONFIG_CPU_SUBTYPE_SHX3
|
||||
set_exception_table_evt(0xd80, do_fpu_state_restore);
|
||||
set_exception_table_evt(0xda0, do_fpu_state_restore);
|
||||
set_exception_table_evt(0xd80, fpu_state_restore_trap_handler);
|
||||
set_exception_table_evt(0xda0, fpu_state_restore_trap_handler);
|
||||
#else
|
||||
set_exception_table_evt(0x800, do_fpu_state_restore);
|
||||
set_exception_table_evt(0x820, do_fpu_state_restore);
|
||||
set_exception_table_evt(0x800, fpu_state_restore_trap_handler);
|
||||
set_exception_table_evt(0x820, fpu_state_restore_trap_handler);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@ extern void save_fpu(struct task_struct *__tsk, struct pt_regs *regs);
|
||||
#define save_fpu(tsk, regs) do { } while (0)
|
||||
#endif
|
||||
|
||||
extern int do_fpu_inst(unsigned short, struct pt_regs *);
|
||||
|
||||
#define unlazy_fpu(tsk, regs) do { \
|
||||
if (test_tsk_thread_flag(tsk, TIF_USEDFPU)) { \
|
||||
save_fpu(tsk, regs); \
|
||||
|
||||
@@ -25,7 +25,8 @@ struct sigcontext {
|
||||
unsigned long sc_mach;
|
||||
unsigned long sc_macl;
|
||||
|
||||
#if defined(__SH4__) || defined(CONFIG_CPU_SH4)
|
||||
#if defined(__SH4__) || defined(CONFIG_CPU_SH4) || \
|
||||
defined(__SH2A__) || defined(CONFIG_CPU_SH2A)
|
||||
/* FPU registers */
|
||||
unsigned long sc_fpregs[16];
|
||||
unsigned long sc_xfpregs[16];
|
||||
|
||||
@@ -205,6 +205,8 @@ asmlinkage void name##_trap_handler(unsigned int vec, struct pt_regs *regs)
|
||||
BUILD_TRAP_HANDLER(address_error);
|
||||
BUILD_TRAP_HANDLER(debug);
|
||||
BUILD_TRAP_HANDLER(bug);
|
||||
BUILD_TRAP_HANDLER(fpu_error);
|
||||
BUILD_TRAP_HANDLER(fpu_state_restore);
|
||||
|
||||
#define arch_align_stack(x) (x)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user