diff options
Diffstat (limited to 'arch/mips/kernel/genex.S')
| -rw-r--r-- | arch/mips/kernel/genex.S | 89 | 
1 files changed, 62 insertions, 27 deletions
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index 8a0096d6281..5c2ba9f08a8 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S @@ -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	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 @@ -160,7 +162,7 @@ LEAF(r4k_wait)  	.set pop  	.endm -	.align  5 +	.align	5  BUILD_ROLLBACK_PROLOGUE handle_int  NESTED(handle_int, PT_SIZE, sp)  #ifdef CONFIG_TRACE_IRQFLAGS @@ -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 @@ -362,7 +375,7 @@ NESTED(nmi_handler, PT_SIZE, sp)  	.set	push  	.set	noat  	SAVE_ALL - 	move	a0, sp +	move	a0, sp  	jal	nmi_exception_handler  	RESTORE_ALL  	.set	mips3 @@ -409,7 +422,7 @@ NESTED(nmi_handler, PT_SIZE, sp)  	   string escapes and emits bogus warnings if it believes to  	   recognize an unknown escape code.  So make the arguments  	   start with an n and gas will believe \n is ok ...  */ -	.macro	__BUILD_verbose	nexception +	.macro	__BUILD_verbose nexception  	LONG_L	a1, PT_EPC(sp)  #ifdef CONFIG_32BIT  	PRINT("Got \nexception at %08lx\012") @@ -442,7 +455,7 @@ NESTED(nmi_handler, PT_SIZE, sp)  	.endm  	.macro	BUILD_HANDLER exception handler clear verbose -	__BUILD_HANDLER	\exception \handler \clear \verbose _int +	__BUILD_HANDLER \exception \handler \clear \verbose _int  	.endm  	BUILD_HANDLER adel ade ade silent		/* #4  */ @@ -456,7 +469,7 @@ NESTED(nmi_handler, PT_SIZE, sp)  	BUILD_HANDLER tr tr sti silent			/* #13 */  	BUILD_HANDLER fpe fpe fpe silent		/* #15 */  	BUILD_HANDLER mdmx mdmx sti silent		/* #22 */ -#ifdef 	CONFIG_HARDWARE_WATCHPOINTS +#ifdef	CONFIG_HARDWARE_WATCHPOINTS  	/*  	 * For watch, interrupts will be enabled after the watch  	 * registers are read. @@ -480,10 +493,10 @@ NESTED(nmi_handler, PT_SIZE, sp)  	.set	noreorder  	/* check if TLB contains a entry for EPC */  	MFC0	k1, CP0_ENTRYHI -	andi	k1, 0xff	/* ASID_MASK */ +	andi	k1, 0xff	/* ASID_MASK patched at run-time!! */  	MFC0	k0, CP0_EPC -	PTR_SRL	k0, _PAGE_SHIFT + 1 -	PTR_SLL	k0, _PAGE_SHIFT + 1 +	PTR_SRL k0, _PAGE_SHIFT + 1 +	PTR_SLL k0, _PAGE_SHIFT + 1  	or	k1, k0  	MTC0	k1, CP0_ENTRYHI  	mtc0_tlbw_hazard @@ -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  |