1 /*
2  * Copyright (c) 2017 Intel Corporation
3  * Copyright 2025 Arm Limited and/or its affiliates <open-source-office@arm.com>
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 /**
9  * @file
10  * @brief Per-arch thread definition
11  *
12  * This file contains definitions for
13  *
14  *  struct _thread_arch
15  *  struct _callee_saved
16   *
17  * necessary to instantiate instances of struct k_thread.
18  */
19 
20 #ifndef ZEPHYR_INCLUDE_ARCH_ARM_THREAD_H_
21 #define ZEPHYR_INCLUDE_ARCH_ARM_THREAD_H_
22 
23 #ifndef _ASMLANGUAGE
24 #include <zephyr/types.h>
25 
26 struct _callee_saved {
27 	uint32_t v1;  /* r4 */
28 	uint32_t v2;  /* r5 */
29 	uint32_t v3;  /* r6 */
30 	uint32_t v4;  /* r7 */
31 	uint32_t v5;  /* r8 */
32 	uint32_t v6;  /* r9 */
33 	uint32_t v7;  /* r10 */
34 	uint32_t v8;  /* r11 */
35 	uint32_t psp; /* r13 */
36 #ifdef CONFIG_USE_SWITCH
37 	uint32_t lr;  /* lr */
38 #endif
39 };
40 
41 typedef struct _callee_saved _callee_saved_t;
42 
43 #if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING)
44 struct _preempt_float {
45 	float  s16;
46 	float  s17;
47 	float  s18;
48 	float  s19;
49 	float  s20;
50 	float  s21;
51 	float  s22;
52 	float  s23;
53 	float  s24;
54 	float  s25;
55 	float  s26;
56 	float  s27;
57 	float  s28;
58 	float  s29;
59 	float  s30;
60 	float  s31;
61 };
62 #endif
63 
64 #if defined(CONFIG_ARM_PAC_PER_THREAD)
65 struct pac_keys {
66 	uint32_t key_0;
67 	uint32_t key_1;
68 	uint32_t key_2;
69 	uint32_t key_3;
70 };
71 #endif
72 
73 struct _thread_arch {
74 
75 	/* interrupt locking key */
76 	uint32_t basepri;
77 
78 	/* r0 in stack frame cannot be written to reliably */
79 	uint32_t swap_return_value;
80 
81 #if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING)
82 	/*
83 	 * No cooperative floating point register set structure exists for
84 	 * the Cortex-M as it automatically saves the necessary registers
85 	 * in its exception stack frame.
86 	 */
87 	struct _preempt_float  preempt_float;
88 #endif
89 
90 #if defined(CONFIG_CPU_AARCH32_CORTEX_A) || defined(CONFIG_CPU_AARCH32_CORTEX_R)
91 	int8_t exception_depth;
92 #endif
93 
94 #if defined(CONFIG_ARM_STORE_EXC_RETURN) || defined(CONFIG_USERSPACE)
95 	/*
96 	 * Status variable holding several thread status flags
97 	 * as follows:
98 	 *
99 	 * byte 0
100 	 * +-bits 4-7-----bit-3----------bit-2--------bit-1---+----bit-0------+
101 	 * :          |             |              |          |               |
102 	 * : reserved |<Guard FLOAT>|   reserved   | reserved |  <priv mode>  |
103 	 * :   bits   |             |              |          | CONTROL.nPRIV |
104 	 * +------------------------------------------------------------------+
105 	 *
106 	 * byte 1
107 	 * +----------------------------bits 8-15-----------------------------+
108 	 * :              Least significant byte of EXC_RETURN                |
109 	 * : bit 15| bit 14| bit 13 | bit 12| bit 11 | bit 10 | bit 9 | bit 8 |
110 	 * :  Res  |   S   |  DCRS  | FType |  Mode  | SPSel  |  Res  |  ES   |
111 	 * +------------------------------------------------------------------+
112 	 *
113 	 * Bit 0: thread's current privileged mode (Supervisor or User mode)
114 	 *        Mirrors CONTROL.nPRIV flag.
115 	 * Bit 2: Deprecated in favor of FType. Note: FType = !CONTROL.FPCA.
116 	 *        indicating whether the thread has an active FP context.
117 	 *        Mirrors CONTROL.FPCA flag.
118 	 * Bit 3: indicating whether the thread is applying the long (FLOAT)
119 	 *        or the default MPU stack guard size.
120 	 *
121 	 * Bits 8-15: Least significant octet of the EXC_RETURN value when a
122 	 *            thread is switched-out. The value is copied from LR when
123 	 *            entering the PendSV handler. When the thread is
124 	 *            switched in again, the value is restored to LR before
125 	 *            exiting the PendSV handler.
126 	 */
127 	union {
128 		uint32_t mode;
129 
130 #if defined(CONFIG_ARM_STORE_EXC_RETURN)
131 		struct {
132 			uint8_t mode_bits;
133 			uint8_t mode_exc_return;
134 			uint16_t mode_reserved2;
135 		};
136 #endif
137 	};
138 
139 #if defined(CONFIG_USERSPACE)
140 	uint32_t priv_stack_start;
141 	uint32_t priv_stack_end;
142 #if defined(CONFIG_CPU_AARCH32_CORTEX_R)
143 	uint32_t sp_usr;
144 #endif
145 #endif
146 #endif
147 
148 #if defined(CONFIG_ARM_PAC_PER_THREAD)
149 	struct pac_keys pac_keys;
150 #endif
151 };
152 
153 #if defined(CONFIG_FPU_SHARING) && defined(CONFIG_MPU_STACK_GUARD)
154 #define Z_ARM_MODE_MPU_GUARD_FLOAT_Msk (1 << 3)
155 #endif
156 typedef struct _thread_arch _thread_arch_t;
157 
158 #endif /* _ASMLANGUAGE */
159 
160 #endif /* ZEPHYR_INCLUDE_ARCH_ARM_THREAD_H_ */
161