zephyr/arch/xtensa/include/xtensa_asm2_context.h
Peter Mitsis 520c8c2283 arch: xtensa: Add space for HiFi registers
Updates the xtensa_irq_base_save_area structure to include space
for saving/restoring the HiFi AudioEngine registers used by CP1.

The starting address of these HiFi AE registers also needs to be
referenced from assembly, so it is added to the set of symbols
symbols for which we need an offset to be auto-generated.

Signed-off-by: Peter Mitsis <peter.mitsis@intel.com>
2024-03-05 10:57:33 +01:00

251 lines
5.4 KiB
C

/*
* Copyright (c) 2017, Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_ASM2_CONTEXT_H_
#define ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_ASM2_CONTEXT_H_
#include <xtensa/corebits.h>
#include <xtensa/config/core-isa.h>
#include <xtensa/config/tie.h>
/*
* Stack frame layout for a saved processor context, in memory order,
* high to low address:
*
* SP-0 <-- Interrupted stack pointer points here
*
* SP-4 Caller A3 spill slot \
* SP-8 Caller A2 spill slot |
* SP-12 Caller A1 spill slot + (Part of ABI standard)
* SP-16 Caller A0 spill slot /
*
* SP-20 Saved A3
* SP-24 Saved A2
* SP-28 Unused (not "Saved A1" because the SP is saved externally as a handle)
* SP-32 Saved A0
*
* SP-36 Saved PC (address to jump to following restore)
* SP-40 Saved/interrupted PS special register
*
* SP-44 Saved SAR special register
*
* SP-48 Saved LBEG special register (if loops enabled)
* SP-52 Saved LEND special register (if loops enabled)
* SP-56 Saved LCOUNT special register (if loops enabled)
*
* SP-60 Saved SCOMPARE special register (if S32C1I enabled)
*
* SP-64 Saved EXCCAUSE special register
*
* SP-68 Saved THREADPTR special register (if processor has thread pointer)
*
* (The above fixed-size region is known as the "base save area" in the
* code below)
*
* - 18 FPU registers (if FPU is present and CONFIG_FPU_SHARING enabled)
*
* - Saved A7 \
* - Saved A6 |
* - Saved A5 +- If not in-use by another frame
* - Saved A4 /
*
* - Saved A11 \
* - Saved A10 |
* - Saved A9 +- If not in-use by another frame
* - Saved A8 /
*
* - Saved A15 \
* - Saved A14 |
* - Saved A13 +- If not in-use by another frame
* - Saved A12 /
*
* - Saved intermediate stack pointer (points to low word of base save
* area, i.e. the saved LCOUNT or SAR). The pointer to this value
* (i.e. the final stack pointer) is stored externally as the
* "restore handle" in the thread context.
*
* Essentially, you can recover a pointer to the BSA by loading *SP.
* Adding the fixed BSA size to that gets you back to the
* original/interrupted stack pointer.
*/
#ifndef __ASSEMBLER__
#include <stdint.h>
#include <zephyr/toolchain.h>
/**
* Base Save Area (BSA) during interrupt.
*
* This saves the registers during interrupt entrance
* so they can be restored later.
*
* Note that only A0-A3 are saved here. High registers
* are saved after the BSA.
*/
struct xtensa_irq_base_save_area {
#if XCHAL_HAVE_FP && defined(CONFIG_CPU_HAS_FPU) && defined(CONFIG_FPU_SHARING)
uintptr_t fcr;
uintptr_t fsr;
uintptr_t fpu0;
uintptr_t fpu1;
uintptr_t fpu2;
uintptr_t fpu3;
uintptr_t fpu4;
uintptr_t fpu5;
uintptr_t fpu6;
uintptr_t fpu7;
uintptr_t fpu8;
uintptr_t fpu9;
uintptr_t fpu10;
uintptr_t fpu11;
uintptr_t fpu12;
uintptr_t fpu13;
uintptr_t fpu14;
uintptr_t fpu15;
#endif
#if defined(CONFIG_XTENSA_HIFI_SHARING)
/*
* Carve space for the registers used by the HiFi audio engine
* coprocessor (which is always CP1). Carve additional space to
* manage alignment at run-time as we can not yet guarantee the
* alignment of the BSA.
*/
uint8_t hifi[XCHAL_CP1_SA_SIZE + XCHAL_CP1_SA_ALIGN];
#endif
#if XCHAL_HAVE_THREADPTR
uintptr_t threadptr;
#endif
#if XCHAL_HAVE_S32C1I
uintptr_t scompare1;
#endif
uintptr_t exccause;
#if XCHAL_HAVE_LOOPS
uintptr_t lcount;
uintptr_t lend;
uintptr_t lbeg;
#endif
uintptr_t sar;
uintptr_t ps;
uintptr_t pc;
uintptr_t a0;
uintptr_t scratch;
uintptr_t a2;
uintptr_t a3;
uintptr_t caller_a0;
uintptr_t caller_a1;
uintptr_t caller_a2;
uintptr_t caller_a3;
};
typedef struct xtensa_irq_base_save_area _xtensa_irq_bsa_t;
/**
* Raw interrupt stack frame.
*
* This provides a raw interrupt stack frame to make it
* easier to construct general purpose code in loops.
* Avoid using this if possible.
*/
struct xtensa_irq_stack_frame_raw {
_xtensa_irq_bsa_t *ptr_to_bsa;
struct {
uintptr_t r0;
uintptr_t r1;
uintptr_t r2;
uintptr_t r3;
} blks[3];
};
typedef struct xtensa_irq_stack_frame_raw _xtensa_irq_stack_frame_raw_t;
/**
* Interrupt stack frame containing A0 - A15.
*/
struct xtensa_irq_stack_frame_a15 {
_xtensa_irq_bsa_t *ptr_to_bsa;
uintptr_t a12;
uintptr_t a13;
uintptr_t a14;
uintptr_t a15;
uintptr_t a8;
uintptr_t a9;
uintptr_t a10;
uintptr_t a11;
uintptr_t a4;
uintptr_t a5;
uintptr_t a6;
uintptr_t a7;
_xtensa_irq_bsa_t bsa;
};
typedef struct xtensa_irq_stack_frame_a15 _xtensa_irq_stack_frame_a15_t;
/**
* Interrupt stack frame containing A0 - A11.
*/
struct xtensa_irq_stack_frame_a11 {
_xtensa_irq_bsa_t *ptr_to_bsa;
uintptr_t a8;
uintptr_t a9;
uintptr_t a10;
uintptr_t a11;
uintptr_t a4;
uintptr_t a5;
uintptr_t a6;
uintptr_t a7;
_xtensa_irq_bsa_t bsa;
};
typedef struct xtensa_irq_stack_frame_a11 _xtensa_irq_stack_frame_a11_t;
/**
* Interrupt stack frame containing A0 - A7.
*/
struct xtensa_irq_stack_frame_a7 {
_xtensa_irq_bsa_t *ptr_to_bsa;
uintptr_t a4;
uintptr_t a5;
uintptr_t a6;
uintptr_t a7;
_xtensa_irq_bsa_t bsa;
};
typedef struct xtensa_irq_stack_frame_a7 _xtensa_irq_stack_frame_a7_t;
/**
* Interrupt stack frame containing A0 - A3.
*/
struct xtensa_irq_stack_frame_a3 {
_xtensa_irq_bsa_t *ptr_to_bsa;
_xtensa_irq_bsa_t bsa;
};
typedef struct xtensa_irq_stack_frame_a3 _xtensa_irq_stack_frame_a3_t;
#endif /* __ASSEMBLER__ */
#endif /* ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_ASM2_CONTEXT_H_ */