]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Pci/EhciPei/DmaMem.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / EhciPei / DmaMem.c
CommitLineData
2c656af0
SZ
1/** @file\r
2The DMA memory help functions.\r
3\r
4Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>\r
5\r
9d510e61 6SPDX-License-Identifier: BSD-2-Clause-Patent\r
2c656af0
SZ
7\r
8**/\r
9\r
10#include "EhcPeim.h"\r
11\r
12/**\r
13 Provides the controller-specific addresses required to access system memory from a\r
14 DMA bus master.\r
15\r
16 @param IoMmu Pointer to IOMMU PPI.\r
17 @param Operation Indicates if the bus master is going to read or write to system memory.\r
18 @param HostAddress The system memory address to map to the PCI controller.\r
19 @param NumberOfBytes On input the number of bytes to map. On output the number of bytes\r
20 that were mapped.\r
21 @param DeviceAddress The resulting map address for the bus master PCI controller to use to\r
22 access the hosts HostAddress.\r
23 @param Mapping A resulting value to pass to Unmap().\r
24\r
25 @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes.\r
26 @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer.\r
27 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
28 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
29 @retval EFI_DEVICE_ERROR The system hardware could not map the requested address.\r
30\r
31**/\r
32EFI_STATUS\r
33IoMmuMap (\r
34 IN EDKII_IOMMU_PPI *IoMmu,\r
35 IN EDKII_IOMMU_OPERATION Operation,\r
36 IN VOID *HostAddress,\r
37 IN OUT UINTN *NumberOfBytes,\r
38 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,\r
39 OUT VOID **Mapping\r
40 )\r
41{\r
1436aea4
MK
42 EFI_STATUS Status;\r
43 UINT64 Attribute;\r
2c656af0
SZ
44\r
45 if (IoMmu != NULL) {\r
46 Status = IoMmu->Map (\r
47 IoMmu,\r
48 Operation,\r
49 HostAddress,\r
50 NumberOfBytes,\r
51 DeviceAddress,\r
52 Mapping\r
53 );\r
54 if (EFI_ERROR (Status)) {\r
55 return EFI_OUT_OF_RESOURCES;\r
56 }\r
1436aea4 57\r
2c656af0 58 switch (Operation) {\r
1436aea4
MK
59 case EdkiiIoMmuOperationBusMasterRead:\r
60 case EdkiiIoMmuOperationBusMasterRead64:\r
61 Attribute = EDKII_IOMMU_ACCESS_READ;\r
62 break;\r
63 case EdkiiIoMmuOperationBusMasterWrite:\r
64 case EdkiiIoMmuOperationBusMasterWrite64:\r
65 Attribute = EDKII_IOMMU_ACCESS_WRITE;\r
66 break;\r
67 case EdkiiIoMmuOperationBusMasterCommonBuffer:\r
68 case EdkiiIoMmuOperationBusMasterCommonBuffer64:\r
69 Attribute = EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE;\r
70 break;\r
71 default:\r
72 ASSERT (FALSE);\r
73 return EFI_INVALID_PARAMETER;\r
2c656af0 74 }\r
1436aea4 75\r
2c656af0
SZ
76 Status = IoMmu->SetAttribute (\r
77 IoMmu,\r
78 *Mapping,\r
79 Attribute\r
80 );\r
81 if (EFI_ERROR (Status)) {\r
82 IoMmu->Unmap (IoMmu, Mapping);\r
83 *Mapping = NULL;\r
84 return Status;\r
85 }\r
86 } else {\r
1436aea4
MK
87 *DeviceAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress;\r
88 *Mapping = NULL;\r
89 Status = EFI_SUCCESS;\r
2c656af0 90 }\r
1436aea4 91\r
2c656af0
SZ
92 return Status;\r
93}\r
94\r
95/**\r
96 Completes the Map() operation and releases any corresponding resources.\r
97\r
98 @param IoMmu Pointer to IOMMU PPI.\r
99 @param Mapping The mapping value returned from Map().\r
100\r
101**/\r
102VOID\r
103IoMmuUnmap (\r
1436aea4
MK
104 IN EDKII_IOMMU_PPI *IoMmu,\r
105 IN VOID *Mapping\r
2c656af0
SZ
106 )\r
107{\r
108 if (IoMmu != NULL) {\r
109 IoMmu->SetAttribute (IoMmu, Mapping, 0);\r
110 IoMmu->Unmap (IoMmu, Mapping);\r
111 }\r
112}\r
113\r
114/**\r
115 Allocates pages that are suitable for an OperationBusMasterCommonBuffer or\r
116 OperationBusMasterCommonBuffer64 mapping.\r
117\r
118 @param IoMmu Pointer to IOMMU PPI.\r
119 @param Pages The number of pages to allocate.\r
120 @param HostAddress A pointer to store the base system memory address of the\r
121 allocated range.\r
122 @param DeviceAddress The resulting map address for the bus master PCI controller to use to\r
123 access the hosts HostAddress.\r
124 @param Mapping A resulting value to pass to Unmap().\r
125\r
126 @retval EFI_SUCCESS The requested memory pages were allocated.\r
127 @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are\r
128 MEMORY_WRITE_COMBINE and MEMORY_CACHED.\r
129 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
130 @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.\r
131\r
132**/\r
133EFI_STATUS\r
134IoMmuAllocateBuffer (\r
135 IN EDKII_IOMMU_PPI *IoMmu,\r
136 IN UINTN Pages,\r
137 OUT VOID **HostAddress,\r
138 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,\r
139 OUT VOID **Mapping\r
140 )\r
141{\r
142 EFI_STATUS Status;\r
143 UINTN NumberOfBytes;\r
144 EFI_PHYSICAL_ADDRESS HostPhyAddress;\r
145\r
1436aea4 146 *HostAddress = NULL;\r
2c656af0 147 *DeviceAddress = 0;\r
1436aea4 148 *Mapping = NULL;\r
2c656af0
SZ
149\r
150 if (IoMmu != NULL) {\r
151 Status = IoMmu->AllocateBuffer (\r
152 IoMmu,\r
153 EfiBootServicesData,\r
154 Pages,\r
155 HostAddress,\r
156 0\r
157 );\r
158 if (EFI_ERROR (Status)) {\r
159 return EFI_OUT_OF_RESOURCES;\r
160 }\r
161\r
162 NumberOfBytes = EFI_PAGES_TO_SIZE (Pages);\r
1436aea4
MK
163 Status = IoMmu->Map (\r
164 IoMmu,\r
165 EdkiiIoMmuOperationBusMasterCommonBuffer,\r
166 *HostAddress,\r
167 &NumberOfBytes,\r
168 DeviceAddress,\r
169 Mapping\r
170 );\r
2c656af0
SZ
171 if (EFI_ERROR (Status)) {\r
172 IoMmu->FreeBuffer (IoMmu, Pages, *HostAddress);\r
173 *HostAddress = NULL;\r
174 return EFI_OUT_OF_RESOURCES;\r
175 }\r
1436aea4 176\r
2c656af0
SZ
177 Status = IoMmu->SetAttribute (\r
178 IoMmu,\r
179 *Mapping,\r
180 EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE\r
181 );\r
182 if (EFI_ERROR (Status)) {\r
183 IoMmu->Unmap (IoMmu, *Mapping);\r
184 IoMmu->FreeBuffer (IoMmu, Pages, *HostAddress);\r
1436aea4 185 *Mapping = NULL;\r
2c656af0
SZ
186 *HostAddress = NULL;\r
187 return Status;\r
188 }\r
189 } else {\r
190 Status = PeiServicesAllocatePages (\r
191 EfiBootServicesCode,\r
192 Pages,\r
193 &HostPhyAddress\r
194 );\r
195 if (EFI_ERROR (Status)) {\r
196 return EFI_OUT_OF_RESOURCES;\r
197 }\r
1436aea4
MK
198\r
199 *HostAddress = (VOID *)(UINTN)HostPhyAddress;\r
2c656af0 200 *DeviceAddress = HostPhyAddress;\r
1436aea4 201 *Mapping = NULL;\r
2c656af0 202 }\r
1436aea4 203\r
2c656af0
SZ
204 return Status;\r
205}\r
206\r
207/**\r
208 Frees memory that was allocated with AllocateBuffer().\r
209\r
210 @param IoMmu Pointer to IOMMU PPI.\r
211 @param Pages The number of pages to free.\r
212 @param HostAddress The base system memory address of the allocated range.\r
213 @param Mapping The mapping value returned from Map().\r
214\r
215**/\r
216VOID\r
217IoMmuFreeBuffer (\r
1436aea4
MK
218 IN EDKII_IOMMU_PPI *IoMmu,\r
219 IN UINTN Pages,\r
220 IN VOID *HostAddress,\r
221 IN VOID *Mapping\r
2c656af0
SZ
222 )\r
223{\r
224 if (IoMmu != NULL) {\r
225 IoMmu->SetAttribute (IoMmu, Mapping, 0);\r
226 IoMmu->Unmap (IoMmu, Mapping);\r
227 IoMmu->FreeBuffer (IoMmu, Pages, HostAddress);\r
228 }\r
229}\r
230\r
231/**\r
232 Initialize IOMMU.\r
233\r
234 @param IoMmu Pointer to pointer to IOMMU PPI.\r
235\r
236**/\r
237VOID\r
238IoMmuInit (\r
1436aea4 239 OUT EDKII_IOMMU_PPI **IoMmu\r
2c656af0
SZ
240 )\r
241{\r
242 PeiServicesLocatePpi (\r
243 &gEdkiiIoMmuPpiGuid,\r
244 0,\r
245 NULL,\r
1436aea4 246 (VOID **)IoMmu\r
2c656af0
SZ
247 );\r
248}\r