]> git.proxmox.com Git - mirror_edk2.git/blob - SourceLevelDebugPkg/Library/DebugCommunicationLibUsb3/DebugCommunicationLibUsb3Pei.c
SourceLevelDebugPkg: Apply uncrustify changes
[mirror_edk2.git] / SourceLevelDebugPkg / Library / DebugCommunicationLibUsb3 / DebugCommunicationLibUsb3Pei.c
1 /** @file
2 Debug Port Library implementation based on usb3 debug port.
3
4 Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include <PiPei.h>
10 #include <Library/PeiServicesLib.h>
11 #include <Library/HobLib.h>
12 #include <Ppi/MemoryDiscovered.h>
13 #include <Ppi/IoMmu.h>
14 #include "DebugCommunicationLibUsb3Internal.h"
15
16 GUID gUsb3DbgGuid = USB3_DBG_GUID;
17
18 /**
19 USB3 IOMMU PPI notify.
20
21 @param[in] PeiServices Pointer to PEI Services Table.
22 @param[in] NotifyDesc Pointer to the descriptor for the Notification event that
23 caused this function to execute.
24 @param[in] Ppi Pointer to the PPI data associated with this function.
25
26 @retval EFI_STATUS Always return EFI_SUCCESS
27 **/
28 EFI_STATUS
29 EFIAPI
30 Usb3IoMmuPpiNotify (
31 IN EFI_PEI_SERVICES **PeiServices,
32 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
33 IN VOID *Ppi
34 )
35 {
36 USB3_DEBUG_PORT_HANDLE *Instance;
37
38 DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));
39
40 Instance = GetUsb3DebugPortInstance ();
41 ASSERT (Instance != NULL);
42 if (!Instance->Ready) {
43 return EFI_SUCCESS;
44 }
45
46 Instance->InNotify = TRUE;
47
48 //
49 // Reinitialize USB3 debug port with granted DMA buffer from IOMMU PPI.
50 //
51 InitializeUsbDebugHardware (Instance);
52
53 //
54 // Wait some time for host to be ready after re-initialization.
55 //
56 MicroSecondDelay (1000000);
57
58 Instance->InNotify = FALSE;
59
60 return EFI_SUCCESS;
61 }
62
63 EFI_PEI_NOTIFY_DESCRIPTOR mUsb3IoMmuPpiNotifyDesc = {
64 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
65 &gEdkiiIoMmuPpiGuid,
66 Usb3IoMmuPpiNotify
67 };
68
69 /**
70 Allocates pages that are suitable for an OperationBusMasterCommonBuffer or
71 OperationBusMasterCommonBuffer64 mapping.
72
73 @param IoMmu Pointer to IOMMU PPI.
74 @param Pages The number of pages to allocate.
75 @param HostAddress A pointer to store the base system memory address of the
76 allocated range.
77 @param DeviceAddress The resulting map address for the bus master PCI controller to use to
78 access the hosts HostAddress.
79 @param Mapping A resulting value to pass to Unmap().
80
81 @retval EFI_SUCCESS The requested memory pages were allocated.
82 @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are
83 MEMORY_WRITE_COMBINE and MEMORY_CACHED.
84 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
85 @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
86
87 **/
88 EFI_STATUS
89 IoMmuAllocateBuffer (
90 IN EDKII_IOMMU_PPI *IoMmu,
91 IN UINTN Pages,
92 OUT VOID **HostAddress,
93 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
94 OUT VOID **Mapping
95 )
96 {
97 EFI_STATUS Status;
98 UINTN NumberOfBytes;
99
100 *HostAddress = NULL;
101 *DeviceAddress = 0;
102 *Mapping = NULL;
103
104 Status = IoMmu->AllocateBuffer (
105 IoMmu,
106 EfiRuntimeServicesData,
107 Pages,
108 HostAddress,
109 0
110 );
111 if (EFI_ERROR (Status)) {
112 return EFI_OUT_OF_RESOURCES;
113 }
114
115 NumberOfBytes = EFI_PAGES_TO_SIZE (Pages);
116 Status = IoMmu->Map (
117 IoMmu,
118 EdkiiIoMmuOperationBusMasterCommonBuffer,
119 *HostAddress,
120 &NumberOfBytes,
121 DeviceAddress,
122 Mapping
123 );
124 if (EFI_ERROR (Status)) {
125 IoMmu->FreeBuffer (IoMmu, Pages, *HostAddress);
126 *HostAddress = NULL;
127 return EFI_OUT_OF_RESOURCES;
128 }
129
130 Status = IoMmu->SetAttribute (
131 IoMmu,
132 *Mapping,
133 EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE
134 );
135 if (EFI_ERROR (Status)) {
136 IoMmu->Unmap (IoMmu, *Mapping);
137 IoMmu->FreeBuffer (IoMmu, Pages, *HostAddress);
138 *Mapping = NULL;
139 *HostAddress = NULL;
140 return Status;
141 }
142
143 return Status;
144 }
145
146 /**
147 USB3 get IOMMU PPI.
148
149 @return Pointer to IOMMU PPI.
150
151 **/
152 EDKII_IOMMU_PPI *
153 Usb3GetIoMmu (
154 VOID
155 )
156 {
157 EFI_STATUS Status;
158 EDKII_IOMMU_PPI *IoMmu;
159
160 IoMmu = NULL;
161 Status = PeiServicesLocatePpi (
162 &gEdkiiIoMmuPpiGuid,
163 0,
164 NULL,
165 (VOID **)&IoMmu
166 );
167 if (!EFI_ERROR (Status) && (IoMmu != NULL)) {
168 return IoMmu;
169 }
170
171 return NULL;
172 }
173
174 /**
175 Return USB3 debug instance address pointer.
176
177 **/
178 EFI_PHYSICAL_ADDRESS *
179 GetUsb3DebugPortInstanceAddrPtr (
180 VOID
181 )
182 {
183 USB3_DEBUG_PORT_HANDLE *Instance;
184 EFI_PHYSICAL_ADDRESS *AddrPtr;
185 EFI_PEI_HOB_POINTERS Hob;
186 EFI_STATUS Status;
187
188 Hob.Raw = GetFirstGuidHob (&gUsb3DbgGuid);
189 if (Hob.Raw == NULL) {
190 //
191 // Build HOB for the local instance and the buffer to save instance address pointer.
192 // Use the local instance in HOB temporarily.
193 //
194 AddrPtr = BuildGuidHob (
195 &gUsb3DbgGuid,
196 sizeof (EFI_PHYSICAL_ADDRESS) + sizeof (USB3_DEBUG_PORT_HANDLE)
197 );
198 ASSERT (AddrPtr != NULL);
199 ZeroMem (AddrPtr, sizeof (EFI_PHYSICAL_ADDRESS) + sizeof (USB3_DEBUG_PORT_HANDLE));
200 Instance = (USB3_DEBUG_PORT_HANDLE *)(AddrPtr + 1);
201 *AddrPtr = (EFI_PHYSICAL_ADDRESS)(UINTN)Instance;
202 Instance->FromHob = TRUE;
203 Instance->Initialized = USB3DBG_UNINITIALIZED;
204 if (Usb3GetIoMmu () == NULL) {
205 Status = PeiServicesNotifyPpi (&mUsb3IoMmuPpiNotifyDesc);
206 ASSERT_EFI_ERROR (Status);
207 }
208 } else {
209 AddrPtr = GET_GUID_HOB_DATA (Hob.Guid);
210 }
211
212 return AddrPtr;
213 }
214
215 /**
216 Allocate aligned memory for XHC's usage.
217
218 @param BufferSize The size, in bytes, of the Buffer.
219
220 @return A pointer to the allocated buffer or NULL if allocation fails.
221
222 **/
223 VOID *
224 AllocateAlignBuffer (
225 IN UINTN BufferSize
226 )
227 {
228 VOID *Buf;
229 EFI_PHYSICAL_ADDRESS Address;
230 EFI_STATUS Status;
231 VOID *MemoryDiscoveredPpi;
232 EDKII_IOMMU_PPI *IoMmu;
233 VOID *HostAddress;
234 VOID *Mapping;
235
236 Buf = NULL;
237
238 //
239 // Make sure the allocated memory is physical memory.
240 //
241 Status = PeiServicesLocatePpi (
242 &gEfiPeiMemoryDiscoveredPpiGuid,
243 0,
244 NULL,
245 (VOID **)&MemoryDiscoveredPpi
246 );
247 if (!EFI_ERROR (Status)) {
248 IoMmu = Usb3GetIoMmu ();
249 if (IoMmu != NULL) {
250 Status = IoMmuAllocateBuffer (
251 IoMmu,
252 EFI_SIZE_TO_PAGES (BufferSize),
253 &HostAddress,
254 &Address,
255 &Mapping
256 );
257 if (!EFI_ERROR (Status)) {
258 ASSERT (Address == ((EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress));
259 Buf = (VOID *)(UINTN)Address;
260 }
261 } else {
262 Status = PeiServicesAllocatePages (
263 EfiACPIMemoryNVS,
264 EFI_SIZE_TO_PAGES (BufferSize),
265 &Address
266 );
267 if (!EFI_ERROR (Status)) {
268 Buf = (VOID *)(UINTN)Address;
269 }
270 }
271 }
272
273 return Buf;
274 }