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
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.
20 Single Segment Pci Configuration PPI
26 #include "PciCfgInternal.h"
32 @param PeiServices An indirect pointer to the PEI Services Table
33 published by the PEI Foundation.
34 @param This Pointer to local data for the interface.
35 @param Width The width of the access. Enumerated in bytes.
36 @param Address The physical address of the access.
37 @param Buffer A pointer to the buffer of data.
39 @retval EFI_SUCCESS The function completed successfully.
40 @retval EFI_INVALID_PARAMETER Unsupported width
47 IN EFI_PEI_SERVICES
**PeiServices
,
48 IN EFI_PEI_PCI_CFG_PPI
*This
,
49 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width
,
56 PciLibAddress
= PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS
*) &Address
);
58 if (Width
== EfiPeiPciCfgWidthUint8
) {
59 *((UINT8
*) Buffer
) = PciRead8 (PciLibAddress
);
60 } else if (Width
== EfiPeiPciCfgWidthUint16
) {
61 if ((PciLibAddress
& 0x01) == 0) {
63 // Aligned Pci address access
65 WriteUnaligned16 (((UINT16
*) Buffer
), PciRead16 (PciLibAddress
));
68 // Unaligned Pci address access, break up the request into byte by byte.
70 *((UINT8
*) Buffer
) = PciRead8 (PciLibAddress
);
71 *((UINT8
*) Buffer
+ 1) = PciRead8 (PciLibAddress
+ 1);
73 } else if (Width
== EfiPeiPciCfgWidthUint32
) {
74 if ((PciLibAddress
& 0x03) == 0) {
76 // Aligned Pci address access
78 WriteUnaligned32 (((UINT32
*) Buffer
), PciRead32 (PciLibAddress
));
79 } else if ((PciLibAddress
& 0x01) == 0) {
81 // Unaligned Pci address access, break up the request into word by word.
83 WriteUnaligned16 (((UINT16
*) Buffer
), PciRead16 (PciLibAddress
));
84 WriteUnaligned16 (((UINT16
*) Buffer
+ 1), PciRead16 (PciLibAddress
+ 2));
87 // Unaligned Pci address access, break up the request into byte by byte.
89 *((UINT8
*) Buffer
) = PciRead8 (PciLibAddress
);
90 *((UINT8
*) Buffer
+ 1) = PciRead8 (PciLibAddress
+ 1);
91 *((UINT8
*) Buffer
+ 2) = PciRead8 (PciLibAddress
+ 2);
92 *((UINT8
*) Buffer
+ 3) = PciRead8 (PciLibAddress
+ 3);
95 return EFI_INVALID_PARAMETER
;
105 @param PeiServices An indirect pointer to the PEI Services Table
106 published by the PEI Foundation.
107 @param This Pointer to local data for the interface.
108 @param Width The width of the access. Enumerated in bytes.
109 @param Address The physical address of the access.
110 @param Buffer A pointer to the buffer of data.
112 @retval EFI_SUCCESS The function completed successfully.
115 @retval EFI_INVALID_PARAMETER Unsupported width
122 IN EFI_PEI_SERVICES
**PeiServices
,
123 IN EFI_PEI_PCI_CFG_PPI
*This
,
124 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width
,
131 PciLibAddress
= PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS
*) &Address
);
133 if (Width
== EfiPeiPciCfgWidthUint8
) {
134 PciWrite8 (PciLibAddress
, *((UINT8
*) Buffer
));
135 } else if (Width
== EfiPeiPciCfgWidthUint16
) {
136 if ((PciLibAddress
& 0x01) == 0) {
138 // Aligned Pci address access
140 PciWrite16 (PciLibAddress
, ReadUnaligned16 ((UINT16
*) Buffer
));
143 // Unaligned Pci address access, break up the request into byte by byte.
145 PciWrite8 (PciLibAddress
, *((UINT8
*) Buffer
));
146 PciWrite8 (PciLibAddress
+ 1, *((UINT8
*) Buffer
+ 1));
148 } else if (Width
== EfiPeiPciCfgWidthUint32
) {
149 if ((PciLibAddress
& 0x03) == 0) {
151 // Aligned Pci address access
153 PciWrite32 (PciLibAddress
, ReadUnaligned32 ((UINT32
*) Buffer
));
154 } else if ((PciLibAddress
& 0x01) == 0) {
156 // Unaligned Pci address access, break up the request into word by word.
158 PciWrite16 (PciLibAddress
, ReadUnaligned16 ((UINT16
*) Buffer
));
159 PciWrite16 (PciLibAddress
+ 2, ReadUnaligned16 ((UINT16
*) Buffer
+ 1));
162 // Unaligned Pci address access, break up the request into byte by byte.
164 PciWrite8 (PciLibAddress
, *((UINT8
*) Buffer
));
165 PciWrite8 (PciLibAddress
+ 1, *((UINT8
*) Buffer
+ 1));
166 PciWrite8 (PciLibAddress
+ 2, *((UINT8
*) Buffer
+ 2));
167 PciWrite8 (PciLibAddress
+ 3, *((UINT8
*) Buffer
+ 3));
170 return EFI_INVALID_PARAMETER
;
178 PCI read-modify-write operation.
180 @param PeiServices An indirect pointer to the PEI Services Table
181 published by the PEI Foundation.
182 @param This Pointer to local data for the interface.
183 @param Width The width of the access. Enumerated in bytes.
184 @param Address The physical address of the access.
185 @param SetBits Value of the bits to set.
186 @param ClearBits Value of the bits to clear.
188 @retval EFI_SUCCESS The function completed successfully.
189 @retval EFI_INVALID_PARAMETER Unsupported width
196 IN EFI_PEI_SERVICES
**PeiServices
,
197 IN EFI_PEI_PCI_CFG_PPI
*This
,
198 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width
,
206 PciLibAddress
= PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS
*) &Address
);
207 if (Width
== EfiPeiPciCfgWidthUint8
) {
208 PciAndThenOr8 (PciLibAddress
, (UINT8
)~ClearBits
, (UINT8
)SetBits
);
209 } else if (Width
== EfiPeiPciCfgWidthUint16
) {
210 if ((PciLibAddress
& 0x01) == 0) {
212 // Aligned Pci address access
214 PciAndThenOr16 (PciLibAddress
, (UINT16
)~ClearBits
, (UINT16
)SetBits
);
217 // Unaligned Pci address access, break up the request into byte by byte.
219 PciAndThenOr8 (PciLibAddress
, (UINT8
)~ClearBits
, (UINT8
)SetBits
);
220 PciAndThenOr8 (PciLibAddress
+ 1, (UINT8
)~(ClearBits
>> 8), (UINT8
)(SetBits
>> 8));
222 } else if (Width
== EfiPeiPciCfgWidthUint32
) {
223 if ((PciLibAddress
& 0x03) == 0) {
225 // Aligned Pci address access
227 PciAndThenOr32 (PciLibAddress
, (UINT32
)~ClearBits
, (UINT32
)SetBits
);
228 } else if ((PciLibAddress
& 0x01) == 0) {
230 // Unaligned Pci address access, break up the request into word by word.
232 PciAndThenOr16 (PciLibAddress
, (UINT16
)~ClearBits
, (UINT16
)SetBits
);
233 PciAndThenOr16 (PciLibAddress
+ 2, (UINT16
)~(ClearBits
>> 16), (UINT16
)(SetBits
>> 16));
236 // Unaligned Pci address access, break up the request into byte by byte.
238 PciAndThenOr8 (PciLibAddress
, (UINT8
)~ClearBits
, (UINT8
)SetBits
);
239 PciAndThenOr8 (PciLibAddress
+ 1, (UINT8
)~(ClearBits
>> 8), (UINT8
)(SetBits
>> 8));
240 PciAndThenOr8 (PciLibAddress
+ 2, (UINT8
)~(ClearBits
>> 16), (UINT8
)(SetBits
>> 16));
241 PciAndThenOr8 (PciLibAddress
+ 3, (UINT8
)~(ClearBits
>> 24), (UINT8
)(SetBits
>> 24));
244 return EFI_INVALID_PARAMETER
;