1 /*
2  * Copyright (c) 2017 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @file
9  * @brief Per-arch thread definition
10  *
11  * This file contains definitions for
12  *
13  *  struct _thread_arch
14  *  struct _callee_saved
15  *
16  * necessary to instantiate instances of struct k_thread.
17  */
18 
19 #ifndef ZEPHYR_INCLUDE_ARCH_RISCV_THREAD_H_
20 #define ZEPHYR_INCLUDE_ARCH_RISCV_THREAD_H_
21 
22 #ifndef _ASMLANGUAGE
23 #include <zephyr/types.h>
24 
25 #if !defined(RV_FP_TYPE) && defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING)
26 #ifdef CONFIG_CPU_HAS_FPU_DOUBLE_PRECISION
27 #define RV_FP_TYPE uint64_t
28 #else
29 #define RV_FP_TYPE uint32_t
30 #endif
31 #endif
32 
33 #ifdef CONFIG_RISCV_PMP
34 #ifdef CONFIG_64BIT
35 #define	RISCV_PMP_CFG_NUM	(CONFIG_PMP_SLOT >> 3)
36 #else
37 #define	RISCV_PMP_CFG_NUM	(CONFIG_PMP_SLOT >> 2)
38 #endif
39 #endif
40 
41 #ifdef CONFIG_PMP_STACK_GUARD
42 /*
43  * PMP entries:
44  *   (1 for interrupt stack guard: None)
45  *   4 for stacks guard: None
46  *   1 for RAM: RW
47  *   1 for other address space: RWX
48  */
49 #define PMP_REGION_NUM_FOR_STACK_GUARD	6
50 #define PMP_CFG_CSR_NUM_FOR_STACK_GUARD	2
51 #endif /* CONFIG_PMP_STACK_GUARD */
52 
53 #ifdef CONFIG_PMP_POWER_OF_TWO_ALIGNMENT
54 #ifdef CONFIG_USERSPACE
55 #ifdef CONFIG_PMP_STACK_GUARD
56 /*
57  * 1 for interrupt stack guard: None
58  * 1 for core state: R
59  * 1 for program and read only data: RX
60  * 1 for user thread stack: RW
61  */
62 #define PMP_REGION_NUM_FOR_U_THREAD	4
63 #else /* CONFIG_PMP_STACK_GUARD */
64 /*
65  * 1 for core state: R
66  * 1 for program and read only data: RX
67  * 1 for user thread stack: RW
68  */
69 #define PMP_REGION_NUM_FOR_U_THREAD	3
70 #endif /* CONFIG_PMP_STACK_GUARD */
71 #define PMP_MAX_DYNAMIC_REGION	(CONFIG_PMP_SLOT - PMP_REGION_NUM_FOR_U_THREAD)
72 #endif /* CONFIG_USERSPACE */
73 
74 #else /* CONFIG_PMP_POWER_OF_TWO_ALIGNMENT */
75 
76 #ifdef CONFIG_USERSPACE
77 #ifdef CONFIG_PMP_STACK_GUARD
78 /*
79  * 1 for interrupt stack guard: None
80  * 1 for core state: R
81  * 2 for program and read only data: RX
82  * 2 for user thread stack: RW
83  */
84 #define PMP_REGION_NUM_FOR_U_THREAD	6
85 #else /* CONFIG_PMP_STACK_GUARD */
86 /*
87  * 1 for core state: R
88  * 2 for program and read only data: RX
89  * 2 for user thread stack: RW
90  */
91 #define PMP_REGION_NUM_FOR_U_THREAD	5
92 #endif /* CONFIG_PMP_STACK_GUARD */
93 #define PMP_MAX_DYNAMIC_REGION	((CONFIG_PMP_SLOT - \
94 				PMP_REGION_NUM_FOR_U_THREAD) >> 1)
95 #endif /* CONFIG_USERSPACE */
96 #endif /* CONFIG_PMP_POWER_OF_TWO_ALIGNMENT */
97 
98 /*
99  * The following structure defines the list of registers that need to be
100  * saved/restored when a cooperative context switch occurs.
101  */
102 struct _callee_saved {
103 	ulong_t sp;	/* Stack pointer, (x2 register) */
104 
105 	ulong_t s0;	/* saved register/frame pointer */
106 	ulong_t s1;	/* saved register */
107 	ulong_t s2;	/* saved register */
108 	ulong_t s3;	/* saved register */
109 	ulong_t s4;	/* saved register */
110 	ulong_t s5;	/* saved register */
111 	ulong_t s6;	/* saved register */
112 	ulong_t s7;	/* saved register */
113 	ulong_t s8;	/* saved register */
114 	ulong_t s9;	/* saved register */
115 	ulong_t s10;	/* saved register */
116 	ulong_t s11;	/* saved register */
117 
118 #if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING)
119 	uint32_t fcsr;		/* Control and status register */
120 	RV_FP_TYPE fs0;		/* saved floating-point register */
121 	RV_FP_TYPE fs1;		/* saved floating-point register */
122 	RV_FP_TYPE fs2;		/* saved floating-point register */
123 	RV_FP_TYPE fs3;		/* saved floating-point register */
124 	RV_FP_TYPE fs4;		/* saved floating-point register */
125 	RV_FP_TYPE fs5;		/* saved floating-point register */
126 	RV_FP_TYPE fs6;		/* saved floating-point register */
127 	RV_FP_TYPE fs7;		/* saved floating-point register */
128 	RV_FP_TYPE fs8;		/* saved floating-point register */
129 	RV_FP_TYPE fs9;		/* saved floating-point register */
130 	RV_FP_TYPE fs10;	/* saved floating-point register */
131 	RV_FP_TYPE fs11;	/* saved floating-point register */
132 #endif
133 };
134 typedef struct _callee_saved _callee_saved_t;
135 
136 struct _thread_arch {
137 	uint32_t swap_return_value; /* Return value of z_swap() */
138 
139 #ifdef CONFIG_PMP_STACK_GUARD
140 	ulong_t s_pmpcfg[PMP_CFG_CSR_NUM_FOR_STACK_GUARD];
141 	ulong_t s_pmpaddr[PMP_REGION_NUM_FOR_STACK_GUARD];
142 #endif
143 
144 #ifdef CONFIG_USERSPACE
145 	ulong_t priv_stack_start;
146 	ulong_t user_sp;
147 	ulong_t unfinished_syscall;
148 	ulong_t u_pmpcfg[RISCV_PMP_CFG_NUM];
149 	ulong_t u_pmpaddr[CONFIG_PMP_SLOT];
150 #endif
151 };
152 
153 typedef struct _thread_arch _thread_arch_t;
154 
155 #endif /* _ASMLANGUAGE */
156 
157 #endif /* ZEPHYR_INCLUDE_ARCH_RISCV_THREAD_H_ */
158