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