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.1.10 */
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 /* */
85 /**************************************************************************/
_ux_hcd_sim_host_initialize(UX_HCD * hcd)86 UINT _ux_hcd_sim_host_initialize(UX_HCD *hcd)
87 {
88
89 UX_SLAVE_DCD *dcd;
90 UX_DCD_SIM_SLAVE *dcd_sim_slave;
91 UX_HCD_SIM_HOST *hcd_sim_host;
92 UINT status;
93
94
95 /* The controller initialized here is of host simulator type. */
96 hcd -> ux_hcd_controller_type = UX_HCD_SIM_HOST_CONTROLLER;
97
98 /* Allocate memory for this host simulator HCD instance. */
99 hcd_sim_host = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_HCD_SIM_HOST));
100 if (hcd_sim_host == UX_NULL)
101 return(UX_MEMORY_INSUFFICIENT);
102
103 /* Set the pointer to the host simulator HCD. */
104 hcd -> ux_hcd_controller_hardware = (VOID *) hcd_sim_host;
105
106 /* Set the generic HCD owner for the host simulator HCD. */
107 hcd_sim_host -> ux_hcd_sim_host_hcd_owner = hcd;
108
109 /* Initialize the function collector for this HCD. */
110 hcd -> ux_hcd_entry_function = _ux_hcd_sim_host_entry;
111
112 #if UX_MAX_DEVICES > 1
113 /* Initialize the max bandwidth for periodic endpoints. In simulation this is
114 not very important. */
115 hcd -> ux_hcd_available_bandwidth = UX_HCD_SIM_HOST_AVAILABLE_BANDWIDTH;
116 #endif
117
118 /* Set the state of the controller to HALTED first. */
119 hcd -> ux_hcd_status = UX_HCD_STATUS_HALTED;
120
121 /* Allocate the list of EDs. All EDs are allocated on 16 byte memory boundary. */
122 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);
123 if (hcd_sim_host -> ux_hcd_sim_host_ed_list == UX_NULL)
124 status = UX_MEMORY_INSUFFICIENT;
125 else
126 status = UX_SUCCESS;
127
128 /* Allocate the list of TDs. All TDs are allocated on 32 byte memory boundary. */
129 if (status == UX_SUCCESS)
130 {
131 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);
132 if (hcd_sim_host -> ux_hcd_sim_host_td_list == UX_NULL)
133 status = UX_MEMORY_INSUFFICIENT;
134 }
135
136 /* Allocate the list of isochronous TDs. All TDs are allocated on 32 byte memory boundary. */
137 if (status == UX_SUCCESS)
138 {
139 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);
140 if (hcd_sim_host -> ux_hcd_sim_host_iso_td_list == UX_NULL)
141 status = UX_MEMORY_INSUFFICIENT;
142 }
143
144 /* Initialize the periodic tree. */
145 if (status == UX_SUCCESS)
146 status = _ux_hcd_sim_host_periodic_tree_create(hcd_sim_host);
147
148 /* Initialize the scheduler. */
149 if (status == UX_SUCCESS)
150 {
151 /* Set the host controller into the operational state. */
152 hcd -> ux_hcd_status = UX_HCD_STATUS_OPERATIONAL;
153
154 /* The asynchronous queues are empty for now. */
155 hcd_sim_host -> ux_hcd_sim_host_queue_empty = UX_TRUE;
156
157 /* The periodic scheduler is not active. */
158 hcd_sim_host -> ux_hcd_sim_host_periodic_scheduler_active = 0;
159
160 /* We start a timer that will invoke the simulator every timer tick. */
161 status = _ux_host_timer_create(&hcd_sim_host -> ux_hcd_sim_host_timer, "USBX Simulation Timer",
162 _ux_hcd_sim_host_timer_function, (ULONG) (ALIGN_TYPE) hcd_sim_host, 1, 1, UX_AUTO_ACTIVATE);
163 }
164
165 UX_TIMER_EXTENSION_PTR_SET(&(hcd_sim_host -> ux_hcd_sim_host_timer), hcd_sim_host)
166
167 /* Free up resources and return when there is error. */
168 if (status != UX_SUCCESS)
169 {
170
171 /* Set the host controller into the halt state. */
172 hcd -> ux_hcd_status = UX_HCD_STATUS_HALTED;
173
174 /* The last resource, timer is not created or created error,
175 * no need to delete. */
176
177 if (hcd_sim_host -> ux_hcd_sim_host_iso_td_list)
178 _ux_utility_memory_free(hcd_sim_host -> ux_hcd_sim_host_iso_td_list);
179 if (hcd_sim_host -> ux_hcd_sim_host_td_list)
180 _ux_utility_memory_free(hcd_sim_host -> ux_hcd_sim_host_td_list);
181 if (hcd_sim_host -> ux_hcd_sim_host_ed_list)
182 _ux_utility_memory_free(hcd_sim_host -> ux_hcd_sim_host_ed_list);
183 _ux_utility_memory_free(hcd_sim_host);
184
185 return(status);
186 }
187
188 /* Link the HCD to DCD driver. */
189 if (_ux_system_slave)
190 {
191 dcd = &_ux_system_slave -> ux_system_slave_dcd;
192 if (dcd)
193 {
194 dcd_sim_slave = (UX_DCD_SIM_SLAVE *) dcd -> ux_slave_dcd_controller_hardware;
195 if (dcd_sim_slave)
196 dcd_sim_slave -> ux_dcd_sim_slave_hcd = (VOID *)hcd;
197 }
198 }
199
200 /* Get the number of ports on the controller. The number of ports needs to be reflected both
201 for the generic HCD container and the local sim_host container. In the simulator,
202 the number of ports is hardwired to 1 only. */
203 hcd -> ux_hcd_nb_root_hubs = 1;
204 hcd_sim_host -> ux_hcd_sim_host_nb_root_hubs = 1;
205 hcd_sim_host -> ux_hcd_sim_host_port_status[0] = UX_PS_CCS | UX_PS_DS_FS;
206
207 /* Something happened on this port. Signal it to the root hub thread. */
208 hcd -> ux_hcd_root_hub_signal[0] = 1;
209
210 /* We need to simulate a Root HUB Status Change for the USB stack since the simulator
211 has not root HUB per se. */
212 status = _ux_host_semaphore_put_rc(&_ux_system_host -> ux_system_host_enum_semaphore);
213 if (status != UX_SUCCESS)
214
215 /* Resources are still ready but
216 * failed to simulate Root HUB change! */
217 return(UX_SEMAPHORE_ERROR);
218
219 /* Return successful completion. */
220 return(UX_SUCCESS);
221 }
222
223