1 /* 2 * Copyright (c) 2017, Intel Corporation 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 #ifndef ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_ASM2_CONTEXT_H_ 7 #define ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_ASM2_CONTEXT_H_ 8 9 #if defined(__XT_CLANG__) 10 #include <xtensa/xtensa-types.h> 11 #endif 12 13 #include <xtensa/corebits.h> 14 #include <xtensa/config/core-isa.h> 15 #include <xtensa/config/tie.h> 16 17 /* 18 * Stack frame layout for a saved processor context, in memory order, 19 * high to low address: 20 * 21 * SP-0 <-- Interrupted stack pointer points here 22 * 23 * SP-4 Caller A3 spill slot \ 24 * SP-8 Caller A2 spill slot | 25 * SP-12 Caller A1 spill slot + (Part of ABI standard) 26 * SP-16 Caller A0 spill slot / 27 * 28 * SP-20 Saved A3 29 * SP-24 Saved A2 30 * SP-28 Unused (not "Saved A1" because the SP is saved externally as a handle) 31 * SP-32 Saved A0 32 * 33 * SP-36 Saved PC (address to jump to following restore) 34 * SP-40 Saved/interrupted PS special register 35 * 36 * SP-44 Saved SAR special register 37 * 38 * SP-48 Saved LBEG special register (if loops enabled) 39 * SP-52 Saved LEND special register (if loops enabled) 40 * SP-56 Saved LCOUNT special register (if loops enabled) 41 * 42 * SP-60 Saved SCOMPARE special register (if S32C1I enabled) 43 * 44 * SP-64 Saved EXCCAUSE special register 45 * 46 * SP-68 Saved THREADPTR special register (if processor has thread pointer) 47 * 48 * (The above fixed-size region is known as the "base save area" in the 49 * code below) 50 * 51 * - 18 FPU registers (if FPU is present and CONFIG_FPU_SHARING enabled) 52 * 53 * - Saved A7 \ 54 * - Saved A6 | 55 * - Saved A5 +- If not in-use by another frame 56 * - Saved A4 / 57 * 58 * - Saved A11 \ 59 * - Saved A10 | 60 * - Saved A9 +- If not in-use by another frame 61 * - Saved A8 / 62 * 63 * - Saved A15 \ 64 * - Saved A14 | 65 * - Saved A13 +- If not in-use by another frame 66 * - Saved A12 / 67 * 68 * - Saved intermediate stack pointer (points to low word of base save 69 * area, i.e. the saved LCOUNT or SAR). The pointer to this value 70 * (i.e. the final stack pointer) is stored externally as the 71 * "restore handle" in the thread context. 72 * 73 * Essentially, you can recover a pointer to the BSA by loading *SP. 74 * Adding the fixed BSA size to that gets you back to the 75 * original/interrupted stack pointer. 76 */ 77 78 #ifndef __ASSEMBLER__ 79 80 #include <stdint.h> 81 #include <zephyr/toolchain.h> 82 83 /** 84 * Base Save Area (BSA) during interrupt. 85 * 86 * This saves the registers during interrupt entrance 87 * so they can be restored later. 88 * 89 * Note that only A0-A3 are saved here. High registers 90 * are saved after the BSA. 91 */ 92 struct xtensa_irq_base_save_area { 93 #if XCHAL_HAVE_FP && defined(CONFIG_CPU_HAS_FPU) && defined(CONFIG_FPU_SHARING) 94 uintptr_t fcr; 95 uintptr_t fsr; 96 uintptr_t fpu0; 97 uintptr_t fpu1; 98 uintptr_t fpu2; 99 uintptr_t fpu3; 100 uintptr_t fpu4; 101 uintptr_t fpu5; 102 uintptr_t fpu6; 103 uintptr_t fpu7; 104 uintptr_t fpu8; 105 uintptr_t fpu9; 106 uintptr_t fpu10; 107 uintptr_t fpu11; 108 uintptr_t fpu12; 109 uintptr_t fpu13; 110 uintptr_t fpu14; 111 uintptr_t fpu15; 112 #endif 113 114 #if defined(CONFIG_XTENSA_HIFI_SHARING) 115 116 /* 117 * Carve space for the registers used by the HiFi audio engine 118 * coprocessor (which is always CP1). Carve additional space to 119 * manage alignment at run-time as we can not yet guarantee the 120 * alignment of the BSA. 121 */ 122 123 uint8_t hifi[XCHAL_CP1_SA_SIZE + XCHAL_CP1_SA_ALIGN]; 124 #endif 125 126 #if XCHAL_HAVE_THREADPTR 127 uintptr_t threadptr; 128 #endif 129 130 #if XCHAL_HAVE_S32C1I 131 uintptr_t scompare1; 132 #endif 133 134 uintptr_t exccause; 135 136 #if XCHAL_HAVE_LOOPS 137 uintptr_t lcount; 138 uintptr_t lend; 139 uintptr_t lbeg; 140 #endif 141 142 uintptr_t sar; 143 uintptr_t ps; 144 uintptr_t pc; 145 uintptr_t a0; 146 uintptr_t scratch; 147 uintptr_t a2; 148 uintptr_t a3; 149 150 uintptr_t caller_a0; 151 uintptr_t caller_a1; 152 uintptr_t caller_a2; 153 uintptr_t caller_a3; 154 }; 155 156 typedef struct xtensa_irq_base_save_area _xtensa_irq_bsa_t; 157 158 /** 159 * Raw interrupt stack frame. 160 * 161 * This provides a raw interrupt stack frame to make it 162 * easier to construct general purpose code in loops. 163 * Avoid using this if possible. 164 */ 165 struct xtensa_irq_stack_frame_raw { 166 _xtensa_irq_bsa_t *ptr_to_bsa; 167 168 struct { 169 uintptr_t r0; 170 uintptr_t r1; 171 uintptr_t r2; 172 uintptr_t r3; 173 } blks[3]; 174 }; 175 176 typedef struct xtensa_irq_stack_frame_raw _xtensa_irq_stack_frame_raw_t; 177 178 /** 179 * Interrupt stack frame containing A0 - A15. 180 */ 181 struct xtensa_irq_stack_frame_a15 { 182 _xtensa_irq_bsa_t *ptr_to_bsa; 183 184 uintptr_t a12; 185 uintptr_t a13; 186 uintptr_t a14; 187 uintptr_t a15; 188 189 uintptr_t a8; 190 uintptr_t a9; 191 uintptr_t a10; 192 uintptr_t a11; 193 194 uintptr_t a4; 195 uintptr_t a5; 196 uintptr_t a6; 197 uintptr_t a7; 198 199 _xtensa_irq_bsa_t bsa; 200 }; 201 202 typedef struct xtensa_irq_stack_frame_a15 _xtensa_irq_stack_frame_a15_t; 203 204 /** 205 * Interrupt stack frame containing A0 - A11. 206 */ 207 struct xtensa_irq_stack_frame_a11 { 208 _xtensa_irq_bsa_t *ptr_to_bsa; 209 210 uintptr_t a8; 211 uintptr_t a9; 212 uintptr_t a10; 213 uintptr_t a11; 214 215 uintptr_t a4; 216 uintptr_t a5; 217 uintptr_t a6; 218 uintptr_t a7; 219 220 _xtensa_irq_bsa_t bsa; 221 }; 222 223 typedef struct xtensa_irq_stack_frame_a11 _xtensa_irq_stack_frame_a11_t; 224 225 /** 226 * Interrupt stack frame containing A0 - A7. 227 */ 228 struct xtensa_irq_stack_frame_a7 { 229 _xtensa_irq_bsa_t *ptr_to_bsa; 230 231 uintptr_t a4; 232 uintptr_t a5; 233 uintptr_t a6; 234 uintptr_t a7; 235 236 _xtensa_irq_bsa_t bsa; 237 }; 238 239 typedef struct xtensa_irq_stack_frame_a7 _xtensa_irq_stack_frame_a7_t; 240 241 /** 242 * Interrupt stack frame containing A0 - A3. 243 */ 244 struct xtensa_irq_stack_frame_a3 { 245 _xtensa_irq_bsa_t *ptr_to_bsa; 246 247 _xtensa_irq_bsa_t bsa; 248 }; 249 250 typedef struct xtensa_irq_stack_frame_a3 _xtensa_irq_stack_frame_a3_t; 251 252 #endif /* __ASSEMBLER__ */ 253 254 #endif /* ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_ASM2_CONTEXT_H_ */ 255