36 Urb->Signature = XHC_URB_SIG;
38 Urb->Ring = &Xhc->CmdRing;
41 Urb->TrbStart = Urb->Ring->RingEnqueue;
43 Urb->TrbStart->CycleBit = Urb->Ring->RingPCS & BIT0;
44 Urb->TrbEnd = Urb->TrbStart;
78 if ((Xhc ==
NULL) || (CmdTrb ==
NULL)) {
79 return EFI_INVALID_PARAMETER;
82 Status = EFI_DEVICE_ERROR;
85 DEBUG ((DEBUG_ERROR,
"XhcPeiCmdTransfer: HC is halted or has system error\n"));
94 DEBUG ((DEBUG_ERROR,
"XhcPeiCmdTransfer: failed to create URB\n"));
95 Status = EFI_OUT_OF_RESOURCES;
100 *EvtTrb = Urb->EvtTrb;
102 if (Urb->Result == EFI_USB_NOERROR) {
154 Urb->Signature = XHC_URB_SIG;
157 Ep->BusAddr = BusAddr;
158 Ep->EpAddr = (UINT8)(EpAddr & 0x0F);
159 Ep->Direction = ((EpAddr & 0x80) != 0) ? EfiUsbDataIn : EfiUsbDataOut;
160 Ep->DevSpeed = DevSpeed;
161 Ep->MaxPacket = MaxPacket;
164 Urb->Request = Request;
166 Urb->DataLen = DataLen;
167 Urb->Callback = Callback;
168 Urb->Context = Context;
171 if (EFI_ERROR (Status)) {
172 DEBUG ((DEBUG_ERROR,
"XhcPeiCreateUrb: XhcPeiCreateTransferTrb Failed, Status = %r\n", Status));
193 if ((Xhc ==
NULL) || (Urb ==
NULL)) {
233 return EFI_DEVICE_ERROR;
236 Urb->Finished =
FALSE;
237 Urb->StartDone =
FALSE;
238 Urb->EndDone =
FALSE;
240 Urb->Result = EFI_USB_NOERROR;
243 EPRing = (
TRANSFER_RING *)(
UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1];
245 OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;
246 if (Xhc->HcCParams.Data.Csz == 0) {
247 EPType = (UINT8)((
DEVICE_CONTEXT *)OutputContext)->EP[Dci-1].EPType;
255 if ((Urb->Data !=
NULL) && (Urb->DataMap ==
NULL)) {
256 if (((UINT8)(Urb->Ep.Direction)) == EfiUsbDataIn) {
263 Status =
IoMmuMap (MapOp, Urb->Data, &Len, &PhyAddr, &Map);
265 if (EFI_ERROR (Status) || (Len != Urb->DataLen)) {
266 DEBUG ((DEBUG_ERROR,
"XhcCreateTransferTrb: Fail to map Urb->Data.\n"));
267 return EFI_OUT_OF_RESOURCES;
270 Urb->DataPhy = (VOID *)((
UINTN)PhyAddr);
278 Urb->TrbStart = EPRing->RingEnqueue;
280 case ED_CONTROL_BIDIR:
284 TrbStart = (
TRB *)(
UINTN)EPRing->RingEnqueue;
285 TrbStart->TrbCtrSetup.bmRequestType = Urb->Request->RequestType;
286 TrbStart->TrbCtrSetup.bRequest = Urb->Request->Request;
287 TrbStart->TrbCtrSetup.wValue = Urb->Request->Value;
288 TrbStart->TrbCtrSetup.wIndex = Urb->Request->Index;
289 TrbStart->TrbCtrSetup.wLength = Urb->Request->Length;
290 TrbStart->TrbCtrSetup.Length = 8;
291 TrbStart->TrbCtrSetup.IntTarget = 0;
292 TrbStart->TrbCtrSetup.IOC = 1;
293 TrbStart->TrbCtrSetup.IDT = 1;
294 TrbStart->TrbCtrSetup.Type = TRB_TYPE_SETUP_STAGE;
295 if (Urb->DataLen > 0) {
296 if (Urb->Ep.Direction == EfiUsbDataIn) {
297 TrbStart->TrbCtrSetup.TRT = 3;
298 }
else if (Urb->Ep.Direction == EfiUsbDataOut) {
299 TrbStart->TrbCtrSetup.TRT = 2;
301 DEBUG ((DEBUG_ERROR,
"XhcPeiCreateTransferTrb: Direction sholud be IN or OUT when Data exists!\n"));
305 TrbStart->TrbCtrSetup.TRT = 0;
311 TrbStart->TrbCtrSetup.CycleBit = EPRing->RingPCS & BIT0;
317 if (Urb->DataLen > 0) {
319 TrbStart = (
TRB *)(
UINTN)EPRing->RingEnqueue;
320 TrbStart->TrbCtrData.TRBPtrLo = XHC_LOW_32BIT (Urb->DataPhy);
321 TrbStart->TrbCtrData.TRBPtrHi = XHC_HIGH_32BIT (Urb->DataPhy);
322 TrbStart->TrbCtrData.Length = (UINT32)Urb->DataLen;
323 TrbStart->TrbCtrData.TDSize = 0;
324 TrbStart->TrbCtrData.IntTarget = 0;
325 TrbStart->TrbCtrData.ISP = 1;
326 TrbStart->TrbCtrData.IOC = 1;
327 TrbStart->TrbCtrData.IDT = 0;
328 TrbStart->TrbCtrData.CH = 0;
329 TrbStart->TrbCtrData.Type = TRB_TYPE_DATA_STAGE;
330 if (Urb->Ep.Direction == EfiUsbDataIn) {
331 TrbStart->TrbCtrData.DIR = 1;
332 }
else if (Urb->Ep.Direction == EfiUsbDataOut) {
333 TrbStart->TrbCtrData.DIR = 0;
335 TrbStart->TrbCtrData.DIR = 0;
341 TrbStart->TrbCtrData.CycleBit = EPRing->RingPCS & BIT0;
350 TrbStart = (
TRB *)(
UINTN)EPRing->RingEnqueue;
351 TrbStart->TrbCtrStatus.IntTarget = 0;
352 TrbStart->TrbCtrStatus.IOC = 1;
353 TrbStart->TrbCtrStatus.CH = 0;
354 TrbStart->TrbCtrStatus.Type = TRB_TYPE_STATUS_STAGE;
355 if (Urb->Ep.Direction == EfiUsbDataIn) {
356 TrbStart->TrbCtrStatus.DIR = 0;
357 }
else if (Urb->Ep.Direction == EfiUsbDataOut) {
358 TrbStart->TrbCtrStatus.DIR = 1;
360 TrbStart->TrbCtrStatus.DIR = 0;
366 TrbStart->TrbCtrStatus.CycleBit = EPRing->RingPCS & BIT0;
381 TrbStart = (
TRB *)(
UINTN)EPRing->RingEnqueue;
382 while (TotalLen < Urb->DataLen) {
383 if ((TotalLen + 0x10000) >= Urb->DataLen) {
384 Len = Urb->DataLen - TotalLen;
389 TrbStart = (
TRB *)(
UINTN)EPRing->RingEnqueue;
390 TrbStart->TrbNormal.TRBPtrLo = XHC_LOW_32BIT ((UINT8 *)Urb->DataPhy + TotalLen);
391 TrbStart->TrbNormal.TRBPtrHi = XHC_HIGH_32BIT ((UINT8 *)Urb->DataPhy + TotalLen);
392 TrbStart->TrbNormal.Length = (UINT32)Len;
393 TrbStart->TrbNormal.TDSize = 0;
394 TrbStart->TrbNormal.IntTarget = 0;
395 TrbStart->TrbNormal.ISP = 1;
396 TrbStart->TrbNormal.IOC = 1;
397 TrbStart->TrbNormal.Type = TRB_TYPE_NORMAL;
401 TrbStart->TrbNormal.CycleBit = EPRing->RingPCS & BIT0;
408 Urb->TrbNum = TrbNum;
412 case ED_INTERRUPT_OUT:
413 case ED_INTERRUPT_IN:
417 TrbStart = (
TRB *)(
UINTN)EPRing->RingEnqueue;
418 while (TotalLen < Urb->DataLen) {
419 if ((TotalLen + 0x10000) >= Urb->DataLen) {
420 Len = Urb->DataLen - TotalLen;
425 TrbStart = (
TRB *)(
UINTN)EPRing->RingEnqueue;
426 TrbStart->TrbNormal.TRBPtrLo = XHC_LOW_32BIT ((UINT8 *)Urb->DataPhy + TotalLen);
427 TrbStart->TrbNormal.TRBPtrHi = XHC_HIGH_32BIT ((UINT8 *)Urb->DataPhy + TotalLen);
428 TrbStart->TrbNormal.Length = (UINT32)Len;
429 TrbStart->TrbNormal.TDSize = 0;
430 TrbStart->TrbNormal.IntTarget = 0;
431 TrbStart->TrbNormal.ISP = 1;
432 TrbStart->TrbNormal.IOC = 1;
433 TrbStart->TrbNormal.Type = TRB_TYPE_NORMAL;
437 TrbStart->TrbNormal.CycleBit = EPRing->RingPCS & BIT0;
444 Urb->TrbNum = TrbNum;
449 DEBUG ((DEBUG_INFO,
"Not supported EPType 0x%x!\n", EPType));
484 return EFI_DEVICE_ERROR;
489 DEBUG ((DEBUG_INFO,
"XhcPeiRecoverHaltedEndpoint: Recovery Halted Slot = %x, Dci = %x\n", SlotId, Dci));
495 if (EFI_ERROR (Status)) {
496 DEBUG ((DEBUG_ERROR,
"XhcPeiRecoverHaltedEndpoint: Reset Endpoint Failed, Status = %r\n", Status));
504 if (EFI_ERROR (Status)) {
505 DEBUG ((DEBUG_ERROR,
"XhcPeiRecoverHaltedEndpoint: Set Dequeue Pointer Failed, Status = %r\n", Status));
544 return EFI_DEVICE_ERROR;
549 DEBUG ((DEBUG_INFO,
"XhcPeiDequeueTrbFromEndpoint: Stop Slot = %x, Dci = %x\n", SlotId, Dci));
555 if (EFI_ERROR (Status)) {
556 DEBUG ((DEBUG_ERROR,
"XhcPeiDequeueTrbFromEndpoint: Stop Endpoint Failed, Status = %r\n", Status));
564 if (EFI_ERROR (Status)) {
565 DEBUG ((DEBUG_ERROR,
"XhcPeiDequeueTrbFromEndpoint: Set Dequeue Pointer Failed, Status = %r\n", Status));
597 CheckedTrb = Urb->Ring->RingSeg0;
599 ASSERT (Urb->Ring->TrbNumber == CMD_RING_TRB_NUMBER || Urb->Ring->TrbNumber == TR_RING_TRB_NUMBER);
601 for (Index = 0; Index < Urb->Ring->TrbNumber; Index++) {
602 if (Trb == CheckedTrb) {
639 ASSERT ((Xhc !=
NULL) && (Urb !=
NULL));
650 Urb->Result |= EFI_USB_ERR_SYSTEM;
658 for (Index = 0; Index < Xhc->EventRing.TrbNumber; Index++) {
660 if (Status == EFI_NOT_READY) {
670 if ((EvtTrb->Type != TRB_TYPE_COMMAND_COMPLT_EVENT) && (EvtTrb->Type != TRB_TYPE_TRANS_EVENT)) {
692 switch (EvtTrb->Completecode) {
693 case TRB_COMPLETION_STALL_ERROR:
694 CheckedUrb->Result |= EFI_USB_ERR_STALL;
695 CheckedUrb->Finished =
TRUE;
696 DEBUG ((DEBUG_ERROR,
"XhcPeiCheckUrbResult: STALL_ERROR! Completecode = %x\n", EvtTrb->Completecode));
699 case TRB_COMPLETION_BABBLE_ERROR:
700 CheckedUrb->Result |= EFI_USB_ERR_BABBLE;
701 CheckedUrb->Finished =
TRUE;
702 DEBUG ((DEBUG_ERROR,
"XhcPeiCheckUrbResult: BABBLE_ERROR! Completecode = %x\n", EvtTrb->Completecode));
705 case TRB_COMPLETION_DATA_BUFFER_ERROR:
706 CheckedUrb->Result |= EFI_USB_ERR_BUFFER;
707 CheckedUrb->Finished =
TRUE;
708 DEBUG ((DEBUG_ERROR,
"XhcPeiCheckUrbResult: ERR_BUFFER! Completecode = %x\n", EvtTrb->Completecode));
711 case TRB_COMPLETION_USB_TRANSACTION_ERROR:
712 CheckedUrb->Result |= EFI_USB_ERR_TIMEOUT;
713 CheckedUrb->Finished =
TRUE;
714 DEBUG ((DEBUG_ERROR,
"XhcPeiCheckUrbResult: TRANSACTION_ERROR! Completecode = %x\n", EvtTrb->Completecode));
717 case TRB_COMPLETION_SHORT_PACKET:
718 case TRB_COMPLETION_SUCCESS:
719 if (EvtTrb->Completecode == TRB_COMPLETION_SHORT_PACKET) {
720 DEBUG ((DEBUG_VERBOSE,
"XhcPeiCheckUrbResult: short packet happens!\n"));
723 TRBType = (UINT8)(TRBPtr->Type);
724 if ((TRBType == TRB_TYPE_DATA_STAGE) ||
725 (TRBType == TRB_TYPE_NORMAL) ||
726 (TRBType == TRB_TYPE_ISOCH))
734 DEBUG ((DEBUG_ERROR,
"XhcPeiCheckUrbResult: Transfer Default Error Occur! Completecode = 0x%x!\n", EvtTrb->Completecode));
735 CheckedUrb->Result |= EFI_USB_ERR_TIMEOUT;
736 CheckedUrb->Finished =
TRUE;
743 if (TRBPtr == CheckedUrb->TrbStart) {
744 CheckedUrb->StartDone =
TRUE;
747 if (TRBPtr == CheckedUrb->TrbEnd) {
748 CheckedUrb->EndDone =
TRUE;
751 if (CheckedUrb->StartDone && CheckedUrb->EndDone) {
752 CheckedUrb->Finished =
TRUE;
767 XhcDequeue = (UINT64)(
LShiftU64 ((UINT64)High, 32) | Low);
771 if ((XhcDequeue & (~0x0F)) != (PhyAddr & (~0x0F))) {
780 return Urb->Finished;
799 IN BOOLEAN CmdTransfer,
817 return EFI_DEVICE_ERROR;
824 Loop = Timeout * XHC_1_MILLISECOND;
831 for (Index = 0; Index < Loop; Index++) {
841 Urb->Result = EFI_USB_ERR_TIMEOUT;
842 Status = EFI_TIMEOUT;
843 }
else if (Urb->Result != EFI_USB_NOERROR) {
844 Status = EFI_DEVICE_ERROR;
875 DEBUG ((DEBUG_INFO,
"XhcPeiPollPortStatusChange: PortChangeStatus: %x PortStatus: %x\n", PortState->PortChangeStatus, PortState->PortStatus));
879 if ((PortState->PortChangeStatus & (
USB_PORT_STAT_C_CONNECTION | USB_PORT_STAT_C_ENABLE | USB_PORT_STAT_C_OVERCURRENT | USB_PORT_STAT_C_RESET)) == 0) {
883 if (ParentRouteChart.Dword == 0) {
884 RouteChart.Route.RouteString = 0;
885 RouteChart.Route.RootPortNum = Port + 1;
886 RouteChart.Route.TierNum = 1;
889 RouteChart.Route.RouteString = ParentRouteChart.Route.RouteString | (Port << (4 * (ParentRouteChart.Route.TierNum - 1)));
891 RouteChart.Route.RouteString = ParentRouteChart.Route.RouteString | (15 << (4 * (ParentRouteChart.Route.TierNum - 1)));
894 RouteChart.Route.RootPortNum = ParentRouteChart.Route.RootPortNum;
895 RouteChart.Route.TierNum = ParentRouteChart.Route.TierNum + 1;
900 if (Xhc->HcCParams.Data.Csz == 0) {
907 if (((PortState->PortStatus & USB_PORT_STAT_ENABLE) != 0) &&
913 Speed = EFI_USB_SPEED_FULL;
914 if ((PortState->PortStatus & USB_PORT_STAT_LOW_SPEED) != 0) {
915 Speed = EFI_USB_SPEED_LOW;
916 }
else if ((PortState->PortStatus & USB_PORT_STAT_HIGH_SPEED) != 0) {
917 Speed = EFI_USB_SPEED_HIGH;
918 }
else if ((PortState->PortStatus & USB_PORT_STAT_SUPER_SPEED) != 0) {
926 if ((SlotId == 0) && ((PortState->PortChangeStatus & USB_PORT_STAT_C_RESET) != 0)) {
927 if (Xhc->HcCParams.Data.Csz == 0) {
955 ASSERT (EpAddr <= 15);
960 Index = (UINT8)(2 * EpAddr);
961 if (Direction == EfiUsbDataIn) {
986 for (Index = 0; Index < 255; Index++) {
987 if (Xhc->UsbDevContext[Index + 1].Enabled &&
988 (Xhc->UsbDevContext[Index + 1].SlotId != 0) &&
989 (Xhc->UsbDevContext[Index + 1].BusDevAddr == BusDevAddr))
999 return Xhc->UsbDevContext[Index + 1].SlotId;
1019 for (Index = 0; Index < 255; Index++) {
1020 if (Xhc->UsbDevContext[Index + 1].Enabled &&
1021 (Xhc->UsbDevContext[Index + 1].SlotId != 0) &&
1022 (Xhc->UsbDevContext[Index + 1].RouteString.Dword == RouteString.Dword))
1032 return Xhc->UsbDevContext[Index + 1].SlotId;
1074 IN UINT16 ParentPort,
1076 IN UINT8 DeviceSpeed
1085 UINT8 DeviceAddress;
1093 CmdTrb.CycleBit = 1;
1094 CmdTrb.Type = TRB_TYPE_EN_SLOT;
1099 XHC_GENERIC_TIMEOUT,
1102 if (EFI_ERROR (Status)) {
1103 DEBUG ((DEBUG_ERROR,
"XhcPeiInitializeDeviceSlot: Enable Slot Failed, Status = %r\n", Status));
1107 ASSERT (EvtTrb->SlotId <= Xhc->MaxSlotsEn);
1108 DEBUG ((DEBUG_INFO,
"XhcPeiInitializeDeviceSlot: Enable Slot Successfully, The Slot ID = 0x%x\n", EvtTrb->SlotId));
1109 SlotId = (UINT8)EvtTrb->SlotId;
1110 ASSERT (SlotId != 0);
1113 Xhc->UsbDevContext[SlotId].Enabled =
TRUE;
1114 Xhc->UsbDevContext[SlotId].SlotId = SlotId;
1115 Xhc->UsbDevContext[SlotId].RouteString.Dword = RouteChart.Dword;
1116 Xhc->UsbDevContext[SlotId].ParentRouteString.Dword = ParentRouteChart.Dword;
1123 ASSERT (InputContext !=
NULL);
1124 ASSERT (((
UINTN)InputContext & 0x3F) == 0);
1127 Xhc->UsbDevContext[SlotId].InputContext = (VOID *)InputContext;
1134 InputContext->InputControlContext.Dword2 |= (BIT0 | BIT1);
1139 InputContext->Slot.RouteString = RouteChart.Route.RouteString;
1140 InputContext->Slot.Speed = DeviceSpeed + 1;
1141 InputContext->Slot.ContextEntries = 1;
1142 InputContext->Slot.RootHubPortNum = RouteChart.Route.RootPortNum;
1144 if (RouteChart.Route.RouteString != 0) {
1149 ASSERT (ParentSlotId != 0);
1153 ParentDeviceContext = (
DEVICE_CONTEXT *)Xhc->UsbDevContext[ParentSlotId].OutputContext;
1154 if ((ParentDeviceContext->Slot.TTPortNum == 0) &&
1155 (ParentDeviceContext->Slot.TTHubSlotId == 0))
1157 if ((ParentDeviceContext->Slot.Speed == (EFI_USB_SPEED_HIGH + 1)) && (DeviceSpeed < EFI_USB_SPEED_HIGH)) {
1162 InputContext->Slot.TTPortNum = ParentPort;
1163 InputContext->Slot.TTHubSlotId = ParentSlotId;
1169 InputContext->Slot.TTPortNum = ParentDeviceContext->Slot.TTPortNum;
1170 InputContext->Slot.TTHubSlotId = ParentDeviceContext->Slot.TTHubSlotId;
1174 if (DeviceSpeed == EFI_USB_SPEED_HIGH) {
1175 InputContext->Slot.Speed = ParentDeviceContext->Slot.Speed;
1184 Xhc->UsbDevContext[SlotId].EndpointTransferRing[0] = EndpointTransferRing;
1189 InputContext->EP[0].EPType = ED_CONTROL_BIDIR;
1192 InputContext->EP[0].MaxPacketSize = 512;
1193 }
else if (DeviceSpeed == EFI_USB_SPEED_HIGH) {
1194 InputContext->EP[0].MaxPacketSize = 64;
1196 InputContext->EP[0].MaxPacketSize = 8;
1203 InputContext->EP[0].AverageTRBLength = 8;
1204 InputContext->EP[0].MaxBurstSize = 0;
1205 InputContext->EP[0].Interval = 0;
1206 InputContext->EP[0].MaxPStreams = 0;
1207 InputContext->EP[0].Mult = 0;
1208 InputContext->EP[0].CErr = 3;
1215 ((
TRANSFER_RING *)(
UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[0])->RingSeg0,
1219 InputContext->EP[0].PtrLo = XHC_LOW_32BIT (PhyAddr) | BIT0;
1220 InputContext->EP[0].PtrHi = XHC_HIGH_32BIT (PhyAddr);
1226 ASSERT (OutputContext !=
NULL);
1227 ASSERT (((
UINTN)OutputContext & 0x3F) == 0);
1230 Xhc->UsbDevContext[SlotId].OutputContext = OutputContext;
1239 Xhc->DCBAA[SlotId] = (UINT64)(
UINTN)PhyAddr;
1249 ZeroMem (&CmdTrbAddr,
sizeof (CmdTrbAddr));
1251 CmdTrbAddr.PtrLo = XHC_LOW_32BIT (PhyAddr);
1252 CmdTrbAddr.PtrHi = XHC_HIGH_32BIT (PhyAddr);
1253 CmdTrbAddr.CycleBit = 1;
1254 CmdTrbAddr.Type = TRB_TYPE_ADDRESS_DEV;
1255 CmdTrbAddr.SlotId = Xhc->UsbDevContext[SlotId].SlotId;
1259 XHC_GENERIC_TIMEOUT,
1262 if (!EFI_ERROR (Status)) {
1263 DeviceAddress = (UINT8)OutputContext->Slot.DeviceAddress;
1264 DEBUG ((DEBUG_INFO,
"XhcPeiInitializeDeviceSlot: Address %d assigned successfully\n", DeviceAddress));
1265 Xhc->UsbDevContext[SlotId].XhciDevAddr = DeviceAddress;
1268 DEBUG ((DEBUG_INFO,
"XhcPeiInitializeDeviceSlot: Enable Slot, Status = %r\n", Status));
1289 IN UINT16 ParentPort,
1291 IN UINT8 DeviceSpeed
1300 UINT8 DeviceAddress;
1308 CmdTrb.CycleBit = 1;
1309 CmdTrb.Type = TRB_TYPE_EN_SLOT;
1314 XHC_GENERIC_TIMEOUT,
1317 if (EFI_ERROR (Status)) {
1318 DEBUG ((DEBUG_ERROR,
"XhcPeiInitializeDeviceSlot64: Enable Slot Failed, Status = %r\n", Status));
1322 ASSERT (EvtTrb->SlotId <= Xhc->MaxSlotsEn);
1323 DEBUG ((DEBUG_INFO,
"XhcPeiInitializeDeviceSlot64: Enable Slot Successfully, The Slot ID = 0x%x\n", EvtTrb->SlotId));
1324 SlotId = (UINT8)EvtTrb->SlotId;
1325 ASSERT (SlotId != 0);
1328 Xhc->UsbDevContext[SlotId].Enabled =
TRUE;
1329 Xhc->UsbDevContext[SlotId].SlotId = SlotId;
1330 Xhc->UsbDevContext[SlotId].RouteString.Dword = RouteChart.Dword;
1331 Xhc->UsbDevContext[SlotId].ParentRouteString.Dword = ParentRouteChart.Dword;
1338 ASSERT (InputContext !=
NULL);
1339 ASSERT (((
UINTN)InputContext & 0x3F) == 0);
1342 Xhc->UsbDevContext[SlotId].InputContext = (VOID *)InputContext;
1349 InputContext->InputControlContext.Dword2 |= (BIT0 | BIT1);
1354 InputContext->Slot.RouteString = RouteChart.Route.RouteString;
1355 InputContext->Slot.Speed = DeviceSpeed + 1;
1356 InputContext->Slot.ContextEntries = 1;
1357 InputContext->Slot.RootHubPortNum = RouteChart.Route.RootPortNum;
1359 if (RouteChart.Route.RouteString != 0) {
1364 ASSERT (ParentSlotId != 0);
1368 ParentDeviceContext = (
DEVICE_CONTEXT_64 *)Xhc->UsbDevContext[ParentSlotId].OutputContext;
1369 if ((ParentDeviceContext->Slot.TTPortNum == 0) &&
1370 (ParentDeviceContext->Slot.TTHubSlotId == 0))
1372 if ((ParentDeviceContext->Slot.Speed == (EFI_USB_SPEED_HIGH + 1)) && (DeviceSpeed < EFI_USB_SPEED_HIGH)) {
1377 InputContext->Slot.TTPortNum = ParentPort;
1378 InputContext->Slot.TTHubSlotId = ParentSlotId;
1384 InputContext->Slot.TTPortNum = ParentDeviceContext->Slot.TTPortNum;
1385 InputContext->Slot.TTHubSlotId = ParentDeviceContext->Slot.TTHubSlotId;
1389 if (DeviceSpeed == EFI_USB_SPEED_HIGH) {
1390 InputContext->Slot.Speed = ParentDeviceContext->Slot.Speed;
1399 Xhc->UsbDevContext[SlotId].EndpointTransferRing[0] = EndpointTransferRing;
1404 InputContext->EP[0].EPType = ED_CONTROL_BIDIR;
1407 InputContext->EP[0].MaxPacketSize = 512;
1408 }
else if (DeviceSpeed == EFI_USB_SPEED_HIGH) {
1409 InputContext->EP[0].MaxPacketSize = 64;
1411 InputContext->EP[0].MaxPacketSize = 8;
1418 InputContext->EP[0].AverageTRBLength = 8;
1419 InputContext->EP[0].MaxBurstSize = 0;
1420 InputContext->EP[0].Interval = 0;
1421 InputContext->EP[0].MaxPStreams = 0;
1422 InputContext->EP[0].Mult = 0;
1423 InputContext->EP[0].CErr = 3;
1430 ((
TRANSFER_RING *)(
UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[0])->RingSeg0,
1434 InputContext->EP[0].PtrLo = XHC_LOW_32BIT (PhyAddr) | BIT0;
1435 InputContext->EP[0].PtrHi = XHC_HIGH_32BIT (PhyAddr);
1441 ASSERT (OutputContext !=
NULL);
1442 ASSERT (((
UINTN)OutputContext & 0x3F) == 0);
1445 Xhc->UsbDevContext[SlotId].OutputContext = OutputContext;
1454 Xhc->DCBAA[SlotId] = (UINT64)(
UINTN)PhyAddr;
1464 ZeroMem (&CmdTrbAddr,
sizeof (CmdTrbAddr));
1466 CmdTrbAddr.PtrLo = XHC_LOW_32BIT (PhyAddr);
1467 CmdTrbAddr.PtrHi = XHC_HIGH_32BIT (PhyAddr);
1468 CmdTrbAddr.CycleBit = 1;
1469 CmdTrbAddr.Type = TRB_TYPE_ADDRESS_DEV;
1470 CmdTrbAddr.SlotId = Xhc->UsbDevContext[SlotId].SlotId;
1474 XHC_GENERIC_TIMEOUT,
1477 if (!EFI_ERROR (Status)) {
1478 DeviceAddress = (UINT8)OutputContext->Slot.DeviceAddress;
1479 DEBUG ((DEBUG_INFO,
"XhcPeiInitializeDeviceSlot64: Address %d assigned successfully\n", DeviceAddress));
1480 Xhc->UsbDevContext[SlotId].XhciDevAddr = DeviceAddress;
1483 DEBUG ((DEBUG_INFO,
"XhcPeiInitializeDeviceSlot64: Enable Slot, Status = %r\n", Status));
1512 for (Index = 0; Index < 255; Index++) {
1513 if (!Xhc->UsbDevContext[Index + 1].Enabled ||
1514 (Xhc->UsbDevContext[Index + 1].SlotId == 0) ||
1515 (Xhc->UsbDevContext[Index + 1].ParentRouteString.Dword != Xhc->UsbDevContext[SlotId].RouteString.Dword))
1522 if (EFI_ERROR (Status)) {
1523 DEBUG ((DEBUG_ERROR,
"XhcPeiDisableSlotCmd: failed to disable child, ignore error\n"));
1524 Xhc->UsbDevContext[Index + 1].SlotId = 0;
1531 DEBUG ((DEBUG_INFO,
"XhcPeiDisableSlotCmd: Disable device slot %d!\n", SlotId));
1533 ZeroMem (&CmdTrbDisSlot,
sizeof (CmdTrbDisSlot));
1534 CmdTrbDisSlot.CycleBit = 1;
1535 CmdTrbDisSlot.Type = TRB_TYPE_DIS_SLOT;
1536 CmdTrbDisSlot.SlotId = SlotId;
1540 XHC_GENERIC_TIMEOUT,
1543 if (EFI_ERROR (Status)) {
1544 DEBUG ((DEBUG_ERROR,
"XhcPeiDisableSlotCmd: Disable Slot Command Failed, Status = %r\n", Status));
1551 Xhc->DCBAA[SlotId] = 0;
1556 for (Index = 0; Index < 31; Index++) {
1557 if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index] !=
NULL) {
1558 RingSeg = ((
TRANSFER_RING *)(
UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index])->RingSeg0;
1559 if (RingSeg !=
NULL) {
1563 FreePool (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index]);
1564 Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index] =
NULL;
1568 for (Index = 0; Index < Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations; Index++) {
1569 if (Xhc->UsbDevContext[SlotId].ConfDesc[Index] !=
NULL) {
1570 FreePool (Xhc->UsbDevContext[SlotId].ConfDesc[Index]);
1574 if (Xhc->UsbDevContext[SlotId].InputContext !=
NULL) {
1578 if (Xhc->UsbDevContext[SlotId].OutputContext !=
NULL) {
1587 Xhc->UsbDevContext[SlotId].Enabled =
FALSE;
1588 Xhc->UsbDevContext[SlotId].SlotId = 0;
1590 DEBUG ((DEBUG_INFO,
"XhcPeiDisableSlotCmd: Disable Slot Command, Status = %r\n", Status));
1619 for (Index = 0; Index < 255; Index++) {
1620 if (!Xhc->UsbDevContext[Index + 1].Enabled ||
1621 (Xhc->UsbDevContext[Index + 1].SlotId == 0) ||
1622 (Xhc->UsbDevContext[Index + 1].ParentRouteString.Dword != Xhc->UsbDevContext[SlotId].RouteString.Dword))
1629 if (EFI_ERROR (Status)) {
1630 DEBUG ((DEBUG_ERROR,
"XhcPeiDisableSlotCmd64: failed to disable child, ignore error\n"));
1631 Xhc->UsbDevContext[Index + 1].SlotId = 0;
1638 DEBUG ((DEBUG_INFO,
"XhcPeiDisableSlotCmd64: Disable device slot %d!\n", SlotId));
1640 ZeroMem (&CmdTrbDisSlot,
sizeof (CmdTrbDisSlot));
1641 CmdTrbDisSlot.CycleBit = 1;
1642 CmdTrbDisSlot.Type = TRB_TYPE_DIS_SLOT;
1643 CmdTrbDisSlot.SlotId = SlotId;
1647 XHC_GENERIC_TIMEOUT,
1650 if (EFI_ERROR (Status)) {
1651 DEBUG ((DEBUG_ERROR,
"XhcPeiDisableSlotCmd64: Disable Slot Command Failed, Status = %r\n", Status));
1658 Xhc->DCBAA[SlotId] = 0;
1663 for (Index = 0; Index < 31; Index++) {
1664 if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index] !=
NULL) {
1665 RingSeg = ((
TRANSFER_RING *)(
UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index])->RingSeg0;
1666 if (RingSeg !=
NULL) {
1670 FreePool (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index]);
1671 Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index] =
NULL;
1675 for (Index = 0; Index < Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations; Index++) {
1676 if (Xhc->UsbDevContext[SlotId].ConfDesc[Index] !=
NULL) {
1677 FreePool (Xhc->UsbDevContext[SlotId].ConfDesc[Index]);
1681 if (Xhc->UsbDevContext[SlotId].InputContext !=
NULL) {
1685 if (Xhc->UsbDevContext[SlotId].OutputContext !=
NULL) {
1694 Xhc->UsbDevContext[SlotId].Enabled =
FALSE;
1695 Xhc->UsbDevContext[SlotId].SlotId = 0;
1697 DEBUG ((DEBUG_INFO,
"XhcPeiDisableSlotCmd64: Disable Slot Command, Status = %r\n", Status));
1716 IN UINT8 DeviceSpeed,
1742 InputContext = Xhc->UsbDevContext[SlotId].InputContext;
1743 OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;
1747 ASSERT (ConfigDesc !=
NULL);
1752 for (Index = 0; Index < ConfigDesc->NumInterfaces; Index++) {
1753 while ((IfDesc->DescriptorType != USB_DESC_TYPE_INTERFACE) || (IfDesc->AlternateSetting != 0)) {
1757 NumEp = IfDesc->NumEndpoints;
1758 if ((NumEp == 0) && (MaxDci == 0)) {
1763 for (EpIndex = 0; EpIndex < NumEp; EpIndex++) {
1764 while (EpDesc->DescriptorType != USB_DESC_TYPE_ENDPOINT) {
1768 EpAddr = (UINT8)(EpDesc->EndpointAddress & 0x0F);
1769 Direction = (UINT8)((EpDesc->EndpointAddress & 0x80) ? EfiUsbDataIn : EfiUsbDataOut);
1776 InputContext->InputControlContext.Dword2 |= (BIT0 << Dci);
1777 InputContext->EP[Dci-1].MaxPacketSize = EpDesc->MaxPacketSize;
1783 InputContext->EP[Dci-1].MaxBurstSize = 0x0;
1785 InputContext->EP[Dci-1].MaxBurstSize = 0x0;
1788 switch (EpDesc->Attributes & USB_ENDPOINT_TYPE_MASK) {
1789 case USB_ENDPOINT_BULK:
1790 if (Direction == EfiUsbDataIn) {
1791 InputContext->EP[Dci-1].CErr = 3;
1792 InputContext->EP[Dci-1].EPType = ED_BULK_IN;
1794 InputContext->EP[Dci-1].CErr = 3;
1795 InputContext->EP[Dci-1].EPType = ED_BULK_OUT;
1798 InputContext->EP[Dci-1].AverageTRBLength = 0x1000;
1799 if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] ==
NULL) {
1801 Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *)EndpointTransferRing;
1806 case USB_ENDPOINT_ISO:
1807 if (Direction == EfiUsbDataIn) {
1808 InputContext->EP[Dci-1].CErr = 0;
1809 InputContext->EP[Dci-1].EPType = ED_ISOCH_IN;
1811 InputContext->EP[Dci-1].CErr = 0;
1812 InputContext->EP[Dci-1].EPType = ED_ISOCH_OUT;
1819 if (DeviceSpeed == EFI_USB_SPEED_FULL) {
1820 Interval = EpDesc->Interval;
1821 ASSERT (Interval >= 1 && Interval <= 16);
1822 InputContext->EP[Dci-1].Interval = Interval + 2;
1824 Interval = EpDesc->Interval;
1825 ASSERT (Interval >= 1 && Interval <= 16);
1826 InputContext->EP[Dci-1].Interval = Interval - 1;
1832 DEBUG ((DEBUG_INFO,
"XhcPeiSetConfigCmd: Unsupport ISO EP found, Transfer ring is not allocated.\n"));
1835 case USB_ENDPOINT_INTERRUPT:
1836 if (Direction == EfiUsbDataIn) {
1837 InputContext->EP[Dci-1].CErr = 3;
1838 InputContext->EP[Dci-1].EPType = ED_INTERRUPT_IN;
1840 InputContext->EP[Dci-1].CErr = 3;
1841 InputContext->EP[Dci-1].EPType = ED_INTERRUPT_OUT;
1844 InputContext->EP[Dci-1].AverageTRBLength = 0x1000;
1845 InputContext->EP[Dci-1].MaxESITPayload = EpDesc->MaxPacketSize;
1849 if ((DeviceSpeed == EFI_USB_SPEED_FULL) || (DeviceSpeed == EFI_USB_SPEED_LOW)) {
1850 Interval = EpDesc->Interval;
1854 ASSERT (Interval != 0);
1855 InputContext->EP[Dci-1].Interval = (UINT32)
HighBitSet32 ((UINT32)Interval) + 3;
1857 Interval = EpDesc->Interval;
1858 ASSERT (Interval >= 1 && Interval <= 16);
1862 InputContext->EP[Dci-1].Interval = Interval - 1;
1865 if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] ==
NULL) {
1867 Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *)EndpointTransferRing;
1873 case USB_ENDPOINT_CONTROL:
1877 DEBUG ((DEBUG_INFO,
"XhcPeiSetConfigCmd: Unsupport Control EP found, Transfer ring is not allocated.\n"));
1879 DEBUG ((DEBUG_INFO,
"XhcPeiSetConfigCmd: Unknown EP found, Transfer ring is not allocated.\n"));
1886 ((
TRANSFER_RING *)(
UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0,
1892 InputContext->EP[Dci-1].PtrLo = XHC_LOW_32BIT (PhyAddr);
1893 InputContext->EP[Dci-1].PtrHi = XHC_HIGH_32BIT (PhyAddr);
1901 InputContext->InputControlContext.Dword2 |= BIT0;
1902 InputContext->Slot.ContextEntries = MaxDci;
1906 ZeroMem (&CmdTrbCfgEP,
sizeof (CmdTrbCfgEP));
1908 CmdTrbCfgEP.PtrLo = XHC_LOW_32BIT (PhyAddr);
1909 CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (PhyAddr);
1910 CmdTrbCfgEP.CycleBit = 1;
1911 CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT;
1912 CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId;
1913 DEBUG ((DEBUG_INFO,
"XhcSetConfigCmd: Configure Endpoint\n"));
1917 XHC_GENERIC_TIMEOUT,
1920 if (EFI_ERROR (Status)) {
1921 DEBUG ((DEBUG_ERROR,
"XhcSetConfigCmd: Config Endpoint Failed, Status = %r\n", Status));
1942 IN UINT8 DeviceSpeed,
1968 InputContext = Xhc->UsbDevContext[SlotId].InputContext;
1969 OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;
1973 ASSERT (ConfigDesc !=
NULL);
1978 for (Index = 0; Index < ConfigDesc->NumInterfaces; Index++) {
1979 while ((IfDesc->DescriptorType != USB_DESC_TYPE_INTERFACE) || (IfDesc->AlternateSetting != 0)) {
1983 NumEp = IfDesc->NumEndpoints;
1984 if ((NumEp == 0) && (MaxDci == 0)) {
1989 for (EpIndex = 0; EpIndex < NumEp; EpIndex++) {
1990 while (EpDesc->DescriptorType != USB_DESC_TYPE_ENDPOINT) {
1994 EpAddr = (UINT8)(EpDesc->EndpointAddress & 0x0F);
1995 Direction = (UINT8)((EpDesc->EndpointAddress & 0x80) ? EfiUsbDataIn : EfiUsbDataOut);
2003 InputContext->InputControlContext.Dword2 |= (BIT0 << Dci);
2004 InputContext->EP[Dci-1].MaxPacketSize = EpDesc->MaxPacketSize;
2010 InputContext->EP[Dci-1].MaxBurstSize = 0x0;
2012 InputContext->EP[Dci-1].MaxBurstSize = 0x0;
2015 switch (EpDesc->Attributes & USB_ENDPOINT_TYPE_MASK) {
2016 case USB_ENDPOINT_BULK:
2017 if (Direction == EfiUsbDataIn) {
2018 InputContext->EP[Dci-1].CErr = 3;
2019 InputContext->EP[Dci-1].EPType = ED_BULK_IN;
2021 InputContext->EP[Dci-1].CErr = 3;
2022 InputContext->EP[Dci-1].EPType = ED_BULK_OUT;
2025 InputContext->EP[Dci-1].AverageTRBLength = 0x1000;
2026 if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] ==
NULL) {
2028 Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *)EndpointTransferRing;
2033 case USB_ENDPOINT_ISO:
2034 if (Direction == EfiUsbDataIn) {
2035 InputContext->EP[Dci-1].CErr = 0;
2036 InputContext->EP[Dci-1].EPType = ED_ISOCH_IN;
2038 InputContext->EP[Dci-1].CErr = 0;
2039 InputContext->EP[Dci-1].EPType = ED_ISOCH_OUT;
2046 if (DeviceSpeed == EFI_USB_SPEED_FULL) {
2047 Interval = EpDesc->Interval;
2048 ASSERT (Interval >= 1 && Interval <= 16);
2049 InputContext->EP[Dci-1].Interval = Interval + 2;
2051 Interval = EpDesc->Interval;
2052 ASSERT (Interval >= 1 && Interval <= 16);
2053 InputContext->EP[Dci-1].Interval = Interval - 1;
2059 DEBUG ((DEBUG_INFO,
"XhcPeiSetConfigCmd64: Unsupport ISO EP found, Transfer ring is not allocated.\n"));
2062 case USB_ENDPOINT_INTERRUPT:
2063 if (Direction == EfiUsbDataIn) {
2064 InputContext->EP[Dci-1].CErr = 3;
2065 InputContext->EP[Dci-1].EPType = ED_INTERRUPT_IN;
2067 InputContext->EP[Dci-1].CErr = 3;
2068 InputContext->EP[Dci-1].EPType = ED_INTERRUPT_OUT;
2071 InputContext->EP[Dci-1].AverageTRBLength = 0x1000;
2072 InputContext->EP[Dci-1].MaxESITPayload = EpDesc->MaxPacketSize;
2076 if ((DeviceSpeed == EFI_USB_SPEED_FULL) || (DeviceSpeed == EFI_USB_SPEED_LOW)) {
2077 Interval = EpDesc->Interval;
2081 ASSERT (Interval != 0);
2082 InputContext->EP[Dci-1].Interval = (UINT32)
HighBitSet32 ((UINT32)Interval) + 3;
2084 Interval = EpDesc->Interval;
2085 ASSERT (Interval >= 1 && Interval <= 16);
2089 InputContext->EP[Dci-1].Interval = Interval - 1;
2092 if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] ==
NULL) {
2094 Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *)EndpointTransferRing;
2100 case USB_ENDPOINT_CONTROL:
2104 DEBUG ((DEBUG_INFO,
"XhcPeiSetConfigCmd64: Unsupport Control EP found, Transfer ring is not allocated.\n"));
2106 DEBUG ((DEBUG_INFO,
"XhcPeiSetConfigCmd64: Unknown EP found, Transfer ring is not allocated.\n"));
2113 ((
TRANSFER_RING *)(
UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0,
2121 InputContext->EP[Dci-1].PtrLo = XHC_LOW_32BIT (PhyAddr);
2122 InputContext->EP[Dci-1].PtrHi = XHC_HIGH_32BIT (PhyAddr);
2130 InputContext->InputControlContext.Dword2 |= BIT0;
2131 InputContext->Slot.ContextEntries = MaxDci;
2135 ZeroMem (&CmdTrbCfgEP,
sizeof (CmdTrbCfgEP));
2137 CmdTrbCfgEP.PtrLo = XHC_LOW_32BIT (PhyAddr);
2138 CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (PhyAddr);
2139 CmdTrbCfgEP.CycleBit = 1;
2140 CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT;
2141 CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId;
2142 DEBUG ((DEBUG_INFO,
"XhcSetConfigCmd64: Configure Endpoint\n"));
2146 XHC_GENERIC_TIMEOUT,
2149 if (EFI_ERROR (Status)) {
2150 DEBUG ((DEBUG_ERROR,
"XhcSetConfigCmd64: Config Endpoint Failed, Status = %r\n", Status));
2170 IN UINT32 MaxPacketSize
2179 ASSERT (Xhc->UsbDevContext[SlotId].SlotId != 0);
2184 InputContext = Xhc->UsbDevContext[SlotId].InputContext;
2187 InputContext->InputControlContext.Dword2 |= BIT1;
2188 InputContext->EP[0].MaxPacketSize = MaxPacketSize;
2190 ZeroMem (&CmdTrbEvalu,
sizeof (CmdTrbEvalu));
2192 CmdTrbEvalu.PtrLo = XHC_LOW_32BIT (PhyAddr);
2193 CmdTrbEvalu.PtrHi = XHC_HIGH_32BIT (PhyAddr);
2194 CmdTrbEvalu.CycleBit = 1;
2195 CmdTrbEvalu.Type = TRB_TYPE_EVALU_CONTXT;
2196 CmdTrbEvalu.SlotId = Xhc->UsbDevContext[SlotId].SlotId;
2197 DEBUG ((DEBUG_INFO,
"XhcEvaluateContext: Evaluate context\n"));
2201 XHC_GENERIC_TIMEOUT,
2204 if (EFI_ERROR (Status)) {
2205 DEBUG ((DEBUG_ERROR,
"XhcEvaluateContext: Evaluate Context Failed, Status = %r\n", Status));
2225 IN UINT32 MaxPacketSize
2234 ASSERT (Xhc->UsbDevContext[SlotId].SlotId != 0);
2239 InputContext = Xhc->UsbDevContext[SlotId].InputContext;
2242 InputContext->InputControlContext.Dword2 |= BIT1;
2243 InputContext->EP[0].MaxPacketSize = MaxPacketSize;
2245 ZeroMem (&CmdTrbEvalu,
sizeof (CmdTrbEvalu));
2247 CmdTrbEvalu.PtrLo = XHC_LOW_32BIT (PhyAddr);
2248 CmdTrbEvalu.PtrHi = XHC_HIGH_32BIT (PhyAddr);
2249 CmdTrbEvalu.CycleBit = 1;
2250 CmdTrbEvalu.Type = TRB_TYPE_EVALU_CONTXT;
2251 CmdTrbEvalu.SlotId = Xhc->UsbDevContext[SlotId].SlotId;
2252 DEBUG ((DEBUG_INFO,
"XhcEvaluateContext64: Evaluate context 64\n"));
2256 XHC_GENERIC_TIMEOUT,
2259 if (EFI_ERROR (Status)) {
2260 DEBUG ((DEBUG_ERROR,
"XhcEvaluateContext64: Evaluate Context Failed, Status = %r\n", Status));
2294 ASSERT (Xhc->UsbDevContext[SlotId].SlotId != 0);
2295 InputContext = Xhc->UsbDevContext[SlotId].InputContext;
2296 OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;
2303 InputContext->InputControlContext.Dword2 |= BIT0;
2309 InputContext->Slot.Hub = 1;
2310 InputContext->Slot.PortNum = PortNum;
2311 InputContext->Slot.TTT = TTT;
2312 InputContext->Slot.MTT = MTT;
2314 ZeroMem (&CmdTrbCfgEP,
sizeof (CmdTrbCfgEP));
2316 CmdTrbCfgEP.PtrLo = XHC_LOW_32BIT (PhyAddr);
2317 CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (PhyAddr);
2318 CmdTrbCfgEP.CycleBit = 1;
2319 CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT;
2320 CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId;
2321 DEBUG ((DEBUG_INFO,
"Configure Hub Slot Context\n"));
2325 XHC_GENERIC_TIMEOUT,
2328 if (EFI_ERROR (Status)) {
2329 DEBUG ((DEBUG_ERROR,
"XhcConfigHubContext: Config Endpoint Failed, Status = %r\n", Status));
2363 ASSERT (Xhc->UsbDevContext[SlotId].SlotId != 0);
2364 InputContext = Xhc->UsbDevContext[SlotId].InputContext;
2365 OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;
2372 InputContext->InputControlContext.Dword2 |= BIT0;
2378 InputContext->Slot.Hub = 1;
2379 InputContext->Slot.PortNum = PortNum;
2380 InputContext->Slot.TTT = TTT;
2381 InputContext->Slot.MTT = MTT;
2383 ZeroMem (&CmdTrbCfgEP,
sizeof (CmdTrbCfgEP));
2385 CmdTrbCfgEP.PtrLo = XHC_LOW_32BIT (PhyAddr);
2386 CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (PhyAddr);
2387 CmdTrbCfgEP.CycleBit = 1;
2388 CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT;
2389 CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId;
2390 DEBUG ((DEBUG_INFO,
"Configure Hub Slot Context 64\n"));
2394 XHC_GENERIC_TIMEOUT,
2397 if (EFI_ERROR (Status)) {
2398 DEBUG ((DEBUG_ERROR,
"XhcConfigHubContext64: Config Endpoint Failed, Status = %r\n", Status));
2427 DEBUG ((DEBUG_INFO,
"XhcPeiStopEndpoint: Slot = 0x%x, Dci = 0x%x\n", SlotId, Dci));
2432 ZeroMem (&CmdTrbStopED,
sizeof (CmdTrbStopED));
2433 CmdTrbStopED.CycleBit = 1;
2434 CmdTrbStopED.Type = TRB_TYPE_STOP_ENDPOINT;
2435 CmdTrbStopED.EDID = Dci;
2436 CmdTrbStopED.SlotId = SlotId;
2440 XHC_GENERIC_TIMEOUT,
2443 if (EFI_ERROR (Status)) {
2444 DEBUG ((DEBUG_ERROR,
"XhcPeiStopEndpoint: Stop Endpoint Failed, Status = %r\n", Status));
2473 DEBUG ((DEBUG_INFO,
"XhcPeiResetEndpoint: Slot = 0x%x, Dci = 0x%x\n", SlotId, Dci));
2478 ZeroMem (&CmdTrbResetED,
sizeof (CmdTrbResetED));
2479 CmdTrbResetED.CycleBit = 1;
2480 CmdTrbResetED.Type = TRB_TYPE_RESET_ENDPOINT;
2481 CmdTrbResetED.EDID = Dci;
2482 CmdTrbResetED.SlotId = SlotId;
2486 XHC_GENERIC_TIMEOUT,
2489 if (EFI_ERROR (Status)) {
2490 DEBUG ((DEBUG_ERROR,
"XhcPeiResetEndpoint: Reset Endpoint Failed, Status = %r\n", Status));
2523 DEBUG ((DEBUG_INFO,
"XhcPeiSetTrDequeuePointer: Slot = 0x%x, Dci = 0x%x, Urb = 0x%x\n", SlotId, Dci, Urb));
2528 ZeroMem (&CmdSetTRDeq,
sizeof (CmdSetTRDeq));
2530 CmdSetTRDeq.PtrLo = XHC_LOW_32BIT (PhyAddr) | Urb->Ring->RingPCS;
2531 CmdSetTRDeq.PtrHi = XHC_HIGH_32BIT (PhyAddr);
2532 CmdSetTRDeq.CycleBit = 1;
2533 CmdSetTRDeq.Type = TRB_TYPE_SET_TR_DEQUE;
2534 CmdSetTRDeq.Endpoint = Dci;
2535 CmdSetTRDeq.SlotId = SlotId;
2539 XHC_GENERIC_TIMEOUT,
2542 if (EFI_ERROR (Status)) {
2543 DEBUG ((DEBUG_ERROR,
"XhcPeiSetTrDequeuePointer: Set TR Dequeue Pointer Failed, Status = %r\n", Status));
2567 ASSERT (EvtRing !=
NULL);
2569 *NewEvtTrb = EvtRing->EventRingDequeue;
2571 if (EvtRing->EventRingDequeue == EvtRing->EventRingEnqueue) {
2572 return EFI_NOT_READY;
2575 EvtRing->EventRingDequeue++;
2579 if ((
UINTN)EvtRing->EventRingDequeue >= ((
UINTN)EvtRing->EventRingSeg0 + sizeof (
TRB_TEMPLATE) * EvtRing->TrbNumber)) {
2580 EvtRing->EventRingDequeue = EvtRing->EventRingSeg0;
2604 ASSERT (EvtRing !=
NULL);
2610 EvtTrb = EvtRing->EventRingDequeue;
2612 for (Index = 0; Index < EvtRing->TrbNumber; Index++) {
2613 if (EvtTrb->CycleBit != EvtRing->EventRingCCS) {
2620 EvtTrb = EvtRing->EventRingSeg0;
2621 EvtRing->EventRingCCS = (EvtRing->EventRingCCS) ? 0 : 1;
2625 if (Index < EvtRing->TrbNumber) {
2626 EvtRing->EventRingEnqueue = EvtTrb;
2647 if (EventRing->EventRingSeg0 ==
NULL) {
2681 ASSERT (EventRing !=
NULL);
2685 ASSERT (Buf !=
NULL);
2686 ASSERT (((
UINTN)Buf & 0x3F) == 0);
2691 EventRing->EventRingSeg0 = Buf;
2692 EventRing->TrbNumber = EVENT_RING_TRB_NUMBER;
2693 EventRing->EventRingDequeue = (
TRB_TEMPLATE *)EventRing->EventRingSeg0;
2694 EventRing->EventRingEnqueue = (
TRB_TEMPLATE *)EventRing->EventRingSeg0;
2700 EventRing->EventRingCCS = 1;
2704 ASSERT (Buf !=
NULL);
2705 ASSERT (((
UINTN)Buf & 0x3F) == 0);
2709 EventRing->ERSTBase = ERSTBase;
2710 ERSTBase->PtrLo = XHC_LOW_32BIT (DequeuePhy);
2711 ERSTBase->PtrHi = XHC_HIGH_32BIT (DequeuePhy);
2712 ERSTBase->RingTrbSize = EVENT_RING_TRB_NUMBER;
2733 XHC_LOW_32BIT ((UINT64)(
UINTN)DequeuePhy)
2737 XHC_ERDP_OFFSET + 4,
2738 XHC_HIGH_32BIT ((UINT64)(
UINTN)DequeuePhy)
2749 XHC_LOW_32BIT ((UINT64)(
UINTN)ERSTPhy)
2753 XHC_ERSTBA_OFFSET + 4,
2754 XHC_HIGH_32BIT ((UINT64)(
UINTN)ERSTPhy)
2780 ASSERT (TrsRing !=
NULL);
2784 TrsTrb = TrsRing->RingEnqueue;
2785 ASSERT (TrsTrb !=
NULL);
2787 for (Index = 0; Index < TrsRing->TrbNumber; Index++) {
2788 if (TrsTrb->CycleBit != (TrsRing->RingPCS & BIT0)) {
2793 if ((UINT8)TrsTrb->Type == TRB_TYPE_LINK) {
2794 ASSERT (((
LINK_TRB *)TrsTrb)->TC != 0);
2798 ((
LINK_TRB *)TrsTrb)->CycleBit = TrsRing->RingPCS & BIT0;
2802 TrsRing->RingPCS = (TrsRing->RingPCS & BIT0) ? 0 : 1;
2807 ASSERT (Index != TrsRing->TrbNumber);
2809 if (TrsTrb != TrsRing->RingEnqueue) {
2810 TrsRing->RingEnqueue = TrsTrb;
2816 TrsTrb->Parameter1 = 0;
2817 TrsTrb->Parameter2 = 0;
2821 TrsTrb->Control = 0;
2846 ASSERT (Buf !=
NULL);
2847 ASSERT (((
UINTN)Buf & 0x3F) == 0);
2850 TransferRing->RingSeg0 = Buf;
2851 TransferRing->TrbNumber = TrbNum;
2852 TransferRing->RingEnqueue = (
TRB_TEMPLATE *)TransferRing->RingSeg0;
2853 TransferRing->RingDequeue = (
TRB_TEMPLATE *)TransferRing->RingSeg0;
2854 TransferRing->RingPCS = 1;
2861 EndTrb->Type = TRB_TYPE_LINK;
2863 EndTrb->PtrLo = XHC_LOW_32BIT (PhyAddr);
2864 EndTrb->PtrHi = XHC_HIGH_32BIT (PhyAddr);
2872 EndTrb->CycleBit = 0;
2890 UINT32 MaxScratchpadBufs;
2893 UINT64 *ScratchEntry;
2896 UINTN *ScratchEntryMap;
2903 ASSERT (Xhc->MemPool !=
NULL);
2909 Xhc->MaxSlotsEn = Xhc->HcSParams1.Data.MaxSlots;
2910 ASSERT (Xhc->MaxSlotsEn >= 1 && Xhc->MaxSlotsEn <= 255);
2919 Size = (Xhc->MaxSlotsEn + 1) *
sizeof (UINT64);
2921 ASSERT (Dcbaa !=
NULL);
2928 MaxScratchpadBufs = ((Xhc->HcSParams2.Data.ScratchBufHi) << 5) | (Xhc->HcSParams2.Data.ScratchBufLo);
2929 Xhc->MaxScratchpadBufs = MaxScratchpadBufs;
2930 ASSERT (MaxScratchpadBufs <= 1023);
2931 if (MaxScratchpadBufs != 0) {
2936 ASSERT (ScratchEntryMap !=
NULL);
2937 Xhc->ScratchEntryMap = ScratchEntryMap;
2943 ASSERT (ScratchEntry !=
NULL);
2944 Xhc->ScratchEntry = ScratchEntry;
2950 (VOID **)&ScratchBuf,
2956 ZeroMem (ScratchBuf, MaxScratchpadBufs *
sizeof (UINT64));
2957 Xhc->ScratchBuf = ScratchBuf;
2962 for (Index = 0; Index < MaxScratchpadBufs; Index++) {
2963 ScratchEntryPhy = 0;
2967 (VOID **)&ScratchEntry[Index],
2969 (VOID **)&ScratchEntryMap[Index]
2972 ZeroMem ((VOID *)(
UINTN)ScratchEntry[Index], Xhc->PageSize);
2976 *ScratchBuf++ = ScratchEntryPhy;
2983 *(UINT64 *)Dcbaa = (UINT64)(
UINTN)ScratchPhy;
2990 Xhc->DCBAA = (UINT64 *)(
UINTN)Dcbaa;
2999 DEBUG ((DEBUG_INFO,
"XhcPeiInitSched:DCBAA=0x%x\n", Xhc->DCBAA));
3014 ASSERT ((CmdRingPhy & 0x3F) == 0);
3015 CmdRingPhy |= XHC_CRCR_RCS;
3023 DEBUG ((DEBUG_INFO,
"XhcPeiInitSched:XHC_CRCR=0x%x\n", Xhc->CmdRing.RingSeg0));
3030 for (Index = 0; Index < (UINT16)(Xhc->HcSParams1.Data.MaxIntrs); Index++) {
3039 DEBUG ((DEBUG_INFO,
"XhcPeiInitSched:XHC_EVENTRING=0x%x\n", Xhc->EventRing.EventRingSeg0));
3054 UINT64 *ScratchEntry;
3056 if (Xhc->ScratchBuf !=
NULL) {
3057 ScratchEntry = Xhc->ScratchEntry;
3058 for (Index = 0; Index < Xhc->MaxScratchpadBufs; Index++) {
3073 if (Xhc->CmdRing.RingSeg0 !=
NULL) {
3075 Xhc->CmdRing.RingSeg0 =
NULL;
3080 if (Xhc->DCBAA !=
NULL) {
3081 UsbHcFreeMem (Xhc->MemPool, Xhc->DCBAA, (Xhc->MaxSlotsEn + 1) * sizeof (UINT64));
3088 if (Xhc->MemPool !=
NULL) {
3090 Xhc->MemPool =
NULL;
EFI_STATUS IoMmuUnmap(IN VOID *Mapping)
EFI_STATUS IoMmuMap(IN EDKII_IOMMU_OPERATION Operation, IN VOID *HostAddress, IN OUT UINTN *NumberOfBytes, OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, OUT VOID **Mapping)
UINTN EFIAPI MicroSecondDelay(IN UINTN MicroSeconds)
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
INTN EFIAPI HighBitSet32(IN UINT32 Operand)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS UsbHcFreeMemPool(IN USBHC_MEM_POOL *Pool)
VOID UsbHcFreeMem(IN USBHC_MEM_POOL *Pool, IN VOID *Mem, IN UINTN Size)
VOID * UsbHcAllocateMem(IN USBHC_MEM_POOL *Pool, IN UINTN Size)
USBHC_MEM_POOL * UsbHcInitMemPool(IN EFI_PCI_IO_PROTOCOL *PciIo, IN BOOLEAN Check4G, IN UINT32 Which4G)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG(Expression)
#define USB_PORT_STAT_C_CONNECTION
#define EFI_USB_SPEED_SUPER
4.8 Gb/s, USB 3.0 XHCI HC.
#define USB_PORT_STAT_CONNECTION
EFI_STATUS(EFIAPI * EFI_ASYNC_USB_TRANSFER_CALLBACK)(IN VOID *Data, IN UINTN DataLength, IN VOID *Context, IN UINT32 Status)
@ EdkiiIoMmuOperationBusMasterWrite
@ EdkiiIoMmuOperationBusMasterRead
UINT64 EFI_PHYSICAL_ADDRESS
#define EFI_SIZE_TO_PAGES(Size)
EFI_PHYSICAL_ADDRESS UsbHcGetPciAddrForHostAddr(IN USBHC_MEM_POOL *Pool, IN VOID *Mem, IN UINTN Size, IN BOOLEAN Alignment)
EFI_STATUS UsbHcAllocateAlignedPages(IN EFI_PCI_IO_PROTOCOL *PciIo, IN UINTN Pages, IN UINTN Alignment, OUT VOID **HostAddress, OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, OUT VOID **Mapping)
EFI_PHYSICAL_ADDRESS UsbHcGetHostAddrForPciAddr(IN USBHC_MEM_POOL *Pool, IN VOID *Mem, IN UINTN Size, IN BOOLEAN Alignment)
VOID UsbHcFreeAlignedPages(IN EFI_PCI_IO_PROTOCOL *PciIo, IN VOID *HostAddress, IN UINTN Pages, VOID *Mapping)
BOOLEAN XhcPeiIsHalt(IN PEI_XHC_DEV *Xhc)
VOID XhcPeiClearRuntimeRegBit(IN PEI_XHC_DEV *Xhc, IN UINT32 Offset, IN UINT32 Bit)
UINT32 XhcPeiReadOpReg(IN PEI_XHC_DEV *Xhc, IN UINT32 Offset)
BOOLEAN XhcPeiIsSysError(IN PEI_XHC_DEV *Xhc)
VOID XhcPeiWriteOpReg(IN PEI_XHC_DEV *Xhc, IN UINT32 Offset, IN UINT32 Data)
VOID XhcPeiSetRuntimeRegBit(IN PEI_XHC_DEV *Xhc, IN UINT32 Offset, IN UINT32 Bit)
UINT32 XhcPeiReadRuntimeReg(IN PEI_XHC_DEV *Xhc, IN UINT32 Offset)
VOID XhcPeiClearOpRegBit(IN PEI_XHC_DEV *Xhc, IN UINT32 Offset, IN UINT32 Bit)
VOID XhcPeiWriteDoorBellReg(IN PEI_XHC_DEV *Xhc, IN UINT32 Offset, IN UINT32 Data)
VOID XhcPeiWriteRuntimeReg(IN PEI_XHC_DEV *Xhc, IN UINT32 Offset, IN UINT32 Data)
EFI_STATUS XhcPeiDisableSlotCmd64(IN PEI_XHC_DEV *Xhc, IN UINT8 SlotId)
UINT8 XhcPeiRouteStringToSlotId(IN PEI_XHC_DEV *Xhc, IN USB_DEV_ROUTE RouteString)
VOID XhcPeiInitSched(IN PEI_XHC_DEV *Xhc)
EFI_STATUS XhcPeiEvaluateContext(IN PEI_XHC_DEV *Xhc, IN UINT8 SlotId, IN UINT32 MaxPacketSize)
EFI_STATUS XhcPeiSetConfigCmd(IN PEI_XHC_DEV *Xhc, IN UINT8 SlotId, IN UINT8 DeviceSpeed, IN USB_CONFIG_DESCRIPTOR *ConfigDesc)
EFI_STATUS XhcPeiSetConfigCmd64(IN PEI_XHC_DEV *Xhc, IN UINT8 SlotId, IN UINT8 DeviceSpeed, IN USB_CONFIG_DESCRIPTOR *ConfigDesc)
EFI_STATUS XhcPeiCheckNewEvent(IN PEI_XHC_DEV *Xhc, IN EVENT_RING *EvtRing, OUT TRB_TEMPLATE **NewEvtTrb)
EFI_STATUS XhcPeiRecoverHaltedEndpoint(IN PEI_XHC_DEV *Xhc, IN URB *Urb)
VOID XhcPeiRingDoorBell(IN PEI_XHC_DEV *Xhc, IN UINT8 SlotId, IN UINT8 Dci)
VOID XhcPeiFreeSched(IN PEI_XHC_DEV *Xhc)
EFI_STATUS XhcPeiConfigHubContext(IN PEI_XHC_DEV *Xhc, IN UINT8 SlotId, IN UINT8 PortNum, IN UINT8 TTT, IN UINT8 MTT)
EFI_STATUS XhcPeiEvaluateContext64(IN PEI_XHC_DEV *Xhc, IN UINT8 SlotId, IN UINT32 MaxPacketSize)
EFI_STATUS XhcPeiSyncTrsRing(IN PEI_XHC_DEV *Xhc, IN TRANSFER_RING *TrsRing)
EFI_STATUS XhcPeiDisableSlotCmd(IN PEI_XHC_DEV *Xhc, IN UINT8 SlotId)
VOID XhcPeiFreeUrb(IN PEI_XHC_DEV *Xhc, IN URB *Urb)
URB * XhcPeiCreateCmdTrb(IN PEI_XHC_DEV *Xhc, IN TRB_TEMPLATE *CmdTrb)
EFI_STATUS XhcPeiInitializeDeviceSlot64(IN PEI_XHC_DEV *Xhc, IN USB_DEV_ROUTE ParentRouteChart, IN UINT16 ParentPort, IN USB_DEV_ROUTE RouteChart, IN UINT8 DeviceSpeed)
EFI_STATUS XhcPeiConfigHubContext64(IN PEI_XHC_DEV *Xhc, IN UINT8 SlotId, IN UINT8 PortNum, IN UINT8 TTT, IN UINT8 MTT)
EFI_STATUS EFIAPI XhcPeiResetEndpoint(IN PEI_XHC_DEV *Xhc, IN UINT8 SlotId, IN UINT8 Dci)
EFI_STATUS EFIAPI XhcPeiStopEndpoint(IN PEI_XHC_DEV *Xhc, IN UINT8 SlotId, IN UINT8 Dci)
UINT8 XhcPeiBusDevAddrToSlotId(IN PEI_XHC_DEV *Xhc, IN UINT8 BusDevAddr)
EFI_STATUS XhcPeiCreateTransferTrb(IN PEI_XHC_DEV *Xhc, IN URB *Urb)
VOID XhcPeiFreeEventRing(IN PEI_XHC_DEV *Xhc, IN EVENT_RING *EventRing)
EFI_STATUS XhcPeiSyncEventRing(IN PEI_XHC_DEV *Xhc, IN EVENT_RING *EvtRing)
BOOLEAN XhcPeiCheckUrbResult(IN PEI_XHC_DEV *Xhc, IN URB *Urb)
URB * XhcPeiCreateUrb(IN PEI_XHC_DEV *Xhc, IN UINT8 BusAddr, IN UINT8 EpAddr, IN UINT8 DevSpeed, IN UINTN MaxPacket, IN UINTN Type, IN EFI_USB_DEVICE_REQUEST *Request, IN VOID *Data, IN UINTN DataLen, IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback, IN VOID *Context)
EFI_STATUS XhcPeiInitializeDeviceSlot(IN PEI_XHC_DEV *Xhc, IN USB_DEV_ROUTE ParentRouteChart, IN UINT16 ParentPort, IN USB_DEV_ROUTE RouteChart, IN UINT8 DeviceSpeed)
EFI_STATUS XhcPeiExecTransfer(IN PEI_XHC_DEV *Xhc, IN BOOLEAN CmdTransfer, IN URB *Urb, IN UINTN Timeout)
EFI_STATUS XhcPeiCmdTransfer(IN PEI_XHC_DEV *Xhc, IN TRB_TEMPLATE *CmdTrb, IN UINTN Timeout, OUT TRB_TEMPLATE **EvtTrb)
VOID XhcPeiCreateTransferRing(IN PEI_XHC_DEV *Xhc, IN UINTN TrbNum, OUT TRANSFER_RING *TransferRing)
EFI_STATUS XhcPeiDequeueTrbFromEndpoint(IN PEI_XHC_DEV *Xhc, IN URB *Urb)
VOID XhcPeiCreateEventRing(IN PEI_XHC_DEV *Xhc, OUT EVENT_RING *EventRing)
UINT8 XhcPeiEndpointToDci(IN UINT8 EpAddr, IN EFI_USB_DATA_DIRECTION Direction)
EFI_STATUS XhcPeiPollPortStatusChange(IN PEI_XHC_DEV *Xhc, IN USB_DEV_ROUTE ParentRouteChart, IN UINT8 Port, IN EFI_USB_PORT_STATUS *PortState)
EFI_STATUS EFIAPI XhcPeiSetTrDequeuePointer(IN PEI_XHC_DEV *Xhc, IN UINT8 SlotId, IN UINT8 Dci, IN URB *Urb)
BOOLEAN XhcPeiIsTransferRingTrb(IN TRB_TEMPLATE *Trb, IN URB *Urb)