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