arch/xtensa: Use ZSR assignments for the alloca exception
This is actually Cadence-authored code, but its use of EXCSAVE1 as a sideband input to the exception handler is very much in the same family of tricks. Use ZSR assignments here too. Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This commit is contained in:
parent
ca7024e1d6
commit
3c7905b916
2 changed files with 16 additions and 12 deletions
|
@ -1,8 +1,10 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Cadence Design Systems, Inc.
|
||||
* Copyright (c) 2022 Intel Corporation
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <xtensa/coreasm.h>
|
||||
#include <zsr.h>
|
||||
|
||||
/* WINDOW OVERFLOW AND UNDERFLOW EXCEPTION VECTORS AND ALLOCA EXCEPTION
|
||||
* HANDLER
|
||||
|
@ -80,13 +82,15 @@ _WindowUnderflow4:
|
|||
rfwu
|
||||
|
||||
/* Handle alloca exception generated by interruptee executing 'movsp'.
|
||||
* This uses space between the window vectors, so is essentially "free".
|
||||
* All interruptee's regs are intact except a0 which is saved in EXCSAVE_1,
|
||||
* and PS.EXCM has been set by the exception hardware (can't be interrupted).
|
||||
* The fact the alloca exception was taken means the registers associated with
|
||||
* the base-save area have been spilled and will be restored by the underflow
|
||||
* handler, so those 4 registers are available for scratch.
|
||||
* The code is optimized to avoid unaligned branches and minimize cache misses.
|
||||
* This uses space between the window vectors, so is essentially
|
||||
* "free". All interruptee's regs are intact except a0 which is saved
|
||||
* in $ZSR_ALLOCA (assigned at build time, see gen_zsr.py for
|
||||
* details), and PS.EXCM has been set by the exception hardware (can't
|
||||
* be interrupted). The fact the alloca exception was taken means the
|
||||
* registers associated with the base-save area have been spilled and
|
||||
* will be restored by the underflow handler, so those 4 registers are
|
||||
* available for scratch. The code is optimized to avoid unaligned
|
||||
* branches and minimize cache misses.
|
||||
*/
|
||||
|
||||
.align 4
|
||||
|
@ -98,7 +102,7 @@ _xt_alloca_exc:
|
|||
rsr a2, PS
|
||||
extui a3, a2, XCHAL_PS_OWB_SHIFT, XCHAL_PS_OWB_BITS
|
||||
xor a3, a3, a4 /* bits changed from old to current windowbase */
|
||||
rsr a4, EXCSAVE_1 /* restore original a0 (now in a4) */
|
||||
rsr a4, ZSR_ALLOCA /* restore original a0 (now in a4) */
|
||||
slli a3, a3, XCHAL_PS_OWB_SHIFT
|
||||
xor a2, a2, a3 /* flip changed bits in old window base */
|
||||
wsr a2, PS /* update PS.OWB to new window base */
|
||||
|
|
|
@ -348,18 +348,18 @@ DEF_EXCINT XCHAL_DEBUGLEVEL, _handle_excint, xtensa_debugint_c
|
|||
* to save these five cycles during other exceptions and L1
|
||||
* interrupts. Maybe revisit at some point, with better benchmarking.
|
||||
* Note that _xt_alloca_exc is Xtensa-authored code which expects A0
|
||||
* to have been saved to EXCSAVE1, which is an unfortunate ABI given
|
||||
* that Zephyr code otherwise does not use the EXCSAVE registers.
|
||||
* to have been saved to EXCSAVE1, we've modified it to use the zsr.h
|
||||
* API to get assigned a scratch register.
|
||||
*/
|
||||
.pushsection .UserExceptionVector.text, "ax"
|
||||
.global _Level1RealVector
|
||||
_Level1RealVector:
|
||||
wsr.excsave1 a0
|
||||
wsr a0, ZSR_ALLOCA
|
||||
rsr.exccause a0
|
||||
bnei a0, EXCCAUSE_ALLOCA, _not_alloca
|
||||
j _xt_alloca_exc
|
||||
_not_alloca:
|
||||
rsr.excsave1 a0
|
||||
rsr a0, ZSR_ALLOCA
|
||||
j _Level1Vector
|
||||
.popsection
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue