diff options
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 | ||
