Kaynağa Gözat

[uhci] Add support for UHCI host controllers

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 9 yıl önce
ebeveyn
işleme
6dba29b18f

+ 3
- 0
src/config/config_usb.c Dosyayı Görüntüle

@@ -40,3 +40,6 @@ REQUIRE_OBJECT ( xhci );
40 40
 #ifdef USB_HCD_EHCI
41 41
 REQUIRE_OBJECT ( ehci );
42 42
 #endif
43
+#ifdef USB_HCD_UHCI
44
+REQUIRE_OBJECT ( uhci );
45
+#endif

+ 1
- 0
src/config/defaults/pcbios.h Dosyayı Görüntüle

@@ -38,6 +38,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
38 38
 
39 39
 #define	USB_HCD_XHCI		/* xHCI USB host controller */
40 40
 #define	USB_HCD_EHCI		/* EHCI USB host controller */
41
+#define	USB_HCD_UHCI		/* UHCI USB host controller */
41 42
 
42 43
 #define	REBOOT_CMD		/* Reboot command */
43 44
 #define	CPUID_CMD		/* x86 CPU feature detection command */

+ 1
- 0
src/config/usb.h Dosyayı Görüntüle

@@ -17,6 +17,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
17 17
  */
18 18
 //#undef	USB_HCD_XHCI		/* xHCI USB host controller */
19 19
 //#undef	USB_HCD_EHCI		/* EHCI USB host controller */
20
+//#undef	USB_HCD_UHCI		/* UHCI USB host controller */
20 21
 
21 22
 #include <config/named.h>
22 23
 #include NAMED_CONFIG(usb.h)

+ 1573
- 0
src/drivers/usb/uhci.c
Dosya farkı çok büyük olduğundan ihmal edildi
Dosyayı Görüntüle


+ 348
- 0
src/drivers/usb/uhci.h Dosyayı Görüntüle

