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