Zephyr Project API 4.4.99
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
thread_stack.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
12
22
23#ifndef ZEPHYR_INCLUDE_KERNEL_THREAD_STACK_H
24#define ZEPHYR_INCLUDE_KERNEL_THREAD_STACK_H
25
26#if !defined(_ASMLANGUAGE)
27#include <zephyr/arch/cpu.h>
28#include <zephyr/sys/util.h>
29
30#ifdef __cplusplus
31extern "C" {
32#endif
33
34/* Using typedef deliberately here, this is quite intended to be an opaque
35 * type.
36 *
37 * The purpose of this data type is to clearly distinguish between the
38 * declared symbol for a stack (of type k_thread_stack_t) and the underlying
39 * buffer which composes the stack data actually used by the underlying
40 * thread; they cannot be used interchangeably as some arches precede the
41 * stack buffer region with guard areas that trigger a MPU or MMU fault
42 * if written to.
43 *
44 * APIs that want to work with the buffer inside should continue to use
45 * char *.
46 *
47 * Stacks should always be created with K_THREAD_STACK_DEFINE().
48 */
49struct __packed z_thread_stack_element {
50 char data;
51};
52
59
60
71static inline char *z_stack_ptr_align(char *ptr)
72{
73 return (char *)ROUND_DOWN(ptr, ARCH_STACK_PTR_ALIGN);
74}
75#define Z_STACK_PTR_ALIGN(ptr) ((uintptr_t)z_stack_ptr_align((char *)(ptr)))
76
90#define Z_STACK_PTR_TO_FRAME(type, ptr) \
91 (type *)((ptr) - sizeof(type))
92
93#ifdef ARCH_KERNEL_STACK_RESERVED
94#define K_KERNEL_STACK_RESERVED ((size_t)ARCH_KERNEL_STACK_RESERVED)
95#else
96#define K_KERNEL_STACK_RESERVED ((size_t)0)
97#endif /* ARCH_KERNEL_STACK_RESERVED */
98
99#define Z_KERNEL_STACK_SIZE_ADJUST(size) (ROUND_UP(size, \
100 ARCH_STACK_PTR_ALIGN) + \
101 K_KERNEL_STACK_RESERVED)
102
103#ifdef ARCH_KERNEL_STACK_OBJ_ALIGN
104#define Z_KERNEL_STACK_OBJ_ALIGN ARCH_KERNEL_STACK_OBJ_ALIGN
105#else
106#define Z_KERNEL_STACK_OBJ_ALIGN ARCH_STACK_PTR_ALIGN
107#endif /* ARCH_KERNEL_STACK_OBJ_ALIGN */
108
109#define K_KERNEL_STACK_LEN(size) \
110 ROUND_UP(Z_KERNEL_STACK_SIZE_ADJUST(size), Z_KERNEL_STACK_OBJ_ALIGN)
111
116
117#ifdef CONFIG_HW_SHADOW_STACK
125#define k_thread_hw_shadow_stack_t arch_thread_hw_shadow_stack_t
126
136#define K_THREAD_HW_SHADOW_STACK_SIZE(size_) \
137 ARCH_THREAD_HW_SHADOW_STACK_SIZE(size_)
138
148#define K_KERNEL_HW_SHADOW_STACK_DECLARE(sym, size) \
149 ARCH_THREAD_HW_SHADOW_STACK_DECLARE(__ ## sym ## _shstk, size)
150
161#define K_KERNEL_HW_SHADOW_STACK_ARRAY_DECLARE(sym, nmemb, size) \
162 ARCH_THREAD_HW_SHADOW_STACK_ARRAY_DECLARE(__ ## sym ## _shstk_arr, \
163 nmemb, size)
164
165struct _stack_to_hw_shadow_stack {
166 k_thread_stack_t *stack;
167 k_thread_hw_shadow_stack_t *shstk_addr;
168 size_t size;
169};
170
171
183#define K_THREAD_HW_SHADOW_STACK_DEFINE(sym, size_) \
184 ARCH_THREAD_HW_SHADOW_STACK_DEFINE(__ ## sym ## _shstk, size_); \
185 static const STRUCT_SECTION_ITERABLE(_stack_to_hw_shadow_stack, \
186 sym ## _stack_to_shstk_attach) = { \
187 .stack = sym, \
188 .shstk_addr = __ ## sym ## _shstk, \
189 .size = size_, \
190 }
191
192struct _stack_to_hw_shadow_stack_arr {
193 uintptr_t stack_addr;
194 uintptr_t shstk_addr;
195 size_t stack_size;
196 size_t shstk_size;
197 size_t nmemb;
198};
199
212#define K_THREAD_HW_SHADOW_STACK_ARRAY_DEFINE(sym, nmemb_, size_) \
213 ARCH_THREAD_HW_SHADOW_STACK_ARRAY_DEFINE(__ ## sym ## _shstk_arr, nmemb_, \
214 K_THREAD_HW_SHADOW_STACK_SIZE(size_)); \
215 static const STRUCT_SECTION_ITERABLE(_stack_to_hw_shadow_stack_arr, \
216 sym ## _stack_to_shstk_attach) = { \
217 .stack_addr = (uintptr_t)sym, \
218 .stack_size = K_KERNEL_STACK_LEN(size_), \
219 .nmemb = nmemb_, \
220 .shstk_addr = (uintptr_t)__ ## sym ## _shstk_arr, \
221 .shstk_size = K_THREAD_HW_SHADOW_STACK_SIZE(size_), \
222 }
223
232#define k_thread_hw_shadow_stack_attach arch_thread_hw_shadow_stack_attach
233
234struct _thread_hw_shadow_stack_static {
235 struct k_thread *thread;
236 k_thread_hw_shadow_stack_t *shstk_addr;
237 size_t size;
238};
239
252#define K_THREAD_HW_SHADOW_STACK_ATTACH(thread_, shstk_addr_, size_) \
253 static const STRUCT_SECTION_ITERABLE(_thread_hw_shadow_stack_static, \
254 thread ## _shstk_attach_static) = { \
255 .thread = thread_, \
256 .shstk_addr = shstk_addr_, \
257 .size = size_, \
258 }
259
260#else
261#define K_KERNEL_HW_SHADOW_STACK_DECLARE(sym, size)
262#define K_KERNEL_HW_SHADOW_STACK_ARRAY_DECLARE(sym, nmemb, size)
263#define K_THREAD_HW_SHADOW_STACK_DEFINE(sym, size)
264#define K_THREAD_HW_SHADOW_STACK_ARRAY_DEFINE(sym, nmemb, size_)
265#endif
266
276#define K_KERNEL_STACK_DECLARE(sym, size) \
277 K_KERNEL_HW_SHADOW_STACK_DECLARE(sym, K_THREAD_HW_SHADOW_STACK_SIZE(size)); \
278 extern struct z_thread_stack_element \
279 sym[K_KERNEL_STACK_LEN(size)]
280
291#define K_KERNEL_STACK_ARRAY_DECLARE(sym, nmemb, size) \
292 K_KERNEL_HW_SHADOW_STACK_ARRAY_DECLARE(sym, nmemb, K_THREAD_HW_SHADOW_STACK_SIZE(size)); \
293 extern struct z_thread_stack_element \
294 sym[nmemb][K_KERNEL_STACK_LEN(size)]
295
315#define Z_KERNEL_STACK_DEFINE_IN(sym, size, lsect) \
316 struct z_thread_stack_element lsect \
317 __aligned(Z_KERNEL_STACK_OBJ_ALIGN) \
318 sym[K_KERNEL_STACK_LEN(size)]
319
328#define Z_KERNEL_STACK_ARRAY_DEFINE_IN(sym, nmemb, size, lsect) \
329 struct z_thread_stack_element lsect \
330 __aligned(Z_KERNEL_STACK_OBJ_ALIGN) \
331 sym[nmemb][K_KERNEL_STACK_LEN(size)]
332
354#define K_KERNEL_STACK_DEFINE(sym, size) \
355 Z_KERNEL_STACK_DEFINE_IN(sym, size, __kstackmem); \
356 K_THREAD_HW_SHADOW_STACK_DEFINE(sym, \
357 K_THREAD_HW_SHADOW_STACK_SIZE(size))
358
368#define K_KERNEL_STACK_ARRAY_DEFINE(sym, nmemb, size) \
369 Z_KERNEL_STACK_ARRAY_DEFINE_IN(sym, nmemb, size, __kstackmem); \
370 K_THREAD_HW_SHADOW_STACK_ARRAY_DEFINE(sym, nmemb, size)
371
381#define K_KERNEL_STACK_MEMBER(sym, size) \
382 Z_KERNEL_STACK_DEFINE_IN(sym, size,)
383
384#define K_KERNEL_STACK_SIZEOF(sym) (sizeof(sym) - K_KERNEL_STACK_RESERVED)
385
387
389{
390 return (char *)sym + K_KERNEL_STACK_RESERVED;
391}
392#ifndef CONFIG_USERSPACE
393#define K_THREAD_STACK_RESERVED K_KERNEL_STACK_RESERVED
394#define K_THREAD_STACK_SIZEOF K_KERNEL_STACK_SIZEOF
395#define K_THREAD_STACK_LEN K_KERNEL_STACK_LEN
396#define K_THREAD_STACK_DEFINE K_KERNEL_STACK_DEFINE
397#define K_THREAD_STACK_ARRAY_DEFINE K_KERNEL_STACK_ARRAY_DEFINE
398#define K_THREAD_STACK_BUFFER K_KERNEL_STACK_BUFFER
399#define K_THREAD_STACK_DECLARE K_KERNEL_STACK_DECLARE
400#define K_THREAD_STACK_ARRAY_DECLARE K_KERNEL_STACK_ARRAY_DECLARE
401#else
417#ifdef ARCH_THREAD_STACK_RESERVED
418#define K_THREAD_STACK_RESERVED ((size_t)(ARCH_THREAD_STACK_RESERVED))
419#else
420#define K_THREAD_STACK_RESERVED ((size_t)0U)
421#endif /* ARCH_THREAD_STACK_RESERVED */
422
448#if defined(ARCH_THREAD_STACK_OBJ_ALIGN)
449#define Z_THREAD_STACK_OBJ_ALIGN(size) \
450 ARCH_THREAD_STACK_OBJ_ALIGN(Z_THREAD_STACK_SIZE_ADJUST(size))
451#else
452#define Z_THREAD_STACK_OBJ_ALIGN(size) ARCH_STACK_PTR_ALIGN
453#endif /* ARCH_THREAD_STACK_OBJ_ALIGN */
454
481#if defined(ARCH_THREAD_STACK_SIZE_ADJUST)
482#define Z_THREAD_STACK_SIZE_ADJUST(size) \
483 ARCH_THREAD_STACK_SIZE_ADJUST((size) + K_THREAD_STACK_RESERVED)
484#else
485#define Z_THREAD_STACK_SIZE_ADJUST(size) \
486 (ROUND_UP((size), ARCH_STACK_PTR_ALIGN) + K_THREAD_STACK_RESERVED)
487#endif /* ARCH_THREAD_STACK_SIZE_ADJUST */
488
493
503#define K_THREAD_STACK_DECLARE(sym, size) \
504 extern struct z_thread_stack_element \
505 sym[K_THREAD_STACK_LEN(size)]
506
517#define K_THREAD_STACK_ARRAY_DECLARE(sym, nmemb, size) \
518 extern struct z_thread_stack_element \
519 sym[nmemb][K_THREAD_STACK_LEN(size)]
520
535#define K_THREAD_STACK_SIZEOF(sym) (sizeof(sym) - K_THREAD_STACK_RESERVED)
536
565#define Z_THREAD_STACK_DEFINE_IN(sym, size, lsect) \
566 struct z_thread_stack_element lsect \
567 __aligned(Z_THREAD_STACK_OBJ_ALIGN(size)) \
568 sym[K_THREAD_STACK_LEN(size)]
569
584#define Z_THREAD_STACK_ARRAY_DEFINE_IN(sym, nmemb, size, lsect) \
585 struct z_thread_stack_element lsect \
586 __aligned(Z_THREAD_STACK_OBJ_ALIGN(size)) \
587 sym[nmemb][K_THREAD_STACK_LEN(size)]
588
615#define K_THREAD_STACK_DEFINE(sym, size) \
616 Z_THREAD_STACK_DEFINE_IN(sym, size, __stackmem)
617
631#define K_THREAD_STACK_LEN(size) \
632 ROUND_UP(Z_THREAD_STACK_SIZE_ADJUST(size), \
633 Z_THREAD_STACK_OBJ_ALIGN(size))
634
648#define K_THREAD_STACK_ARRAY_DEFINE(sym, nmemb, size) \
649 Z_THREAD_STACK_ARRAY_DEFINE_IN(sym, nmemb, size, __stackmem)
650
652
668{
669 return (char *)sym + K_THREAD_STACK_RESERVED;
670}
671
672#endif /* CONFIG_USERSPACE */
673
674#ifdef __cplusplus
675}
676#endif
677
678#endif /* _ASMLANGUAGE */
679#endif /* ZEPHYR_INCLUDE_KERNEL_THREAD_STACK_H */
#define ARCH_STACK_PTR_ALIGN
Definition arch.h:98
struct z_thread_stack_element k_thread_stack_t
Typedef of struct z_thread_stack_element.
Definition arch_interface.h:46
#define ROUND_DOWN(x, align)
Value of x rounded down to the previous multiple of align.
Definition util.h:325
#define K_THREAD_STACK_RESERVED
Indicate how much additional memory is reserved for stack objects.
Definition thread_stack.h:420
static char * K_THREAD_STACK_BUFFER(k_thread_stack_t *sym)
Get a pointer to the physical stack buffer.
Definition thread_stack.h:667
static char * K_KERNEL_STACK_BUFFER(k_thread_stack_t *sym)
Definition thread_stack.h:388
#define K_KERNEL_STACK_RESERVED
Definition thread_stack.h:96
__UINTPTR_TYPE__ uintptr_t
Definition stdint.h:105
Misc utilities.