1 /**************************************************************************/
2 /* */
3 /* Copyright (c) Microsoft Corporation. All rights reserved. */
4 /* */
5 /* This software is licensed under the Microsoft Software License */
6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */
7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
8 /* and in the root directory of this software. */
9 /* */
10 /**************************************************************************/
11
12
13 /**************************************************************************/
14 /**************************************************************************/
15 /** */
16 /** USBX Component */
17 /** */
18 /** System */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23
24 /* Define UX_SYSTEM_INIT to bring in the USBX version ID string. */
25
26 #define UX_SYSTEM_INIT
27
28
29 /* Include necessary system files. */
30
31 #define UX_SOURCE_CODE
32
33 #include "ux_api.h"
34 #include "ux_system.h"
35
36 /* Define the USBX system data structure. */
37
38 UX_SYSTEM *_ux_system;
39 UX_SYSTEM_OTG *_ux_system_otg;
40
41 /* Define names of all the packed descriptors in USBX. */
42
43 UCHAR _ux_system_endpoint_descriptor_structure[] = {1,1,1,1,2,1 };
44 UCHAR _ux_system_device_descriptor_structure[] = {1,1,2,1,1,1,1,2,2,2,1,1,1,1};
45 UCHAR _ux_system_configuration_descriptor_structure[] = {1,1,2,1,1,1,1,1};
46 UCHAR _ux_system_interface_descriptor_structure[] = {1,1,1,1,1,1,1,1,1};
47 UCHAR _ux_system_interface_association_descriptor_structure[] = {1,1,1,1,1,1,1,1};
48 UCHAR _ux_system_string_descriptor_structure[] = {1,1,2};
49 UCHAR _ux_system_dfu_functional_descriptor_structure[] = {1,1,1,2,2,2};
50 UCHAR _ux_system_class_audio_interface_descriptor_structure[] = {1,1,1,1,1,1,1,1};
51 UCHAR _ux_system_class_audio_input_terminal_descriptor_structure[] = {1,1,1,1,2,1,1,2,1,1};
52 UCHAR _ux_system_class_audio_output_terminal_descriptor_structure[] = {1,1,1,1,2,1,1,1};
53 UCHAR _ux_system_class_audio_feature_unit_descriptor_structure[] = {1,1,1,1,1,1,1};
54 UCHAR _ux_system_class_audio_streaming_interface_descriptor_structure[] = {1,1,1,1,1,1};
55 UCHAR _ux_system_class_audio_streaming_endpoint_descriptor_structure[] = {1,1,1,1,1,1};
56 UCHAR _ux_system_hub_descriptor_structure[] = {1,1,1,2,1,1,1,1};
57 UCHAR _ux_system_hid_descriptor_structure[] = {1,1,2,1,1,1,2};
58 UCHAR _ux_system_class_pima_storage_structure[] = {2,2,2,4,4,4,4,4};
59 UCHAR _ux_system_class_pima_object_structure[] = {4,2,2,4,2,4,4,4,4,4,4,4,2,4,4};
60 UCHAR _ux_system_ecm_interface_descriptor_structure[] = {1,1,1,1,4,2,2,1};
61
62 UCHAR _ux_system_bos_descriptor_structure[] = {1,1,2,1};
63 UCHAR _ux_system_usb_2_0_extension_descriptor_structure[] = {1,1,1,4};
64 UCHAR _ux_system_container_id_descriptor_structure[] = {1,1,1,1,4,4,4,4};
65
66
67 /**************************************************************************/
68 /* */
69 /* FUNCTION RELEASE */
70 /* */
71 /* _ux_system_initialize PORTABLE C */
72 /* 6.3.0 */
73 /* AUTHOR */
74 /* */
75 /* Chaoqiong Xiao, Microsoft Corporation */
76 /* */
77 /* DESCRIPTION */
78 /* */
79 /* This function initializes the various control data structures for */
80 /* the USBX system. */
81 /* */
82 /* INPUT */
83 /* */
84 /* regular_memory_pool_start Start of non cached memory pool */
85 /* regular_memory_size Size of non cached memory pool */
86 /* cache_safe_memory_pool_start Start of cached memory pool */
87 /* cache_safe_memory_size Size of cached memory pool */
88 /* */
89 /* OUTPUT */
90 /* */
91 /* None */
92 /* */
93 /* CALLS */
94 /* */
95 /* _ux_utility_memory_allocate Allocate memory */
96 /* _ux_utility_memory_set Set memory */
97 /* _ux_utility_mutex_create Create mutex */
98 /* */
99 /* CALLED BY */
100 /* */
101 /* Application */
102 /* */
103 /* RELEASE HISTORY */
104 /* */
105 /* DATE NAME DESCRIPTION */
106 /* */
107 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
108 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
109 /* verified memset and memcpy */
110 /* cases, */
111 /* resulting in version 6.1 */
112 /* 12-31-2020 Chaoqiong Xiao Modified comment(s), */
113 /* added BOS support, */
114 /* resulting in version 6.1.3 */
115 /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
116 /* added standalone support, */
117 /* resulting in version 6.1.10 */
118 /* 10-31-2023 Chaoqiong Xiao Modified comment(s), */
119 /* refined memory management, */
120 /* added UX_ASSERT check for */
121 /* STD descriptor parse size, */
122 /* resulting in version 6.3.0 */
123 /* */
124 /**************************************************************************/
_ux_system_initialize(VOID * regular_memory_pool_start,ULONG regular_memory_size,VOID * cache_safe_memory_pool_start,ULONG cache_safe_memory_size)125 UINT _ux_system_initialize(VOID *regular_memory_pool_start, ULONG regular_memory_size,
126 VOID *cache_safe_memory_pool_start, ULONG cache_safe_memory_size)
127 {
128 ALIGN_TYPE int_memory_pool_start;
129 VOID *regular_memory_pool_end;
130 VOID *cache_safe_memory_pool_end;
131 ULONG memory_pool_offset;
132 #if !defined(UX_STANDALONE)
133 UINT status;
134 #endif
135 ULONG pool_size;
136
137 /* Check if the regular memory pool is valid. */
138 if ((regular_memory_pool_start == UX_NULL) || (regular_memory_size == 0))
139 return(UX_INVALID_PARAMETER);
140
141 /* Reset memory block */
142 _ux_utility_memory_set(regular_memory_pool_start, 0, regular_memory_size); /* Use case of memset is verified. */
143
144 /* Set the _ux_system structure at the start of our regular memory */
145 _ux_system = (UX_SYSTEM *) regular_memory_pool_start;
146
147 /* Add to the memory offset the size of the allocated block. */
148 memory_pool_offset = sizeof(UX_SYSTEM);
149
150 #ifndef UX_DEVICE_SIDE_ONLY
151
152 /* Set the _ux_system_host structure. */
153 _ux_system_host = (UX_SYSTEM_HOST *) (((UCHAR *) regular_memory_pool_start) + memory_pool_offset);
154
155 /* Add to the memory offset the size of the allocated block. */
156 memory_pool_offset += (ULONG)sizeof(UX_SYSTEM_HOST);
157
158 #endif
159
160 #ifndef UX_HOST_SIDE_ONLY
161
162 /* Set the _ux_system_slave structure. */
163 _ux_system_slave = (UX_SYSTEM_SLAVE *) (((UCHAR *) regular_memory_pool_start) + memory_pool_offset);
164
165 /* Add to the memory offset the size of the allocated block. */
166 memory_pool_offset += (ULONG)sizeof(UX_SYSTEM_SLAVE);
167
168 #endif
169
170
171 #ifdef UX_OTG_SUPPORT
172
173 /* Set the _ux_system_otg structure. */
174 _ux_system_otg = (UX_SYSTEM_OTG *) (((UCHAR *) regular_memory_pool_start) + memory_pool_offset);
175
176 /* Add to the memory offset the size of the allocated block. */
177 memory_pool_offset += (ULONG)sizeof(UX_SYSTEM_OTG);
178 #endif
179
180 /* Set the regular memory pool structure. */
181 _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] = (UX_MEMORY_BYTE_POOL *) (((UCHAR *) regular_memory_pool_start) + memory_pool_offset);
182
183 /* Add to the memory offset the size of the allocated block. */
184 memory_pool_offset += (ULONG)sizeof(UX_MEMORY_BYTE_POOL);
185
186 /* Check if the cache save memory pool is valid. */
187 if ((cache_safe_memory_pool_start != UX_NULL) && (cache_safe_memory_size != 0))
188 {
189
190 /* Set the cache safe memory pool structure. */
191 _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_CACHE_SAFE] = (UX_MEMORY_BYTE_POOL *) (((UCHAR *) regular_memory_pool_start) + memory_pool_offset);
192
193 /* Add to the memory offset the size of the allocated block. */
194 memory_pool_offset += (ULONG)sizeof(UX_MEMORY_BYTE_POOL);
195 }
196 else
197 {
198
199 /* Set the cache safe memory pool structure to regular pool. */
200 _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_CACHE_SAFE] = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR];
201 }
202
203 /* Make sure the regular memory pool is aligned properly */
204 int_memory_pool_start = (ALIGN_TYPE) (((UCHAR *) regular_memory_pool_start) + memory_pool_offset);
205 int_memory_pool_start += UX_ALIGN_MIN;
206 int_memory_pool_start &= ~((ALIGN_TYPE)UX_ALIGN_MIN);
207
208 /* Set the end of the regular memory pool. */
209 regular_memory_pool_end = (void *) (((UCHAR *) regular_memory_pool_start) + regular_memory_size);
210
211 /* Check if we have memory available. */
212 if (int_memory_pool_start >= (ALIGN_TYPE)regular_memory_pool_end)
213 {
214
215 /* No memory available. */
216 return(UX_MEMORY_INSUFFICIENT);
217 }
218
219 /* get the regular memory pool size. */
220 pool_size = (ULONG) (((ALIGN_TYPE) regular_memory_pool_end) - int_memory_pool_start);
221
222 /* Create the regular memory pool. */
223 _ux_utility_memory_byte_pool_create(_ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR],
224 (UX_MEMORY_BYTE_POOL *)int_memory_pool_start,
225 pool_size);
226
227 /* Check the definition of the cache safe pool. If the application or controller do not require any cache safe memory,
228 define the cached safe memory region as the regular memory region. */
229 if ((cache_safe_memory_pool_start != UX_NULL) && (cache_safe_memory_size != 0))
230 {
231
232 /* Reset this memory block */
233 _ux_utility_memory_set(cache_safe_memory_pool_start, 0, cache_safe_memory_size); /* Use case of memset is verified. */
234
235 /* Make sure the cache safe memory pool is aligned properly */
236 int_memory_pool_start = (ALIGN_TYPE) cache_safe_memory_pool_start;
237 int_memory_pool_start += UX_ALIGN_MIN;
238 int_memory_pool_start &= ~((ALIGN_TYPE)UX_ALIGN_MIN);
239
240 cache_safe_memory_pool_end = (void *) (((UCHAR *) cache_safe_memory_pool_start) + cache_safe_memory_size);
241
242 /* Check if we have memory available. */
243 if (int_memory_pool_start >= (ALIGN_TYPE) cache_safe_memory_pool_end)
244 {
245
246 /* No memory available. */
247 return(UX_MEMORY_INSUFFICIENT);
248 }
249
250 pool_size = (ULONG) (((ALIGN_TYPE) cache_safe_memory_pool_end) - int_memory_pool_start);
251
252 _ux_utility_memory_byte_pool_create(_ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_CACHE_SAFE],
253 (UX_MEMORY_BYTE_POOL *)int_memory_pool_start, pool_size);
254 }
255
256 #ifdef UX_ENABLE_MEMORY_STATISTICS
257 _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_min_free =
258 _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
259 _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_CACHE_SAFE] -> ux_byte_pool_min_free =
260 _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_CACHE_SAFE] -> ux_byte_pool_available;
261
262 /* Other fields are kept zero. */
263 #endif
264
265 #ifdef UX_ENABLE_DEBUG_LOG
266
267 /* Obtain memory for storing the debug log. */
268 _ux_system -> ux_system_debug_log_buffer = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, UX_DEBUG_LOG_SIZE);
269 if (_ux_system -> ux_system_debug_log_buffer == UX_NULL)
270 return(UX_MEMORY_INSUFFICIENT);
271
272 /* Setup the head and tail pointers. */
273 _ux_system -> ux_system_debug_log_head = _ux_system -> ux_system_debug_log_buffer;
274 _ux_system -> ux_system_debug_log_tail = _ux_system -> ux_system_debug_log_buffer;
275
276 /* Keep the size in system structure variable. */
277 _ux_system -> ux_system_debug_log_size = UX_DEBUG_LOG_SIZE;
278
279 #endif
280
281 #if !defined(UX_STANDALONE)
282
283 /* Create the Mutex object used by USBX to control critical sections. */
284 status = _ux_system_mutex_create(&_ux_system -> ux_system_mutex, "ux_system_mutex");
285 if(status != UX_SUCCESS)
286 return(UX_MUTEX_ERROR);
287 #endif
288
289 return(UX_SUCCESS);
290 }
291
292
293 /**************************************************************************/
294 /* */
295 /* FUNCTION RELEASE */
296 /* */
297 /* _uxe_system_initialize PORTABLE C */
298 /* 6.3.0 */
299 /* AUTHOR */
300 /* */
301 /* Chaoqiong Xiao, Microsoft Corporation */
302 /* */
303 /* DESCRIPTION */
304 /* */
305 /* This function checks errors in system initialization function call. */
306 /* */
307 /* INPUT */
308 /* */
309 /* regular_memory_pool_start Start of non cached memory pool */
310 /* regular_memory_size Size of non cached memory pool */
311 /* cache_safe_memory_pool_start Start of cached memory pool */
312 /* cache_safe_memory_size Size of cached memory pool */
313 /* */
314 /* OUTPUT */
315 /* */
316 /* None */
317 /* */
318 /* CALLS */
319 /* */
320 /* _ux_system_initialize Get encoded feedback */
321 /* */
322 /* CALLED BY */
323 /* */
324 /* Application */
325 /* */
326 /* RELEASE HISTORY */
327 /* */
328 /* DATE NAME DESCRIPTION */
329 /* */
330 /* 10-31-2023 Chaoqiong Xiao Initial Version 6.3.0 */
331 /* */
332 /**************************************************************************/
_uxe_system_initialize(VOID * regular_memory_pool_start,ULONG regular_memory_size,VOID * cache_safe_memory_pool_start,ULONG cache_safe_memory_size)333 UINT _uxe_system_initialize(VOID *regular_memory_pool_start, ULONG regular_memory_size,
334 VOID *cache_safe_memory_pool_start, ULONG cache_safe_memory_size)
335 {
336
337 /* Compiling option check of descriptors structs. */
338 UX_ASSERT((_ux_utility_descriptor_parse_size(_ux_system_endpoint_descriptor_structure, UX_ENDPOINT_DESCRIPTOR_ENTRIES, 0x3u)) == sizeof(UX_ENDPOINT_DESCRIPTOR));
339 UX_ASSERT((_ux_utility_descriptor_parse_size(_ux_system_device_descriptor_structure, UX_DEVICE_DESCRIPTOR_ENTRIES, 0x3u)) == sizeof(UX_DEVICE_DESCRIPTOR));
340 UX_ASSERT((_ux_utility_descriptor_parse_size(_ux_system_configuration_descriptor_structure, UX_CONFIGURATION_DESCRIPTOR_ENTRIES, 0x3u)) == sizeof(UX_CONFIGURATION_DESCRIPTOR));
341 UX_ASSERT((_ux_utility_descriptor_parse_size(_ux_system_interface_descriptor_structure, UX_INTERFACE_DESCRIPTOR_ENTRIES, 0x3u)) == sizeof(UX_INTERFACE_DESCRIPTOR));
342 UX_ASSERT((_ux_utility_descriptor_parse_size(_ux_system_interface_association_descriptor_structure, UX_INTERFACE_ASSOCIATION_DESCRIPTOR_ENTRIES, 0x3u)) == sizeof(UX_INTERFACE_ASSOCIATION_DESCRIPTOR));
343 UX_ASSERT((_ux_utility_descriptor_parse_size(_ux_system_string_descriptor_structure, UX_STRING_DESCRIPTOR_ENTRIES, 0x3u)) == sizeof(UX_STRING_DESCRIPTOR));
344 UX_ASSERT((_ux_utility_descriptor_parse_size(_ux_system_dfu_functional_descriptor_structure, UX_DFU_FUNCTIONAL_DESCRIPTOR_ENTRIES, 0x3u)) == sizeof(UX_DFU_FUNCTIONAL_DESCRIPTOR));
345 UX_ASSERT((_ux_utility_descriptor_parse_size(_ux_system_bos_descriptor_structure, UX_BOS_DESCRIPTOR_ENTRIES, 0x3u)) == sizeof(UX_BOS_DESCRIPTOR));
346 UX_ASSERT((_ux_utility_descriptor_parse_size(_ux_system_usb_2_0_extension_descriptor_structure, UX_USB_2_0_EXTENSION_DESCRIPTOR_ENTRIES, 0x3u)) == sizeof(UX_USB_2_0_EXTENSION_DESCRIPTOR));
347 UX_ASSERT((_ux_utility_descriptor_parse_size(_ux_system_container_id_descriptor_structure, UX_CONTAINER_ID_DESCRIPTOR_ENTRIES, 0x3u)) == sizeof(UX_CONTAINER_ID_DESCRIPTOR));
348
349
350 /* Sanity check. */
351 if ((regular_memory_pool_start == UX_NULL) || (regular_memory_size == 0))
352 return(UX_INVALID_PARAMETER);
353
354 /* Invoke system initialization function. */
355 return(_ux_system_initialize(regular_memory_pool_start, regular_memory_size,
356 cache_safe_memory_pool_start, cache_safe_memory_size));
357 }
358