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 #include <xtensa/corebits.h> 10 #include <xtensa/config/core-isa.h> 11 12 /* 13 * Stack frame layout for a saved processor context, in memory order, 14 * high to low address: 15 * 16 * SP-0 <-- Interrupted stack pointer points here 17 * 18 * SP-4 Caller A3 spill slot \ 19 * SP-8 Caller A2 spill slot | 20 * SP-12 Caller A1 spill slot + (Part of ABI standard) 21 * SP-16 Caller A0 spill slot / 22 * 23 * SP-20 Saved A3 24 * SP-24 Saved A2 25 * SP-28 Unused (not "Saved A1" because the SP is saved externally as a handle) 26 * SP-32 Saved A0 27 * 28 * SP-36 Saved PC (address to jump to following restore) 29 * SP-40 Saved/interrupted PS special register 30 * 31 * SP-44 Saved SAR special register 32 * 33 * SP-48 Saved LBEG special register (if loops enabled) 34 * SP-52 Saved LEND special register (if loops enabled) 35 * SP-56 Saved LCOUNT special register (if loops enabled) 36 * 37 * SP-60 Saved SCOMPARE special register (if S32C1I enabled) 38 * 39 * (The above fixed-size region is known as the "base save area" in the 40 * code below) 41 * 42 * - Saved A7 \ 43 * - Saved A6 | 44 * - Saved A5 +- If not in-use by another frame 45 * - Saved A4 / 46 * 47 * - Saved A11 \ 48 * - Saved A10 | 49 * - Saved A9 +- If not in-use by another frame 50 * - Saved A8 / 51 * 52 * - Saved A15 \ 53 * - Saved A14 | 54 * - Saved A13 +- If not in-use by another frame 55 * - Saved A12 / 56 * 57 * - Saved intermediate stack pointer (points to low word of base save 58 * area, i.e. the saved LCOUNT or SAR). The pointer to this value 59 * (i.e. the final stack pointer) is stored externally as the 60 * "restore handle" in the thread context. 61 * 62 * Essentially, you can recover a pointer to the BSA by loading *SP. 63 * Adding the fixed BSA size to that gets you back to the 64 * original/interrupted stack pointer. 65 */ 66 67 #define BASE_SAVE_AREA_SIZE_COMMON 44 68 #define BASE_SAVE_AREA_SIZE_EXCCAUSE 4 69 70 #if XCHAL_HAVE_LOOPS 71 #define BASE_SAVE_AREA_SIZE_LOOPS 12 72 #else 73 #define BASE_SAVE_AREA_SIZE_LOOPS 0 74 #endif 75 76 #if XCHAL_HAVE_S32C1I 77 #define BASE_SAVE_AREA_SIZE_SCOMPARE 4 78 #else 79 #define BASE_SAVE_AREA_SIZE_SCOMPARE 0 80 #endif 81 82 #if XCHAL_HAVE_THREADPTR && defined(CONFIG_THREAD_LOCAL_STORAGE) 83 #define BASE_SAVE_AREA_SIZE_THREADPTR 4 84 #else 85 #define BASE_SAVE_AREA_SIZE_THREADPTR 0 86 #endif 87 88 #define BASE_SAVE_AREA_SIZE \ 89 (BASE_SAVE_AREA_SIZE_COMMON + \ 90 BASE_SAVE_AREA_SIZE_LOOPS + \ 91 BASE_SAVE_AREA_SIZE_EXCCAUSE + \ 92 BASE_SAVE_AREA_SIZE_SCOMPARE + \ 93 BASE_SAVE_AREA_SIZE_THREADPTR) 94 95 #define BSA_A3_OFF (BASE_SAVE_AREA_SIZE - 20) 96 #define BSA_A2_OFF (BASE_SAVE_AREA_SIZE - 24) 97 #define BSA_SCRATCH_OFF (BASE_SAVE_AREA_SIZE - 28) 98 #define BSA_A0_OFF (BASE_SAVE_AREA_SIZE - 32) 99 #define BSA_PC_OFF (BASE_SAVE_AREA_SIZE - 36) 100 #define BSA_PS_OFF (BASE_SAVE_AREA_SIZE - 40) 101 #define BSA_SAR_OFF (BASE_SAVE_AREA_SIZE - 44) 102 #define BSA_LBEG_OFF (BASE_SAVE_AREA_SIZE - 48) 103 #define BSA_LEND_OFF (BASE_SAVE_AREA_SIZE - 52) 104 #define BSA_LCOUNT_OFF (BASE_SAVE_AREA_SIZE - 56) 105 106 #define BSA_EXCCAUSE_OFF \ 107 (BASE_SAVE_AREA_SIZE - \ 108 (BASE_SAVE_AREA_SIZE_COMMON + \ 109 BASE_SAVE_AREA_SIZE_LOOPS + \ 110 BASE_SAVE_AREA_SIZE_EXCCAUSE)) 111 #if XCHAL_HAVE_S32C1I 112 #define BSA_SCOMPARE1_OFF \ 113 (BASE_SAVE_AREA_SIZE - \ 114 (BASE_SAVE_AREA_SIZE_COMMON + \ 115 BASE_SAVE_AREA_SIZE_LOOPS + \ 116 BASE_SAVE_AREA_SIZE_EXCCAUSE + \ 117 BASE_SAVE_AREA_SIZE_SCOMPARE)) 118 #endif 119 120 #if XCHAL_HAVE_THREADPTR && defined(CONFIG_THREAD_LOCAL_STORAGE) 121 #define BSA_THREADPTR_OFF \ 122 (BASE_SAVE_AREA_SIZE - \ 123 (BASE_SAVE_AREA_SIZE_COMMON + \ 124 BASE_SAVE_AREA_SIZE_LOOPS + \ 125 BASE_SAVE_AREA_SIZE_EXCCAUSE + \ 126 BASE_SAVE_AREA_SIZE_SCOMPARE + \ 127 BASE_SAVE_AREA_SIZE_THREADPTR)) 128 #endif 129 130 #endif /* ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_ASM2_CONTEXT_H_ */ 131