1 /*
2  * Copyright (c) 2020 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #ifndef ZEPHYR_INCLUDE_SYS_INTERNAL_KOBJECT_INTERNAL_H
7 #define ZEPHYR_INCLUDE_SYS_INTERNAL_KOBJECT_INTERNAL_H
8 
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12 
13 /**
14  * @defgroup usermode_internal_apis User Mode Internal APIs
15  * @ingroup internal_api
16  * @{
17  */
18 
19 #if defined(CONFIG_USERSPACE) || defined(__DOXYGEN__)
20 #if defined(CONFIG_GEN_PRIV_STACKS) || defined(__DOXYGEN__)
21 /* Metadata struct for K_OBJ_THREAD_STACK_ELEMENT */
22 struct z_stack_data {
23 	/* Size of the entire stack object, including reserved areas */
24 	size_t size;
25 
26 	/* Stack buffer for privilege mode elevations */
27 	uint8_t *priv;
28 };
29 #endif /* CONFIG_GEN_PRIV_STACKS */
30 
31 /* Object extra data. Only some objects use this, determined by object type */
32 union k_object_data {
33 	/* Backing mutex for K_OBJ_SYS_MUTEX */
34 	struct k_mutex *mutex;
35 
36 	/* Numerical thread ID for K_OBJ_THREAD */
37 	unsigned int thread_id;
38 
39 #if defined(CONFIG_GEN_PRIV_STACKS) || defined(__DOXYGEN__)
40 	/* Metadata for K_OBJ_THREAD_STACK_ELEMENT */
41 	const struct z_stack_data *stack_data;
42 #else
43 	/* Stack buffer size for K_OBJ_THREAD_STACK_ELEMENT */
44 	size_t stack_size;
45 #endif /* CONFIG_GEN_PRIV_STACKS */
46 
47 	/* Futex wait queue and spinlock for K_OBJ_FUTEX */
48 	struct z_futex_data *futex_data;
49 
50 	/* All other objects */
51 	int unused;
52 };
53 
54 /**
55  * @brief Table generated by gperf, these objects are retrieved via
56  * k_object_find().
57  *
58  * @note This is an internal API. Do not use unless you are extending
59  *       functionality in the Zephyr tree.
60  */
61 struct k_object {
62 	void *name;
63 	uint8_t perms[CONFIG_MAX_THREAD_BYTES];
64 	uint8_t type;
65 	uint8_t flags;
66 	union k_object_data data;
67 } __packed __aligned(4);
68 
69 struct k_object_assignment {
70 	struct k_thread *thread;
71 	void * const *objects;
72 };
73 
74 
75 /**
76  * Lookup a kernel object and init its metadata if it exists
77  *
78  * Calling this on an object will make it usable from userspace.
79  * Intended to be called as the last statement in kernel object init
80  * functions.
81  *
82  * @param obj Address of the kernel object
83  *
84  * @note This is an internal API. Do not use unless you are extending
85  *       functionality in the Zephyr tree.
86  */
87 void k_object_init(const void *obj);
88 
89 
90 #else
91 /* LCOV_EXCL_START */
92 static inline void k_object_init(const void *obj)
93 {
94 	ARG_UNUSED(obj);
95 }
96 /* LCOV_EXCL_STOP */
97 #endif /* !CONFIG_USERSPACE */
98 
99 #ifdef CONFIG_DYNAMIC_OBJECTS
100 /**
101  * Allocate memory and install as a generic kernel object
102  *
103  * This is a low-level function to allocate some memory, and register that
104  * allocated memory in the kernel object lookup tables with type K_OBJ_ANY.
105  * Initialization state and thread permissions will be cleared. The
106  * returned k_object's data value will be uninitialized.
107  *
108  * Most users will want to use k_object_alloc() instead.
109  *
110  * Memory allocated will be drawn from the calling thread's reasource pool
111  * and may be freed later by passing the actual object pointer (found
112  * in the returned k_object's 'name' member) to k_object_free().
113  *
114  * @param align Required memory alignment for the allocated object
115  * @param size Size of the allocated object
116  * @return NULL on insufficient memory
117  * @return A pointer to the associated k_object that is installed in the
118  *	kernel object tables
119  *
120  * @note This is an internal API. Do not use unless you are extending
121  *       functionality in the Zephyr tree.
122  */
123 struct k_object *k_object_create_dynamic_aligned(size_t align, size_t size);
124 
125 /**
126  * Allocate memory and install as a generic kernel object
127  *
128  * This is a low-level function to allocate some memory, and register that
129  * allocated memory in the kernel object lookup tables with type K_OBJ_ANY.
130  * Initialization state and thread permissions will be cleared. The
131  * returned k_object's data value will be uninitialized.
132  *
133  * Most users will want to use k_object_alloc() instead.
134  *
135  * Memory allocated will be drawn from the calling thread's reasource pool
136  * and may be freed later by passing the actual object pointer (found
137  * in the returned k_object's 'name' member) to k_object_free().
138  *
139  * @param size Size of the allocated object
140  * @return NULL on insufficient memory
141  * @return A pointer to the associated k_object that is installed in the
142  *	kernel object tables
143  *
144  * @note This is an internal API. Do not use unless you are extending
145  *       functionality in the Zephyr tree.
146  */
k_object_create_dynamic(size_t size)147 static inline struct k_object *k_object_create_dynamic(size_t size)
148 {
149 	return k_object_create_dynamic_aligned(0, size);
150 }
151 
152 #else
153 
154 /* LCOV_EXCL_START */
k_object_create_dynamic_aligned(size_t align,size_t size)155 static inline struct k_object *k_object_create_dynamic_aligned(size_t align,
156 							       size_t size)
157 {
158 	ARG_UNUSED(align);
159 	ARG_UNUSED(size);
160 
161 	return NULL;
162 }
163 
k_object_create_dynamic(size_t size)164 static inline struct k_object *k_object_create_dynamic(size_t size)
165 {
166 	ARG_UNUSED(size);
167 
168 	return NULL;
169 }
170 
171 /* LCOV_EXCL_STOP */
172 #endif /* CONFIG_DYNAMIC_OBJECTS */
173 
174 /** @} */
175 
176 #ifdef __cplusplus
177 }
178 #endif
179 
180 #endif
181