@@ -0,0 +1,348 @@
1
+#ifndef _IPXE_UHCI_H
2
+#define _IPXE_UHCI_H
3
+
4
+/** @file
5
+ *
6
+ * USB Universal Host Controller Interface (UHCI) driver
7
+ *
8
+ */
9
+
10
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11
+
12
+#include <assert.h>
13
+#include <ipxe/pci.h>
14
+#include <ipxe/usb.h>
15
+
16
+/** Minimum alignment required for data structures
17
+ *
18
+ * With the exception of the frame list (which is page-aligned), data
19
+ * structures used by UHCI generally require 16-byte alignment.
20
+ */
21
+#define UHCI_ALIGN 16
22
+
23
+/** Number of ports */
24
+#define UHCI_PORTS 2
25
+
26
+/** Maximum transfer size */
27
+#define UHCI_MTU 1280
28
+
29
+/** I/O BAR size */
30
+#define UHCI_BAR_SIZE 0x14
31
+
32
+/** USB command register */
33
+#define UHCI_USBCMD 0x00
34
+
35
+/** Max packet is 64 bytes */
36
+#define UHCI_USBCMD_MAX64 0x0080
37
+
38
+/** Host controller reset */
39
+#define UHCI_USBCMD_HCRESET 0x0002
40
+
41
+/** Run/stop */
42
+#define UHCI_USBCMD_RUN 0x0001
43
+
44
+/** USB status register */
45
+#define UHCI_USBSTS 0x02
46
+
47
+/** Host controller halted */
48
+#define UHCI_USBSTS_HCHALTED 0x0020
49
+
50
+/** USB interrupt */
51
+#define UHCI_USBSTS_USBINT 0x0001
52
+
53
+/** Frame list base address register */
54
+#define UHCI_FLBASEADD 0x08
55
+
56
+/** Port status and control register */
57
+#define UHCI_PORTSC(port) ( 0x0e + ( (port) << 1 ) )
58
+
59
+/** Port reset */
60
+#define UHCI_PORTSC_PR 0x0200
61
+
62
+/** Low-speed device attached */
63
+#define UHCI_PORTSC_LS 0x0100
64
+
65
+/** Port enabled/disabled change */
66
+#define UHCI_PORTSC_PEC 0x0008
67
+
68
+/** Port enabled */
69
+#define UHCI_PORTSC_PED 0x0004
70
+
71
+/** Connect status change */
72
+#define UHCI_PORTSC_CSC 0x0002
73
+
74
+/** Current connect status */
75
+#define UHCI_PORTSC_CCS 0x0001
76
+
77
+/** Port status change mask */
78
+#define UHCI_PORTSC_CHANGE ( UHCI_PORTSC_CSC | UHCI_PORTSC_PEC )
79
+
80
+/** Depth-first processing */
81
+#define UHCI_LINK_DEPTH_FIRST 0x00000004UL
82
+
83
+/** Queue head type */
84
+#define UHCI_LINK_TYPE_QH 0x00000002UL
85
+
86
+/** List terminator */
87
+#define UHCI_LINK_TERMINATE 0x00000001UL
88
+
89
+/** Number of frames in frame list */
90
+#define UHCI_FRAMES 1024
91
+
92
+/** A frame list */
93
+struct uhci_frame_list {
94
+	/** Link pointer */
95
+	uint32_t link[UHCI_FRAMES];
96
+} __attribute__ (( packed ));
97
+
98
+/** A transfer descriptor */
99
+struct uhci_transfer_descriptor {
100
+	/** Link pointer */
101
+	uint32_t link;
102
+	/** Actual length */
103
+	uint16_t actual;
104
+	/** Status */
105
+	uint8_t status;
106
+	/** Flags */
107
+	uint8_t flags;
108
+	/** Control */
109
+	uint32_t control;
110
+	/** Buffer pointer */
111
+	uint32_t data;
112
+} __attribute__ (( packed ));
113
+
114
+/** Length mask */
115
+#define UHCI_LEN_MASK 0x7ff
116
+
117
+/** Actual length */
118
+#define UHCI_ACTUAL_LEN( actual ) ( ( (actual) + 1 ) & UHCI_LEN_MASK )
119
+
120
+/** Active */
121
+#define UHCI_STATUS_ACTIVE 0x80
122
+
123
+/** Stalled */
124
+#define UHCI_STATUS_STALLED 0x40
125
+
126
+/** Data buffer error */
127
+#define UHCI_STATUS_BUFFER 0x20
128
+
129
+/** Babble detected */
130
+#define UHCI_STATUS_BABBLE 0x10
131
+
132
+/** NAK received */
133
+#define UHCI_STATUS_NAK 0x08
134
+
135
+/** CRC/timeout error */
136
+#define UHCI_STATUS_CRC_TIMEOUT 0x04
137
+
138
+/** Bitstuff error */
139
+#define UHCI_STATUS_BITSTUFF 0x02
140
+
141
+/** Short packet detect */
142
+#define UHCI_FL_SPD 0x20
143
+
144
+/** Error counter */
145
+#define UHCI_FL_CERR( count ) ( (count) << 3 )
146
+
147
+/** Error counter maximum value */
148
+#define UHCI_FL_CERR_MAX UHCI_FL_CERR ( 3 )
149
+
150
+/** Low speed device */
151
+#define UHCI_FL_LS 0x04
152
+
153
+/** Interrupt on completion */
154
+#define UHCI_FL_IOC 0x01
155
+
156
+/** Packet ID */
157
+#define UHCI_CONTROL_PID( pid ) ( (pid) << 0 )
158
+
159
+/** Packet ID mask */
160
+#define UHCI_CONTROL_PID_MASK UHCI_CONTROL_PID ( 0xff )
161
+
162
+/** Device address */
163
+#define UHCI_CONTROL_DEVICE( address ) ( (address) << 8 )
164
+
165
+/** Endpoint address */
166
+#define UHCI_CONTROL_ENDPOINT( address ) ( (address) << 15 )
167
+
168
+/** Data toggle */
169
+#define UHCI_CONTROL_TOGGLE ( 1 << 19 )
170
+
171
+/** Data length */
172
+#define UHCI_CONTROL_LEN( len ) ( ( ( (len) - 1 ) & UHCI_LEN_MASK ) << 21 )
173
+
174
+/** Check for data packet
175
+ *
176
+ * This check is based on the fact that only USB_PID_SETUP has bit 2
177
+ * set.
178
+ */
179
+#define UHCI_DATA_PACKET( control ) ( ! ( control & 0x04 ) )
180
+
181
+/** Check for short packet */
182
+#define UHCI_SHORT_PACKET( control, actual ) \
183
+	( ( ( (control) >> 21 ) ^ (actual) ) & UHCI_LEN_MASK )
184
+
185
+/** USB legacy support register (in PCI configuration space) */
186
+#define UHCI_USBLEGSUP 0xc0
187
+
188
+/** USB legacy support default value */
189
+#define UHCI_USBLEGSUP_DEFAULT 0x2000
190
+
191
+/** A queue head */
192
+struct uhci_queue_head {
193
+	/** Horizontal link pointer */
194
+	uint32_t link;
195
+	/** Current transfer descriptor */
196
+	uint32_t current;
197
+} __attribute__ (( packed ));
198
+
199
+/** A single UHCI transfer
200
+ *
201
+ * UHCI hardware is extremely simple, and requires software to build
202
+ * the entire packet schedule (including manually handling all of the
203
+ * data toggles).  The hardware requires at least 16 bytes of transfer
204
+ * descriptors per 64 bytes of transmitted/received data.  We allocate
205
+ * the transfer descriptors at the time that the transfer is enqueued,
206
+ * to avoid the need to allocate unreasonably large blocks when the
207
+ * endpoint is opened.
208
+ */
209
+struct uhci_transfer {
210
+	/** Producer counter */
211
+	unsigned int prod;
212
+	/** Consumer counter */
213
+	unsigned int cons;
214
+	/** Completed data length */
215
+	size_t len;
216
+
217
+	/** Transfer descriptors */
218
+	struct uhci_transfer_descriptor *desc;
219
+
220
+	/** I/O buffer */
221
+	struct io_buffer *iobuf;
222
+};
223
+
224
+/** Number of transfer descriptors in a ring
225
+ *
226
+ * This is a policy decision.
227
+ */
228
+#define UHCI_RING_COUNT 16
229
+
230
+/** A transfer ring */
231
+struct uhci_ring {
232
+	/** Producer counter */
233
+	unsigned int prod;
234
+	/** Consumer counter */
235
+	unsigned int cons;
236
+
237
+	/** Maximum packet length */
238
+	size_t mtu;
239
+	/** Base flags
240
+	 *
241
+	 * This incorporates the CERR and LS bits
242
+	 */
243
+	uint8_t flags;
244
+	/** Base control word
245
+	 *
246
+	 * This incorporates the device address, the endpoint address,
247
+	 * and the data toggle for the next descriptor to be enqueued.
248
+	 */
249
+	uint32_t control;
250
+
251
+	/** Transfers */
252
+	struct uhci_transfer *xfer[UHCI_RING_COUNT];
253
+	/** End of transfer ring (if non-empty) */
254
+	struct uhci_transfer *end;
255
+
256
+	/** Queue head */
257
+	struct uhci_queue_head *head;
258
+};
259
+
260
+/**
261
+ * Calculate space used in transfer ring
262
+ *
263
+ * @v ring		Transfer ring
264
+ * @ret fill		Number of entries used
265
+ */
266
+static inline __attribute__ (( always_inline )) unsigned int
267
+uhci_ring_fill ( struct uhci_ring *ring ) {
268
+	unsigned int fill;
269
+
270
+	fill = ( ring->prod - ring->cons );
271
+	assert ( fill <= UHCI_RING_COUNT );
272
+	return fill;
273
+}
274
+
275
+/**
276
+ * Calculate space remaining in transfer ring
277
+ *
278
+ * @v ring		Transfer ring
279
+ * @ret remaining	Number of entries remaining
280
+ */
281
+static inline __attribute__ (( always_inline )) unsigned int
282
+uhci_ring_remaining ( struct uhci_ring *ring ) {
283
+	unsigned int fill = uhci_ring_fill ( ring );
284
+
285
+	return ( UHCI_RING_COUNT - fill );
286
+}
287
+
288
+/** Maximum time to wait for host controller to stop
289
+ *
290
+ * This is a policy decision.
291
+ */
292
+#define UHCI_STOP_MAX_WAIT_MS 100
293
+
294
+/** Maximum time to wait for reset to complete
295
+ *
296
+ * This is a policy decision.
297
+ */
298
+#define UHCI_RESET_MAX_WAIT_MS 500
299
+
300
+/** Maximum time to wait for a port to be enabled
301
+ *
302
+ * This is a policy decision.
303
+ */
304
+#define UHCI_PORT_ENABLE_MAX_WAIT_MS 500
305
+
306
+/** A UHCI device */
307
+struct uhci_device {
308
+	/** Registers */
309
+	unsigned long regs;
310
+
311
+	/** EHCI companion controller bus:dev.fn address (if any) */
312
+	unsigned int companion;
313
+
314
+	/** Asynchronous queue head */
315
+	struct uhci_queue_head *head;
316
+	/** Frame list */
317
+	struct uhci_frame_list *frame;
318
+
319
+	/** List of all endpoints */
320
+	struct list_head endpoints;
321
+	/** Asynchronous schedule */
322
+	struct list_head async;
323
+	/** Periodic schedule
324
+	 *
325
+	 * Listed in decreasing order of endpoint interval.
326
+	 */
327
+	struct list_head periodic;
328
+
329
+	/** USB bus */
330
+	struct usb_bus *bus;
331
+};
332
+
333
+/** A UHCI endpoint */
334
+struct uhci_endpoint {
335
+	/** UHCI device */
336
+	struct uhci_device *uhci;
337
+	/** USB endpoint */
338
+	struct usb_endpoint *ep;
339
+	/** List of all endpoints */
340
+	struct list_head list;
341
+	/** Endpoint schedule */
342
+	struct list_head schedule;
343
+
344
+	/** Transfer ring */
345
+	struct uhci_ring ring;
346
+};
347
+
348
+#endif /* _IPXE_UHCI_H */

