]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c
1) remove wrong global variable usage because it will bring data corrupt if there...
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / XhciDxe / XhciReg.c
CommitLineData
92870c98 1/** @file\r
2\r
3 The XHCI register operation routines.\r
4\r
5Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
6This program and the accompanying materials\r
7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "Xhci.h"\r
17\r
18/**\r
19 Read 1-byte width XHCI capability register.\r
20\r
a9292c13 21 @param Xhc The XHCI Instance.\r
92870c98 22 @param Offset The offset of the 1-byte width capability register.\r
23\r
24 @return The register content read.\r
25 @retval If err, return 0xFF.\r
26\r
27**/\r
28UINT8\r
29XhcReadCapReg8 (\r
a9292c13 30 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 31 IN UINT32 Offset\r
32 )\r
33{\r
34 UINT8 Data;\r
35 EFI_STATUS Status;\r
36\r
37 Status = Xhc->PciIo->Mem.Read (\r
38 Xhc->PciIo,\r
39 EfiPciIoWidthUint8,\r
40 XHC_BAR_INDEX,\r
41 (UINT64) Offset,\r
42 1,\r
43 &Data\r
44 );\r
45\r
46 if (EFI_ERROR (Status)) {\r
47 DEBUG ((EFI_D_ERROR, "XhcReadCapReg: Pci Io read error - %r at %d\n", Status, Offset));\r
48 Data = 0xFF;\r
49 }\r
50\r
51 return Data;\r
52}\r
53\r
54/**\r
55 Read 4-bytes width XHCI capability register.\r
56\r
a9292c13 57 @param Xhc The XHCI Instance.\r
92870c98 58 @param Offset The offset of the 4-bytes width capability register.\r
59\r
60 @return The register content read.\r
61 @retval If err, return 0xFFFFFFFF.\r
62\r
63**/\r
64UINT32\r
65XhcReadCapReg (\r
a9292c13 66 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 67 IN UINT32 Offset\r
68 )\r
69{\r
70 UINT32 Data;\r
71 EFI_STATUS Status;\r
72\r
73 Status = Xhc->PciIo->Mem.Read (\r
74 Xhc->PciIo,\r
75 EfiPciIoWidthUint32,\r
76 XHC_BAR_INDEX,\r
77 (UINT64) Offset,\r
78 1,\r
79 &Data\r
80 );\r
81\r
82 if (EFI_ERROR (Status)) {\r
83 DEBUG ((EFI_D_ERROR, "XhcReadCapReg: Pci Io read error - %r at %d\n", Status, Offset));\r
84 Data = 0xFFFFFFFF;\r
85 }\r
86\r
87 return Data;\r
88}\r
89\r
90/**\r
91 Read 4-bytes width XHCI Operational register.\r
92\r
a9292c13 93 @param Xhc The XHCI Instance.\r
92870c98 94 @param Offset The offset of the 4-bytes width operational register.\r
95\r
96 @return The register content read.\r
97 @retval If err, return 0xFFFFFFFF.\r
98\r
99**/\r
100UINT32\r
101XhcReadOpReg (\r
a9292c13 102 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 103 IN UINT32 Offset\r
104 )\r
105{\r
106 UINT32 Data;\r
107 EFI_STATUS Status;\r
108\r
109 ASSERT (Xhc->CapLength != 0);\r
110\r
111 Status = Xhc->PciIo->Mem.Read (\r
112 Xhc->PciIo,\r
113 EfiPciIoWidthUint32,\r
114 XHC_BAR_INDEX,\r
115 (UINT64) (Xhc->CapLength + Offset),\r
116 1,\r
117 &Data\r
118 );\r
119\r
120 if (EFI_ERROR (Status)) {\r
121 DEBUG ((EFI_D_ERROR, "XhcReadOpReg: Pci Io Read error - %r at %d\n", Status, Offset));\r
122 Data = 0xFFFFFFFF;\r
123 }\r
124\r
125 return Data;\r
126}\r
127\r
128/**\r
129 Write the data to the 4-bytes width XHCI operational register.\r
130\r
a9292c13 131 @param Xhc The XHCI Instance.\r
92870c98 132 @param Offset The offset of the 4-bytes width operational register.\r
133 @param Data The data to write.\r
134\r
135**/\r
136VOID\r
137XhcWriteOpReg (\r
a9292c13 138 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 139 IN UINT32 Offset,\r
140 IN UINT32 Data\r
141 )\r
142{\r
143 EFI_STATUS Status;\r
144\r
145 ASSERT (Xhc->CapLength != 0);\r
146\r
147 Status = Xhc->PciIo->Mem.Write (\r
148 Xhc->PciIo,\r
149 EfiPciIoWidthUint32,\r
150 XHC_BAR_INDEX,\r
151 (UINT64) (Xhc->CapLength + Offset),\r
152 1,\r
153 &Data\r
154 );\r
155\r
156 if (EFI_ERROR (Status)) {\r
157 DEBUG ((EFI_D_ERROR, "XhcWriteOpReg: Pci Io Write error: %r at %d\n", Status, Offset));\r
158 }\r
159}\r
160\r
161/**\r
162 Write the data to the 2-bytes width XHCI operational register.\r
163\r
a9292c13 164 @param Xhc The XHCI Instance.\r
92870c98 165 @param Offset The offset of the 2-bytes width operational register.\r
166 @param Data The data to write.\r
167\r
168**/\r
169VOID\r
170XhcWriteOpReg16 (\r
a9292c13 171 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 172 IN UINT32 Offset,\r
173 IN UINT16 Data\r
174 )\r
175{\r
176 EFI_STATUS Status;\r
177\r
178 ASSERT (Xhc->CapLength != 0);\r
179\r
180 Status = Xhc->PciIo->Mem.Write (\r
181 Xhc->PciIo,\r
182 EfiPciIoWidthUint16,\r
183 XHC_BAR_INDEX,\r
184 (UINT64) (Xhc->CapLength + Offset),\r
185 1,\r
186 &Data\r
187 );\r
188\r
189 if (EFI_ERROR (Status)) {\r
190 DEBUG ((EFI_D_ERROR, "XhcWriteOpReg16: Pci Io Write error: %r at %d\n", Status, Offset));\r
191 }\r
192}\r
193\r
194/**\r
195 Write the data to the 8-bytes width XHCI operational register.\r
196\r
a9292c13 197 @param Xhc The XHCI Instance.\r
92870c98 198 @param Offset The offset of the 8-bytes width operational register.\r
199 @param Data The data to write.\r
200\r
201**/\r
202VOID\r
203XhcWriteOpReg64 (\r
a9292c13 204 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 205 IN UINT32 Offset,\r
206 IN UINT64 Data\r
207 )\r
208{\r
209 EFI_STATUS Status;\r
210\r
211 ASSERT (Xhc->CapLength != 0);\r
212\r
213 Status = Xhc->PciIo->Mem.Write (\r
214 Xhc->PciIo,\r
215 EfiPciIoWidthUint64,\r
216 XHC_BAR_INDEX,\r
217 (UINT64) (Xhc->CapLength + Offset),\r
218 1,\r
219 &Data\r
220 );\r
221\r
222 if (EFI_ERROR (Status)) {\r
223 DEBUG ((EFI_D_ERROR, "XhcWriteOpReg64: Pci Io Write error: %r at %d\n", Status, Offset));\r
224 }\r
225}\r
226\r
227/**\r
228 Read XHCI door bell register.\r
229\r
a9292c13 230 @param Xhc The XHCI Instance.\r
92870c98 231 @param Offset The offset of the door bell register.\r
232\r
233 @return The register content read\r
234\r
235**/\r
236UINT32\r
237XhcReadDoorBellReg (\r
a9292c13 238 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 239 IN UINT32 Offset\r
240 )\r
241{\r
242 UINT32 Data;\r
243 EFI_STATUS Status;\r
244\r
245 ASSERT (Xhc->DBOff != 0);\r
246\r
247 Status = Xhc->PciIo->Mem.Read (\r
248 Xhc->PciIo,\r
249 EfiPciIoWidthUint32,\r
250 XHC_BAR_INDEX,\r
251 (UINT64) (Xhc->DBOff + Offset),\r
252 1,\r
253 &Data\r
254 );\r
255\r
256 if (EFI_ERROR (Status)) {\r
257 DEBUG ((EFI_D_ERROR, "XhcReadDoorBellReg: Pci Io Read error - %r at %d\n", Status, Offset));\r
258 Data = 0xFFFFFFFF;\r
259 }\r
260\r
261 return Data;\r
262}\r
263\r
264/**\r
265 Write the data to the XHCI door bell register.\r
266\r
a9292c13 267 @param Xhc The XHCI Instance.\r
92870c98 268 @param Offset The offset of the door bell register.\r
269 @param Data The data to write.\r
270\r
271**/\r
272VOID\r
273XhcWriteDoorBellReg (\r
a9292c13 274 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 275 IN UINT32 Offset,\r
276 IN UINT32 Data\r
277 )\r
278{\r
279 EFI_STATUS Status;\r
280\r
281 ASSERT (Xhc->DBOff != 0);\r
282\r
283 Status = Xhc->PciIo->Mem.Write (\r
284 Xhc->PciIo,\r
285 EfiPciIoWidthUint32,\r
286 XHC_BAR_INDEX,\r
287 (UINT64) (Xhc->DBOff + Offset),\r
288 1,\r
289 &Data\r
290 );\r
291\r
292 if (EFI_ERROR (Status)) {\r
293 DEBUG ((EFI_D_ERROR, "XhcWriteOpReg: Pci Io Write error: %r at %d\n", Status, Offset));\r
294 }\r
295}\r
296\r
297/**\r
298 Read XHCI runtime register.\r
299\r
a9292c13 300 @param Xhc The XHCI Instance.\r
92870c98 301 @param Offset The offset of the runtime register.\r
302\r
303 @return The register content read\r
304\r
305**/\r
306UINT32\r
307XhcReadRuntimeReg (\r
a9292c13 308 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 309 IN UINT32 Offset\r
310 )\r
311{\r
312 UINT32 Data;\r
313 EFI_STATUS Status;\r
314\r
315 ASSERT (Xhc->RTSOff != 0);\r
316\r
317 Status = Xhc->PciIo->Mem.Read (\r
318 Xhc->PciIo,\r
319 EfiPciIoWidthUint32,\r
320 XHC_BAR_INDEX,\r
321 (UINT64) (Xhc->RTSOff + Offset),\r
322 1,\r
323 &Data\r
324 );\r
325\r
326 if (EFI_ERROR (Status)) {\r
327 DEBUG ((EFI_D_ERROR, "XhcReadRuntimeReg: Pci Io Read error - %r at %d\n", Status, Offset));\r
328 Data = 0xFFFFFFFF;\r
329 }\r
330\r
331 return Data;\r
332}\r
333\r
334/**\r
335 Read 8-bytes width XHCI runtime register.\r
336\r
a9292c13 337 @param Xhc The XHCI Instance.\r
92870c98 338 @param Offset The offset of the 8-bytes width runtime register.\r
339\r
340 @return The register content read\r
341\r
342**/\r
343UINT64\r
344XhcReadRuntimeReg64 (\r
a9292c13 345 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 346 IN UINT32 Offset\r
347 )\r
348{\r
349 UINT64 Data;\r
350 EFI_STATUS Status;\r
351\r
352 ASSERT (Xhc->RTSOff != 0);\r
353\r
354 Status = Xhc->PciIo->Mem.Read (\r
355 Xhc->PciIo,\r
356 EfiPciIoWidthUint64,\r
357 XHC_BAR_INDEX,\r
358 (UINT64) (Xhc->RTSOff + Offset),\r
359 1,\r
360 &Data\r
361 );\r
362\r
363 if (EFI_ERROR (Status)) {\r
364 DEBUG ((EFI_D_ERROR, "XhcReadRuntimeReg64: Pci Io Read error - %r at %d\n", Status, Offset));\r
ce9b5900 365 Data = 0xFFFFFFFFFFFFFFFFULL;\r
92870c98 366 }\r
367\r
368 return Data;\r
369}\r
370\r
371/**\r
372 Write the data to the XHCI runtime register.\r
373\r
a9292c13 374 @param Xhc The XHCI Instance.\r
92870c98 375 @param Offset The offset of the runtime register.\r
376 @param Data The data to write.\r
377\r
378**/\r
379VOID\r
380XhcWriteRuntimeReg (\r
a9292c13 381 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 382 IN UINT32 Offset,\r
383 IN UINT32 Data\r
384 )\r
385{\r
386 EFI_STATUS Status;\r
387\r
388 ASSERT (Xhc->RTSOff != 0);\r
389\r
390 Status = Xhc->PciIo->Mem.Write (\r
391 Xhc->PciIo,\r
392 EfiPciIoWidthUint32,\r
393 XHC_BAR_INDEX,\r
394 (UINT64) (Xhc->RTSOff + Offset),\r
395 1,\r
396 &Data\r
397 );\r
398\r
399 if (EFI_ERROR (Status)) {\r
400 DEBUG ((EFI_D_ERROR, "XhcWriteRuntimeReg: Pci Io Write error: %r at %d\n", Status, Offset));\r
401 }\r
402}\r
403\r
404/**\r
405 Write the data to the 8-bytes width XHCI runtime register.\r
406\r
a9292c13 407 @param Xhc The XHCI Instance.\r
92870c98 408 @param Offset The offset of the 8-bytes width runtime register.\r
409 @param Data The data to write.\r
410\r
411**/\r
412VOID\r
413XhcWriteRuntimeReg64 (\r
a9292c13 414 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 415 IN UINT32 Offset,\r
416 IN UINT64 Data\r
417 )\r
418{\r
419 EFI_STATUS Status;\r
420\r
421 ASSERT (Xhc->RTSOff != 0);\r
422\r
423 Status = Xhc->PciIo->Mem.Write (\r
424 Xhc->PciIo,\r
425 EfiPciIoWidthUint64,\r
426 XHC_BAR_INDEX,\r
427 (UINT64) (Xhc->RTSOff + Offset),\r
428 1,\r
429 &Data\r
430 );\r
431\r
432 if (EFI_ERROR (Status)) {\r
433 DEBUG ((EFI_D_ERROR, "XhcWriteRuntimeReg64: Pci Io Write error: %r at %d\n", Status, Offset));\r
434 }\r
435}\r
436\r
437/**\r
438 Read XHCI extended capability register.\r
439\r
a9292c13 440 @param Xhc The XHCI Instance.\r
92870c98 441 @param Offset The offset of the extended capability register.\r
442\r
443 @return The register content read\r
444\r
445**/\r
446UINT32\r
447XhcReadExtCapReg (\r
a9292c13 448 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 449 IN UINT32 Offset\r
450 )\r
451{\r
452 UINT32 Data;\r
453 EFI_STATUS Status;\r
454\r
455 ASSERT (Xhc->ExtCapRegBase != 0);\r
456\r
457 Status = Xhc->PciIo->Mem.Read (\r
458 Xhc->PciIo,\r
459 EfiPciIoWidthUint32,\r
460 XHC_BAR_INDEX,\r
461 (UINT64) (Xhc->ExtCapRegBase + Offset),\r
462 1,\r
463 &Data\r
464 );\r
465\r
466 if (EFI_ERROR (Status)) {\r
467 DEBUG ((EFI_D_ERROR, "XhcReadExtCapReg: Pci Io Read error - %r at %d\n", Status, Offset));\r
468 Data = 0xFFFFFFFF;\r
469 }\r
470\r
471 return Data;\r
472}\r
473\r
474/**\r
475 Write the data to the XHCI extended capability register.\r
476\r
a9292c13 477 @param Xhc The XHCI Instance.\r
92870c98 478 @param Offset The offset of the extended capability register.\r
479 @param Data The data to write.\r
480\r
481**/\r
482VOID\r
483XhcWriteExtCapReg (\r
a9292c13 484 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 485 IN UINT32 Offset,\r
486 IN UINT32 Data\r
487 )\r
488{\r
489 EFI_STATUS Status;\r
490\r
491 ASSERT (Xhc->ExtCapRegBase != 0);\r
492\r
493 Status = Xhc->PciIo->Mem.Write (\r
494 Xhc->PciIo,\r
495 EfiPciIoWidthUint32,\r
496 XHC_BAR_INDEX,\r
497 (UINT64) (Xhc->ExtCapRegBase + Offset),\r
498 1,\r
499 &Data\r
500 );\r
501\r
502 if (EFI_ERROR (Status)) {\r
503 DEBUG ((EFI_D_ERROR, "XhcWriteExtCapReg: Pci Io Write error: %r at %d\n", Status, Offset));\r
504 }\r
505}\r
506\r
507\r
508/**\r
509 Set one bit of the runtime register while keeping other bits.\r
510\r
a9292c13 511 @param Xhc The XHCI Instance.\r
92870c98 512 @param Offset The offset of the runtime register.\r
513 @param Bit The bit mask of the register to set.\r
514\r
515**/\r
516VOID\r
517XhcSetRuntimeRegBit (\r
a9292c13 518 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 519 IN UINT32 Offset,\r
520 IN UINT32 Bit\r
521 )\r
522{\r
523 UINT32 Data;\r
524\r
525 Data = XhcReadRuntimeReg (Xhc, Offset);\r
526 Data |= Bit;\r
527 XhcWriteRuntimeReg (Xhc, Offset, Data);\r
528}\r
529\r
530/**\r
531 Clear one bit of the runtime register while keeping other bits.\r
532\r
a9292c13 533 @param Xhc The XHCI Instance.\r
92870c98 534 @param Offset The offset of the runtime register.\r
535 @param Bit The bit mask of the register to set.\r
536\r
537**/\r
538VOID\r
539XhcClearRuntimeRegBit (\r
a9292c13 540 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 541 IN UINT32 Offset,\r
542 IN UINT32 Bit\r
543 )\r
544{\r
545 UINT32 Data;\r
546\r
547 Data = XhcReadRuntimeReg (Xhc, Offset);\r
548 Data &= ~Bit;\r
549 XhcWriteRuntimeReg (Xhc, Offset, Data);\r
550}\r
551\r
552/**\r
553 Set one bit of the operational register while keeping other bits.\r
554\r
a9292c13 555 @param Xhc The XHCI Instance.\r
92870c98 556 @param Offset The offset of the operational register.\r
557 @param Bit The bit mask of the register to set.\r
558\r
559**/\r
560VOID\r
561XhcSetOpRegBit (\r
a9292c13 562 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 563 IN UINT32 Offset,\r
564 IN UINT32 Bit\r
565 )\r
566{\r
567 UINT32 Data;\r
568\r
569 Data = XhcReadOpReg (Xhc, Offset);\r
570 Data |= Bit;\r
571 XhcWriteOpReg (Xhc, Offset, Data);\r
572}\r
573\r
574\r
575/**\r
576 Clear one bit of the operational register while keeping other bits.\r
577\r
a9292c13 578 @param Xhc The XHCI Instance.\r
92870c98 579 @param Offset The offset of the operational register.\r
580 @param Bit The bit mask of the register to clear.\r
581\r
582**/\r
583VOID\r
584XhcClearOpRegBit (\r
a9292c13 585 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 586 IN UINT32 Offset,\r
587 IN UINT32 Bit\r
588 )\r
589{\r
590 UINT32 Data;\r
591\r
592 Data = XhcReadOpReg (Xhc, Offset);\r
593 Data &= ~Bit;\r
594 XhcWriteOpReg (Xhc, Offset, Data);\r
595}\r
596\r
597/**\r
598 Wait the operation register's bit as specified by Bit\r
599 to become set (or clear).\r
600\r
a9292c13 601 @param Xhc The XHCI Instance.\r
92870c98 602 @param Offset The offset of the operation register.\r
603 @param Bit The bit of the register to wait for.\r
604 @param WaitToSet Wait the bit to set or clear.\r
605 @param Timeout The time to wait before abort (in millisecond, ms).\r
606\r
607 @retval EFI_SUCCESS The bit successfully changed by host controller.\r
608 @retval EFI_TIMEOUT The time out occurred.\r
609\r
610**/\r
611EFI_STATUS\r
612XhcWaitOpRegBit (\r
a9292c13 613 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 614 IN UINT32 Offset,\r
615 IN UINT32 Bit,\r
616 IN BOOLEAN WaitToSet,\r
617 IN UINT32 Timeout\r
618 )\r
619{\r
620 UINT32 Index;\r
a9292c13 621 UINTN Loop;\r
92870c98 622\r
a9292c13 623 Loop = (Timeout * XHC_1_MILLISECOND / XHC_POLL_DELAY) + 1;\r
624\r
625 for (Index = 0; Index < Loop; Index++) {\r
92870c98 626 if (XHC_REG_BIT_IS_SET (Xhc, Offset, Bit) == WaitToSet) {\r
627 return EFI_SUCCESS;\r
628 }\r
629\r
a9292c13 630 gBS->Stall (XHC_POLL_DELAY);\r
92870c98 631 }\r
632\r
633 return EFI_TIMEOUT;\r
634}\r
635\r
636/**\r
637 Set Bios Ownership\r
638\r
a9292c13 639 @param Xhc The XHCI Instance.\r
92870c98 640\r
641**/\r
642VOID\r
643XhcSetBiosOwnership (\r
a9292c13 644 IN USB_XHCI_INSTANCE *Xhc\r
92870c98 645 )\r
646{\r
647 UINT32 Buffer;\r
648\r
649 DEBUG ((EFI_D_INFO, "XhcSetBiosOwnership: called to set BIOS ownership\n"));\r
650\r
651 Buffer = XhcReadExtCapReg (Xhc, Xhc->UsbLegSupOffset);\r
652 Buffer = ((Buffer & (~USBLEGSP_OS_SEMAPHORE)) | USBLEGSP_BIOS_SEMAPHORE);\r
653 XhcWriteExtCapReg (Xhc, Xhc->UsbLegSupOffset, Buffer);\r
654}\r
655\r
656/**\r
657 Clear Bios Ownership\r
658\r
a9292c13 659 @param Xhc The XHCI Instance.\r
92870c98 660\r
661**/\r
662VOID\r
663XhcClearBiosOwnership (\r
a9292c13 664 IN USB_XHCI_INSTANCE *Xhc\r
92870c98 665 )\r
666{\r
667 UINT32 Buffer;\r
668\r
669 DEBUG ((EFI_D_INFO, "XhcClearBiosOwnership: called to clear BIOS ownership\n"));\r
670\r
671 Buffer = XhcReadExtCapReg (Xhc, Xhc->UsbLegSupOffset);\r
672 Buffer = ((Buffer & (~USBLEGSP_BIOS_SEMAPHORE)) | USBLEGSP_OS_SEMAPHORE);\r
673 XhcWriteExtCapReg (Xhc, Xhc->UsbLegSupOffset, Buffer);\r
674}\r
675\r
676/**\r
677 Calculate the XHCI legacy support capability register offset.\r
678\r
a9292c13 679 @param Xhc The XHCI Instance.\r
92870c98 680\r
681 @return The offset of XHCI legacy support capability register.\r
682\r
683**/\r
684UINT32\r
685XhcGetLegSupCapAddr (\r
a9292c13 686 IN USB_XHCI_INSTANCE *Xhc\r
92870c98 687 )\r
688{\r
689 UINT32 ExtCapOffset;\r
690 UINT8 NextExtCapReg;\r
691 UINT32 Data;\r
692\r
693 ExtCapOffset = 0;\r
694\r
695 do {\r
696 //\r
697 // Check if the extended capability register's capability id is USB Legacy Support.\r
698 //\r
699 Data = XhcReadExtCapReg (Xhc, ExtCapOffset);\r
700 if ((Data & 0xFF) == 0x1) {\r
701 return ExtCapOffset;\r
702 }\r
703 //\r
704 // If not, then traverse all of the ext capability registers till finding out it.\r
705 //\r
ce9b5900 706 NextExtCapReg = (UINT8)((Data >> 8) & 0xFF);\r
92870c98 707 ExtCapOffset += (NextExtCapReg << 2);\r
708 } while (NextExtCapReg != 0);\r
709\r
710 return 0;\r
711}\r
712\r
713/**\r
714 Whether the XHCI host controller is halted.\r
715\r
a9292c13 716 @param Xhc The XHCI Instance.\r
92870c98 717\r
718 @retval TRUE The controller is halted.\r
719 @retval FALSE It isn't halted.\r
720\r
721**/\r
722BOOLEAN\r
723XhcIsHalt (\r
a9292c13 724 IN USB_XHCI_INSTANCE *Xhc\r
92870c98 725 )\r
726{\r
727 return XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT);\r
728}\r
729\r
730\r
731/**\r
732 Whether system error occurred.\r
733\r
a9292c13 734 @param Xhc The XHCI Instance.\r
92870c98 735\r
736 @retval TRUE System error happened.\r
737 @retval FALSE No system error.\r
738\r
739**/\r
740BOOLEAN\r
741XhcIsSysError (\r
a9292c13 742 IN USB_XHCI_INSTANCE *Xhc\r
92870c98 743 )\r
744{\r
745 return XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HSE);\r
746}\r
747\r
748/**\r
749 Reset the XHCI host controller.\r
750\r
a9292c13 751 @param Xhc The XHCI Instance.\r
92870c98 752 @param Timeout Time to wait before abort (in millisecond, ms).\r
753\r
754 @retval EFI_SUCCESS The XHCI host controller is reset.\r
755 @return Others Failed to reset the XHCI before Timeout.\r
756\r
757**/\r
758EFI_STATUS\r
759XhcResetHC (\r
a9292c13 760 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 761 IN UINT32 Timeout\r
762 )\r
763{\r
764 EFI_STATUS Status;\r
765\r
766 DEBUG ((EFI_D_INFO, "XhcResetHC!\n"));\r
767 //\r
768 // Host can only be reset when it is halt. If not so, halt it\r
769 //\r
770 if (!XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT)) {\r
771 Status = XhcHaltHC (Xhc, Timeout);\r
772\r
773 if (EFI_ERROR (Status)) {\r
774 return Status;\r
775 }\r
776 }\r
777\r
778 XhcSetOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RESET);\r
779 Status = XhcWaitOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RESET, FALSE, Timeout);\r
780 return Status;\r
781}\r
782\r
783\r
784/**\r
785 Halt the XHCI host controller.\r
786\r
a9292c13 787 @param Xhc The XHCI Instance.\r
92870c98 788 @param Timeout Time to wait before abort (in millisecond, ms).\r
789\r
790 @return EFI_SUCCESS The XHCI host controller is halt.\r
791 @return EFI_TIMEOUT Failed to halt the XHCI before Timeout.\r
792\r
793**/\r
794EFI_STATUS\r
795XhcHaltHC (\r
a9292c13 796 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 797 IN UINT32 Timeout\r
798 )\r
799{\r
800 EFI_STATUS Status;\r
801\r
802 XhcClearOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RUN);\r
803 Status = XhcWaitOpRegBit (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT, TRUE, Timeout);\r
804 return Status;\r
805}\r
806\r
807\r
808/**\r
809 Set the XHCI host controller to run.\r
810\r
a9292c13 811 @param Xhc The XHCI Instance.\r
92870c98 812 @param Timeout Time to wait before abort (in millisecond, ms).\r
813\r
814 @return EFI_SUCCESS The XHCI host controller is running.\r
815 @return EFI_TIMEOUT Failed to set the XHCI to run before Timeout.\r
816\r
817**/\r
818EFI_STATUS\r
819XhcRunHC (\r
a9292c13 820 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 821 IN UINT32 Timeout\r
822 )\r
823{\r
824 EFI_STATUS Status;\r
825\r
826 XhcSetOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RUN);\r
827 Status = XhcWaitOpRegBit (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT, FALSE, Timeout);\r
828 return Status;\r
829}\r
830\r