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 /** Host Simulator Controller Driver */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23 #define UX_SOURCE_CODE
24
25
26 /* Include necessary system files. */
27
28 #include "ux_api.h"
29 #include "ux_hcd_sim_host.h"
30 #include "ux_dcd_sim_slave.h"
31
32
33 /**************************************************************************/
34 /* */
35 /* FUNCTION RELEASE */
36 /* */
37 /* _ux_hcd_sim_host_initialize PORTABLE C */
38 /* 6.3.0 */
39 /* AUTHOR */
40 /* */
41 /* Chaoqiong Xiao, Microsoft Corporation */
42 /* */
43 /* DESCRIPTION */
44 /* */
45 /* This function initializes the simulated host controller */
46 /* */
47 /* INPUT */
48 /* */
49 /* HCD Pointer to HCD */
50 /* */
51 /* OUTPUT */
52 /* */
53 /* Completion Status */
54 /* */
55 /* CALLS */
56 /* */
57 /* _ux_hcd_sim_host_periodic_tree_create Create periodic tree */
58 /* _ux_utility_memory_allocate Allocate memory block */
59 /* _ux_utility_semaphore_put Semaphore put */
60 /* _ux_utility_timer_create Create timer */
61 /* */
62 /* CALLED BY */
63 /* */
64 /* Host Simulator Controller Driver */
65 /* */
66 /* RELEASE HISTORY */
67 /* */
68 /* DATE NAME DESCRIPTION */
69 /* */
70 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
71 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
72 /* optimized based on compile */
73 /* definitions, used UX prefix */
74 /* to refer to TX symbols */
75 /* instead of using them */
76 /* directly, */
77 /* resulting in version 6.1 */
78 /* 04-02-2021 Chaoqiong Xiao Modified comment(s), */
79 /* added link with DCD, */
80 /* resulting in version 6.1.6 */
81 /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
82 /* added standalone support, */
83 /* resulting in version 6.1.10 */
84 /* 10-31-2023 Yajun Xia Modified comment(s), */
85 /* refined memory management, */
86 /* resulting in version 6.3.0 */
87 /* */
88 /**************************************************************************/
_ux_hcd_sim_host_initialize(UX_HCD * hcd)89 UINT _ux_hcd_sim_host_initialize(UX_HCD *hcd)
90 {
91
92 UX_SLAVE_DCD *dcd;
93 UX_DCD_SIM_SLAVE *dcd_sim_slave;
94 UX_HCD_SIM_HOST *hcd_sim_host;
95 UINT status = UX_ERROR;
96
97
98 /* The controller initialized here is of host simulator type. */
99 hcd -> ux_hcd_controller_type = UX_HCD_SIM_HOST_CONTROLLER;
100
101 /* Allocate memory for this host simulator HCD instance. */
102 hcd_sim_host = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_HCD_SIM_HOST));
103 if (hcd_sim_host == UX_NULL)
104 return(UX_MEMORY_INSUFFICIENT);
105
106 /* Set the pointer to the host simulator HCD. */
107 hcd -> ux_hcd_controller_hardware = (VOID *) hcd_sim_host;
108
109 /* Set the generic HCD owner for the host simulator HCD. */
110 hcd_sim_host -> ux_hcd_sim_host_hcd_owner = hcd;
111
112 /* Initialize the function collector for this HCD. */
113 hcd -> ux_hcd_entry_function = _ux_hcd_sim_host_entry;
114
115 #if UX_MAX_DEVICES > 1
116 /* Initialize the max bandwidth for periodic endpoints. In simulation this is
117 not very important. */
118 hcd -> ux_hcd_available_bandwidth = UX_HCD_SIM_HOST_AVAILABLE_BANDWIDTH;
119 #endif
120
121 /* Set the state of the controller to HALTED first. */
122 hcd -> ux_hcd_status = UX_HCD_STATUS_HALTED;
123
124 /* Allocate the list of EDs. All EDs are allocated on 16 byte memory boundary. */
125 if (_ux_system_host -> ux_system_host_max_ed != 0)
126 {
127 hcd_sim_host -> ux_hcd_sim_host_ed_list = _ux_utility_memory_allocate(UX_ALIGN_16, UX_REGULAR_MEMORY, (ULONG)sizeof(UX_HCD_SIM_HOST_ED) * _ux_system_host -> ux_system_host_max_ed);
128 if (hcd_sim_host -> ux_hcd_sim_host_ed_list == UX_NULL)
129 status = UX_MEMORY_INSUFFICIENT;
130 else
131 status = UX_SUCCESS;
132 }
133
134 /* Allocate the list of TDs. All TDs are allocated on 32 byte memory boundary. */
135 if ((status == UX_SUCCESS) && (_ux_system_host -> ux_system_host_max_td != 0))
136 {
137 hcd_sim_host -> ux_hcd_sim_host_td_list = _ux_utility_memory_allocate(UX_ALIGN_32, UX_REGULAR_MEMORY, (ULONG)sizeof(UX_HCD_SIM_HOST_TD) * _ux_system_host -> ux_system_host_max_td);
138 if (hcd_sim_host -> ux_hcd_sim_host_td_list == UX_NULL)
139 status = UX_MEMORY_INSUFFICIENT;
140 }
141
142 /* Allocate the list of isochronous TDs. All TDs are allocated on 32 byte memory boundary. */
143 if ((status == UX_SUCCESS) && (_ux_system_host -> ux_system_host_max_iso_td != 0))
144 {
145 hcd_sim_host -> ux_hcd_sim_host_iso_td_list = _ux_utility_memory_allocate(UX_ALIGN_32, UX_REGULAR_MEMORY, (ULONG)sizeof(UX_HCD_SIM_HOST_ISO_TD) * _ux_system_host -> ux_system_host_max_iso_td);
146 if (hcd_sim_host -> ux_hcd_sim_host_iso_td_list == UX_NULL)
147 status = UX_MEMORY_INSUFFICIENT;
148 }
149
150 /* Initialize the periodic tree. */
151 if (status == UX_SUCCESS)
152 status = _ux_hcd_sim_host_periodic_tree_create(hcd_sim_host);
153
154 /* Initialize the scheduler. */
155 if (status == UX_SUCCESS)
156 {
157 /* Set the host controller into the operational state. */
158 hcd -> ux_hcd_status = UX_HCD_STATUS_OPERATIONAL;
159
160 /* The asynchronous queues are empty for now. */
161 hcd_sim_host -> ux_hcd_sim_host_queue_empty = UX_TRUE;
162
163 /* The periodic scheduler is not active. */
164 hcd_sim_host -> ux_hcd_sim_host_periodic_scheduler_active = 0;
165
166 /* We start a timer that will invoke the simulator every timer tick. */
167 status = _ux_host_timer_create(&hcd_sim_host -> ux_hcd_sim_host_timer, "USBX Simulation Timer",
168 _ux_hcd_sim_host_timer_function, (ULONG) (ALIGN_TYPE) hcd_sim_host, 1, 1, UX_AUTO_ACTIVATE);
169 }
170
171 UX_TIMER_EXTENSION_PTR_SET(&(hcd_sim_host -> ux_hcd_sim_host_timer), hcd_sim_host)
172
173 /* Free up resources and return when there is error. */
174 if (status != UX_SUCCESS)
175 {
176
177 /* Set the host controller into the halt state. */
178 hcd -> ux_hcd_status = UX_HCD_STATUS_HALTED;
179
180 /* The last resource, timer is not created or created error,
181 * no need to delete. */
182
183 if (hcd_sim_host -> ux_hcd_sim_host_iso_td_list)
184 _ux_utility_memory_free(hcd_sim_host -> ux_hcd_sim_host_iso_td_list);
185 if (hcd_sim_host -> ux_hcd_sim_host_td_list)
186 _ux_utility_memory_free(hcd_sim_host -> ux_hcd_sim_host_td_list);
187 if (hcd_sim_host -> ux_hcd_sim_host_ed_list)
188 _ux_utility_memory_free(hcd_sim_host -> ux_hcd_sim_host_ed_list);
189 _ux_utility_memory_free(hcd_sim_host);
190
191 return(status);
192 }
193
194 /* Link the HCD to DCD driver. */
195 if (_ux_system_slave)
196 {
197 dcd = &_ux_system_slave -> ux_system_slave_dcd;
198 if (dcd)
199 {
200 dcd_sim_slave = (UX_DCD_SIM_SLAVE *) dcd -> ux_slave_dcd_controller_hardware;
201 if (dcd_sim_slave)
202 dcd_sim_slave -> ux_dcd_sim_slave_hcd = (VOID *)hcd;
203 }
204 }
205
206 /* Get the number of ports on the controller. The number of ports needs to be reflected both
207 for the generic HCD container and the local sim_host container. In the simulator,
208 the number of ports is hardwired to 1 only. */
209 hcd -> ux_hcd_nb_root_hubs = 1;
210 hcd_sim_host -> ux_hcd_sim_host_nb_root_hubs = 1;
211 hcd_sim_host -> ux_hcd_sim_host_port_status[0] = UX_PS_CCS | UX_PS_DS_FS;
212
213 /* Something happened on this port. Signal it to the root hub thread. */
214 hcd -> ux_hcd_root_hub_signal[0] = 1;
215
216 /* We need to simulate a Root HUB Status Change for the USB stack since the simulator
217 has not root HUB per se. */
218 status = _ux_host_semaphore_put_rc(&_ux_system_host -> ux_system_host_enum_semaphore);
219 if (status != UX_SUCCESS)
220
221 /* Resources are still ready but
222 * failed to simulate Root HUB change! */
223 return(UX_SEMAPHORE_ERROR);
224
225 /* Return successful completion. */
226 return(UX_SUCCESS);
227 }
228
229