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

Commit 2a0b24f5 authored by Steven J. Hill's avatar Steven J. Hill Committed by Ralf Baechle
Browse files

MIPS: microMIPS: Add support for exception handling.



All exceptions must be taken in microMIPS mode, never in classic
MIPS mode or the kernel falls apart. A few NOP instructions are
used to maintain the correct alignment of microMIPS versions of
the exception vectors.

Signed-off-by: default avatarSteven J. Hill <Steven.Hill@imgtec.com>
parent 102cedc3
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -596,6 +596,7 @@
#define MIPS_CONF3_RXI		(_ULCAST_(1) << 12)
#define MIPS_CONF3_ULRI		(_ULCAST_(1) << 13)
#define MIPS_CONF3_ISA		(_ULCAST_(3) << 14)
#define MIPS_CONF3_ISA_OE	(_ULCAST_(3) << 16)
#define MIPS_CONF3_VZ		(_ULCAST_(1) << 23)

#define MIPS_CONF4_MMUSIZEEXT	(_ULCAST_(255) << 0)
+6 −6
Original line number Diff line number Diff line
@@ -139,7 +139,7 @@
1:		move	ra, k0
		li	k0, 3
		mtc0	k0, $22
#endif /* CONFIG_CPU_LOONGSON2F */
#endif /* CONFIG_CPU_JUMP_WORKAROUNDS */
#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
		lui	k1, %hi(kernelsp)
#else
@@ -189,6 +189,7 @@
		LONG_S	$0, PT_R0(sp)
		mfc0	v1, CP0_STATUS
		LONG_S	$2, PT_R2(sp)
		LONG_S	v1, PT_STATUS(sp)
#ifdef CONFIG_MIPS_MT_SMTC
		/*
		 * Ideally, these instructions would be shuffled in
@@ -200,21 +201,20 @@
		LONG_S	k0, PT_TCSTATUS(sp)
#endif /* CONFIG_MIPS_MT_SMTC */
		LONG_S	$4, PT_R4(sp)
		LONG_S	$5, PT_R5(sp)
		LONG_S	v1, PT_STATUS(sp)
		mfc0	v1, CP0_CAUSE
		LONG_S	$6, PT_R6(sp)
		LONG_S	$7, PT_R7(sp)
		LONG_S	$5, PT_R5(sp)
		LONG_S	v1, PT_CAUSE(sp)
		LONG_S	$6, PT_R6(sp)
		MFC0	v1, CP0_EPC
		LONG_S	$7, PT_R7(sp)
#ifdef CONFIG_64BIT
		LONG_S	$8, PT_R8(sp)
		LONG_S	$9, PT_R9(sp)
#endif
		LONG_S	v1, PT_EPC(sp)
		LONG_S	$25, PT_R25(sp)
		LONG_S	$28, PT_R28(sp)
		LONG_S	$31, PT_R31(sp)
		LONG_S	v1, PT_EPC(sp)
		ori	$28, sp, _THREAD_MASK
		xori	$28, _THREAD_MASK
#ifdef CONFIG_CPU_CAVIUM_OCTEON
+3 −0
Original line number Diff line number Diff line
@@ -470,6 +470,9 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c)
		c->options |= MIPS_CPU_ULRI;
	if (config3 & MIPS_CONF3_ISA)
		c->options |= MIPS_CPU_MICROMIPS;
#ifdef CONFIG_CPU_MICROMIPS
	write_c0_config3(read_c0_config3() | MIPS_CONF3_ISA_OE);
#endif
	if (config3 & MIPS_CONF3_VZ)
		c->ases |= MIPS_ASE_VZ;

+54 −19
Original line number Diff line number Diff line
@@ -5,8 +5,8 @@
 *
 * Copyright (C) 1994 - 2000, 2001, 2003 Ralf Baechle
 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
 * Copyright (C) 2001 MIPS Technologies, Inc.
 * Copyright (C) 2002, 2007  Maciej W. Rozycki
 * Copyright (C) 2001, 2012 MIPS Technologies, Inc.  All rights reserved.
 */
#include <linux/init.h>

@@ -21,8 +21,10 @@
#include <asm/war.h>
#include <asm/thread_info.h>

#ifdef CONFIG_MIPS_MT_SMTC
#define PANIC_PIC(msg)					\
		.set	push;				\
		.set	nomicromips;			\
		.set	reorder;			\
		PTR_LA	a0,8f;				\
		.set	noat;				\
@@ -31,17 +33,10 @@
9:		b	9b;				\
		.set	pop;				\
		TEXT(msg)
#endif

	__INIT

NESTED(except_vec0_generic, 0, sp)
	PANIC_PIC("Exception vector 0 called")
	END(except_vec0_generic)

