microblaze: Fix MSR flags when returning from exception
The issue was that the service routine was sometimes returning with the wrong flags set in the MSR. In this case, EIP bit was set while returning to User Mode which is an illegal combination since exceptions are always handled in privileged mode. In order for MicroBlaze to take an interrupt, the MSR must have IE=1, BIP=0 and EIP=0. Signed-off-by: Stefan Asserhall <stefana@xilinx.com> Signed-off-by: Goran Bilski <goran@xilinx.com> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
This commit is contained in:
parent
faf154cd49
commit
14ef905bb2
|
@ -245,6 +245,13 @@ syscall_debug_table:
|
|||
mts rmsr , r11; \
|
||||
RESTORE_REGS_GP
|
||||
|
||||
#define RESTORE_REGS_RTBD \
|
||||
lwi r11, r1, PT_MSR; \
|
||||
andni r11, r11, MSR_EIP; /* clear EIP */ \
|
||||
ori r11, r11, MSR_EE | MSR_BIP; /* set EE and BIP */ \
|
||||
mts rmsr , r11; \
|
||||
RESTORE_REGS_GP
|
||||
|
||||
#define SAVE_STATE \
|
||||
swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* save stack */ \
|
||||
/* See if already in kernel mode.*/ \
|
||||
|
@ -430,7 +437,7 @@ C_ENTRY(ret_from_trap):
|
|||
swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */
|
||||
VM_OFF;
|
||||
tophys(r1,r1);
|
||||
RESTORE_REGS;
|
||||
RESTORE_REGS_RTBD;
|
||||
addik r1, r1, PT_SIZE /* Clean up stack space. */
|
||||
lwi r1, r1, PT_R1 - PT_SIZE;/* Restore user stack pointer. */
|
||||
bri 6f;
|
||||
|
@ -439,7 +446,7 @@ C_ENTRY(ret_from_trap):
|
|||
2: set_bip; /* Ints masked for state restore */
|
||||
VM_OFF;
|
||||
tophys(r1,r1);
|
||||
RESTORE_REGS;
|
||||
RESTORE_REGS_RTBD;
|
||||
addik r1, r1, PT_SIZE /* Clean up stack space. */
|
||||
tovirt(r1,r1);
|
||||
6:
|
||||
|
@ -615,7 +622,7 @@ C_ENTRY(ret_from_exc):
|
|||
VM_OFF;
|
||||
tophys(r1,r1);
|
||||
|
||||
RESTORE_REGS;
|
||||
RESTORE_REGS_RTBD;
|
||||
addik r1, r1, PT_SIZE /* Clean up stack space. */
|
||||
|
||||
lwi r1, r1, PT_R1 - PT_SIZE; /* Restore user stack pointer. */
|
||||
|
@ -624,7 +631,7 @@ C_ENTRY(ret_from_exc):
|
|||
2: set_bip; /* Ints masked for state restore */
|
||||
VM_OFF;
|
||||
tophys(r1,r1);
|
||||
RESTORE_REGS;
|
||||
RESTORE_REGS_RTBD;
|
||||
addik r1, r1, PT_SIZE /* Clean up stack space. */
|
||||
|
||||
tovirt(r1,r1);
|
||||
|
@ -850,7 +857,7 @@ dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */
|
|||
VM_OFF;
|
||||
tophys(r1,r1);
|
||||
/* MS: Restore all regs */
|
||||
RESTORE_REGS
|
||||
RESTORE_REGS_RTBD
|
||||
addik r1, r1, PT_SIZE /* Clean up stack space */
|
||||
lwi r1, r1, PT_R1 - PT_SIZE; /* Restore user stack pointer */
|
||||
DBTRAP_return_user: /* MS: Make global symbol for debugging */
|
||||
|
@ -861,7 +868,7 @@ DBTRAP_return_user: /* MS: Make global symbol for debugging */
|
|||
2: VM_OFF;
|
||||
tophys(r1,r1);
|
||||
/* MS: Restore all regs */
|
||||
RESTORE_REGS
|
||||
RESTORE_REGS_RTBD
|
||||
lwi r14, r1, PT_R14;
|
||||
lwi r16, r1, PT_PC;
|
||||
addik r1, r1, PT_SIZE; /* MS: Clean up stack space */
|
||||
|
|
Loading…
Reference in New Issue