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