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