Skip to content

Commit

Permalink
MIPS: microMIPS: Add support for exception handling.
Browse files Browse the repository at this point in the history
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: Steven J. Hill <Steven.Hill@imgtec.com>
  • Loading branch information
Steven J. Hill authored and Ralf Baechle committed May 9, 2013
1 parent 102cedc commit 2a0b24f
Show file tree
Hide file tree
Showing 9 changed files with 353 additions and 107 deletions.
1 change: 1 addition & 0 deletions arch/mips/include/asm/mipsregs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
12 changes: 6 additions & 6 deletions arch/mips/include/asm/stackframe.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
3 changes: 3 additions & 0 deletions arch/mips/kernel/cpu-probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
73 changes: 54 additions & 19 deletions arch/mips/kernel/genex.S
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand All @@ -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 push; \
.set nomicromips; \
.set reorder; \
PTR_LA a0,8f; \
.set noat; \
Expand All @@ -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.
*
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
lui k0, 0x7c03
lw k1, (k1)
ori k0, 0xe83b
.set reorder
#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
Expand Down
9 changes: 9 additions & 0 deletions arch/mips/kernel/scall32-o32.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions arch/mips/kernel/smtc-asm.S
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ CAN WE PROVE THAT WE WON'T DO THIS IF INTS DISABLED??
.text
.align 5
FEXPORT(__smtc_ipi_vector)
#ifdef CONFIG_CPU_MICROMIPS
nop
#endif
.set noat
/* Disable thread scheduling to make Status update atomic */
DMT 27 # dmt k1
Expand Down
Loading

0 comments on commit 2a0b24f

Please sign in to comment.