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