]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Pci/EhciPei/DmaMem.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[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
42 EFI_STATUS Status;\r
43 UINT64 Attribute;\r
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
57 switch (Operation) {\r
58 case EdkiiIoMmuOperationBusMasterRead:\r
59 case EdkiiIoMmuOperationBusMasterRead64:\r
60 Attribute = EDKII_IOMMU_ACCESS_READ;\r
61 break;\r
62 case EdkiiIoMmuOperationBusMasterWrite:\r
63 case EdkiiIoMmuOperationBusMasterWrite64:\r
64 Attribute = EDKII_IOMMU_ACCESS_WRITE;\r
65 break;\r
66 case EdkiiIoMmuOperationBusMasterCommonBuffer:\r
67 case EdkiiIoMmuOperationBusMasterCommonBuffer64:\r
68 Attribute = EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE;\r
69 break;\r
70 default:\r
71 ASSERT(FALSE);\r
72 return EFI_INVALID_PARAMETER;\r
73 }\r
74 Status = IoMmu->SetAttribute (\r
75 IoMmu,\r
76 *Mapping,\r
77 Attribute\r
78 );\r
79 if (EFI_ERROR (Status)) {\r
80 IoMmu->Unmap (IoMmu, Mapping);\r
81 *Mapping = NULL;\r
82 return Status;\r
83 }\r
84 } else {\r
85 *DeviceAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;\r
86 *Mapping = NULL;\r
87 Status = EFI_SUCCESS;\r
88 }\r
89 return Status;\r
90}\r
91\r
92/**\r
93 Completes the Map() operation and releases any corresponding resources.\r
94\r
95 @param IoMmu Pointer to IOMMU PPI.\r
96 @param Mapping The mapping value returned from Map().\r
97\r
98**/\r
99VOID\r
100IoMmuUnmap (\r
101 IN EDKII_IOMMU_PPI *IoMmu,\r
102 IN VOID *Mapping\r
103 )\r
104{\r
105 if (IoMmu != NULL) {\r
106 IoMmu->SetAttribute (IoMmu, Mapping, 0);\r
107 IoMmu->Unmap (IoMmu, Mapping);\r
108 }\r
109}\r
110\r
111/**\r
112 Allocates pages that are suitable for an OperationBusMasterCommonBuffer or\r
113 OperationBusMasterCommonBuffer64 mapping.\r
114\r
115 @param IoMmu Pointer to IOMMU PPI.\r
116 @param Pages The number of pages to allocate.\r
117 @param HostAddress A pointer to store the base system memory address of the\r
118 allocated range.\r
119 @param DeviceAddress The resulting map address for the bus master PCI controller to use to\r
120 access the hosts HostAddress.\r
121 @param Mapping A resulting value to pass to Unmap().\r
122\r
123 @retval EFI_SUCCESS The requested memory pages were allocated.\r
124 @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are\r
125 MEMORY_WRITE_COMBINE and MEMORY_CACHED.\r
126 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
127 @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.\r
128\r
129**/\r
130EFI_STATUS\r
131IoMmuAllocateBuffer (\r
132 IN EDKII_IOMMU_PPI *IoMmu,\r
133 IN UINTN Pages,\r
134 OUT VOID **HostAddress,\r
135 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,\r
136 OUT VOID **Mapping\r
137 )\r
138{\r
139 EFI_STATUS Status;\r
140 UINTN NumberOfBytes;\r
141 EFI_PHYSICAL_ADDRESS HostPhyAddress;\r
142\r
143 *HostAddress = NULL;\r
144 *DeviceAddress = 0;\r
145 *Mapping = NULL;\r
146\r
147 if (IoMmu != NULL) {\r
148 Status = IoMmu->AllocateBuffer (\r
149 IoMmu,\r
150 EfiBootServicesData,\r
151 Pages,\r
152 HostAddress,\r
153 0\r
154 );\r
155 if (EFI_ERROR (Status)) {\r
156 return EFI_OUT_OF_RESOURCES;\r
157 }\r
158\r
159 NumberOfBytes = EFI_PAGES_TO_SIZE (Pages);\r
160 Status = IoMmu->Map (\r
161 IoMmu,\r
162 EdkiiIoMmuOperationBusMasterCommonBuffer,\r
163 *HostAddress,\r
164 &NumberOfBytes,\r
165 DeviceAddress,\r
166 Mapping\r
167 );\r
168 if (EFI_ERROR (Status)) {\r
169 IoMmu->FreeBuffer (IoMmu, Pages, *HostAddress);\r
170 *HostAddress = NULL;\r
171 return EFI_OUT_OF_RESOURCES;\r
172 }\r
173 Status = IoMmu->SetAttribute (\r
174 IoMmu,\r
175 *Mapping,\r
176 EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE\r
177 );\r
178 if (EFI_ERROR (Status)) {\r
179 IoMmu->Unmap (IoMmu, *Mapping);\r
180 IoMmu->FreeBuffer (IoMmu, Pages, *HostAddress);\r
181 *Mapping = NULL;\r
182 *HostAddress = NULL;\r
183 return Status;\r
184 }\r
185 } else {\r
186 Status = PeiServicesAllocatePages (\r
187 EfiBootServicesCode,\r
188 Pages,\r
189 &HostPhyAddress\r
190 );\r
191 if (EFI_ERROR (Status)) {\r
192 return EFI_OUT_OF_RESOURCES;\r
193 }\r
194 *HostAddress = (VOID *) (UINTN) HostPhyAddress;\r
195 *DeviceAddress = HostPhyAddress;\r
196 *Mapping = NULL;\r
197 }\r
198 return Status;\r
199}\r
200\r
201/**\r
202 Frees memory that was allocated with AllocateBuffer().\r
203\r
204 @param IoMmu Pointer to IOMMU PPI.\r
205 @param Pages The number of pages to free.\r
206 @param HostAddress The base system memory address of the allocated range.\r
207 @param Mapping The mapping value returned from Map().\r
208\r
209**/\r
210VOID\r
211IoMmuFreeBuffer (\r
212 IN EDKII_IOMMU_PPI *IoMmu,\r
213 IN UINTN Pages,\r
214 IN VOID *HostAddress,\r
215 IN VOID *Mapping\r
216 )\r
217{\r
218 if (IoMmu != NULL) {\r
219 IoMmu->SetAttribute (IoMmu, Mapping, 0);\r
220 IoMmu->Unmap (IoMmu, Mapping);\r
221 IoMmu->FreeBuffer (IoMmu, Pages, HostAddress);\r
222 }\r
223}\r
224\r
225/**\r
226 Initialize IOMMU.\r
227\r
228 @param IoMmu Pointer to pointer to IOMMU PPI.\r
229\r
230**/\r
231VOID\r
232IoMmuInit (\r
233 OUT EDKII_IOMMU_PPI **IoMmu\r
234 )\r
235{\r
236 PeiServicesLocatePpi (\r
237 &gEdkiiIoMmuPpiGuid,\r
238 0,\r
239 NULL,\r
240 (VOID **) IoMmu\r
241 );\r
242}\r
243\r