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