]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Universal/PcatSingleSegmentPciCfgPei/PciCfg.c
1. EDK_RELEASE_VERSION removed;
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / PcatSingleSegmentPciCfgPei / PciCfg.c
CommitLineData
3dbba770 1/** @file\r
12232778 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
14Module Name:\r
15\r
16 PciCfg.c\r
17\r
18Abstract:\r
19\r
20 Single Segment Pci Configuration PPI\r
21\r
22Revision History\r
23\r
3dbba770 24**/\r
12232778 25\r
26#include "PciCfgInternal.h"\r
27\r
28\r
29/**\r
30 PCI read operation.\r
31\r
32 @param PeiServices An indirect pointer to the PEI Services Table\r
33 published by the PEI Foundation.\r
34 @param This Pointer to local data for the interface.\r
35 @param Width The width of the access. Enumerated in bytes.\r
36 @param Address The physical address of the access.\r
37 @param Buffer A pointer to the buffer of data.\r
38\r
39 @retval EFI_SUCCESS The function completed successfully.\r
40 @retval EFI_INVALID_PARAMETER Unsupported width\r
41 enumeration.\r
42\r
43**/\r
44EFI_STATUS\r
45EFIAPI\r
46PciCfgRead (\r
47 IN EFI_PEI_SERVICES **PeiServices,\r
48 IN EFI_PEI_PCI_CFG_PPI *This,\r
49 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,\r
50 IN UINT64 Address,\r
51 IN OUT VOID *Buffer\r
52 )\r
53{\r
54 UINTN PciLibAddress;\r
55\r
d8b61daa 56 PciLibAddress = PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &Address);\r
12232778 57\r
8191cd5e
LG
58 if (Width == EfiPeiPciCfgWidthUint8) {\r
59 *((UINT8 *) Buffer) = PciRead8 (PciLibAddress);\r
60 } else if (Width == EfiPeiPciCfgWidthUint16) {\r
61 if ((PciLibAddress & 0x01) == 0) {\r
62 //\r
63 // Aligned Pci address access\r
64 //\r
65 WriteUnaligned16 (((UINT16 *) Buffer), PciRead16 (PciLibAddress));\r
66 } else {\r
67 //\r
68 // Unaligned Pci address access, break up the request into byte by byte.\r
69 //\r
70 *((UINT8 *) Buffer) = PciRead8 (PciLibAddress);\r
71 *((UINT8 *) Buffer + 1) = PciRead8 (PciLibAddress + 1);\r
72 }\r
73 } else if (Width == EfiPeiPciCfgWidthUint32) {\r
74 if ((PciLibAddress & 0x03) == 0) {\r
75 //\r
76 // Aligned Pci address access\r
77 //\r
78 WriteUnaligned32 (((UINT32 *) Buffer), PciRead32 (PciLibAddress));\r
79 } else if ((PciLibAddress & 0x01) == 0) {\r
80 //\r
81 // Unaligned Pci address access, break up the request into word by word.\r
82 //\r
83 WriteUnaligned16 (((UINT16 *) Buffer), PciRead16 (PciLibAddress));\r
84 WriteUnaligned16 (((UINT16 *) Buffer + 1), PciRead16 (PciLibAddress + 2));\r
85 } else {\r
86 //\r
87 // Unaligned Pci address access, break up the request into byte by byte.\r
88 //\r
89 *((UINT8 *) Buffer) = PciRead8 (PciLibAddress);\r
90 *((UINT8 *) Buffer + 1) = PciRead8 (PciLibAddress + 1);\r
91 *((UINT8 *) Buffer + 2) = PciRead8 (PciLibAddress + 2);\r
92 *((UINT8 *) Buffer + 3) = PciRead8 (PciLibAddress + 3);\r
93 }\r
94 } else {\r
95 return EFI_INVALID_PARAMETER;\r
12232778 96 }\r
8191cd5e 97\r
bcd70414 98 return EFI_SUCCESS;\r
12232778 99}\r
100\r
101\r
102/**\r
103 PCI 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 @param This Pointer to local data for the interface.\r
108 @param Width The width of the access. Enumerated in bytes.\r
109 @param Address The physical address of the access.\r
110 @param Buffer A pointer to the buffer of data.\r
111\r
112 @retval EFI_SUCCESS The function completed successfully.\r
113 \r
114 \r
115 @retval EFI_INVALID_PARAMETER Unsupported width\r
116 enumeration.\r
117 \r
118**/\r
119EFI_STATUS\r
120EFIAPI\r
121PciCfgWrite (\r
122 IN EFI_PEI_SERVICES **PeiServices,\r
123 IN EFI_PEI_PCI_CFG_PPI *This,\r
124 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,\r
125 IN UINT64 Address,\r
126 IN OUT VOID *Buffer\r
127 )\r
128{\r
129 UINTN PciLibAddress;\r
130\r
d8b61daa 131 PciLibAddress = PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &Address);\r
12232778 132\r
8191cd5e
LG
133 if (Width == EfiPeiPciCfgWidthUint8) {\r
134 PciWrite8 (PciLibAddress, *((UINT8 *) Buffer));\r
135 } else if (Width == EfiPeiPciCfgWidthUint16) {\r
136 if ((PciLibAddress & 0x01) == 0) {\r
137 //\r
138 // Aligned Pci address access\r
139 //\r
140 PciWrite16 (PciLibAddress, ReadUnaligned16 ((UINT16 *) Buffer));\r
141 } else {\r
142 //\r
143 // Unaligned Pci address access, break up the request into byte by byte.\r
144 //\r
145 PciWrite8 (PciLibAddress, *((UINT8 *) Buffer));\r
146 PciWrite8 (PciLibAddress + 1, *((UINT8 *) Buffer + 1)); \r
147 }\r
148 } else if (Width == EfiPeiPciCfgWidthUint32) {\r
149 if ((PciLibAddress & 0x03) == 0) {\r
150 //\r
151 // Aligned Pci address access\r
152 //\r
153 PciWrite32 (PciLibAddress, ReadUnaligned32 ((UINT32 *) Buffer));\r
154 } else if ((PciLibAddress & 0x01) == 0) {\r
155 //\r
156 // Unaligned Pci address access, break up the request into word by word.\r
157 //\r
158 PciWrite16 (PciLibAddress, ReadUnaligned16 ((UINT16 *) Buffer));\r
159 PciWrite16 (PciLibAddress + 2, ReadUnaligned16 ((UINT16 *) Buffer + 1));\r
160 } else {\r
161 //\r
162 // Unaligned Pci address access, break up the request into byte by byte.\r
163 //\r
164 PciWrite8 (PciLibAddress, *((UINT8 *) Buffer));\r
165 PciWrite8 (PciLibAddress + 1, *((UINT8 *) Buffer + 1)); \r
166 PciWrite8 (PciLibAddress + 2, *((UINT8 *) Buffer + 2)); \r
167 PciWrite8 (PciLibAddress + 3, *((UINT8 *) Buffer + 3)); \r
168 }\r
169 } else {\r
170 return EFI_INVALID_PARAMETER;\r
bcd70414 171 }\r
8191cd5e 172\r
bcd70414 173 return EFI_SUCCESS;\r
12232778 174}\r
175\r
176\r
177/**\r
178 PCI read-modify-write operation.\r
179\r
180 @param PeiServices An indirect pointer to the PEI Services Table\r
181 published by the PEI Foundation.\r
182 @param This Pointer to local data for the interface.\r
183 @param Width The width of the access. Enumerated in bytes.\r
184 @param Address The physical address of the access.\r
185 @param SetBits Value of the bits to set.\r
186 @param ClearBits Value of the bits to clear.\r
187\r
188 @retval EFI_SUCCESS The function completed successfully.\r
189 @retval EFI_INVALID_PARAMETER Unsupported width\r
190 enumeration.\r
191\r
192**/\r
193EFI_STATUS\r
194EFIAPI\r
195PciCfgModify (\r
196 IN EFI_PEI_SERVICES **PeiServices,\r
197 IN EFI_PEI_PCI_CFG_PPI *This,\r
198 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,\r
199 IN UINT64 Address,\r
200 IN UINTN SetBits,\r
201 IN UINTN ClearBits\r
202 )\r
203{\r
204 UINTN PciLibAddress;\r
205\r
d8b61daa 206 PciLibAddress = PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &Address);\r
8191cd5e
LG
207 if (Width == EfiPeiPciCfgWidthUint8) {\r
208 PciAndThenOr8 (PciLibAddress, (UINT8)~ClearBits, (UINT8)SetBits);\r
209 } else if (Width == EfiPeiPciCfgWidthUint16) {\r
210 if ((PciLibAddress & 0x01) == 0) {\r
211 //\r
212 // Aligned Pci address access\r
213 //\r
12232778 214 PciAndThenOr16 (PciLibAddress, (UINT16)~ClearBits, (UINT16)SetBits);\r
8191cd5e
LG
215 } else {\r
216 //\r
217 // Unaligned Pci address access, break up the request into byte by byte.\r
218 //\r
219 PciAndThenOr8 (PciLibAddress, (UINT8)~ClearBits, (UINT8)SetBits);\r
220 PciAndThenOr8 (PciLibAddress + 1, (UINT8)~(ClearBits >> 8), (UINT8)(SetBits >> 8));\r
221 }\r
222 } else if (Width == EfiPeiPciCfgWidthUint32) {\r
223 if ((PciLibAddress & 0x03) == 0) {\r
224 //\r
225 // Aligned Pci address access\r
226 //\r
12232778 227 PciAndThenOr32 (PciLibAddress, (UINT32)~ClearBits, (UINT32)SetBits);\r
8191cd5e
LG
228 } else if ((PciLibAddress & 0x01) == 0) {\r
229 //\r
230 // Unaligned Pci address access, break up the request into word by word.\r
231 //\r
232 PciAndThenOr16 (PciLibAddress, (UINT16)~ClearBits, (UINT16)SetBits);\r
233 PciAndThenOr16 (PciLibAddress + 2, (UINT16)~(ClearBits >> 16), (UINT16)(SetBits >> 16));\r
234 } else {\r
235 //\r
236 // Unaligned Pci address access, break up the request into byte by byte.\r
237 //\r
238 PciAndThenOr8 (PciLibAddress, (UINT8)~ClearBits, (UINT8)SetBits);\r
239 PciAndThenOr8 (PciLibAddress + 1, (UINT8)~(ClearBits >> 8), (UINT8)(SetBits >> 8));\r
240 PciAndThenOr8 (PciLibAddress + 2, (UINT8)~(ClearBits >> 16), (UINT8)(SetBits >> 16));\r
241 PciAndThenOr8 (PciLibAddress + 3, (UINT8)~(ClearBits >> 24), (UINT8)(SetBits >> 24));\r
242 }\r
243 } else {\r
244 return EFI_INVALID_PARAMETER;\r
12232778 245 }\r
8191cd5e 246\r
bcd70414 247 return EFI_SUCCESS;\r
12232778 248}\r
bcd70414 249\r