]> git.proxmox.com Git - mirror_edk2.git/blob - SourceLevelDebugPkg/Library/DebugCommunicationLibUsb/DebugCommunicationLibUsb.c
Change the library global variable to add library name prefix to avoid potential...
[mirror_edk2.git] / SourceLevelDebugPkg / Library / DebugCommunicationLibUsb / DebugCommunicationLibUsb.c
1 /** @file
2 Debug Port Library implementation based on usb debug port.
3
4 Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php.
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include <Base.h>
16 #include <IndustryStandard/Pci.h>
17 #include <IndustryStandard/Usb.h>
18 #include <Library/IoLib.h>
19 #include <Library/PciLib.h>
20 #include <Library/PcdLib.h>
21 #include <Library/TimerLib.h>
22 #include <Library/DebugCommunicationLib.h>
23 #include <Library/BaseMemoryLib.h>
24 #include <Library/BaseLib.h>
25 #include <Library/DebugLib.h>
26
27 #define SETUP_PID 0x2D
28 #define INPUT_PID 0x69
29 #define OUTPUT_PID 0xE1
30 #define ERROR_PID 0x55
31 #define DATA0_PID 0xC3
32 #define DATA1_PID 0x4B
33 #define DATA2_PID 0x87
34 #define MDATA_PID 0x0F
35 #define ACK_PID 0xD2
36 #define NAK_PID 0x5A
37 #define STALL_PID 0x1E
38 #define NYET_PID 0x96
39
40 #define PCI_CAPABILITY_ID_DEBUG_PORT 0x0A
41 #define USB_DEBUG_PORT_MAX_PACKET_SIZE 0x08
42
43 #define USB_DEBUG_PORT_IN_USE BIT10
44 #define USB_DEBUG_PORT_ENABLE BIT28
45 #define USB_DEBUG_PORT_OWNER BIT30
46
47 #define USB_PORT_LINE_STATUS_LS 0x400
48 #define USB_PORT_LINE_STATUS_MASK 0xC00
49
50 //
51 // Usb debug device descriptor, which is defined at
52 // USB2 Debug Device Specification.
53 //
54 typedef struct _USB_DEBUG_PORT_DESCRIPTOR {
55 UINT8 Length;
56 UINT8 DescriptorType;
57 UINT8 DebugInEndpoint;
58 UINT8 DebugOutEndpoint;
59 }USB_DEBUG_PORT_DESCRIPTOR;
60
61 USB_DEVICE_REQUEST mDebugCommunicationLibUsbGetDebugDescriptor = {
62 0x80,
63 USB_REQ_GET_DESCRIPTOR,
64 (UINT16)(0x0A << 8),
65 0x0000,
66 sizeof(USB_DEBUG_PORT_DESCRIPTOR)
67 };
68
69 USB_DEVICE_REQUEST mDebugCommunicationLibUsbSetDebugFeature = {
70 0x0,
71 USB_REQ_SET_FEATURE,
72 (UINT16)(0x06),
73 0x0000,
74 0x0
75 };
76
77 USB_DEVICE_REQUEST mDebugCommunicationLibUsbSetDebugAddress = {
78 0x0,
79 USB_REQ_SET_ADDRESS,
80 (UINT16)(0x7F),
81 0x0000,
82 0x0
83 };
84
85 //
86 // Usb debug port register file, which is defined at
87 // EHCI Specification.
88 //
89 typedef struct _USB_DEBUG_PORT_REGISTER {
90 UINT32 ControlStatus;
91 UINT8 TokenPid;
92 UINT8 SendPid;
93 UINT8 ReceivedPid;
94 UINT8 Reserved1;
95 UINT8 DataBuffer[8];
96 UINT8 UsbEndPoint;
97 UINT8 UsbAddress;
98 UINT8 Reserved2;
99 UINT8 Reserved3;
100 }USB_DEBUG_PORT_REGISTER;
101
102 //
103 // The state machine of usb debug port
104 //
105 #define USBDBG_NO_DEV 0 // No device present at debug port
106 #define USBDBG_NO_DBG_CAB 1 // The device attached is not usb debug cable
107 #define USBDBG_DBG_CAB 2 // The device attached is usb debug cable
108 #define USBDBG_INIT_DONE 4 // The usb debug cable device is initialized
109 #define USBDBG_RESET 8 // The system is reset
110
111 #pragma pack(1)
112 //
113 // The internal data structure of DEBUG_PORT_HANDLE, which stores some
114 // important datum which are used across various phases.
115 //
116 typedef struct _USB_DEBUG_PORT_HANDLE{
117 //
118 // The usb debug port memory BAR number in EHCI configuration space.
119 //
120 UINT8 DebugPortBarNumber;
121 UINT8 Initialized;
122 //
123 // The offset of usb debug port registers in EHCI memory range.
124 //
125 UINT16 DebugPortOffset;
126 //
127 // The usb debug port memory BAR address.
128 //
129 UINT32 UsbDebugPortMemoryBase;
130 //
131 // The EHCI memory BAR address.
132 //
133 UINT32 EhciMemoryBase;
134 //
135 // The Bulk In endpoint toggle bit.
136 //
137 UINT8 BulkInToggle;
138 //
139 // The Bulk Out endpoint toggle bit.
140 //
141 UINT8 BulkOutToggle;
142 //
143 // The available data length in the following data buffer.
144 //
145 UINT8 DataCount;
146 //
147 // The data buffer. Maximum length is 8 bytes.
148 //
149 UINT8 Data[8];
150 //
151 // Timter settings
152 //
153 UINT64 TimerFrequency;
154 UINT64 TimerCycle;
155 BOOLEAN TimerCountDown;
156 } USB_DEBUG_PORT_HANDLE;
157 #pragma pack()
158
159 //
160 // The global variable which can be used after memory is ready.
161 //
162 USB_DEBUG_PORT_HANDLE mDebugCommunicationLibUsbDebugPortHandle;
163
164 /**
165 Check if the timer is timeout.
166
167 @param[in] UsbDebugPortHandle Pointer to USB Debug port handle
168 @param[in] Timer The start timer from the begin.
169 @param[in] TimeoutTicker Ticker number need time out.
170
171 @return TRUE Timer time out occurs.
172 @retval FALSE Timer does not time out.
173
174 **/
175 BOOLEAN
176 IsTimerTimeout (
177 IN USB_DEBUG_PORT_HANDLE *UsbDebugPortHandle,
178 IN UINT64 Timer,
179 IN UINT64 TimeoutTicker
180 )
181 {
182 UINT64 CurrentTimer;
183 UINT64 Delta;
184
185 CurrentTimer = GetPerformanceCounter ();
186
187 if (UsbDebugPortHandle->TimerCountDown) {
188 //
189 // The timer counter counts down. Check for roll over condition.
190 //
191 if (CurrentTimer < Timer) {
192 Delta = Timer - CurrentTimer;
193 } else {
194 //
195 // Handle one roll-over.
196 //
197 Delta = UsbDebugPortHandle->TimerCycle - (CurrentTimer - Timer);
198 }
199 } else {
200 //
201 // The timer counter counts up. Check for roll over condition.
202 //
203 if (CurrentTimer > Timer) {
204 Delta = CurrentTimer - Timer;
205 } else {
206 //
207 // Handle one roll-over.
208 //
209 Delta = UsbDebugPortHandle->TimerCycle - (Timer - CurrentTimer);
210 }
211 }
212
213 return (BOOLEAN) (Delta >= TimeoutTicker);
214 }
215
216 /**
217 Calculate the usb debug port bar address.
218
219 @param DebugPortOffset Get usb debug port offset in the usb debug port memory space.
220 @param DebugPortBarNumbar Get the bar number at which usb debug port is located.
221
222 @retval RETURN_UNSUPPORTED The usb host controller does not supported usb debug port capability.
223 @retval RETURN_SUCCESS Get bar and offset successfully.
224
225 **/
226 RETURN_STATUS
227 EFIAPI
228 CalculateUsbDebugPortBar (
229 OUT UINT16 *DebugPortOffset,
230 OUT UINT8 *DebugPortBarNumbar
231 )
232 {
233 UINT16 PciStatus;
234 UINT16 VendorId;
235 UINT16 DeviceId;
236 UINT8 ProgInterface;
237 UINT8 SubClassCode;
238 UINT8 BaseCode;
239 UINT8 CapabilityPtr;
240 UINT8 CapabilityId;
241
242 VendorId = PciRead16 (PcdGet32(PcdUsbEhciPciAddress) + PCI_VENDOR_ID_OFFSET);
243 DeviceId = PciRead16 (PcdGet32(PcdUsbEhciPciAddress) + PCI_DEVICE_ID_OFFSET);
244
245 if ((VendorId == 0xFFFF) || (DeviceId == 0xFFFF)) {
246 return RETURN_UNSUPPORTED;
247 }
248
249 ProgInterface = PciRead8 (PcdGet32(PcdUsbEhciPciAddress) + PCI_CLASSCODE_OFFSET);
250 SubClassCode = PciRead8 (PcdGet32(PcdUsbEhciPciAddress) + PCI_CLASSCODE_OFFSET + 1);
251 BaseCode = PciRead8 (PcdGet32(PcdUsbEhciPciAddress) + PCI_CLASSCODE_OFFSET + 2);
252
253 if ((ProgInterface != PCI_IF_EHCI) || (SubClassCode != PCI_CLASS_SERIAL_USB) || (BaseCode != PCI_CLASS_SERIAL)) {
254 return RETURN_UNSUPPORTED;
255 }
256
257 //
258 // Enable Ehci Host Controller MMIO Space.
259 //
260 PciStatus = PciRead16 (PcdGet32(PcdUsbEhciPciAddress) + PCI_PRIMARY_STATUS_OFFSET);
261
262 if ((PciStatus & EFI_PCI_STATUS_CAPABILITY) == 0) {
263 //
264 // The Pci Device Doesn't Support Capability Pointer.
265 //
266 return RETURN_UNSUPPORTED;
267 }
268
269 //
270 // Get Pointer To Capability List
271 //
272 CapabilityPtr = PciRead8(PcdGet32(PcdUsbEhciPciAddress) + PCI_CAPBILITY_POINTER_OFFSET);
273
274 //
275 // Find Capability ID 0xA, Which Is For Debug Port
276 //
277 while (CapabilityPtr != 0) {
278 CapabilityId = PciRead8(PcdGet32(PcdUsbEhciPciAddress) + CapabilityPtr);
279 if (CapabilityId == PCI_CAPABILITY_ID_DEBUG_PORT) {
280 break;
281 }
282 CapabilityPtr = PciRead8(PcdGet32(PcdUsbEhciPciAddress) + CapabilityPtr + 1);
283 }
284
285 //
286 // No Debug Port Capability Found
287 //
288 if (CapabilityPtr == 0) {
289 return RETURN_UNSUPPORTED;
290 }
291
292 //
293 // Get The Base Address Of Debug Port Register In Debug Port Capability Register
294 //
295 *DebugPortOffset = (UINT16)(PciRead16(PcdGet32(PcdUsbEhciPciAddress) + CapabilityPtr + 2) & 0x1FFF);
296 *DebugPortBarNumbar = (UINT8)((PciRead16(PcdGet32(PcdUsbEhciPciAddress) + CapabilityPtr + 2) >> 13) - 1);
297
298 return RETURN_SUCCESS;
299 }
300
301 /**
302 Do a usb IN transaction by usb debug port.
303
304 @param DebugPortRegister Pointer to the base address of usb debug port register interface.
305 @param Buffer Pointer to the buffer receiving data.
306 @param Length Number of bytes of the received data.
307 @param Token The token PID for each USB transaction.
308 @param Addr The usb device address for usb transaction.
309 @param Ep The endpoint for usb transaction.
310 @param DataToggle The toggle bit used at usb transaction.
311
312 @retval RETURN_SUCCESS The IN transaction is executed successfully.
313 @retval RETURN_INVALID_PARAMETER The parameters passed in are invalid.
314 @retval RETURN_DEVICE_ERROR The IN transaction comes across error.
315
316 **/
317 RETURN_STATUS
318 EFIAPI
319 UsbDebugPortIn (
320 IN USB_DEBUG_PORT_REGISTER *DebugPortRegister,
321 IN OUT UINT8 *Buffer,
322 OUT UINT8 *Length,
323 IN UINT8 Token,
324 IN UINT8 Addr,
325 IN UINT8 Ep,
326 IN UINT8 DataToggle
327 )
328 {
329 UINTN Index;
330
331 if (Length == NULL) {
332 return RETURN_INVALID_PARAMETER;
333 }
334 *Length = 0;
335
336 DebugPortRegister->TokenPid = Token;
337 if (DataToggle != 0) {
338 DebugPortRegister->SendPid = DATA1_PID;
339 } else {
340 DebugPortRegister->SendPid = DATA0_PID;
341 }
342
343 DebugPortRegister->UsbAddress = (UINT8)(Addr & 0x7F);
344 DebugPortRegister->UsbEndPoint = (UINT8)(Ep & 0xF);
345
346 //
347 // Clearing W/R bit to indicate it's a READ operation
348 //
349 MmioAnd32((UINTN)&DebugPortRegister->ControlStatus, (UINT32)~BIT4);
350
351 //
352 // Setting GO bit as well as clearing DONE bit
353 //
354 MmioOr32((UINTN)&DebugPortRegister->ControlStatus, (UINT32)BIT5);
355
356 //
357 // Wait for completing the request
358 //
359 while ((MmioRead32((UINTN)&DebugPortRegister->ControlStatus) & (UINT32)BIT16) == 0) {
360 if ((MmioRead32((UINTN)&DebugPortRegister->ControlStatus) & (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_ENABLE))
361 != (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_ENABLE)) {
362 return RETURN_DEVICE_ERROR;
363 }
364 }
365
366 //
367 // Clearing DONE bit by writing 1
368 //
369 MmioOr32((UINTN)&DebugPortRegister->ControlStatus, BIT16);
370
371 //
372 // Check if the request is executed successfully or not.
373 //
374 if ((MmioRead32((UINTN)&DebugPortRegister->ControlStatus)) & BIT6) {
375 return RETURN_DEVICE_ERROR;
376 }
377
378 //
379 // Make sure the received data are not beyond the allowable maximum length - 8 byte
380 //
381 if (((MmioRead32((UINTN)&DebugPortRegister->ControlStatus)) & 0xF) > USB_DEBUG_PORT_MAX_PACKET_SIZE) {
382 return RETURN_DEVICE_ERROR;
383 }
384
385 *Length = (UINT8)(MmioRead32((UINTN)&DebugPortRegister->ControlStatus) & 0xF);
386 if (*Length > 8) {
387 return RETURN_DEVICE_ERROR;
388 }
389
390 for (Index = 0; Index < *Length; Index++) {
391 Buffer[Index] = DebugPortRegister->DataBuffer[Index];
392 }
393 return RETURN_SUCCESS;
394 }
395
396 /**
397 Do a usb SETUP/OUT transaction by usb debug port.
398
399 @param DebugPortRegister Pointer to the base address of usb debug port register interface.
400 @param Buffer Pointer to the buffer receiving data.
401 @param Length Number of bytes of the received data.
402 @param Token The token PID for each USB transaction.
403 @param Addr The usb device address for usb transaction.
404 @param Ep The endpoint for usb transaction.
405 @param DataToggle The toggle bit used at usb transaction.
406
407 @retval RETURN_SUCCESS The IN transaction is executed successfully.
408 @retval RETURN_INVALID_PARAMETER The parameters passed in are invalid.
409 @retval RETURN_DEVICE_ERROR The IN transaction comes across error.
410
411 **/
412 RETURN_STATUS
413 EFIAPI
414 UsbDebugPortOut (
415 IN USB_DEBUG_PORT_REGISTER *DebugPortRegister,
416 IN UINT8 *Buffer,
417 IN UINT8 Length,
418 IN UINT8 Token,
419 IN UINT8 Addr,
420 IN UINT8 Ep,
421 IN UINT8 DataToggle
422 )
423 {
424 UINT8 Index;
425
426 if (Length > 8) {
427 return RETURN_INVALID_PARAMETER;
428 }
429
430 DebugPortRegister->TokenPid = Token;
431 if (DataToggle != 0) {
432 DebugPortRegister->SendPid = DATA1_PID;
433 } else {
434 DebugPortRegister->SendPid = DATA0_PID;
435 }
436 DebugPortRegister->UsbAddress = (UINT8)(Addr & 0x7F);
437 DebugPortRegister->UsbEndPoint = (UINT8)(Ep & 0xF);
438
439 //
440 // Fill in the data length and corresponding data.
441 //
442 MmioAnd32((UINTN)&DebugPortRegister->ControlStatus, (UINT32)~0xF);
443 MmioOr32((UINTN)&DebugPortRegister->ControlStatus, Length & 0xF);
444 for (Index = 0; Index < Length; Index++) {
445 DebugPortRegister->DataBuffer[Index] = Buffer[Index];
446 }
447
448 //
449 // Setting W/R bit to indicate it's a WRITE operation
450 //
451 MmioOr32((UINTN)&DebugPortRegister->ControlStatus, BIT4);
452 //
453 // Setting GO bit as well as clearing DONE bit
454 //
455 MmioOr32((UINTN)&DebugPortRegister->ControlStatus, BIT5);
456
457 //
458 // Wait for completing the request
459 //
460 while ((MmioRead32((UINTN)&DebugPortRegister->ControlStatus) & BIT16) == 0) {
461 if ((MmioRead32((UINTN)&DebugPortRegister->ControlStatus) & (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_ENABLE))
462 != (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_ENABLE)) {
463 return RETURN_DEVICE_ERROR;
464 }
465 }
466
467 //
468 // Clearing DONE bit by writing 1
469 //
470 MmioOr32((UINTN)&DebugPortRegister->ControlStatus, BIT16);
471
472 //
473 // Check if the request is executed successfully or not.
474 //
475 if ((MmioRead32((UINTN)&DebugPortRegister->ControlStatus)) & BIT6) {
476 return RETURN_DEVICE_ERROR;
477 }
478
479 //
480 // Make sure the sent data are not beyond the allowable maximum length - 8 byte
481 //
482 if (((MmioRead32((UINTN)&DebugPortRegister->ControlStatus)) & 0xF) > USB_DEBUG_PORT_MAX_PACKET_SIZE) {
483 return RETURN_DEVICE_ERROR;
484 }
485
486 return RETURN_SUCCESS;
487 }
488
489 /**
490 Do a usb control transfer by usb debug port.
491
492 @param DebugPortRegister Pointer to the base address of usb debug port register interface.
493 @param SetupPacket The token PID for each USB transaction.
494 @param Addr The usb device address for usb transaction.
495 @param Ep The endpoint for usb transaction.
496 @param Data Pointer to the buffer receiving data.
497 @param DataLength Number of bytes of the received data.
498
499 @retval RETURN_SUCCESS The IN transaction is executed successfully.
500 @retval RETURN_INVALID_PARAMETER The parameters passed in are invalid.
501 @retval RETURN_DEVICE_ERROR The IN transaction comes across error.
502
503 **/
504 RETURN_STATUS
505 EFIAPI
506 UsbDebugPortControlTransfer (
507 IN USB_DEBUG_PORT_REGISTER *DebugPortRegister,
508 IN USB_DEVICE_REQUEST *SetupPacket,
509 IN UINT8 Addr,
510 IN UINT8 Ep,
511 OUT UINT8 *Data,
512 IN OUT UINT8 *DataLength
513 )
514 {
515 RETURN_STATUS Status;
516 UINT8 Temp;
517 UINT8 ReturnStatus[8];
518
519 //
520 // Setup Phase
521 //
522 Status = UsbDebugPortOut(DebugPortRegister, (UINT8 *)SetupPacket, (UINT8)sizeof(USB_DEVICE_REQUEST), SETUP_PID, Addr, Ep, 0);
523 if (RETURN_ERROR(Status)) {
524 return Status;
525 }
526
527 //
528 // Data Phase
529 //
530 if (DataLength != 0) {
531 if ((SetupPacket->RequestType & BIT7) != 0) {
532 //
533 // Get Data From Device
534 //
535 Status = UsbDebugPortIn(DebugPortRegister, Data, DataLength, INPUT_PID, Addr, Ep, 1);
536 if (RETURN_ERROR(Status)) {
537 return Status;
538 }
539 } else {
540 //
541 // Send Data To Device
542 //
543 Status = UsbDebugPortOut(DebugPortRegister, Data, *DataLength, OUTPUT_PID, Addr, Ep, 1);
544 if (RETURN_ERROR(Status)) {
545 return Status;
546 }
547 }
548 }
549
550 //
551 // Status Phase
552 //
553 if ((SetupPacket->RequestType & BIT7) != 0) {
554 //
555 // For READ operation, Data Toggle in Status Phase Should be 1.
556 //
557 Status = UsbDebugPortOut(DebugPortRegister, NULL, 0, OUTPUT_PID, Addr, Ep, 1);
558 } else {
559 //
560 // For WRITE operation, Data Toggle in Status Phase Should be 1.
561 //
562 Status = UsbDebugPortIn(DebugPortRegister, ReturnStatus, &Temp, INPUT_PID, Addr, Ep, 1);
563 }
564
565 return Status;
566 }
567
568 /**
569 Check if it needs to re-initialize usb debug port hardware.
570
571 During different phases switch, such as SEC to PEI or PEI to DXE or DXE to SMM, we should check
572 whether the usb debug port hardware configuration is changed. Such case can be triggerred by
573 Pci bus resource allocation and so on.
574
575 @param Handle Debug port handle.
576
577 @retval TRUE The usb debug port hardware configuration is changed.
578 @retval FALSE The usb debug port hardware configuration is not changed.
579
580 **/
581 BOOLEAN
582 EFIAPI
583 NeedReinitializeHardware(
584 IN USB_DEBUG_PORT_HANDLE *Handle
585 )
586 {
587 UINT16 PciCmd;
588 UINT32 UsbDebugPortMemoryBase;
589 UINT32 EhciMemoryBase;
590 BOOLEAN Status;
591 USB_DEBUG_PORT_REGISTER *UsbDebugPortRegister;
592
593 Status = FALSE;
594
595 EhciMemoryBase = 0xFFFFFC00 & PciRead32(PcdGet32(PcdUsbEhciPciAddress) + PCI_BASE_ADDRESSREG_OFFSET);
596 if (EhciMemoryBase != Handle->EhciMemoryBase) {
597 Handle->EhciMemoryBase = EhciMemoryBase;
598 Status = TRUE;
599 }
600
601 UsbDebugPortMemoryBase = 0xFFFFFC00 & PciRead32(PcdGet32(PcdUsbEhciPciAddress) + PCI_BASE_ADDRESSREG_OFFSET + Handle->DebugPortBarNumber * 4);
602 if (UsbDebugPortMemoryBase != Handle->UsbDebugPortMemoryBase) {
603 Handle->UsbDebugPortMemoryBase = UsbDebugPortMemoryBase;
604 Status = TRUE;
605 }
606
607 //
608 // Enable Ehci Memory Space Access
609 //
610 PciCmd = PciRead16 (PcdGet32(PcdUsbEhciPciAddress) + PCI_COMMAND_OFFSET);
611 if (((PciCmd & EFI_PCI_COMMAND_MEMORY_SPACE) == 0) || ((PciCmd & EFI_PCI_COMMAND_BUS_MASTER) == 0)) {
612 PciCmd |= EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER;
613 PciWrite16(PcdGet32(PcdUsbEhciPciAddress) + PCI_COMMAND_OFFSET, PciCmd);
614 Status = TRUE;
615 }
616
617 //
618 // If the owner and in_use bit is not set, it means system is doing cold/warm boot or EHCI host controller is reset by system software.
619 //
620 UsbDebugPortRegister = (USB_DEBUG_PORT_REGISTER *)(UINTN)(Handle->UsbDebugPortMemoryBase + Handle->DebugPortOffset);
621 if ((MmioRead32((UINTN)&UsbDebugPortRegister->ControlStatus) & (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_ENABLE | USB_DEBUG_PORT_IN_USE))
622 != (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_ENABLE | USB_DEBUG_PORT_IN_USE)) {
623 Status = TRUE;
624 }
625
626 if (Handle->Initialized == USBDBG_RESET) {
627 Status = TRUE;
628 } else if (Handle->Initialized != USBDBG_INIT_DONE) {
629 Status = TRUE;
630 }
631 return Status;
632 }
633
634 /**
635 Initialize usb debug port hardware.
636
637 1. reset ehci host controller.
638 2. set right port to debug port.
639 3. find a usb debug device is attached by getting debug device descriptor.
640 4. set address for the usb debug device.
641 5. configure the usb debug device to debug mode.
642
643 @param Handle Debug port handle.
644
645 @retval TRUE The usb debug port hardware configuration is changed.
646 @retval FALSE The usb debug port hardware configuration is not changed.
647
648 **/
649 RETURN_STATUS
650 EFIAPI
651 InitializeUsbDebugHardware (
652 IN USB_DEBUG_PORT_HANDLE *Handle
653 )
654 {
655 RETURN_STATUS Status;
656 USB_DEBUG_PORT_REGISTER *UsbDebugPortRegister;
657 USB_DEBUG_PORT_DESCRIPTOR UsbDebugPortDescriptor;
658 UINT16 PciCmd;
659 UINT32 *PortStatus;
660 UINT32 *UsbCmd;
661 UINT32 *UsbStatus;
662 UINT32 *UsbHCSParam;
663 UINT8 DebugPortNumber;
664 UINT8 Length;
665
666 UsbDebugPortRegister = (USB_DEBUG_PORT_REGISTER *)(UINTN)(Handle->UsbDebugPortMemoryBase + Handle->DebugPortOffset);
667 PciCmd = PciRead16 (PcdGet32(PcdUsbEhciPciAddress) + PCI_COMMAND_OFFSET);
668 UsbHCSParam = (UINT32 *)(UINTN)(Handle->EhciMemoryBase + 0x04);
669 UsbCmd = (UINT32 *)(UINTN)(Handle->EhciMemoryBase + 0x20);
670 UsbStatus = (UINT32 *)(UINTN)(Handle->EhciMemoryBase + 0x24);
671
672 //
673 // Check if the debug port is enabled and owned by myself.
674 //
675 if (((MmioRead32((UINTN)&UsbDebugPortRegister->ControlStatus) & (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE))
676 != (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE)) || (Handle->Initialized == USBDBG_RESET)) {
677 DEBUG ((
678 EFI_D_INFO,
679 "UsbDbg: Need to reset the host controller. ControlStatus = %08x\n",
680 MmioRead32((UINTN)&UsbDebugPortRegister->ControlStatus)
681 ));
682 //
683 // If the host controller is halted, then reset and restart it.
684 //
685 if ((MmioRead32((UINTN)UsbStatus) & BIT12) != 0) {
686 DEBUG ((EFI_D_INFO, "UsbDbg: Reset the host controller.\n"));
687 //
688 // reset the host controller.
689 //
690 MmioOr32((UINTN)UsbCmd, BIT1);
691 //
692 // ensure that the host controller is reset.
693 //
694 while ((MmioRead32((UINTN)UsbCmd) & BIT1) != 0);
695
696 MmioOr32((UINTN)UsbCmd, BIT0);
697 // ensure that the host controller is started (HALTED bit must be cleared)
698 while ((MmioRead32((UINTN)UsbStatus) & BIT12) != 0);
699 }
700
701 //
702 // First get the ownership of port 0.
703 //
704 MmioOr32((UINTN)&UsbDebugPortRegister->ControlStatus, USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE);
705
706 MicroSecondDelay (200000);
707 }
708 //
709 // Find out which port is used as debug port.
710 //
711 DebugPortNumber = (UINT8)((MmioRead32((UINTN)UsbHCSParam) & 0x00F00000) >> 20);
712 //
713 // Should find a device is connected at debug port
714 //
715 PortStatus = (UINT32 *)(UINTN)(Handle->EhciMemoryBase + 0x64 + (DebugPortNumber - 1) * 4);
716 if (!(MmioRead32((UINTN)PortStatus) & BIT0)) {
717 Handle->Initialized = USBDBG_NO_DEV;
718 return RETURN_NOT_FOUND;
719 }
720
721 if (Handle->Initialized != USBDBG_INIT_DONE ||
722 (MmioRead32 ((UINTN) &UsbDebugPortRegister->ControlStatus) & USB_DEBUG_PORT_ENABLE) == 0) {
723 DEBUG ((EFI_D_INFO, "UsbDbg: Reset the debug port.\n"));
724 //
725 // Reset the debug port
726 //
727 MmioOr32((UINTN)PortStatus, BIT8);
728 MicroSecondDelay (500000);
729 MmioAnd32((UINTN)PortStatus, (UINT32)~BIT8);
730 while (MmioRead32((UINTN)PortStatus) & BIT8);
731
732 //
733 // The port enabled bit should be set by HW.
734 //
735 if ((MmioRead32((UINTN)PortStatus) & BIT2) == 0) {
736 Handle->Initialized = USBDBG_NO_DBG_CAB;
737 return RETURN_DEVICE_ERROR;
738 }
739
740 //
741 // Enable Usb Debug Port Capability
742 //
743 MmioOr32((UINTN)&UsbDebugPortRegister->ControlStatus, USB_DEBUG_PORT_ENABLE);
744
745 //
746 // initialize the data toggle used by bulk in/out endpoint.
747 //
748 Handle->BulkInToggle = 0;
749 Handle->BulkOutToggle = 0;
750
751 //
752 // set usb debug device address as 0x7F.
753 //
754 Status = UsbDebugPortControlTransfer (UsbDebugPortRegister, &mDebugCommunicationLibUsbSetDebugAddress, 0x0, 0x0, NULL, NULL);
755 if (RETURN_ERROR(Status)) {
756 //
757 // The device can not work well.
758 //
759 Handle->Initialized = USBDBG_NO_DBG_CAB;
760 return Status;
761 }
762
763 //
764 // Start to communicate with Usb Debug Device to see if the attached device is usb debug device or not.
765 //
766 Length = (UINT8)sizeof (USB_DEBUG_PORT_DESCRIPTOR);
767
768 //
769 // Get debug descriptor.
770 //
771 Status = UsbDebugPortControlTransfer (UsbDebugPortRegister, &mDebugCommunicationLibUsbGetDebugDescriptor, 0x7F, 0x0, (UINT8*)&UsbDebugPortDescriptor, &Length);
772 if (RETURN_ERROR(Status)) {
773 //
774 // The device is not a usb debug device.
775 //
776 Handle->Initialized = USBDBG_NO_DBG_CAB;
777 return Status;
778 }
779
780 if (Length != sizeof(USB_DEBUG_PORT_DESCRIPTOR)) {
781 Handle->Initialized = USBDBG_NO_DBG_CAB;
782 return RETURN_DEVICE_ERROR;
783 }
784
785 //
786 // enable the usb debug feature.
787 //
788 Status = UsbDebugPortControlTransfer (UsbDebugPortRegister, &mDebugCommunicationLibUsbSetDebugFeature, 0x7F, 0x0, NULL, NULL);
789 if (RETURN_ERROR(Status)) {
790 //
791 // The device can not work well.
792 //
793 Handle->Initialized = USBDBG_NO_DBG_CAB;
794 return Status;
795 }
796
797 Handle->Initialized = USBDBG_DBG_CAB;
798 }
799
800 //
801 // Set initialized flag
802 //
803 Handle->Initialized = USBDBG_INIT_DONE;
804
805 return RETURN_SUCCESS;
806 }
807
808 /**
809 Read data from debug device and save the datas in buffer.
810
811 Reads NumberOfBytes data bytes from a debug device into the buffer
812 specified by Buffer. The number of bytes actually read is returned.
813 If the return value is less than NumberOfBytes, then the rest operation failed.
814 If NumberOfBytes is zero, then return 0.
815
816 @param Handle Debug port handle.
817 @param Buffer Pointer to the data buffer to store the data read from the debug device.
818 @param NumberOfBytes Number of bytes which will be read.
819 @param Timeout Timeout value for reading from debug device. It unit is Microsecond.
820
821 @retval 0 Read data failed, no data is to be read.
822 @retval >0 Actual number of bytes read from debug device.
823
824 **/
825 UINTN
826 EFIAPI
827 DebugPortReadBuffer (
828 IN DEBUG_PORT_HANDLE Handle,
829 IN UINT8 *Buffer,
830 IN UINTN NumberOfBytes,
831 IN UINTN Timeout
832 )
833 {
834 USB_DEBUG_PORT_HANDLE *UsbDebugPortHandle;
835 USB_DEBUG_PORT_REGISTER *UsbDebugPortRegister;
836 RETURN_STATUS Status;
837 UINT8 Received;
838 UINTN Total;
839 UINTN Remaining;
840 UINT8 Index;
841 UINT8 Length;
842 UINT64 Begin;
843 UINT64 TimeoutTicker;
844 UINT64 TimerRound;
845
846 if (NumberOfBytes == 0 || Buffer == NULL) {
847 return 0;
848 }
849
850 Received = 0;
851 Total = 0;
852 Remaining = 0;
853
854 //
855 // If Handle is NULL, it means memory is ready for use.
856 // Use global variable to store handle value.
857 //
858 if (Handle == NULL) {
859 UsbDebugPortHandle = &mDebugCommunicationLibUsbDebugPortHandle;
860 } else {
861 UsbDebugPortHandle = (USB_DEBUG_PORT_HANDLE *)Handle;
862 }
863
864 if (NeedReinitializeHardware(UsbDebugPortHandle)) {
865 Status = InitializeUsbDebugHardware (UsbDebugPortHandle);
866 if (RETURN_ERROR(Status)) {
867 return 0;
868 }
869 }
870
871 UsbDebugPortRegister = (USB_DEBUG_PORT_REGISTER *)(UINTN)(UsbDebugPortHandle->UsbDebugPortMemoryBase + UsbDebugPortHandle->DebugPortOffset);
872
873 //
874 // First read data from buffer, then read debug port hw to get received data.
875 //
876 if (UsbDebugPortHandle->DataCount > 0) {
877 if (NumberOfBytes <= UsbDebugPortHandle->DataCount) {
878 Total = NumberOfBytes;
879 } else {
880 Total = UsbDebugPortHandle->DataCount;
881 }
882
883 for (Index = 0; Index < Total; Index++) {
884 Buffer[Index] = UsbDebugPortHandle->Data[Index];
885 }
886
887 for (Index = 0; Index < UsbDebugPortHandle->DataCount - Total; Index++) {
888 if (Total + Index >= 8) {
889 return 0;
890 }
891 UsbDebugPortHandle->Data[Index] = UsbDebugPortHandle->Data[Total + Index];
892 }
893 UsbDebugPortHandle->DataCount = (UINT8)(UsbDebugPortHandle->DataCount - (UINT8)Total);
894 }
895
896 //
897 // If Timeout is equal to 0, then it means it should always wait until all datum required are received.
898 //
899 Begin = 0;
900 TimeoutTicker = 0;
901 TimerRound = 0;
902 if (Timeout != 0) {
903 Begin = GetPerformanceCounter ();
904 TimeoutTicker = DivU64x32 (
905 MultU64x64 (
906 UsbDebugPortHandle->TimerFrequency,
907 Timeout
908 ),
909 1000000u
910 );
911 TimerRound = DivU64x64Remainder (
912 TimeoutTicker,
913 DivU64x32 (UsbDebugPortHandle->TimerCycle, 2),
914 &TimeoutTicker
915 );
916 }
917
918 //
919 // Read remaining data by executing one or more usb debug transfer transactions at usb debug port hw.
920 //
921 while (Total < NumberOfBytes) {
922 if (Timeout != 0) {
923 if (TimerRound == 0) {
924 if (IsTimerTimeout (UsbDebugPortHandle, Begin, TimeoutTicker)) {
925 //
926 // If time out occurs.
927 //
928 return 0;
929 }
930 } else {
931 if (IsTimerTimeout (UsbDebugPortHandle, Begin, DivU64x32 (UsbDebugPortHandle->TimerCycle, 2))) {
932 TimerRound --;
933 }
934 }
935 }
936 Remaining = NumberOfBytes - Total;
937 if (Remaining >= USB_DEBUG_PORT_MAX_PACKET_SIZE) {
938 Status = UsbDebugPortIn(UsbDebugPortRegister, Buffer + Total, &Received, INPUT_PID, 0x7f, 0x82, UsbDebugPortHandle->BulkInToggle);
939
940 if (RETURN_ERROR(Status)) {
941 return Total;
942 }
943 } else {
944 Status = UsbDebugPortIn(UsbDebugPortRegister, &UsbDebugPortHandle->Data[0], &Received, INPUT_PID, 0x7f, 0x82, UsbDebugPortHandle->BulkInToggle);
945
946 if (RETURN_ERROR(Status)) {
947 return Total;
948 }
949
950 UsbDebugPortHandle->DataCount = Received;
951
952 if (Remaining <= Received) {
953 Length = (UINT8)Remaining;
954 } else {
955 Length = (UINT8)Received;
956 }
957
958 //
959 // Copy required data from the data buffer to user buffer.
960 //
961 for (Index = 0; Index < Length; Index++) {
962 (Buffer + Total)[Index] = UsbDebugPortHandle->Data[Index];
963 UsbDebugPortHandle->DataCount--;
964 }
965
966 //
967 // reorder the data buffer to make available data arranged from the beginning of the data buffer.
968 //
969 for (Index = 0; Index < Received - Length; Index++) {
970 if (Length + Index >= 8) {
971 return 0;
972 }
973 UsbDebugPortHandle->Data[Index] = UsbDebugPortHandle->Data[Length + Index];
974 }
975 //
976 // fixup the real received length in Buffer.
977 //
978 Received = Length;
979 }
980 UsbDebugPortHandle->BulkInToggle ^= 1;
981 Total += Received;
982 }
983
984 return Total;
985 }
986
987 /**
988 Write data from buffer to debug device.
989
990 Writes NumberOfBytes data bytes from Buffer to the debug device.
991 The number of bytes actually written to the debug device is returned.
992 If the return value is less than NumberOfBytes, then the write operation failed.
993 If NumberOfBytes is zero, then return 0.
994
995 @param Handle Debug port handle.
996 @param Buffer Pointer to the data buffer to be written.
997 @param NumberOfBytes Number of bytes to written to the debug device.
998
999 @retval 0 NumberOfBytes is 0.
1000 @retval >0 The number of bytes written to the debug device.
1001 If this value is less than NumberOfBytes, then the read operation failed.
1002
1003 **/
1004 UINTN
1005 EFIAPI
1006 DebugPortWriteBuffer (
1007 IN DEBUG_PORT_HANDLE Handle,
1008 IN UINT8 *Buffer,
1009 IN UINTN NumberOfBytes
1010 )
1011 {
1012 USB_DEBUG_PORT_HANDLE *UsbDebugPortHandle;
1013 USB_DEBUG_PORT_REGISTER *UsbDebugPortRegister;
1014 RETURN_STATUS Status;
1015 UINT8 Sent;
1016 UINTN Total;
1017 UINT8 ReceivedPid;
1018
1019 if (NumberOfBytes == 0 || Buffer == NULL) {
1020 return 0;
1021 }
1022
1023 Sent = 0;
1024 Total = 0;
1025
1026 //
1027 // If Handle is NULL, it means memory is ready for use.
1028 // Use global variable to store handle value.
1029 //
1030 if (Handle == NULL) {
1031 UsbDebugPortHandle = &mDebugCommunicationLibUsbDebugPortHandle;
1032 } else {
1033 UsbDebugPortHandle = (USB_DEBUG_PORT_HANDLE *)Handle;
1034 }
1035
1036 if (NeedReinitializeHardware(UsbDebugPortHandle)) {
1037 Status = InitializeUsbDebugHardware (UsbDebugPortHandle);
1038 if (RETURN_ERROR(Status)) {
1039 return 0;
1040 }
1041 }
1042
1043 UsbDebugPortRegister = (USB_DEBUG_PORT_REGISTER *)(UINTN)(UsbDebugPortHandle->UsbDebugPortMemoryBase + UsbDebugPortHandle->DebugPortOffset);
1044
1045 while ((Total < NumberOfBytes)) {
1046 if (NumberOfBytes - Total > USB_DEBUG_PORT_MAX_PACKET_SIZE) {
1047 Sent = USB_DEBUG_PORT_MAX_PACKET_SIZE;
1048 } else {
1049 Sent = (UINT8)(NumberOfBytes - Total);
1050 }
1051
1052 Status = UsbDebugPortOut(UsbDebugPortRegister, Buffer + Total, Sent, OUTPUT_PID, 0x7F, 0x01, UsbDebugPortHandle->BulkOutToggle);
1053
1054 if (RETURN_ERROR(Status)) {
1055 return Total;
1056 }
1057
1058 ReceivedPid = (MmioRead8((UINTN)&UsbDebugPortRegister->ReceivedPid));
1059 //
1060 // If received a NAK_PID on write transaction, it means the usb debug device is busy and can not handle this transaction.
1061 // should send the packet again.
1062 //
1063 if (ReceivedPid == NAK_PID) {
1064 Sent = 0;
1065 } else {
1066 UsbDebugPortHandle->BulkOutToggle ^= 1;
1067 }
1068 Total += Sent;
1069 }
1070 return Total;
1071 }
1072
1073 /**
1074 Polls a debug device to see if there is any data waiting to be read.
1075
1076 Polls a debug device to see if there is any data waiting to be read.
1077 If there is data waiting to be read from the debug device, then TRUE is returned.
1078 If there is no data waiting to be read from the debug device, then FALSE is returned.
1079
1080 @param Handle Debug port handle.
1081
1082 @retval TRUE Data is waiting to be read from the debug device.
1083 @retval FALSE There is no data waiting to be read from the serial device.
1084
1085 **/
1086 BOOLEAN
1087 EFIAPI
1088 DebugPortPollBuffer (
1089 IN DEBUG_PORT_HANDLE Handle
1090 )
1091 {
1092 USB_DEBUG_PORT_HANDLE *UsbDebugPortHandle;
1093 USB_DEBUG_PORT_REGISTER *UsbDebugPortRegister;
1094 UINT8 Length;
1095 UINT8 Index;
1096 RETURN_STATUS Status;
1097
1098 //
1099 // If Handle is NULL, it means memory is ready for use.
1100 // Use global variable to store handle value.
1101 //
1102 if (Handle == NULL) {
1103 UsbDebugPortHandle = &mDebugCommunicationLibUsbDebugPortHandle;
1104 } else {
1105 UsbDebugPortHandle = (USB_DEBUG_PORT_HANDLE *)Handle;
1106 }
1107
1108 if (NeedReinitializeHardware(UsbDebugPortHandle)) {
1109 Status = InitializeUsbDebugHardware(UsbDebugPortHandle);
1110 if (RETURN_ERROR(Status)) {
1111 return FALSE;
1112 }
1113 }
1114
1115 //
1116 // If the data buffer is not empty, then return TRUE directly.
1117 // else initialize a usb read transaction and read data to the data buffer.
1118 //
1119 if (UsbDebugPortHandle->DataCount != 0) {
1120 return TRUE;
1121 }
1122
1123 UsbDebugPortRegister = (USB_DEBUG_PORT_REGISTER *)(UINTN)(UsbDebugPortHandle->UsbDebugPortMemoryBase + UsbDebugPortHandle->DebugPortOffset);
1124
1125 UsbDebugPortRegister->TokenPid = INPUT_PID;
1126 if (UsbDebugPortHandle->BulkInToggle == 0) {
1127 UsbDebugPortRegister->SendPid = DATA0_PID;
1128 } else {
1129 UsbDebugPortRegister->SendPid = DATA1_PID;
1130 }
1131 UsbDebugPortRegister->UsbAddress = 0x7F;
1132 UsbDebugPortRegister->UsbEndPoint = 0x82 & 0x0F;
1133
1134 //
1135 // Clearing W/R bit to indicate it's a READ operation
1136 //
1137 MmioAnd32((UINTN)&UsbDebugPortRegister->ControlStatus, (UINT32)~BIT4);
1138 //
1139 // Setting GO bit as well as clearing DONE bit
1140 //
1141 MmioOr32((UINTN)&UsbDebugPortRegister->ControlStatus, (UINT32)BIT5);
1142
1143 //
1144 // Wait for completing the request
1145 //
1146 while ((MmioRead32((UINTN)&UsbDebugPortRegister->ControlStatus) & (UINT32)BIT16) == 0) {
1147 if ((MmioRead32((UINTN)&UsbDebugPortRegister->ControlStatus) & (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_ENABLE))
1148 != (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_ENABLE)) {
1149 return FALSE;
1150 }
1151 }
1152
1153 if ((MmioRead32((UINTN)&UsbDebugPortRegister->ControlStatus)) & BIT6) {
1154 return FALSE;
1155 }
1156
1157 Length = (UINT8)(MmioRead32((UINTN)&UsbDebugPortRegister->ControlStatus) & 0xF);
1158
1159 if (Length > 8) {
1160 return FALSE;
1161 }
1162
1163 UsbDebugPortHandle->BulkInToggle ^= 1;
1164
1165 if (Length == 0) {
1166 return FALSE;
1167 }
1168
1169 for (Index = 0; Index < Length; Index++) {
1170 UsbDebugPortHandle->Data[Index] = UsbDebugPortRegister->DataBuffer[Index];
1171 }
1172 UsbDebugPortHandle->DataCount = Length;
1173
1174 return TRUE;
1175 }
1176
1177 /**
1178 Initialize the debug port.
1179
1180 If Function is not NULL, Debug Communication Libary will call this function
1181 by passing in the Context to be the first parameter. If needed, Debug Communication
1182 Library will create one debug port handle to be the second argument passing in
1183 calling the Function, otherwise it will pass NULL to be the second argument of
1184 Function.
1185
1186 If Function is NULL, and Context is not NULL, the Debug Communication Library could
1187 a) Return the same handle as passed in (as Context parameter).
1188 b) Ignore the input Context parameter and create new hanlde to be returned.
1189
1190 If parameter Function is NULL and Context is NULL, Debug Communication Library could
1191 created a new handle if needed and return it, otherwise it will return NULL.
1192
1193 @param[in] Context Context needed by callback function; it was optional.
1194 @param[in] Function Continue function called by Debug Communication library;
1195 it was optional.
1196
1197 @return The debug port handle created by Debug Communication Library if Function
1198 is not NULL.
1199
1200 **/
1201 DEBUG_PORT_HANDLE
1202 EFIAPI
1203 DebugPortInitialize (
1204 IN VOID *Context,
1205 IN DEBUG_PORT_CONTINUE Function
1206 )
1207 {
1208 RETURN_STATUS Status;
1209 USB_DEBUG_PORT_HANDLE Handle;
1210 USB_DEBUG_PORT_HANDLE *UsbDebugPortHandle;
1211 UINT64 TimerStartValue;
1212 UINT64 TimerEndValue;
1213
1214 //
1215 // Validate the PCD PcdDebugPortHandleBufferSize value
1216 //
1217 ASSERT (PcdGet16 (PcdDebugPortHandleBufferSize) == sizeof (USB_DEBUG_PORT_HANDLE));
1218
1219 if (Function == NULL && Context != NULL) {
1220 UsbDebugPortHandle = (USB_DEBUG_PORT_HANDLE *)Context;
1221 } else {
1222 ZeroMem(&Handle, sizeof (USB_DEBUG_PORT_HANDLE));
1223 UsbDebugPortHandle = &Handle;
1224 }
1225
1226 UsbDebugPortHandle->TimerFrequency = GetPerformanceCounterProperties (
1227 &TimerStartValue,
1228 &TimerEndValue
1229 );
1230 DEBUG ((EFI_D_INFO, "USB Debug Port: TimerFrequency = 0x%lx\n", UsbDebugPortHandle->TimerFrequency));
1231 DEBUG ((EFI_D_INFO, "USB Debug Port: TimerStartValue = 0x%lx\n", TimerStartValue));
1232 DEBUG ((EFI_D_INFO, "USB Debug Port: TimerEndValue = 0x%lx\n", TimerEndValue));
1233
1234 if (TimerEndValue < TimerStartValue) {
1235 UsbDebugPortHandle->TimerCountDown = TRUE;
1236 UsbDebugPortHandle->TimerCycle = TimerStartValue - TimerEndValue;
1237 } else {
1238 UsbDebugPortHandle->TimerCountDown = FALSE;
1239 UsbDebugPortHandle->TimerCycle = TimerEndValue - TimerStartValue;
1240 }
1241
1242 if (Function == NULL && Context != NULL) {
1243 return (DEBUG_PORT_HANDLE *) Context;
1244 }
1245
1246 Status = CalculateUsbDebugPortBar(&Handle.DebugPortOffset, &Handle.DebugPortBarNumber);
1247 if (RETURN_ERROR (Status)) {
1248 DEBUG ((EFI_D_ERROR, "UsbDbg: the pci device pointed by PcdUsbEhciPciAddress is not EHCI host controller or does not support debug port capability!\n"));
1249 goto Exit;
1250 }
1251
1252 Handle.EhciMemoryBase = 0xFFFFFC00 & PciRead32(PcdGet32(PcdUsbEhciPciAddress) + PCI_BASE_ADDRESSREG_OFFSET);
1253
1254 if (Handle.EhciMemoryBase == 0) {
1255 //
1256 // Usb Debug Port MMIO Space Is Not Enabled. Assumption here that DebugPortBase is zero
1257 //
1258 PciWrite32(PcdGet32(PcdUsbEhciPciAddress) + PCI_BASE_ADDRESSREG_OFFSET, PcdGet32(PcdUsbEhciMemorySpaceBase));
1259 Handle.EhciMemoryBase = 0xFFFFFC00 & PciRead32(PcdGet32(PcdUsbEhciPciAddress) + PCI_BASE_ADDRESSREG_OFFSET);
1260 }
1261
1262 Handle.UsbDebugPortMemoryBase = 0xFFFFFC00 & PciRead32(PcdGet32(PcdUsbEhciPciAddress) + PCI_BASE_ADDRESSREG_OFFSET + Handle.DebugPortBarNumber * 4);
1263
1264 if (Handle.UsbDebugPortMemoryBase == 0) {
1265 //
1266 // Usb Debug Port MMIO Space Is Not Enabled. Assumption here that DebugPortBase is zero
1267 //
1268 PciWrite32(PcdGet32(PcdUsbEhciPciAddress) + PCI_BASE_ADDRESSREG_OFFSET + Handle.DebugPortBarNumber * 4, PcdGet32(PcdUsbDebugPortMemorySpaceBase));
1269 Handle.UsbDebugPortMemoryBase = 0xFFFFFC00 & PciRead32(PcdGet32(PcdUsbEhciPciAddress) + PCI_BASE_ADDRESSREG_OFFSET + Handle.DebugPortBarNumber * 4);
1270 }
1271
1272 Handle.Initialized = USBDBG_RESET;
1273
1274 if (NeedReinitializeHardware(&Handle)) {
1275 DEBUG ((EFI_D_ERROR, "UsbDbg: Start EHCI debug port initialization!\n"));
1276 Status = InitializeUsbDebugHardware (&Handle);
1277 if (RETURN_ERROR(Status)) {
1278 DEBUG ((EFI_D_ERROR, "UsbDbg: Failed, please check if USB debug cable is plugged into EHCI debug port correctly!\n"));
1279 goto Exit;
1280 }
1281 }
1282
1283 Exit:
1284
1285 if (Function != NULL) {
1286 Function (Context, &Handle);
1287 } else {
1288 CopyMem(&mDebugCommunicationLibUsbDebugPortHandle, &Handle, sizeof (USB_DEBUG_PORT_HANDLE));
1289 }
1290
1291 return (DEBUG_PORT_HANDLE)(UINTN)&mDebugCommunicationLibUsbDebugPortHandle;
1292 }
1293