]>
Commit | Line | Data |
---|---|---|
0bbb2f3d GH |
1 | /* |
2 | * USB xHCI controller emulation | |
3 | * | |
4 | * Copyright (c) 2011 Securiforest | |
5 | * Date: 2011-05-11 ; Author: Hector Martin <[email protected]> | |
6 | * Based on usb-ohci.c, emulates Renesas NEC USB 3.0 | |
7 | * | |
8 | * This library is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU Lesser General Public | |
10 | * License as published by the Free Software Foundation; either | |
11 | * version 2 of the License, or (at your option) any later version. | |
12 | * | |
13 | * This library is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 | * Lesser General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU Lesser General Public | |
19 | * License along with this library; if not, see <http://www.gnu.org/licenses/>. | |
20 | */ | |
21 | ||
22 | #define TYPE_XHCI "base-xhci" | |
23 | #define TYPE_NEC_XHCI "nec-usb-xhci" | |
24 | #define TYPE_QEMU_XHCI "qemu-xhci" | |
25 | ||
26 | #define XHCI(obj) \ | |
27 | OBJECT_CHECK(XHCIState, (obj), TYPE_XHCI) | |
28 | ||
29 | #define MAXPORTS_2 15 | |
30 | #define MAXPORTS_3 15 | |
31 | ||
32 | #define MAXPORTS (MAXPORTS_2 + MAXPORTS_3) | |
33 | #define MAXSLOTS 64 | |
34 | #define MAXINTRS 16 | |
35 | ||
36 | /* Very pessimistic, let's hope it's enough for all cases */ | |
37 | #define EV_QUEUE (((3 * 24) + 16) * MAXSLOTS) | |
38 | ||
39 | typedef struct XHCIState XHCIState; | |
40 | typedef struct XHCIStreamContext XHCIStreamContext; | |
41 | typedef struct XHCIEPContext XHCIEPContext; | |
42 | ||
43 | enum xhci_flags { | |
44 | XHCI_FLAG_SS_FIRST = 1, | |
45 | XHCI_FLAG_FORCE_PCIE_ENDCAP, | |
46 | XHCI_FLAG_ENABLE_STREAMS, | |
47 | }; | |
48 | ||
49 | typedef enum TRBType { | |
50 | TRB_RESERVED = 0, | |
51 | TR_NORMAL, | |
52 | TR_SETUP, | |
53 | TR_DATA, | |
54 | TR_STATUS, | |
55 | TR_ISOCH, | |
56 | TR_LINK, | |
57 | TR_EVDATA, | |
58 | TR_NOOP, | |
59 | CR_ENABLE_SLOT, | |
60 | CR_DISABLE_SLOT, | |
61 | CR_ADDRESS_DEVICE, | |
62 | CR_CONFIGURE_ENDPOINT, | |
63 | CR_EVALUATE_CONTEXT, | |
64 | CR_RESET_ENDPOINT, | |
65 | CR_STOP_ENDPOINT, | |
66 | CR_SET_TR_DEQUEUE, | |
67 | CR_RESET_DEVICE, | |
68 | CR_FORCE_EVENT, | |
69 | CR_NEGOTIATE_BW, | |
70 | CR_SET_LATENCY_TOLERANCE, | |
71 | CR_GET_PORT_BANDWIDTH, | |
72 | CR_FORCE_HEADER, | |
73 | CR_NOOP, | |
74 | ER_TRANSFER = 32, | |
75 | ER_COMMAND_COMPLETE, | |
76 | ER_PORT_STATUS_CHANGE, | |
77 | ER_BANDWIDTH_REQUEST, | |
78 | ER_DOORBELL, | |
79 | ER_HOST_CONTROLLER, | |
80 | ER_DEVICE_NOTIFICATION, | |
81 | ER_MFINDEX_WRAP, | |
82 | /* vendor specific bits */ | |
83 | CR_VENDOR_NEC_FIRMWARE_REVISION = 49, | |
84 | CR_VENDOR_NEC_CHALLENGE_RESPONSE = 50, | |
85 | } TRBType; | |
86 | ||
87 | typedef enum TRBCCode { | |
88 | CC_INVALID = 0, | |
89 | CC_SUCCESS, | |
90 | CC_DATA_BUFFER_ERROR, | |
91 | CC_BABBLE_DETECTED, | |
92 | CC_USB_TRANSACTION_ERROR, | |
93 | CC_TRB_ERROR, | |
94 | CC_STALL_ERROR, | |
95 | CC_RESOURCE_ERROR, | |
96 | CC_BANDWIDTH_ERROR, | |
97 | CC_NO_SLOTS_ERROR, | |
98 | CC_INVALID_STREAM_TYPE_ERROR, | |
99 | CC_SLOT_NOT_ENABLED_ERROR, | |
100 | CC_EP_NOT_ENABLED_ERROR, | |
101 | CC_SHORT_PACKET, | |
102 | CC_RING_UNDERRUN, | |
103 | CC_RING_OVERRUN, | |
104 | CC_VF_ER_FULL, | |
105 | CC_PARAMETER_ERROR, | |
106 | CC_BANDWIDTH_OVERRUN, | |
107 | CC_CONTEXT_STATE_ERROR, | |
108 | CC_NO_PING_RESPONSE_ERROR, | |
109 | CC_EVENT_RING_FULL_ERROR, | |
110 | CC_INCOMPATIBLE_DEVICE_ERROR, | |
111 | CC_MISSED_SERVICE_ERROR, | |
112 | CC_COMMAND_RING_STOPPED, | |
113 | CC_COMMAND_ABORTED, | |
114 | CC_STOPPED, | |
115 | CC_STOPPED_LENGTH_INVALID, | |
116 | CC_MAX_EXIT_LATENCY_TOO_LARGE_ERROR = 29, | |
117 | CC_ISOCH_BUFFER_OVERRUN = 31, | |
118 | CC_EVENT_LOST_ERROR, | |
119 | CC_UNDEFINED_ERROR, | |
120 | CC_INVALID_STREAM_ID_ERROR, | |
121 | CC_SECONDARY_BANDWIDTH_ERROR, | |
122 | CC_SPLIT_TRANSACTION_ERROR | |
123 | } TRBCCode; | |
124 | ||
125 | typedef struct XHCIRing { | |
126 | dma_addr_t dequeue; | |
127 | bool ccs; | |
128 | } XHCIRing; | |
129 | ||
130 | typedef struct XHCIPort { | |
131 | XHCIState *xhci; | |
132 | uint32_t portsc; | |
133 | uint32_t portnr; | |
134 | USBPort *uport; | |
135 | uint32_t speedmask; | |
136 | char name[16]; | |
137 | MemoryRegion mem; | |
138 | } XHCIPort; | |
139 | ||
140 | typedef struct XHCISlot { | |
141 | bool enabled; | |
142 | bool addressed; | |
143 | dma_addr_t ctx; | |
144 | USBPort *uport; | |
145 | XHCIEPContext *eps[31]; | |
146 | } XHCISlot; | |
147 | ||
148 | typedef struct XHCIEvent { | |
149 | TRBType type; | |
150 | TRBCCode ccode; | |
151 | uint64_t ptr; | |
152 | uint32_t length; | |
153 | uint32_t flags; | |
154 | uint8_t slotid; | |
155 | uint8_t epid; | |
156 | } XHCIEvent; | |
157 | ||
158 | typedef struct XHCIInterrupter { | |
159 | uint32_t iman; | |
160 | uint32_t imod; | |
161 | uint32_t erstsz; | |
162 | uint32_t erstba_low; | |
163 | uint32_t erstba_high; | |
164 | uint32_t erdp_low; | |
165 | uint32_t erdp_high; | |
166 | ||
167 | bool msix_used, er_pcs; | |
168 | ||
169 | dma_addr_t er_start; | |
170 | uint32_t er_size; | |
171 | unsigned int er_ep_idx; | |
172 | ||
173 | /* kept for live migration compat only */ | |
174 | bool er_full_unused; | |
175 | XHCIEvent ev_buffer[EV_QUEUE]; | |
176 | unsigned int ev_buffer_put; | |
177 | unsigned int ev_buffer_get; | |
178 | ||
179 | } XHCIInterrupter; | |
180 | ||
181 | struct XHCIState { | |
182 | /*< private >*/ | |
183 | PCIDevice parent_obj; | |
184 | /*< public >*/ | |
185 | ||
186 | USBBus bus; | |
187 | MemoryRegion mem; | |
188 | MemoryRegion mem_cap; | |
189 | MemoryRegion mem_oper; | |
190 | MemoryRegion mem_runtime; | |
191 | MemoryRegion mem_doorbell; | |
192 | ||
193 | /* properties */ | |
194 | uint32_t numports_2; | |
195 | uint32_t numports_3; | |
196 | uint32_t numintrs; | |
197 | uint32_t numslots; | |
198 | uint32_t flags; | |
199 | uint32_t max_pstreams_mask; | |
200 | OnOffAuto msi; | |
201 | OnOffAuto msix; | |
202 | ||
203 | /* Operational Registers */ | |
204 | uint32_t usbcmd; | |
205 | uint32_t usbsts; | |
206 | uint32_t dnctrl; | |
207 | uint32_t crcr_low; | |
208 | uint32_t crcr_high; | |
209 | uint32_t dcbaap_low; | |
210 | uint32_t dcbaap_high; | |
211 | uint32_t config; | |
212 | ||
213 | USBPort uports[MAX(MAXPORTS_2, MAXPORTS_3)]; | |
214 | XHCIPort ports[MAXPORTS]; | |
215 | XHCISlot slots[MAXSLOTS]; | |
216 | uint32_t numports; | |
217 | ||
218 | /* Runtime Registers */ | |
219 | int64_t mfindex_start; | |
220 | QEMUTimer *mfwrap_timer; | |
221 | XHCIInterrupter intr[MAXINTRS]; | |
222 | ||
223 | XHCIRing cmd_ring; | |
224 | ||
225 | bool nec_quirks; | |
226 | }; |