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