VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugCommunicationLibUsb3/DebugCommunicationLibUsb3Pei.c

Last change on this file was 101291, checked in by vboxsync, 16 months ago

EFI/FirmwareNew: Make edk2-stable202308 build on all supported platforms (using gcc at least, msvc not tested yet), bugref:4643

  • Property svn:eol-style set to native
File size: 7.2 KB
Line 
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
16GUID 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**/
28EFI_STATUS
29EFIAPI
30Usb3IoMmuPpiNotify (
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", __func__));
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
63EFI_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**/
88EFI_STATUS
89IoMmuAllocateBuffer (
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**/
152EDKII_IOMMU_PPI *
153Usb3GetIoMmu (
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**/
178EFI_PHYSICAL_ADDRESS *
179GetUsb3DebugPortInstanceAddrPtr (
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**/
223VOID *
224AllocateAlignBuffer (
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}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette