]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PciCfg2.c
Merge the PI enabling works from the branch
[mirror_edk2.git] / MdeModulePkg / Universal / PcatSingleSegmentPciCfg2Pei / PciCfg2.c
CommitLineData
12232778 1/**\r
2\r
3 Copyright (c) 2006 - 2007, Intel Corporation\r
4 All rights reserved. This program and the accompanying materials\r
5 are licensed and made available under the terms and conditions of the BSD License\r
6 which accompanies this distribution. The full text of the license may be found at\r
7 http://opensource.org/licenses/bsd-license.php\r
8\r
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11\r
12**/\r
13\r
14#include <PiPei.h>\r
15\r
16#include <Ppi/PciCfg2.h>\r
17\r
18#include <Library/BaseLib.h>\r
19#include <Library/DebugLib.h>\r
20#include <Library/PciLib.h>\r
21#include <Library/PeimEntryPoint.h>\r
22\r
2d85ada2 23#include <IndustryStandard/Pci.h>\r
12232778 24\r
d8b61daa 25/**\r
26 Convert EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS to PCI_LIB_ADDRESS.\r
12232778 27\r
d8b61daa 28 @param Address PCI address with\r
29 EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS format.\r
30 \r
31 @return The PCI address with PCI_LIB_ADDRESS format.\r
32 \r
33**/\r
34STATIC\r
35UINTN\r
36PciCfgAddressConvert (\r
37 EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *Address\r
38 )\r
39{\r
40 if (Address->ExtendedRegister == 0) {\r
41 return PCI_LIB_ADDRESS (Address->Bus, Address->Device, Address->Function, Address->Register);\r
42 }\r
43\r
44 return PCI_LIB_ADDRESS (Address->Bus, Address->Device, Address->Function, Address->ExtendedRegister);\r
45}\r
12232778 46\r
47/**\r
48 Reads from a given location in the PCI configuration space.\r
49\r
50 @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation.\r
51\r
52 @param This Pointer to local data for the interface.\r
53\r
54 @param Width The width of the access. Enumerated in bytes.\r
55 See EFI_PEI_PCI_CFG_PPI_WIDTH above.\r
56\r
57 @param Address The physical address of the access. The format of\r
58 the address is described by EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS.\r
59\r
60 @param Buffer A pointer to the buffer of data..\r
61\r
62\r
63 @retval EFI_SUCCESS The function completed successfully.\r
64\r
65 @retval EFI_DEVICE_ERROR There was a problem with the transaction.\r
66\r
67 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting the operation at this\r
68 time.\r
69\r
70**/\r
71EFI_STATUS\r
72EFIAPI \r
73PciCfg2Read (\r
74 IN CONST EFI_PEI_SERVICES **PeiServices,\r
75 IN CONST EFI_PEI_PCI_CFG2_PPI *This,\r
76 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,\r
77 IN UINT64 Address,\r
78 IN OUT VOID *Buffer\r
79);\r
80\r
81/**\r
82 Write to a given location in the PCI configuration space.\r
83\r
84 @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation.\r
85\r
86 @param This Pointer to local data for the interface.\r
87\r
88 @param Width The width of the access. Enumerated in bytes.\r
89 See EFI_PEI_PCI_CFG_PPI_WIDTH above.\r
90\r
91 @param Address The physical address of the access. The format of\r
92 the address is described by EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS.\r
93\r
94 @param Buffer A pointer to the buffer of data..\r
95\r
96\r
97 @retval EFI_SUCCESS The function completed successfully.\r
98\r
99 @retval EFI_DEVICE_ERROR There was a problem with the transaction.\r
100\r
101 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting the operation at this\r
102 time.\r
103\r
104**/\r
105EFI_STATUS\r
106EFIAPI \r
107PciCfg2Write (\r
108 IN CONST EFI_PEI_SERVICES **PeiServices,\r
109 IN CONST EFI_PEI_PCI_CFG2_PPI *This,\r
110 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,\r
111 IN UINT64 Address,\r
112 IN OUT VOID *Buffer\r
113);\r
114\r
115\r
116/**\r
117 PCI read-modify-write operation.\r
118\r
119 @param PeiServices An indirect pointer to the PEI Services Table\r
120 published by the PEI Foundation.\r
121\r
122 @param This Pointer to local data for the interface.\r
123\r
124 @param Width The width of the access. Enumerated in bytes. Type\r
125 EFI_PEI_PCI_CFG_PPI_WIDTH is defined in Read().\r
126\r
127 @param Address The physical address of the access.\r
128\r
129 @param SetBits Points to value to bitwise-OR with the read configuration value.\r
130\r
131 The size of the value is determined by Width.\r
132\r
133 @param ClearBits Points to the value to negate and bitwise-AND with the read configuration value.\r
134 The size of the value is determined by Width.\r
135\r
136\r
137 @retval EFI_SUCCESS The function completed successfully.\r
138\r
139 @retval EFI_DEVICE_ERROR There was a problem with the transaction.\r
140\r
141 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting\r
142 the operation at this time.\r
143\r
144**/\r
145EFI_STATUS\r
146EFIAPI \r
147PciCfg2Modify (\r
148 IN CONST EFI_PEI_SERVICES **PeiServices,\r
149 IN CONST EFI_PEI_PCI_CFG2_PPI *This,\r
150 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,\r
151 IN UINT64 Address,\r
152 IN CONST VOID *SetBits,\r
153 IN CONST VOID *ClearBits\r
154);\r
155\r
156\r
157\r
158/**\r
159 @par Ppi Description:\r
160 The EFI_PEI_PCI_CFG2_PPI interfaces are used to abstract\r
161 accesses to PCI controllers behind a PCI root bridge\r
162 controller.\r
163\r
164 @param Read PCI read services. See the Read() function description.\r
165\r
166 @param Write PCI write services. See the Write() function description.\r
167\r
168 @param Modify PCI read-modify-write services. See the Modify() function description.\r
169\r
170 @param Segment The PCI bus segment which the specified functions will access.\r
171\r
172**/\r
173GLOBAL_REMOVE_IF_UNREFERENCED\r
174EFI_PEI_PCI_CFG2_PPI gPciCfg2Ppi = {\r
175 PciCfg2Read,\r
176 PciCfg2Write,\r
177 PciCfg2Modify\r
178};\r
179\r
180GLOBAL_REMOVE_IF_UNREFERENCED\r
181EFI_PEI_PPI_DESCRIPTOR gPciCfg2PpiList = {\r
182 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
183 &gEfiPciCfg2PpiGuid,\r
184 &gPciCfg2Ppi\r
185};\r
186\r
187/**\r
188 Reads from a given location in the PCI configuration space.\r
189\r
190 @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation.\r
191\r
192 @param This Pointer to local data for the interface.\r
193\r
194 @param Width The width of the access. Enumerated in bytes.\r
195 See EFI_PEI_PCI_CFG_PPI_WIDTH above.\r
196\r
197 @param Address The physical address of the access. The format of\r
198 the address is described by EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS.\r
199\r
200 @param Buffer A pointer to the buffer of data..\r
201\r
202\r
203 @retval EFI_SUCCESS The function completed successfully.\r
204\r
205 @retval EFI_DEVICE_ERROR There was a problem with the transaction.\r
206\r
207 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting the operation at this\r
208 time.\r
209\r
210**/\r
211EFI_STATUS\r
212EFIAPI \r
213PciCfg2Read (\r
214 IN CONST EFI_PEI_SERVICES **PeiServices,\r
215 IN CONST EFI_PEI_PCI_CFG2_PPI *This,\r
216 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,\r
217 IN UINT64 Address,\r
218 IN OUT VOID *Buffer\r
219)\r
220{\r
221 UINTN PciLibAddress;\r
222\r
d8b61daa 223 PciLibAddress = PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &Address);\r
12232778 224\r
225 if (Width == EfiPeiPciCfgWidthUint8) {\r
226 *((UINT8 *) Buffer) = PciRead8 (PciLibAddress);\r
227 } else if (Width == EfiPeiPciCfgWidthUint16) {\r
228 *((UINT16 *) Buffer) = PciRead16 (PciLibAddress);\r
229 } else if (Width == EfiPeiPciCfgWidthUint32) {\r
230 *((UINT32 *) Buffer) = PciRead32 (PciLibAddress);\r
231 } else {\r
232 return EFI_INVALID_PARAMETER;\r
233 }\r
234\r
235 return EFI_SUCCESS;\r
236}\r
237\r
238/**\r
239 Write to a given location in the PCI configuration space.\r
240\r
241 @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation.\r
242\r
243 @param This Pointer to local data for the interface.\r
244\r
245 @param Width The width of the access. Enumerated in bytes.\r
246 See EFI_PEI_PCI_CFG_PPI_WIDTH above.\r
247\r
248 @param Address The physical address of the access. The format of\r
249 the address is described by EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS.\r
250\r
251 @param Buffer A pointer to the buffer of data..\r
252\r
253\r
254 @retval EFI_SUCCESS The function completed successfully.\r
255\r
256 @retval EFI_DEVICE_ERROR There was a problem with the transaction.\r
257\r
258 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting the operation at this\r
259 time.\r
260\r
261**/\r
262EFI_STATUS\r
263EFIAPI \r
264PciCfg2Write (\r
265 IN CONST EFI_PEI_SERVICES **PeiServices,\r
266 IN CONST EFI_PEI_PCI_CFG2_PPI *This,\r
267 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,\r
268 IN UINT64 Address,\r
269 IN OUT VOID *Buffer\r
270)\r
271{\r
272 UINTN PciLibAddress;\r
273\r
d8b61daa 274 PciLibAddress = PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &Address);\r
12232778 275\r
276 if (Width == EfiPeiPciCfgWidthUint8) {\r
277 PciWrite8 (PciLibAddress, *((UINT8 *) Buffer));\r
278 } else if (Width == EfiPeiPciCfgWidthUint16) {\r
279 PciWrite16 (PciLibAddress, *((UINT16 *) Buffer));\r
280 } else if (Width == EfiPeiPciCfgWidthUint32) {\r
281 PciWrite32 (PciLibAddress, *((UINT32 *) Buffer));\r
282 } else {\r
283 return EFI_INVALID_PARAMETER;\r
284 }\r
285\r
286 return EFI_SUCCESS;\r
287}\r
288\r
289\r
290/**\r
291 PCI read-modify-write operation.\r
292\r
293 @param PeiServices An indirect pointer to the PEI Services Table\r
294 published by the PEI Foundation.\r
295\r
296 @param This Pointer to local data for the interface.\r
297\r
298 @param Width The width of the access. Enumerated in bytes. Type\r
299 EFI_PEI_PCI_CFG_PPI_WIDTH is defined in Read().\r
300\r
301 @param Address The physical address of the access.\r
302\r
303 @param SetBits Points to value to bitwise-OR with the read configuration value.\r
304\r
305 The size of the value is determined by Width.\r
306\r
307 @param ClearBits Points to the value to negate and bitwise-AND with the read configuration value.\r
308 The size of the value is determined by Width.\r
309\r
310\r
311 @retval EFI_SUCCESS The function completed successfully.\r
312\r
313 @retval EFI_DEVICE_ERROR There was a problem with the transaction.\r
314\r
315 @retval EFI_DEVICE_NOT_READY The device is not capable of supporting\r
316 the operation at this time.\r
317\r
318**/\r
319EFI_STATUS\r
320EFIAPI \r
321PciCfg2Modify (\r
322 IN CONST EFI_PEI_SERVICES **PeiServices,\r
323 IN CONST EFI_PEI_PCI_CFG2_PPI *This,\r
324 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,\r
325 IN UINT64 Address,\r
326 IN CONST VOID *SetBits,\r
327 IN CONST VOID *ClearBits\r
328)\r
329{\r
702887db 330 UINTN PciLibAddress;\r
331 UINT16 ClearValue16;\r
332 UINT16 SetValue16;\r
333 UINT32 ClearValue32;\r
334 UINT32 SetValue32;\r
12232778 335\r
d8b61daa 336 PciLibAddress = PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &Address);\r
12232778 337\r
338 if (Width == EfiPeiPciCfgWidthUint8) {\r
702887db 339 PciAndThenOr8 (PciLibAddress, (UINT8) (~(*(UINT8 *) ClearBits)), *((UINT8 *) SetBits));\r
12232778 340 } else if (Width == EfiPeiPciCfgWidthUint16) {\r
702887db 341 ClearValue16 = (UINT16) (~ReadUnaligned16 ((UINT16 *) ClearBits));\r
342 SetValue16 = ReadUnaligned16 ((UINT16 *) SetBits);\r
343 PciAndThenOr16 (PciLibAddress, ClearValue16, SetValue16);\r
12232778 344 } else if (Width == EfiPeiPciCfgWidthUint32) {\r
702887db 345 ClearValue32 = (UINT32) (~ReadUnaligned32 ((UINT32 *) ClearBits));\r
346 SetValue32 = ReadUnaligned32 ((UINT32 *) SetBits);\r
347 PciAndThenOr32 (PciLibAddress, ClearValue32, SetValue32);\r
12232778 348 } else {\r
349 return EFI_INVALID_PARAMETER;\r
350 }\r
351 return EFI_SUCCESS;\r
352}\r
353\r
354\r
355EFI_STATUS\r
356EFIAPI\r
357PeimInitializePciCfg (\r
358 IN EFI_FFS_FILE_HEADER *FfsHeader,\r
359 IN EFI_PEI_SERVICES **PeiServices\r
360 )\r
361{\r
362 EFI_STATUS Status;\r
363\r
364 ASSERT ((**PeiServices).Hdr.Revision >= PEI_SERVICES_REVISION);\r
365\r
366 (**PeiServices).PciCfg = &gPciCfg2Ppi;\r
0c2b5da8 367 Status = (**PeiServices).InstallPpi ((CONST EFI_PEI_SERVICES **)PeiServices, &gPciCfg2PpiList);\r
12232778 368\r
369 return Status;\r
370}\r