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.1.10       */
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 /*                                                                        */
119 /**************************************************************************/
_ux_system_initialize(VOID * regular_memory_pool_start,ULONG regular_memory_size,VOID * cache_safe_memory_pool_start,ULONG cache_safe_memory_size)120 UINT  _ux_system_initialize(VOID *regular_memory_pool_start, ULONG regular_memory_size,
121                             VOID *cache_safe_memory_pool_start, ULONG cache_safe_memory_size)
122 {
123 
124 UX_MEMORY_BLOCK     *memory_block;
125 ALIGN_TYPE          int_memory_pool_start;
126 VOID                *regular_memory_pool_end;
127 ULONG               memory_pool_offset;
128 #if !defined(UX_STANDALONE)
129 UINT                status;
130 #endif
131 
132 
133     /* Reset memory block */
134     _ux_utility_memory_set(regular_memory_pool_start, 0, regular_memory_size); /* Use case of memset is verified. */
135 
136     /* Set the _ux_system structure at the start of our regular memory */
137     _ux_system =  (UX_SYSTEM *) regular_memory_pool_start;
138 
139     /* Add to the memory offset the size of the allocated block.  */
140     memory_pool_offset = sizeof(UX_SYSTEM);
141 
142 #ifndef UX_DEVICE_SIDE_ONLY
143 
144     /* Set the _ux_system_host structure.  */
145     _ux_system_host =  (UX_SYSTEM_HOST *) (((UCHAR *) regular_memory_pool_start) + memory_pool_offset);
146 
147     /* Add to the memory offset the size of the allocated block.  */
148     memory_pool_offset += (ULONG)sizeof(UX_SYSTEM_HOST);
149 
150 #endif
151 
152 #ifndef UX_HOST_SIDE_ONLY
153 
154     /* Set the _ux_system_slave structure.  */
155     _ux_system_slave =  (UX_SYSTEM_SLAVE *) (((UCHAR *) regular_memory_pool_start) + memory_pool_offset);
156 
157     /* Add to the memory offset the size of the allocated block.  */
158     memory_pool_offset += (ULONG)sizeof(UX_SYSTEM_SLAVE);
159 
160 #endif
161 
162 
163 #ifdef UX_OTG_SUPPORT
164 
165     /* Set the _ux_system_otg structure.  */
166     _ux_system_otg =  (UX_SYSTEM_OTG *) (((UCHAR *) regular_memory_pool_start) + memory_pool_offset);
167 
168     /* Add to the memory offset the size of the allocated block.  */
169     memory_pool_offset += (ULONG)sizeof(UX_SYSTEM_OTG);
170 #endif
171 
172 
173     /* Set the cache safe memory for the dynamic pool */
174     _ux_system -> ux_system_regular_memory_pool_start =  (UX_MEMORY_BLOCK *) (((UCHAR *) regular_memory_pool_start)
175                                                             + memory_pool_offset);
176 
177     /* Make sure the regular memory pool is aligned properly */
178     int_memory_pool_start =   (ALIGN_TYPE) _ux_system -> ux_system_regular_memory_pool_start;
179     int_memory_pool_start +=  UX_ALIGN_MIN;
180     int_memory_pool_start &=  ~((ALIGN_TYPE)UX_ALIGN_MIN);
181 
182     /* Set the end of the regular memory pool.  */
183     regular_memory_pool_end =  (void *) (((UCHAR *) regular_memory_pool_start) + regular_memory_size);
184 
185     /* Check if we have memory available.  */
186     if (int_memory_pool_start >= (ALIGN_TYPE)regular_memory_pool_end)
187     {
188 
189         /* No memory available.  */
190         return(UX_MEMORY_INSUFFICIENT);
191     }
192 
193     /* Now, we have a project structure allocated, save the regular memory allocation details */
194     _ux_system -> ux_system_regular_memory_pool_size =     (ULONG) (((ALIGN_TYPE) regular_memory_pool_end) - int_memory_pool_start);
195     _ux_system -> ux_system_regular_memory_pool_free =     _ux_system -> ux_system_regular_memory_pool_size;
196     _ux_system -> ux_system_regular_memory_pool_start =    (UX_MEMORY_BLOCK *) int_memory_pool_start;
197 
198     /* Build the first free memory block */
199     memory_block =                             _ux_system -> ux_system_regular_memory_pool_start;
200     memory_block -> ux_memory_block_size =     _ux_system -> ux_system_regular_memory_pool_size - (ULONG)sizeof(UX_MEMORY_BLOCK);
201     memory_block -> ux_memory_block_status =   UX_MEMORY_UNUSED;
202 
203     /* Check the definition of the cache safe pool. If the application or controller do not require any cache safe memory,
204        define the cached safe memory region as the regular memory region.  */
205     if (cache_safe_memory_pool_start == UX_NULL)
206     {
207 
208         /* Cache safe memory is the same as regular memory.  */
209         _ux_system -> ux_system_cache_safe_memory_pool_size =  _ux_system -> ux_system_regular_memory_pool_size;
210         _ux_system -> ux_system_cache_safe_memory_pool_free =  _ux_system -> ux_system_regular_memory_pool_free;
211         _ux_system -> ux_system_cache_safe_memory_pool_start = _ux_system -> ux_system_regular_memory_pool_start;
212     }
213     else
214     {
215 
216         /* Make sure the cache safe memory pool is aligned properly */
217         int_memory_pool_start =   (ALIGN_TYPE) cache_safe_memory_pool_start;
218         int_memory_pool_start +=  UX_ALIGN_MIN;
219         int_memory_pool_start &=  ~((ALIGN_TYPE)UX_ALIGN_MIN);
220 
221         /* Save the cache safe memory allocation details */
222         _ux_system -> ux_system_cache_safe_memory_pool_size =     cache_safe_memory_size - UX_ALIGN_MIN;
223         _ux_system -> ux_system_cache_safe_memory_pool_free =     _ux_system -> ux_system_cache_safe_memory_pool_size;
224         _ux_system -> ux_system_cache_safe_memory_pool_start =    (UX_MEMORY_BLOCK *) int_memory_pool_start;
225 
226         /* Reset this memory block */
227         _ux_utility_memory_set(_ux_system -> ux_system_cache_safe_memory_pool_start, 0, _ux_system -> ux_system_cache_safe_memory_pool_size); /* Use case of memset is verified. */
228 
229         /* Build the first free memory block */
230         memory_block =                             _ux_system -> ux_system_cache_safe_memory_pool_start;
231         memory_block -> ux_memory_block_size =     _ux_system -> ux_system_cache_safe_memory_pool_size - (ULONG)sizeof(UX_MEMORY_BLOCK);
232         memory_block -> ux_memory_block_status =   UX_MEMORY_UNUSED;
233     }
234 
235 #ifdef UX_ENABLE_MEMORY_STATISTICS
236     _ux_system -> ux_system_regular_memory_pool_base = (UCHAR *) _ux_system -> ux_system_regular_memory_pool_start;
237     _ux_system -> ux_system_regular_memory_pool_min_free = _ux_system -> ux_system_regular_memory_pool_free;
238     _ux_system -> ux_system_cache_safe_memory_pool_base = (UCHAR *) _ux_system -> ux_system_cache_safe_memory_pool_start;
239     _ux_system -> ux_system_cache_safe_memory_pool_min_free = _ux_system -> ux_system_cache_safe_memory_pool_free;
240 
241     /* Other fields are kept zero.  */
242 #endif
243 
244 #ifdef UX_ENABLE_DEBUG_LOG
245 
246     /* Obtain memory for storing the debug log.  */
247     _ux_system -> ux_system_debug_log_buffer =  _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, UX_DEBUG_LOG_SIZE);
248     if (_ux_system -> ux_system_debug_log_buffer == UX_NULL)
249         return(UX_MEMORY_INSUFFICIENT);
250 
251     /* Setup the head and tail pointers.  */
252     _ux_system -> ux_system_debug_log_head = _ux_system -> ux_system_debug_log_buffer;
253     _ux_system -> ux_system_debug_log_tail = _ux_system -> ux_system_debug_log_buffer;
254 
255     /* Keep the size in system structure variable.  */
256     _ux_system -> ux_system_debug_log_size = UX_DEBUG_LOG_SIZE;
257 
258 #endif
259 
260 #if !defined(UX_STANDALONE)
261 
262     /* Create the Mutex object used by USBX to control critical sections.  */
263     status =  _ux_system_mutex_create(&_ux_system -> ux_system_mutex, "ux_system_mutex");
264     if(status != UX_SUCCESS)
265         return(UX_MUTEX_ERROR);
266 #endif
267 
268     return(UX_SUCCESS);
269 }
270 
271