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