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