summaryrefslogtreecommitdiff
path: root/arch/xtensa/kernel/vectors.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/xtensa/kernel/vectors.S')
-rw-r--r--arch/xtensa/kernel/vectors.S79
1 files changed, 46 insertions, 33 deletions
diff --git a/arch/xtensa/kernel/vectors.S b/arch/xtensa/kernel/vectors.S
index 332e9d635fb6..1073fe4a584d 100644
--- a/arch/xtensa/kernel/vectors.S
+++ b/arch/xtensa/kernel/vectors.S
@@ -43,10 +43,11 @@
*/
#include <linux/linkage.h>
+#include <linux/pgtable.h>
+#include <asm/asmmacro.h>
#include <asm/ptrace.h>
#include <asm/current.h>
#include <asm/asm-offsets.h>
-#include <asm/pgtable.h>
#include <asm/processor.h>
#include <asm/page.h>
#include <asm/thread_info.h>
@@ -87,7 +88,7 @@ ENDPROC(_UserExceptionVector)
* Kernel exception vector. (Exceptions with PS.UM == 0, PS.EXCM == 0)
*
* We get this exception when we were already in kernel space.
- * We decrement the current stack pointer (kernel) by PT_SIZE and
+ * We decrement the current stack pointer (kernel) by PT_KERNEL_SIZE and
* jump to the first-level handler associated with the exception cause.
*
* Note: we need to preserve space for the spill region.
@@ -99,7 +100,7 @@ ENTRY(_KernelExceptionVector)
xsr a3, excsave1 # save a3, and get dispatch table
wsr a2, depc # save a2
- addi a2, a1, -16-PT_SIZE # adjust stack pointer
+ addi a2, a1, -16 - PT_KERNEL_SIZE # adjust stack pointer
s32i a0, a2, PT_AREG0 # save a0 to ESF
rsr a0, exccause # retrieve exception cause
s32i a0, a2, PT_DEPC # mark it as a regular exception
@@ -205,9 +206,6 @@ ENDPROC(_KernelExceptionVector)
*/
.section .DoubleExceptionVector.text, "ax"
- .begin literal_prefix .DoubleExceptionVector
- .globl _DoubleExceptionVector_WindowUnderflow
- .globl _DoubleExceptionVector_WindowOverflow
ENTRY(_DoubleExceptionVector)
@@ -217,13 +215,18 @@ ENTRY(_DoubleExceptionVector)
/* Check for kernel double exception (usually fatal). */
rsr a2, ps
- _bbci.l a2, PS_UM_BIT, .Lksp
+ _bbsi.l a2, PS_UM_BIT, 1f
+ j .Lksp
+ .align 4
+ .literal_position
+1:
/* Check if we are currently handling a window exception. */
/* Note: We don't need to indicate that we enter a critical section. */
xsr a0, depc # get DEPC, save a0
+#ifdef SUPPORT_WINDOWED
movi a2, WINDOW_VECTORS_VADDR
_bltu a0, a2, .Lfixup
addi a2, a2, WINDOW_VECTORS_SIZE
@@ -273,6 +276,10 @@ _DoubleExceptionVector_WindowUnderflow:
l32i a0, a0, EXC_TABLE_FAST_USER
jx a0
+#else
+ j .Lfixup
+#endif
+
/*
* We only allow the ITLB miss exception if we are in kernel space.
* All other exceptions are unexpected and thus unrecoverable!
@@ -304,8 +311,7 @@ _DoubleExceptionVector_WindowUnderflow:
.Lunrecoverable:
rsr a3, excsave1
wsr a0, excsave1
- movi a0, unrecoverable_exception
- callx0 a0
+ call0 unrecoverable_exception
.Lfixup:/* Check for a fixup handler or if we were in a critical section. */
@@ -342,6 +348,7 @@ _DoubleExceptionVector_WindowUnderflow:
l32i a0, a0, EXC_TABLE_FAST_USER
jx a0
+#ifdef SUPPORT_WINDOWED
/*
* Restart window OVERFLOW exception.
* Currently:
@@ -474,13 +481,12 @@ _DoubleExceptionVector_handle_exception:
rsr a0, depc
rotw -3
j 1b
-
+#endif
ENDPROC(_DoubleExceptionVector)
- .end literal_prefix
+#ifdef SUPPORT_WINDOWED
- .text
/*
* Fixup handler for TLB miss in double exception handler for window owerflow.
* We get here with windowbase set to the window that was being spilled and
@@ -508,6 +514,9 @@ ENDPROC(_DoubleExceptionVector)
* a3: exctable, original value in excsave1
*/
+ __XTENSA_HANDLER
+ .literal_position
+
ENTRY(window_overflow_restore_a0_fixup)
rsr a0, ps
@@ -590,6 +599,8 @@ ENTRY(window_overflow_restore_a0_fixup)
ENDPROC(window_overflow_restore_a0_fixup)
+#endif
+
/*
* Debug interrupt vector
*
@@ -650,6 +661,25 @@ ENTRY(_Level\level\()InterruptVector)
irq_entry_level 5
irq_entry_level 6
+#if XCHAL_EXCM_LEVEL >= 2
+ /*
+ * Continuation of medium priority interrupt dispatch code.
+ * On entry here, a0 contains PS, and EPC2 contains saved a0:
+ */
+ __XTENSA_HANDLER
+ .align 4
+_SimulateUserKernelVectorException:
+ addi a0, a0, (1 << PS_EXCM_BIT)
+#if !XTENSA_FAKE_NMI
+ wsr a0, ps
+#endif
+ bbsi.l a0, PS_UM_BIT, 1f # branch if user mode
+ xsr a0, excsave2 # restore a0
+ j _KernelExceptionVector # simulate kernel vector exception
+1: xsr a0, excsave2 # restore a0
+ j _UserExceptionVector # simulate user vector exception
+#endif
+
/* Window overflow and underflow handlers.
* The handlers must be 64 bytes apart, first starting with the underflow
@@ -668,6 +698,8 @@ ENTRY(_Level\level\()InterruptVector)
.section .WindowVectors.text, "ax"
+#ifdef SUPPORT_WINDOWED
+
/* 4-Register Window Overflow Vector (Handler) */
ENTRY_ALIGN64(_WindowOverflow4)
@@ -680,27 +712,6 @@ ENTRY_ALIGN64(_WindowOverflow4)
ENDPROC(_WindowOverflow4)
-
-#if XCHAL_EXCM_LEVEL >= 2
- /* Not a window vector - but a convenient location
- * (where we know there's space) for continuation of
- * medium priority interrupt dispatch code.
- * On entry here, a0 contains PS, and EPC2 contains saved a0:
- */
- .align 4
-_SimulateUserKernelVectorException:
- addi a0, a0, (1 << PS_EXCM_BIT)
-#if !XTENSA_FAKE_NMI
- wsr a0, ps
-#endif
- bbsi.l a0, PS_UM_BIT, 1f # branch if user mode
- xsr a0, excsave2 # restore a0
- j _KernelExceptionVector # simulate kernel vector exception
-1: xsr a0, excsave2 # restore a0
- j _UserExceptionVector # simulate user vector exception
-#endif
-
-
/* 4-Register Window Underflow Vector (Handler) */
ENTRY_ALIGN64(_WindowUnderflow4)
@@ -789,4 +800,6 @@ ENTRY_ALIGN64(_WindowUnderflow12)
ENDPROC(_WindowUnderflow12)
+#endif
+
.text