forked from luck/tmp_suning_uos_patched
[MIPS] Fast path for rdhwr emulation for TLS
Add special short path for emulationg RDHWR which is used to support TLS. Add an extra prologue for cpu_has_vtag_icache case. Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
parent
656be92f9a
commit
5b10496b6e
|
@ -19,6 +19,7 @@
|
|||
#include <asm/mipsregs.h>
|
||||
#include <asm/stackframe.h>
|
||||
#include <asm/war.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
#define PANIC_PIC(msg) \
|
||||
.set push; \
|
||||
|
@ -378,6 +379,68 @@ NESTED(nmi_handler, PT_SIZE, sp)
|
|||
BUILD_HANDLER dsp dsp sti silent /* #26 */
|
||||
BUILD_HANDLER reserved reserved sti verbose /* others */
|
||||
|
||||
.align 5
|
||||
LEAF(handle_ri_rdhwr_vivt)
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
PANIC_PIC("handle_ri_rdhwr_vivt called")
|
||||
#else
|
||||
.set push
|
||||
.set noat
|
||||
.set noreorder
|
||||
/* check if TLB contains a entry for EPC */
|
||||
MFC0 k1, CP0_ENTRYHI
|
||||
andi k1, 0xff /* ASID_MASK */
|
||||
MFC0 k0, CP0_EPC
|
||||
PTR_SRL k0, PAGE_SHIFT + 1
|
||||
PTR_SLL k0, PAGE_SHIFT + 1
|
||||
or k1, k0
|
||||
MTC0 k1, CP0_ENTRYHI
|
||||
mtc0_tlbw_hazard
|
||||
tlbp
|
||||
tlb_probe_hazard
|
||||
mfc0 k1, CP0_INDEX
|
||||
.set pop
|
||||
bltz k1, handle_ri /* slow path */
|
||||
/* fall thru */
|
||||
#endif
|
||||
END(handle_ri_rdhwr_vivt)
|
||||
|
||||
LEAF(handle_ri_rdhwr)
|
||||
.set push
|
||||
.set noat
|
||||
.set noreorder
|
||||
/* 0x7c03e83b: rdhwr v1,$29 */
|
||||
MFC0 k1, CP0_EPC
|
||||
lui k0, 0x7c03
|
||||
lw k1, (k1)
|
||||
ori k0, 0xe83b
|
||||
.set reorder
|
||||
bne k0, k1, handle_ri /* if not ours */
|
||||
/* The insn is rdhwr. No need to check CAUSE.BD here. */
|
||||
get_saved_sp /* k1 := current_thread_info */
|
||||
.set noreorder
|
||||
MFC0 k0, CP0_EPC
|
||||
#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
|
||||
ori k1, _THREAD_MASK
|
||||
xori k1, _THREAD_MASK
|
||||
LONG_L v1, TI_TP_VALUE(k1)
|
||||
LONG_ADDIU k0, 4
|
||||
jr k0
|
||||
rfe
|
||||
#else
|
||||
LONG_ADDIU k0, 4 /* stall on $k0 */
|
||||
MTC0 k0, CP0_EPC
|
||||
/* I hope three instructions between MTC0 and ERET are enough... */
|
||||
ori k1, _THREAD_MASK
|
||||
xori k1, _THREAD_MASK
|
||||
LONG_L v1, TI_TP_VALUE(k1)
|
||||
.set mips3
|
||||
eret
|
||||
.set mips0
|
||||
#endif
|
||||
.set pop
|
||||
END(handle_ri_rdhwr)
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
/* A temporary overflow handler used by check_daddi(). */
|
||||
|
||||
|
|
|
@ -54,6 +54,8 @@ extern asmlinkage void handle_dbe(void);
|
|||
extern asmlinkage void handle_sys(void);
|
||||
extern asmlinkage void handle_bp(void);
|
||||
extern asmlinkage void handle_ri(void);
|
||||
extern asmlinkage void handle_ri_rdhwr_vivt(void);
|
||||
extern asmlinkage void handle_ri_rdhwr(void);
|
||||
extern asmlinkage void handle_cpu(void);
|
||||
extern asmlinkage void handle_ov(void);
|
||||
extern asmlinkage void handle_tr(void);
|
||||
|
@ -1423,6 +1425,15 @@ void __init set_uncached_handler (unsigned long offset, void *addr, unsigned lon
|
|||
memcpy((void *)(uncached_ebase + offset), addr, size);
|
||||
}
|
||||
|
||||
static int __initdata rdhwr_noopt;
|
||||
static int __init set_rdhwr_noopt(char *str)
|
||||
{
|
||||
rdhwr_noopt = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
__setup("rdhwr_noopt", set_rdhwr_noopt);
|
||||
|
||||
void __init trap_init(void)
|
||||
{
|
||||
extern char except_vec3_generic, except_vec3_r4000;
|
||||
|
@ -1502,7 +1513,9 @@ void __init trap_init(void)
|
|||
|
||||
set_except_vector(8, handle_sys);
|
||||
set_except_vector(9, handle_bp);
|
||||
set_except_vector(10, handle_ri);
|
||||
set_except_vector(10, rdhwr_noopt ? handle_ri :
|
||||
(cpu_has_vtag_icache ?
|
||||
handle_ri_rdhwr_vivt : handle_ri_rdhwr));
|
||||
set_except_vector(11, handle_cpu);
|
||||
set_except_vector(12, handle_ov);
|
||||
set_except_vector(13, handle_tr);
|
||||
|
|
Loading…
Reference in New Issue
Block a user