]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Universal/PcatSingleSegmentPciCfgPei/PciCfg.c
Reviewed the code comments in the Include/Protocol directory for typos, grammar issue...
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / PcatSingleSegmentPciCfgPei / PciCfg.c
1 /** @file
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 Module Name:
15
16 PciCfg.c
17
18 Abstract:
19
20 Single Segment Pci Configuration PPI
21
22 Revision History
23
24 **/
25
26 #include "PciCfgInternal.h"
27
28
29 /**
30 PCI read operation.
31
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.
38
39 @retval EFI_SUCCESS The function completed successfully.
40 @retval EFI_INVALID_PARAMETER Unsupported width
41 enumeration.
42
43 **/
44 EFI_STATUS
45 EFIAPI
46 PciCfgRead (
47 IN EFI_PEI_SERVICES **PeiServices,
48 IN EFI_PEI_PCI_CFG_PPI *This,
49 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,
50 IN UINT64 Address,
51 IN OUT VOID *Buffer
52 )
53 {
54 UINTN PciLibAddress;
55
56 PciLibAddress = PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &Address);
57
58 if (Width == EfiPeiPciCfgWidthUint8) {
59 *((UINT8 *) Buffer) = PciRead8 (PciLibAddress);
60 } else if (Width == EfiPeiPciCfgWidthUint16) {
61 if ((PciLibAddress & 0x01) == 0) {
62 //
63 // Aligned Pci address access
64 //
65 WriteUnaligned16 (((UINT16 *) Buffer), PciRead16 (PciLibAddress));
66 } else {
67 //
68 // Unaligned Pci address access, break up the request into byte by byte.
69 //
70 *((UINT8 *) Buffer) = PciRead8 (PciLibAddress);
71 *((UINT8 *) Buffer + 1) = PciRead8 (PciLibAddress + 1);
72 }
73 } else if (Width == EfiPeiPciCfgWidthUint32) {
74 if ((PciLibAddress & 0x03) == 0) {
75 //
76 // Aligned Pci address access
77 //
78 WriteUnaligned32 (((UINT32 *) Buffer), PciRead32 (PciLibAddress));
79 } else if ((PciLibAddress & 0x01) == 0) {
80 //
81 // Unaligned Pci address access, break up the request into word by word.
82 //
83 WriteUnaligned16 (((UINT16 *) Buffer), PciRead16 (PciLibAddress));
84 WriteUnaligned16 (((UINT16 *) Buffer + 1), PciRead16 (PciLibAddress + 2));
85 } else {
86 //
87 // Unaligned Pci address access, break up the request into byte by byte.
88 //
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);
93 }
94 } else {
95 return EFI_INVALID_PARAMETER;
96 }
97
98 return EFI_SUCCESS;
99 }
100
101
102 /**
103 PCI write operation.
104
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.
111
112 @retval EFI_SUCCESS The function completed successfully.
113
114
115 @retval EFI_INVALID_PARAMETER Unsupported width
116 enumeration.
117
118 **/
119 EFI_STATUS
120 EFIAPI
121 PciCfgWrite (
122 IN EFI_PEI_SERVICES **PeiServices,
123 IN EFI_PEI_PCI_CFG_PPI *This,
124 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,
125 IN UINT64 Address,
126 IN OUT VOID *Buffer
127 )
128 {
129 UINTN PciLibAddress;
130
131 PciLibAddress = PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &Address);
132
133 if (Width == EfiPeiPciCfgWidthUint8) {
134 PciWrite8 (PciLibAddress, *((UINT8 *) Buffer));
135 } else if (Width == EfiPeiPciCfgWidthUint16) {
136 if ((PciLibAddress & 0x01) == 0) {
137 //
138 // Aligned Pci address access
139 //
140 PciWrite16 (PciLibAddress, ReadUnaligned16 ((UINT16 *) Buffer));
141 } else {
142 //
143 // Unaligned Pci address access, break up the request into byte by byte.
144 //
145 PciWrite8 (PciLibAddress, *((UINT8 *) Buffer));
146 PciWrite8 (PciLibAddress + 1, *((UINT8 *) Buffer + 1));
147 }
148 } else if (Width == EfiPeiPciCfgWidthUint32) {
149 if ((PciLibAddress & 0x03) == 0) {
150 //
151 // Aligned Pci address access
152 //
153 PciWrite32 (PciLibAddress, ReadUnaligned32 ((UINT32 *) Buffer));
154 } else if ((PciLibAddress & 0x01) == 0) {
155 //
156 // Unaligned Pci address access, break up the request into word by word.
157 //
158 PciWrite16 (PciLibAddress, ReadUnaligned16 ((UINT16 *) Buffer));
159 PciWrite16 (PciLibAddress + 2, ReadUnaligned16 ((UINT16 *) Buffer + 1));
160 } else {
161 //
162 // Unaligned Pci address access, break up the request into byte by byte.
163 //
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));
168 }
169 } else {
170 return EFI_INVALID_PARAMETER;
171 }
172
173 return EFI_SUCCESS;
174 }
175
176
177 /**
178 PCI read-modify-write operation.
179
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.
187
188 @retval EFI_SUCCESS The function completed successfully.
189 @retval EFI_INVALID_PARAMETER Unsupported width
190 enumeration.
191
192 **/
193 EFI_STATUS
194 EFIAPI
195 PciCfgModify (
196 IN EFI_PEI_SERVICES **PeiServices,
197 IN EFI_PEI_PCI_CFG_PPI *This,
198 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,
199 IN UINT64 Address,
200 IN UINTN SetBits,
201 IN UINTN ClearBits
202 )
203 {
204 UINTN PciLibAddress;
205
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) {
211 //
212 // Aligned Pci address access
213 //
214 PciAndThenOr16 (PciLibAddress, (UINT16)~ClearBits, (UINT16)SetBits);
215 } else {
216 //
217 // Unaligned Pci address access, break up the request into byte by byte.
218 //
219 PciAndThenOr8 (PciLibAddress, (UINT8)~ClearBits, (UINT8)SetBits);
220 PciAndThenOr8 (PciLibAddress + 1, (UINT8)~(ClearBits >> 8), (UINT8)(SetBits >> 8));
221 }
222 } else if (Width == EfiPeiPciCfgWidthUint32) {
223 if ((PciLibAddress & 0x03) == 0) {
224 //
225 // Aligned Pci address access
226 //
227 PciAndThenOr32 (PciLibAddress, (UINT32)~ClearBits, (UINT32)SetBits);
228 } else if ((PciLibAddress & 0x01) == 0) {
229 //
230 // Unaligned Pci address access, break up the request into word by word.
231 //
232 PciAndThenOr16 (PciLibAddress, (UINT16)~ClearBits, (UINT16)SetBits);
233 PciAndThenOr16 (PciLibAddress + 2, (UINT16)~(ClearBits >> 16), (UINT16)(SetBits >> 16));
234 } else {
235 //
236 // Unaligned Pci address access, break up the request into byte by byte.
237 //
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));
242 }
243 } else {
244 return EFI_INVALID_PARAMETER;
245 }
246
247 return EFI_SUCCESS;
248 }
249