xtensa: move fast exception handlers close to vectors

On XIP kernels it makes sense to have exception vectors and fast
exception handlers together (in a fast memory). In addition, with MTD
XIP support both vectors and fast exception handlers must be outside of
the FLASH.

Add section .exception.text and move fast exception handlers to it.
Put it together with vectors when vectors are outside of the .text.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
This commit is contained in:
Max Filippov 2020-01-31 18:48:43 -08:00
parent 58bc6c69af
commit 50722f0bf6
6 changed files with 39 additions and 14 deletions

View File

@ -237,4 +237,6 @@
#error Unsupported Xtensa ABI
#endif
#define __XTENSA_HANDLER .section ".exception.text", "ax"
#endif /* _XTENSA_ASMMACRO_H */

View File

@ -58,6 +58,8 @@
.endif; \
.long THREAD_XTREGS_CP##x
__XTENSA_HANDLER
SAVE_CP_REGS(0)
SAVE_CP_REGS(1)
SAVE_CP_REGS(2)
@ -76,7 +78,6 @@
LOAD_CP_REGS(6)
LOAD_CP_REGS(7)
.section ".rodata", "a"
.align 4
.Lsave_cp_regs_jump_table:
SAVE_CP_REGS_TAB(0)
@ -98,8 +99,6 @@
LOAD_CP_REGS_TAB(6)
LOAD_CP_REGS_TAB(7)
.previous
/*
* coprocessor_flush(struct thread_info*, index)
* a2 a3

View File

@ -939,6 +939,9 @@ ENDPROC(unrecoverable_exception)
/* -------------------------- FAST EXCEPTION HANDLERS ----------------------- */
__XTENSA_HANDLER
.literal_position
/*
* Fast-handler for alloca exceptions
*
@ -1024,7 +1027,7 @@ ENDPROC(fast_alloca)
ENTRY(fast_illegal_instruction_user)
rsr a0, ps
bbsi.l a0, PS_WOE_BIT, user_exception
bbsi.l a0, PS_WOE_BIT, 1f
s32i a3, a2, PT_AREG3
movi a3, PS_WOE_MASK
or a0, a0, a3
@ -1033,6 +1036,8 @@ ENTRY(fast_illegal_instruction_user)
l32i a0, a2, PT_AREG0
rsr a2, depc
rfe
1:
call0 user_exception
ENDPROC(fast_illegal_instruction_user)
#endif
@ -1071,7 +1076,7 @@ ENTRY(fast_syscall_user)
_beqz a0, fast_syscall_spill_registers
_beqi a0, __NR_xtensa, fast_syscall_xtensa
j user_exception
call0 user_exception
ENDPROC(fast_syscall_user)
@ -1762,8 +1767,8 @@ ENTRY(fast_second_level_miss)
rsr a2, ps
bbsi.l a2, PS_UM_BIT, 1f
j _kernel_exception
1: j _user_exception
call0 _kernel_exception
1: call0 _user_exception
ENDPROC(fast_second_level_miss)
@ -1859,13 +1864,14 @@ ENTRY(fast_store_prohibited)
rsr a2, ps
bbsi.l a2, PS_UM_BIT, 1f
j _kernel_exception
1: j _user_exception
call0 _kernel_exception
1: call0 _user_exception
ENDPROC(fast_store_prohibited)
#endif /* CONFIG_MMU */
.text
/*
* System Calls.
*

View File

@ -284,6 +284,8 @@ extern char _UserExceptionVector_text_start;
extern char _UserExceptionVector_text_end;
extern char _DoubleExceptionVector_text_start;
extern char _DoubleExceptionVector_text_end;
extern char _exception_text_start;
extern char _exception_text_end;
#if XCHAL_EXCM_LEVEL >= 2
extern char _Level2InterruptVector_text_start;
extern char _Level2InterruptVector_text_end;
@ -363,6 +365,8 @@ void __init setup_arch(char **cmdline_p)
mem_reserve(__pa(&_DoubleExceptionVector_text_start),
__pa(&_DoubleExceptionVector_text_end));
mem_reserve(__pa(&_exception_text_start),
__pa(&_exception_text_end));
#if XCHAL_EXCM_LEVEL >= 2
mem_reserve(__pa(&_Level2InterruptVector_text_start),
__pa(&_Level2InterruptVector_text_end));

View File

@ -43,6 +43,7 @@
*/
#include <linux/linkage.h>
#include <asm/asmmacro.h>
#include <asm/ptrace.h>
#include <asm/current.h>
#include <asm/asm-offsets.h>
@ -477,7 +478,6 @@ _DoubleExceptionVector_handle_exception:
ENDPROC(_DoubleExceptionVector)
.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
@ -505,6 +505,7 @@ ENDPROC(_DoubleExceptionVector)
* a3: exctable, original value in excsave1
*/
__XTENSA_HANDLER
.literal_position
ENTRY(window_overflow_restore_a0_fixup)

View File

@ -110,6 +110,8 @@ SECTIONS
SECTION_VECTOR (.KernelExceptionVector.text, KERNEL_VECTOR_VADDR)
SECTION_VECTOR (.UserExceptionVector.text, USER_VECTOR_VADDR)
SECTION_VECTOR (.DoubleExceptionVector.text, DOUBLEEXC_VECTOR_VADDR)
*(.exception.text)
#endif
IRQENTRY_TEXT
@ -190,6 +192,8 @@ SECTIONS
.DoubleExceptionVector.text);
RELOCATE_ENTRY(_DebugInterruptVector_text,
.DebugInterruptVector.text);
RELOCATE_ENTRY(_exception_text,
.exception.text);
#endif
#ifdef CONFIG_XIP_KERNEL
RELOCATE_ENTRY(_xip_data, .data);
@ -282,8 +286,7 @@ SECTIONS
.DoubleExceptionVector.text,
DOUBLEEXC_VECTOR_VADDR,
.UserExceptionVector.text)
. = (LOADADDR( .DoubleExceptionVector.text ) + SIZEOF( .DoubleExceptionVector.text ) + 3) & ~ 3;
#define LAST .DoubleExceptionVector.text
#endif
#if !defined(CONFIG_XIP_KERNEL) && defined(CONFIG_SMP)
@ -292,10 +295,20 @@ SECTIONS
.SecondaryResetVector.text,
RESET_VECTOR1_VADDR,
.DoubleExceptionVector.text)
. = LOADADDR(.SecondaryResetVector.text)+SIZEOF(.SecondaryResetVector.text);
#undef LAST
#define LAST .SecondaryResetVector.text
#endif
#ifdef CONFIG_VECTORS_OFFSET
SECTION_VECTOR (_exception_text,
.exception.text,
,
LAST)
#undef LAST
#define LAST .exception.text
#endif
. = (LOADADDR(LAST) + SIZEOF(LAST) + 3) & ~ 3;
. = ALIGN(PAGE_SIZE);