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