NESTED(except_vec1_generic, 0, sp)
	PANIC_PIC("Exception vector 1 called")
	END(except_vec1_generic)

/*
 * General exception vector for all other CPUs.
 *
@@ -138,12 +133,19 @@ LEAF(r4k_wait)
	 nop
	nop
	nop
#ifdef CONFIG_CPU_MICROMIPS
	nop
	nop
	nop
	nop
#endif
	.set	mips3
	wait
	/* end of rollback region (the region size must be power of two) */
	.set	pop
1:
	jr	ra
	nop
	.set	pop
	END(r4k_wait)

	.macro	BUILD_ROLLBACK_PROLOGUE handler
@@ -201,7 +203,11 @@ NESTED(handle_int, PT_SIZE, sp)
	LONG_L	s0, TI_REGS($28)
	LONG_S	sp, TI_REGS($28)
	PTR_LA	ra, ret_from_irq
	j	plat_irq_dispatch
	PTR_LA  v0, plat_irq_dispatch
	jr	v0
#ifdef CONFIG_CPU_MICROMIPS
	nop
#endif
	END(handle_int)

	__INIT
@@ -222,11 +228,14 @@ NESTED(except_vec4, 0, sp)
/*
 * EJTAG debug exception handler.
 * The EJTAG debug exception entry point is 0xbfc00480, which
 * normally is in the boot PROM, so the boot PROM must do a
 * normally is in the boot PROM, so the boot PROM must do an
 * unconditional jump to this vector.
 */
NESTED(except_vec_ejtag_debug, 0, sp)
	j	ejtag_debug_handler
#ifdef CONFIG_CPU_MICROMIPS
	 nop
#endif
	END(except_vec_ejtag_debug)

	__FINIT
@@ -251,9 +260,10 @@ NESTED(except_vec_vi, 0, sp)
FEXPORT(except_vec_vi_mori)
	ori	a0, $0, 0
#endif /* CONFIG_MIPS_MT_SMTC */
	PTR_LA	v1, except_vec_vi_handler
FEXPORT(except_vec_vi_lui)
	lui	v0, 0		/* Patched */
	j	except_vec_vi_handler
	jr	v1
FEXPORT(except_vec_vi_ori)
	 ori	v0, 0		/* Patched */
	.set	pop
@@ -354,6 +364,9 @@ EXPORT(ejtag_debug_buffer)
 */
NESTED(except_vec_nmi, 0, sp)
	j	nmi_handler
#ifdef CONFIG_CPU_MICROMIPS
	 nop
#endif
	END(except_vec_nmi)

	__FINIT
@@ -500,13 +513,35 @@ NESTED(nmi_handler, PT_SIZE, sp)
	.set	push
	.set	noat
	.set	noreorder
	/* 0x7c03e83b: rdhwr v1,$29 */
	/* MIPS32:    0x7c03e83b: rdhwr v1,$29 */
	/* microMIPS: 0x007d6b3c: rdhwr v1,$29 */
	MFC0	k1, CP0_EPC
#if defined(CONFIG_CPU_MICROMIPS) || defined(CONFIG_CPU_MIPS32_R2) || defined(CONFIG_CPU_MIPS64_R2)
	and     k0, k1, 1
	beqz    k0, 1f
	xor     k1, k0
	lhu     k0, (k1)
	lhu     k1, 2(k1)
	ins     k1, k0, 16, 16
	lui     k0, 0x007d
	b       docheck
	ori     k0, 0x6b3c
1:
	lui     k0, 0x7c03
	lw      k1, (k1)
	ori     k0, 0xe83b
#else
	andi    k0, k1, 1
	bnez    k0, handle_ri
	lui     k0, 0x7c03
	lw      k1, (k1)
	ori     k0, 0xe83b
#endif
	.set    reorder
docheck:
	bne	k0, k1, handle_ri	/* if not ours */

isrdhwr:
	/* The insn is rdhwr.  No need to check CAUSE.BD here. */
	get_saved_sp	/* k1 := current_thread_info */
	.set	noreorder
+9 −0
Original line number Diff line number Diff line
@@ -138,9 +138,18 @@ stackargs:
5:	jr	t1
	 sw	t5, 16(sp)		# argument #5 to ksp

#ifdef CONFIG_CPU_MICROMIPS
	sw	t8, 28(sp)		# argument #8 to ksp
	nop
	sw	t7, 24(sp)		# argument #7 to ksp
	nop
	sw	t6, 20(sp)		# argument #6 to ksp
	nop
#else
	sw	t8, 28(sp)		# argument #8 to ksp
	sw	t7, 24(sp)		# argument #7 to ksp
	sw	t6, 20(sp)		# argument #6 to ksp
#endif
6:	j	stack_done		# go back
	 nop
	.set	pop
Loading