aboutsummaryrefslogtreecommitdiffstats
path: root/arch/microblaze/kernel
diff options
context:
space:
mode:
authorMichal Simek <monstr@monstr.eu>2010-06-17 10:03:05 -0400
committerMichal Simek <monstr@monstr.eu>2010-08-04 04:22:48 -0400
commit8b110d157c82f3818fc578b633f0cf7ace9efc22 (patch)
tree1db5254c8b5bc2327170202355c6a3054409e8ac /arch/microblaze/kernel
parentb9ea77e2d37013a4e66c9dad2e629998ff300608 (diff)
microblaze: Optimize SAVE_STATE macro
It is necessary to setup BIP and EE and clear EIP only for unaligned exception handler. The rest of hw exception handlers don't require it. HW exception occured and we are not in virtual mode. That's why we can do operations protected by EIP. Interrupt, next hw exception or syscall can't occur. EIP is cleared by rted. This change speedup page_fault hw exception handler which is critical path. There is also necessary to save R11 content before flag setup for unaligned exception. Signed-off-by: Michal Simek <monstr@monstr.eu>
Diffstat (limited to 'arch/microblaze/kernel')
-rw-r--r--arch/microblaze/kernel/entry.S20
1 files changed, 14 insertions, 6 deletions
diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S
index 3fee82d6e9a2..042657165184 100644
--- a/arch/microblaze/kernel/entry.S
+++ b/arch/microblaze/kernel/entry.S
@@ -507,9 +507,6 @@ C_ENTRY(sys_rt_sigreturn_wrapper):
507#define SAVE_STATE \ 507#define SAVE_STATE \
508 swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* save stack */ \ 508 swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* save stack */ \
509 swi r11, r0, TOPHYS(r0_ram + PTO + PT_R11); /* Save r11 */ \ 509 swi r11, r0, TOPHYS(r0_ram + PTO + PT_R11); /* Save r11 */ \
510 set_bip; /*equalize initial state for all possible entries*/\
511 clear_eip; \
512 set_ee; \
513 /* See if already in kernel mode.*/ \ 510 /* See if already in kernel mode.*/ \
514 mfs r11, rmsr; \ 511 mfs r11, rmsr; \
515 nop; \ 512 nop; \
@@ -569,7 +566,7 @@ C_ENTRY(full_exception_trap):
569 nop 566 nop
570 addik r12, r0, full_exception 567 addik r12, r0, full_exception
571 set_vms; 568 set_vms;
572 rtbd r12, 0; 569 rted r12, 0;
573 nop; 570 nop;
574 571
575/* 572/*
@@ -583,6 +580,17 @@ C_ENTRY(full_exception_trap):
583 * The assembler routine is in "arch/microblaze/kernel/hw_exception_handler.S" 580 * The assembler routine is in "arch/microblaze/kernel/hw_exception_handler.S"
584 */ 581 */
585C_ENTRY(unaligned_data_trap): 582C_ENTRY(unaligned_data_trap):
583 /* MS: I have to save r11 value and then restore it because
584 * set_bit, clear_eip, set_ee use r11 as temp register if MSR
585 * instructions are not used. We don't need to do if MSR instructions
586 * are used and they use r0 instead of r11.
587 * I am using ENTRY_SP which should be primary used only for stack
588 * pointer saving. */
589 swi r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
590 set_bip; /* equalize initial state for all possible entries */
591 clear_eip;
592 set_ee;
593 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
586 SAVE_STATE /* Save registers.*/ 594 SAVE_STATE /* Save registers.*/
587 /* where the trap should return need -8 to adjust for rtsd r15, 8 */ 595 /* where the trap should return need -8 to adjust for rtsd r15, 8 */
588 addik r15, r0, ret_from_exc-8 596 addik r15, r0, ret_from_exc-8
@@ -625,7 +633,7 @@ C_ENTRY(page_fault_data_trap):
625 nop 633 nop
626 addik r12, r0, do_page_fault 634 addik r12, r0, do_page_fault
627 set_vms; 635 set_vms;
628 rtbd r12, 0; /* interrupts enabled */ 636 rted r12, 0; /* interrupts enabled */
629 nop; 637 nop;
630 638
631C_ENTRY(page_fault_instr_trap): 639C_ENTRY(page_fault_instr_trap):
@@ -638,7 +646,7 @@ C_ENTRY(page_fault_instr_trap):
638 ori r7, r0, 0 /* parameter unsigned long error_code */ 646 ori r7, r0, 0 /* parameter unsigned long error_code */
639 addik r12, r0, do_page_fault 647 addik r12, r0, do_page_fault
640 set_vms; 648 set_vms;
641 rtbd r12, 0; /* interrupts enabled */ 649 rted r12, 0; /* interrupts enabled */
642 nop; 650 nop;
643 651
644/* Entry point used to return from an exception. */ 652/* Entry point used to return from an exception. */