aboutsummaryrefslogtreecommitdiff
path: root/arch/microblaze/kernel
diff options
context:
space:
mode:
authorMichal Simek <monstr@monstr.eu>2010-06-17 16:03:05 +0200
committerMichal Simek <monstr@monstr.eu>2010-08-04 10:22:48 +0200
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 3fee82d6e9a..04265716518 100644
--- a/arch/microblaze/kernel/entry.S
+++ b/arch/microblaze/kernel/entry.S
@@ -507,9 +507,6 @@ C_ENTRY(sys_rt_sigreturn_wrapper):
#define SAVE_STATE \
swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* save stack */ \
swi r11, r0, TOPHYS(r0_ram + PTO + PT_R11); /* Save r11 */ \
- set_bip; /*equalize initial state for all possible entries*/\
- clear_eip; \
- set_ee; \
/* See if already in kernel mode.*/ \
mfs r11, rmsr; \
nop; \
@@ -569,7 +566,7 @@ C_ENTRY(full_exception_trap):
nop
addik r12, r0, full_exception
set_vms;
- rtbd r12, 0;
+ rted r12, 0;
nop;
/*
@@ -583,6 +580,17 @@ C_ENTRY(full_exception_trap):
* The assembler routine is in "arch/microblaze/kernel/hw_exception_handler.S"
*/
C_ENTRY(unaligned_data_trap):
+ /* MS: I have to save r11 value and then restore it because
+ * set_bit, clear_eip, set_ee use r11 as temp register if MSR
+ * instructions are not used. We don't need to do if MSR instructions
+ * are used and they use r0 instead of r11.
+ * I am using ENTRY_SP which should be primary used only for stack
+ * pointer saving. */
+ swi r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
+ set_bip; /* equalize initial state for all possible entries */
+ clear_eip;
+ set_ee;
+ lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
SAVE_STATE /* Save registers.*/
/* where the trap should return need -8 to adjust for rtsd r15, 8 */
addik r15, r0, ret_from_exc-8
@@ -625,7 +633,7 @@ C_ENTRY(page_fault_data_trap):
nop
addik r12, r0, do_page_fault
set_vms;
- rtbd r12, 0; /* interrupts enabled */
+ rted r12, 0; /* interrupts enabled */
nop;
C_ENTRY(page_fault_instr_trap):
@@ -638,7 +646,7 @@ C_ENTRY(page_fault_instr_trap):
ori r7, r0, 0 /* parameter unsigned long error_code */
addik r12, r0, do_page_fault
set_vms;
- rtbd r12, 0; /* interrupts enabled */
+ rted r12, 0; /* interrupts enabled */
nop;
/* Entry point used to return from an exception. */