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