diff options
author | Atsushi Nemoto <anemo@mba.ocn.ne.jp> | 2006-09-11 04:50:29 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2006-11-29 20:14:44 -0500 |
commit | 5b10496b6e6577f65b032a5c4c97d0d3a841273c (patch) | |
tree | 996de253070623043619f893afe8aa244ae88e8a /arch/mips/kernel/genex.S | |
parent | 656be92f9ae194ed62bc81310a4589a7cd765f13 (diff) |
[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>
Diffstat (limited to 'arch/mips/kernel/genex.S')
-rw-r--r-- | arch/mips/kernel/genex.S | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index 5baca16993d0..aacd4a005c5f 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <asm/mipsregs.h> | 19 | #include <asm/mipsregs.h> |
20 | #include <asm/stackframe.h> | 20 | #include <asm/stackframe.h> |
21 | #include <asm/war.h> | 21 | #include <asm/war.h> |
22 | #include <asm/page.h> | ||
22 | 23 | ||
23 | #define PANIC_PIC(msg) \ | 24 | #define PANIC_PIC(msg) \ |
24 | .set push; \ | 25 | .set push; \ |
@@ -378,6 +379,68 @@ NESTED(nmi_handler, PT_SIZE, sp) | |||
378 | BUILD_HANDLER dsp dsp sti silent /* #26 */ | 379 | BUILD_HANDLER dsp dsp sti silent /* #26 */ |
379 | BUILD_HANDLER reserved reserved sti verbose /* others */ | 380 | BUILD_HANDLER reserved reserved sti verbose /* others */ |
380 | 381 | ||
382 | .align 5 | ||
383 | LEAF(handle_ri_rdhwr_vivt) | ||
384 | #ifdef CONFIG_MIPS_MT_SMTC | ||
385 | PANIC_PIC("handle_ri_rdhwr_vivt called") | ||
386 | #else | ||
387 | .set push | ||
388 | .set noat | ||
389 | .set noreorder | ||
390 | /* check if TLB contains a entry for EPC */ | ||
391 | MFC0 k1, CP0_ENTRYHI | ||
392 | andi k1, 0xff /* ASID_MASK */ | ||
393 | MFC0 k0, CP0_EPC | ||
394 | PTR_SRL k0, PAGE_SHIFT + 1 | ||
395 | PTR_SLL k0, PAGE_SHIFT + 1 | ||
396 | or k1, k0 | ||
397 | MTC0 k1, CP0_ENTRYHI | ||
398 | mtc0_tlbw_hazard | ||
399 | tlbp | ||
400 | tlb_probe_hazard | ||
401 | mfc0 k1, CP0_INDEX | ||
402 | .set pop | ||
403 | bltz k1, handle_ri /* slow path */ | ||
404 | /* fall thru */ | ||
405 | #endif | ||
406 | END(handle_ri_rdhwr_vivt) | ||
407 | |||
408 | LEAF(handle_ri_rdhwr) | ||
409 | .set push | ||
410 | .set noat | ||
411 | .set noreorder | ||
412 | /* 0x7c03e83b: rdhwr v1,$29 */ | ||
413 | MFC0 k1, CP0_EPC | ||
414 | lui k0, 0x7c03 | ||
415 | lw k1, (k1) | ||
416 | ori k0, 0xe83b | ||
417 | .set reorder | ||
418 | bne k0, k1, handle_ri /* if not ours */ | ||
419 | /* The insn is rdhwr. No need to check CAUSE.BD here. */ | ||
420 | get_saved_sp /* k1 := current_thread_info */ | ||
421 | .set noreorder | ||
422 | MFC0 k0, CP0_EPC | ||
423 | #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) | ||
424 | ori k1, _THREAD_MASK | ||
425 | xori k1, _THREAD_MASK | ||
426 | LONG_L v1, TI_TP_VALUE(k1) | ||
427 | LONG_ADDIU k0, 4 | ||
428 | jr k0 | ||
429 | rfe | ||
430 | #else | ||
431 | LONG_ADDIU k0, 4 /* stall on $k0 */ | ||
432 | MTC0 k0, CP0_EPC | ||
433 | /* I hope three instructions between MTC0 and ERET are enough... */ | ||
434 | ori k1, _THREAD_MASK | ||
435 | xori k1, _THREAD_MASK | ||
436 | LONG_L v1, TI_TP_VALUE(k1) | ||
437 | .set mips3 | ||
438 | eret | ||
439 | .set mips0 | ||
440 | #endif | ||
441 | .set pop | ||
442 | END(handle_ri_rdhwr) | ||
443 | |||
381 | #ifdef CONFIG_64BIT | 444 | #ifdef CONFIG_64BIT |
382 | /* A temporary overflow handler used by check_daddi(). */ | 445 | /* A temporary overflow handler used by check_daddi(). */ |
383 | 446 | ||