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