+ 1
- 0
src/include/ipxe/errfile.h Dosyayı Görüntüle

@@ -80,6 +80,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
80 80
 #define ERRFILE_usbhub		     ( ERRFILE_DRIVER | 0x00080000 )
81 81
 #define ERRFILE_xhci		     ( ERRFILE_DRIVER | 0x00090000 )
82 82
 #define ERRFILE_ehci		     ( ERRFILE_DRIVER | 0x000a0000 )
83
+#define ERRFILE_uhci		     ( ERRFILE_DRIVER | 0x000b0000 )
83 84
 
84 85
 #define ERRFILE_nvs		     ( ERRFILE_DRIVER | 0x00100000 )
85 86
 #define ERRFILE_spi		     ( ERRFILE_DRIVER | 0x00110000 )

+ 10
- 0
src/include/ipxe/usb.h Dosyayı Görüntüle

@@ -54,6 +54,16 @@ enum usb_speed {
54 54
 	USB_SPEED_SUPER = USB_SPEED ( 5, 3 ),
55 55
 };
56 56
 
57
+/** USB packet IDs */
58
+enum usb_pid {
59
+	/** IN PID */
60
+	USB_PID_IN = 0x69,
61
+	/** OUT PID */
62
+	USB_PID_OUT = 0xe1,
63
+	/** SETUP PID */
64
+	USB_PID_SETUP = 0x2d,
65
+};
66
+
57 67
 /** A USB setup data packet */
58 68
 struct usb_setup_packet {
59 69
 	/** Request */

Loading…
İptal
Kaydet