Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a36d8225 authored by David Daney's avatar David Daney Committed by Ralf Baechle
Browse files

MIPS: OCTEON: Enable use of FPU



Some versions of the assembler will not assemble CFC1 for OCTEON, so
override the ISA for these.

Add r4k_fpu.o to handle low level FPU initialization.

Modify octeon_switch.S to save the FPU registers.  And include
r4k_switch.S to pick up more FPU support.

Get rid of "#define cpu_has_fpu		0"

Signed-off-by: default avatarDavid Daney <david.daney@cavium.com>
Signed-off-by: default avatarAndreas Herrmann <andreas.herrmann@caviumnetworks.com>
Cc: linux-mips@linux-mips.org
Cc: James Hogan <james.hogan@imgtec.com>
Cc: kvm@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/7006/


Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent dadaa1c2
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@
#define cpu_has_3k_cache	0
#define cpu_has_4k_cache	0
#define cpu_has_tx39_cache	0
#define cpu_has_fpu		0
#define cpu_has_counter		1
#define cpu_has_watch		1
#define cpu_has_divec		1
+1 −1
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ obj-$(CONFIG_CPU_R4K_FPU) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_CPU_R3000)		+= r2300_fpu.o r2300_switch.o
obj-$(CONFIG_CPU_R6000)		+= r6000_fpu.o r4k_switch.o
obj-$(CONFIG_CPU_TX39XX)	+= r2300_fpu.o r2300_switch.o
obj-$(CONFIG_CPU_CAVIUM_OCTEON) += octeon_switch.o
obj-$(CONFIG_CPU_CAVIUM_OCTEON)	+= r4k_fpu.o octeon_switch.o

obj-$(CONFIG_SMP)		+= smp.o
obj-$(CONFIG_SMP_UP)		+= smp-up.o
+5 −1
Original line number Diff line number Diff line
@@ -562,7 +562,11 @@ int __compute_return_epc_for_insn(struct pt_regs *regs,
	case cop1_op:
		preempt_disable();
		if (is_fpu_owner())
			asm volatile("cfc1\t%0,$31" : "=r" (fcr31));
			asm volatile(
				".set push\n"
				"\t.set mips1\n"
				"\tcfc1\t%0,$31\n"
				"\t.set pop" : "=r" (fcr31));
		else
			fcr31 = current->thread.fpu.fcr31;
		preempt_enable();
+61 −23
Original line number Diff line number Diff line
@@ -10,24 +10,12 @@
 * Copyright (C) 2000 MIPS Technologies, Inc.
 *    written by Carsten Langgaard, carstenl@mips.com
 */
#include <asm/asm.h>
#include <asm/cachectl.h>
#include <asm/fpregdef.h>
#include <asm/mipsregs.h>
#include <asm/asm-offsets.h>
#include <asm/pgtable-bits.h>
#include <asm/regdef.h>
#include <asm/stackframe.h>
#include <asm/thread_info.h>

#include <asm/asmmacro.h>

/*
 * Offset to the current process status flags, the first 32 bytes of the
 * stack are not used.
 */
#define ST_OFF (_THREAD_SIZE - 32 - PT_SIZE + PT_STATUS)

#define USE_ALTERNATE_RESUME_IMPL 1
	.set push
	.set arch=mips64r2
#include "r4k_switch.S"
	.set pop
/*
 * task_struct *resume(task_struct *prev, task_struct *next,
 *		       struct thread_info *next_ti, int usedfpu)
@@ -40,6 +28,61 @@
	cpu_save_nonscratch a0
	LONG_S	ra, THREAD_REG31(a0)

	/*
	 * check if we need to save FPU registers
	 */
	PTR_L	t3, TASK_THREAD_INFO(a0)
	LONG_L	t0, TI_FLAGS(t3)
	li	t1, _TIF_USEDFPU
	and	t2, t0, t1
	beqz	t2, 1f
	nor	t1, zero, t1

	and	t0, t0, t1
	LONG_S	t0, TI_FLAGS(t3)

	/*
	 * clear saved user stack CU1 bit
	 */
	LONG_L	t0, ST_OFF(t3)
	li	t1, ~ST0_CU1
	and	t0, t0, t1
	LONG_S	t0, ST_OFF(t3)

	.set push
	.set arch=mips64r2
	fpu_save_double a0 t0 t1		# c0_status passed in t0
						# clobbers t1
	.set pop
1:

	/* check if we need to save COP2 registers */
	PTR_L	t2, TASK_THREAD_INFO(a0)
	LONG_L	t0, ST_OFF(t2)
	bbit0	t0, 30, 1f

	/* Disable COP2 in the stored process state */
	li	t1, ST0_CU2
	xor	t0, t1
	LONG_S	t0, ST_OFF(t2)

	/* Enable COP2 so we can save it */
	mfc0	t0, CP0_STATUS
	or	t0, t1
	mtc0	t0, CP0_STATUS

	/* Save COP2 */
	daddu	a0, THREAD_CP2
	jal octeon_cop2_save
	dsubu	a0, THREAD_CP2

	/* Disable COP2 now that we are done */
	mfc0	t0, CP0_STATUS
	li	t1, ST0_CU2
	xor	t0, t1
	mtc0	t0, CP0_STATUS

1:
#if CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0
	/* Check if we need to store CVMSEG state */
	mfc0	t0, $11,7	/* CvmMemCtl */
@@ -85,12 +128,7 @@
	move	$28, a2
	cpu_restore_nonscratch a1

#if (_THREAD_SIZE - 32) < 0x8000
	PTR_ADDIU	t0, $28, _THREAD_SIZE - 32
#else
	PTR_LI		t0, _THREAD_SIZE - 32
	PTR_ADDU	t0, $28
#endif
	PTR_ADDU	t0, $28, _THREAD_SIZE - 32
	set_saved_sp	t0, t1, t2

	mfc0	t1, CP0_STATUS		/* Do we really need this? */
+3 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
 */
#define ST_OFF (_THREAD_SIZE - 32 - PT_SIZE + PT_STATUS)

#ifndef USE_ALTERNATE_RESUME_IMPL
/*
 * task_struct *resume(task_struct *prev, task_struct *next,
 *		       struct thread_info *next_ti, s32 fp_save)
@@ -99,6 +100,8 @@
	jr	ra
	END(resume)

#endif /* USE_ALTERNATE_RESUME_IMPL */

/*
 * Save a thread's fp context.
 */
Loading