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