root / hw / usb / hcd-ehci.h @ adbecc89
History | View | Annotate | Download (11.5 kB)
1 |
/*
|
---|---|
2 |
* QEMU USB EHCI Emulation
|
3 |
*
|
4 |
* This library is free software; you can redistribute it and/or
|
5 |
* modify it under the terms of the GNU Lesser General Public
|
6 |
* License as published by the Free Software Foundation; either
|
7 |
* version 2 of the License, or(at your option) any later version.
|
8 |
*
|
9 |
* This library is distributed in the hope that it will be useful,
|
10 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
12 |
* Lesser General Public License for more details.
|
13 |
*
|
14 |
* You should have received a copy of the GNU General Public License
|
15 |
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
16 |
*/
|
17 |
#ifndef HW_USB_EHCI_H
|
18 |
#define HW_USB_EHCI_H 1 |
19 |
|
20 |
#include "hw/hw.h" |
21 |
#include "qemu/timer.h" |
22 |
#include "hw/usb.h" |
23 |
#include "monitor/monitor.h" |
24 |
#include "trace.h" |
25 |
#include "sysemu/dma.h" |
26 |
#include "sysemu/sysemu.h" |
27 |
#include "hw/pci/pci.h" |
28 |
#include "hw/sysbus.h" |
29 |
|
30 |
#ifndef EHCI_DEBUG
|
31 |
#define EHCI_DEBUG 0 |
32 |
#endif
|
33 |
|
34 |
#if EHCI_DEBUG
|
35 |
#define DPRINTF printf
|
36 |
#else
|
37 |
#define DPRINTF(...)
|
38 |
#endif
|
39 |
|
40 |
#define MMIO_SIZE 0x1000 |
41 |
#define CAPA_SIZE 0x10 |
42 |
|
43 |
#define NB_PORTS 6 /* Max. Number of downstream ports */ |
44 |
|
45 |
typedef struct EHCIPacket EHCIPacket; |
46 |
typedef struct EHCIQueue EHCIQueue; |
47 |
typedef struct EHCIState EHCIState; |
48 |
|
49 |
/* EHCI spec version 1.0 Section 3.3
|
50 |
*/
|
51 |
typedef struct EHCIitd { |
52 |
uint32_t next; |
53 |
|
54 |
uint32_t transact[8];
|
55 |
#define ITD_XACT_ACTIVE (1 << 31) |
56 |
#define ITD_XACT_DBERROR (1 << 30) |
57 |
#define ITD_XACT_BABBLE (1 << 29) |
58 |
#define ITD_XACT_XACTERR (1 << 28) |
59 |
#define ITD_XACT_LENGTH_MASK 0x0fff0000 |
60 |
#define ITD_XACT_LENGTH_SH 16 |
61 |
#define ITD_XACT_IOC (1 << 15) |
62 |
#define ITD_XACT_PGSEL_MASK 0x00007000 |
63 |
#define ITD_XACT_PGSEL_SH 12 |
64 |
#define ITD_XACT_OFFSET_MASK 0x00000fff |
65 |
|
66 |
uint32_t bufptr[7];
|
67 |
#define ITD_BUFPTR_MASK 0xfffff000 |
68 |
#define ITD_BUFPTR_SH 12 |
69 |
#define ITD_BUFPTR_EP_MASK 0x00000f00 |
70 |
#define ITD_BUFPTR_EP_SH 8 |
71 |
#define ITD_BUFPTR_DEVADDR_MASK 0x0000007f |
72 |
#define ITD_BUFPTR_DEVADDR_SH 0 |
73 |
#define ITD_BUFPTR_DIRECTION (1 << 11) |
74 |
#define ITD_BUFPTR_MAXPKT_MASK 0x000007ff |
75 |
#define ITD_BUFPTR_MAXPKT_SH 0 |
76 |
#define ITD_BUFPTR_MULT_MASK 0x00000003 |
77 |
#define ITD_BUFPTR_MULT_SH 0 |
78 |
} EHCIitd; |
79 |
|
80 |
/* EHCI spec version 1.0 Section 3.4
|
81 |
*/
|
82 |
typedef struct EHCIsitd { |
83 |
uint32_t next; /* Standard next link pointer */
|
84 |
uint32_t epchar; |
85 |
#define SITD_EPCHAR_IO (1 << 31) |
86 |
#define SITD_EPCHAR_PORTNUM_MASK 0x7f000000 |
87 |
#define SITD_EPCHAR_PORTNUM_SH 24 |
88 |
#define SITD_EPCHAR_HUBADD_MASK 0x007f0000 |
89 |
#define SITD_EPCHAR_HUBADDR_SH 16 |
90 |
#define SITD_EPCHAR_EPNUM_MASK 0x00000f00 |
91 |
#define SITD_EPCHAR_EPNUM_SH 8 |
92 |
#define SITD_EPCHAR_DEVADDR_MASK 0x0000007f |
93 |
|
94 |
uint32_t uframe; |
95 |
#define SITD_UFRAME_CMASK_MASK 0x0000ff00 |
96 |
#define SITD_UFRAME_CMASK_SH 8 |
97 |
#define SITD_UFRAME_SMASK_MASK 0x000000ff |
98 |
|
99 |
uint32_t results; |
100 |
#define SITD_RESULTS_IOC (1 << 31) |
101 |
#define SITD_RESULTS_PGSEL (1 << 30) |
102 |
#define SITD_RESULTS_TBYTES_MASK 0x03ff0000 |
103 |
#define SITD_RESULTS_TYBYTES_SH 16 |
104 |
#define SITD_RESULTS_CPROGMASK_MASK 0x0000ff00 |
105 |
#define SITD_RESULTS_CPROGMASK_SH 8 |
106 |
#define SITD_RESULTS_ACTIVE (1 << 7) |
107 |
#define SITD_RESULTS_ERR (1 << 6) |
108 |
#define SITD_RESULTS_DBERR (1 << 5) |
109 |
#define SITD_RESULTS_BABBLE (1 << 4) |
110 |
#define SITD_RESULTS_XACTERR (1 << 3) |
111 |
#define SITD_RESULTS_MISSEDUF (1 << 2) |
112 |
#define SITD_RESULTS_SPLITXSTATE (1 << 1) |
113 |
|
114 |
uint32_t bufptr[2];
|
115 |
#define SITD_BUFPTR_MASK 0xfffff000 |
116 |
#define SITD_BUFPTR_CURROFF_MASK 0x00000fff |
117 |
#define SITD_BUFPTR_TPOS_MASK 0x00000018 |
118 |
#define SITD_BUFPTR_TPOS_SH 3 |
119 |
#define SITD_BUFPTR_TCNT_MASK 0x00000007 |
120 |
|
121 |
uint32_t backptr; /* Standard next link pointer */
|
122 |
} EHCIsitd; |
123 |
|
124 |
/* EHCI spec version 1.0 Section 3.5
|
125 |
*/
|
126 |
typedef struct EHCIqtd { |
127 |
uint32_t next; /* Standard next link pointer */
|
128 |
uint32_t altnext; /* Standard next link pointer */
|
129 |
uint32_t token; |
130 |
#define QTD_TOKEN_DTOGGLE (1 << 31) |
131 |
#define QTD_TOKEN_TBYTES_MASK 0x7fff0000 |
132 |
#define QTD_TOKEN_TBYTES_SH 16 |
133 |
#define QTD_TOKEN_IOC (1 << 15) |
134 |
#define QTD_TOKEN_CPAGE_MASK 0x00007000 |
135 |
#define QTD_TOKEN_CPAGE_SH 12 |
136 |
#define QTD_TOKEN_CERR_MASK 0x00000c00 |
137 |
#define QTD_TOKEN_CERR_SH 10 |
138 |
#define QTD_TOKEN_PID_MASK 0x00000300 |
139 |
#define QTD_TOKEN_PID_SH 8 |
140 |
#define QTD_TOKEN_ACTIVE (1 << 7) |
141 |
#define QTD_TOKEN_HALT (1 << 6) |
142 |
#define QTD_TOKEN_DBERR (1 << 5) |
143 |
#define QTD_TOKEN_BABBLE (1 << 4) |
144 |
#define QTD_TOKEN_XACTERR (1 << 3) |
145 |
#define QTD_TOKEN_MISSEDUF (1 << 2) |
146 |
#define QTD_TOKEN_SPLITXSTATE (1 << 1) |
147 |
#define QTD_TOKEN_PING (1 << 0) |
148 |
|
149 |
uint32_t bufptr[5]; /* Standard buffer pointer */ |
150 |
#define QTD_BUFPTR_MASK 0xfffff000 |
151 |
#define QTD_BUFPTR_SH 12 |
152 |
} EHCIqtd; |
153 |
|
154 |
/* EHCI spec version 1.0 Section 3.6
|
155 |
*/
|
156 |
typedef struct EHCIqh { |
157 |
uint32_t next; /* Standard next link pointer */
|
158 |
|
159 |
/* endpoint characteristics */
|
160 |
uint32_t epchar; |
161 |
#define QH_EPCHAR_RL_MASK 0xf0000000 |
162 |
#define QH_EPCHAR_RL_SH 28 |
163 |
#define QH_EPCHAR_C (1 << 27) |
164 |
#define QH_EPCHAR_MPLEN_MASK 0x07FF0000 |
165 |
#define QH_EPCHAR_MPLEN_SH 16 |
166 |
#define QH_EPCHAR_H (1 << 15) |
167 |
#define QH_EPCHAR_DTC (1 << 14) |
168 |
#define QH_EPCHAR_EPS_MASK 0x00003000 |
169 |
#define QH_EPCHAR_EPS_SH 12 |
170 |
#define EHCI_QH_EPS_FULL 0 |
171 |
#define EHCI_QH_EPS_LOW 1 |
172 |
#define EHCI_QH_EPS_HIGH 2 |
173 |
#define EHCI_QH_EPS_RESERVED 3 |
174 |
|
175 |
#define QH_EPCHAR_EP_MASK 0x00000f00 |
176 |
#define QH_EPCHAR_EP_SH 8 |
177 |
#define QH_EPCHAR_I (1 << 7) |
178 |
#define QH_EPCHAR_DEVADDR_MASK 0x0000007f |
179 |
#define QH_EPCHAR_DEVADDR_SH 0 |
180 |
|
181 |
/* endpoint capabilities */
|
182 |
uint32_t epcap; |
183 |
#define QH_EPCAP_MULT_MASK 0xc0000000 |
184 |
#define QH_EPCAP_MULT_SH 30 |
185 |
#define QH_EPCAP_PORTNUM_MASK 0x3f800000 |
186 |
#define QH_EPCAP_PORTNUM_SH 23 |
187 |
#define QH_EPCAP_HUBADDR_MASK 0x007f0000 |
188 |
#define QH_EPCAP_HUBADDR_SH 16 |
189 |
#define QH_EPCAP_CMASK_MASK 0x0000ff00 |
190 |
#define QH_EPCAP_CMASK_SH 8 |
191 |
#define QH_EPCAP_SMASK_MASK 0x000000ff |
192 |
#define QH_EPCAP_SMASK_SH 0 |
193 |
|
194 |
uint32_t current_qtd; /* Standard next link pointer */
|
195 |
uint32_t next_qtd; /* Standard next link pointer */
|
196 |
uint32_t altnext_qtd; |
197 |
#define QH_ALTNEXT_NAKCNT_MASK 0x0000001e |
198 |
#define QH_ALTNEXT_NAKCNT_SH 1 |
199 |
|
200 |
uint32_t token; /* Same as QTD token */
|
201 |
uint32_t bufptr[5]; /* Standard buffer pointer */ |
202 |
#define BUFPTR_CPROGMASK_MASK 0x000000ff |
203 |
#define BUFPTR_FRAMETAG_MASK 0x0000001f |
204 |
#define BUFPTR_SBYTES_MASK 0x00000fe0 |
205 |
#define BUFPTR_SBYTES_SH 5 |
206 |
} EHCIqh; |
207 |
|
208 |
/* EHCI spec version 1.0 Section 3.7
|
209 |
*/
|
210 |
typedef struct EHCIfstn { |
211 |
uint32_t next; /* Standard next link pointer */
|
212 |
uint32_t backptr; /* Standard next link pointer */
|
213 |
} EHCIfstn; |
214 |
|
215 |
enum async_state {
|
216 |
EHCI_ASYNC_NONE = 0,
|
217 |
EHCI_ASYNC_INITIALIZED, |
218 |
EHCI_ASYNC_INFLIGHT, |
219 |
EHCI_ASYNC_FINISHED, |
220 |
}; |
221 |
|
222 |
struct EHCIPacket {
|
223 |
EHCIQueue *queue; |
224 |
QTAILQ_ENTRY(EHCIPacket) next; |
225 |
|
226 |
EHCIqtd qtd; /* copy of current QTD (being worked on) */
|
227 |
uint32_t qtdaddr; /* address QTD read from */
|
228 |
|
229 |
USBPacket packet; |
230 |
QEMUSGList sgl; |
231 |
int pid;
|
232 |
enum async_state async;
|
233 |
}; |
234 |
|
235 |
struct EHCIQueue {
|
236 |
EHCIState *ehci; |
237 |
QTAILQ_ENTRY(EHCIQueue) next; |
238 |
uint32_t seen; |
239 |
uint64_t ts; |
240 |
int async;
|
241 |
int transact_ctr;
|
242 |
|
243 |
/* cached data from guest - needs to be flushed
|
244 |
* when guest removes an entry (doorbell, handshake sequence)
|
245 |
*/
|
246 |
EHCIqh qh; /* copy of current QH (being worked on) */
|
247 |
uint32_t qhaddr; /* address QH read from */
|
248 |
uint32_t qtdaddr; /* address QTD read from */
|
249 |
int last_pid; /* pid of last packet executed */ |
250 |
USBDevice *dev; |
251 |
QTAILQ_HEAD(pkts_head, EHCIPacket) packets; |
252 |
}; |
253 |
|
254 |
typedef QTAILQ_HEAD(EHCIQueueHead, EHCIQueue) EHCIQueueHead;
|
255 |
|
256 |
struct EHCIState {
|
257 |
USBBus bus; |
258 |
DeviceState *device; |
259 |
qemu_irq irq; |
260 |
MemoryRegion mem; |
261 |
AddressSpace *as; |
262 |
MemoryRegion mem_caps; |
263 |
MemoryRegion mem_opreg; |
264 |
MemoryRegion mem_ports; |
265 |
int companion_count;
|
266 |
uint16_t capsbase; |
267 |
uint16_t opregbase; |
268 |
uint16_t portscbase; |
269 |
uint16_t portnr; |
270 |
|
271 |
/* properties */
|
272 |
uint32_t maxframes; |
273 |
|
274 |
/*
|
275 |
* EHCI spec version 1.0 Section 2.3
|
276 |
* Host Controller Operational Registers
|
277 |
*/
|
278 |
uint8_t caps[CAPA_SIZE]; |
279 |
union {
|
280 |
uint32_t opreg[0x44/sizeof(uint32_t)]; |
281 |
struct {
|
282 |
uint32_t usbcmd; |
283 |
uint32_t usbsts; |
284 |
uint32_t usbintr; |
285 |
uint32_t frindex; |
286 |
uint32_t ctrldssegment; |
287 |
uint32_t periodiclistbase; |
288 |
uint32_t asynclistaddr; |
289 |
uint32_t notused[9];
|
290 |
uint32_t configflag; |
291 |
}; |
292 |
}; |
293 |
uint32_t portsc[NB_PORTS]; |
294 |
|
295 |
/*
|
296 |
* Internal states, shadow registers, etc
|
297 |
*/
|
298 |
QEMUTimer *frame_timer; |
299 |
QEMUBH *async_bh; |
300 |
uint32_t astate; /* Current state in asynchronous schedule */
|
301 |
uint32_t pstate; /* Current state in periodic schedule */
|
302 |
USBPort ports[NB_PORTS]; |
303 |
USBPort *companion_ports[NB_PORTS]; |
304 |
uint32_t usbsts_pending; |
305 |
uint32_t usbsts_frindex; |
306 |
EHCIQueueHead aqueues; |
307 |
EHCIQueueHead pqueues; |
308 |
|
309 |
/* which address to look at next */
|
310 |
uint32_t a_fetch_addr; |
311 |
uint32_t p_fetch_addr; |
312 |
|
313 |
USBPacket ipacket; |
314 |
QEMUSGList isgl; |
315 |
|
316 |
uint64_t last_run_ns; |
317 |
uint32_t async_stepdown; |
318 |
uint32_t periodic_sched_active; |
319 |
bool int_req_by_async;
|
320 |
}; |
321 |
|
322 |
extern const VMStateDescription vmstate_ehci; |
323 |
|
324 |
void usb_ehci_init(EHCIState *s, DeviceState *dev);
|
325 |
void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp);
|
326 |
|
327 |
#define TYPE_PCI_EHCI "pci-ehci-usb" |
328 |
#define PCI_EHCI(obj) OBJECT_CHECK(EHCIPCIState, (obj), TYPE_PCI_EHCI)
|
329 |
|
330 |
typedef struct EHCIPCIState { |
331 |
/*< private >*/
|
332 |
PCIDevice pcidev; |
333 |
/*< public >*/
|
334 |
|
335 |
EHCIState ehci; |
336 |
} EHCIPCIState; |
337 |
|
338 |
|
339 |
#define TYPE_SYS_BUS_EHCI "sysbus-ehci-usb" |
340 |
#define TYPE_EXYNOS4210_EHCI "exynos4210-ehci-usb" |
341 |
#define TYPE_TEGRA2_EHCI "tegra2-ehci-usb" |
342 |
#define TYPE_FUSBH200_EHCI "fusbh200-ehci-usb" |
343 |
|
344 |
#define SYS_BUS_EHCI(obj) \
|
345 |
OBJECT_CHECK(EHCISysBusState, (obj), TYPE_SYS_BUS_EHCI) |
346 |
#define SYS_BUS_EHCI_CLASS(class) \
|
347 |
OBJECT_CLASS_CHECK(SysBusEHCIClass, (class), TYPE_SYS_BUS_EHCI) |
348 |
#define SYS_BUS_EHCI_GET_CLASS(obj) \
|
349 |
OBJECT_GET_CLASS(SysBusEHCIClass, (obj), TYPE_SYS_BUS_EHCI) |
350 |
|
351 |
typedef struct EHCISysBusState { |
352 |
/*< private >*/
|
353 |
SysBusDevice parent_obj; |
354 |
/*< public >*/
|
355 |
|
356 |
EHCIState ehci; |
357 |
} EHCISysBusState; |
358 |
|
359 |
typedef struct SysBusEHCIClass { |
360 |
/*< private >*/
|
361 |
SysBusDeviceClass parent_class; |
362 |
/*< public >*/
|
363 |
|
364 |
uint16_t capsbase; |
365 |
uint16_t opregbase; |
366 |
uint16_t portscbase; |
367 |
uint16_t portnr; |
368 |
} SysBusEHCIClass; |
369 |
|
370 |
#define FUSBH200_EHCI(obj) \
|
371 |
OBJECT_CHECK(FUSBH200EHCIState, (obj), TYPE_FUSBH200_EHCI) |
372 |
|
373 |
typedef struct FUSBH200EHCIState { |
374 |
/*< private >*/
|
375 |
EHCISysBusState parent_obj; |
376 |
/*< public >*/
|
377 |
|
378 |
MemoryRegion mem_vendor; |
379 |
} FUSBH200EHCIState; |
380 |
|
381 |
#endif
|