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