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