]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BasePciCf8Lib/PciCf8Lib.c
MdePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdePkg / Library / BasePciCf8Lib / PciCf8Lib.c
CommitLineData
e1f414b6 1/** @file\r
5c57f3ea 2 PCI CF8 Library functions that use I/O ports 0xCF8 and 0xCFC to perform PCI Configuration cycles.\r
3 Layers on top of an I/O Library instance.\r
e1f414b6 4\r
9095d37b 5 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
9344f092 6 SPDX-License-Identifier: BSD-2-Clause-Patent\r
e1f414b6 7\r
e1f414b6 8**/\r
9\r
c892d846 10\r
c7d265a9 11#include <Base.h>\r
c892d846 12\r
0c62737d 13#include <Library/BaseLib.h>\r
c7d265a9 14#include <Library/PciCf8Lib.h>\r
15#include <Library/IoLib.h>\r
16#include <Library/DebugLib.h>\r
e1f414b6 17\r
18//\r
19// Declare I/O Ports used to perform PCI Confguration Cycles\r
20//\r
21#define PCI_CONFIGURATION_ADDRESS_PORT 0xCF8\r
22#define PCI_CONFIGURATION_DATA_PORT 0xCFC\r
23\r
e1f414b6 24/**\r
ad400b07 25 Convert a PCI Library address to PCI CF8 formatted address.\r
26\r
27 Declare macro to convert PCI Library address to PCI CF8 formatted address.\r
28 Bit fields of PCI Library and CF8 formatted address is as follows:\r
29 PCI Library formatted address CF8 Formatted Address\r
30 ============================= ======================\r
31 Bits 00..11 Register Bits 00..07 Register\r
32 Bits 12..14 Function Bits 08..10 Function\r
33 Bits 15..19 Device Bits 11..15 Device\r
34 Bits 20..27 Bus Bits 16..23 Bus\r
35 Bits 28..31 Reserved(MBZ) Bits 24..30 Reserved(MBZ)\r
36 Bits 31..31 Must be 1\r
e1f414b6 37\r
38 @param A The address to convert.\r
39\r
40 @retval The coverted address.\r
41\r
42**/\r
43#define PCI_TO_CF8_ADDRESS(A) \\r
44 ((UINT32) ((((A) >> 4) & 0x00ffff00) | ((A) & 0xfc) | 0x80000000))\r
45\r
ad400b07 46/**\r
47 Assert the validity of a PCI CF8 address. A valid PCI CF8 address should contain 1's\r
48 only in the low 28 bits, excluding bits 08..11.\r
49\r
50 @param A The address to validate.\r
51 @param M Additional bits to assert to be zero.\r
52\r
53**/\r
54#define ASSERT_INVALID_PCI_ADDRESS(A,M) \\r
55 ASSERT (((A) & (~0xffff0ff | (M))) == 0)\r
56\r
3e3ae634 57/**\r
9095d37b 58 Registers a PCI device so PCI configuration registers may be accessed after\r
3e3ae634 59 SetVirtualAddressMap().\r
9095d37b
LG
60\r
61 Registers the PCI device specified by Address so all the PCI configuration registers\r
d11195a3 62 associated with that PCI device may be accessed after SetVirtualAddressMap() is called.\r
9095d37b 63\r
3e3ae634 64 If Address > 0x0FFFFFFF, then ASSERT().\r
59ceeabe 65 If the register specified by Address >= 0x100, then ASSERT().\r
3e3ae634 66\r
2fc59a00 67 @param Address The address that encodes the PCI Bus, Device, Function and\r
3e3ae634 68 Register.\r
9095d37b 69\r
3e3ae634 70 @retval RETURN_SUCCESS The PCI device was registered for runtime access.\r
9095d37b 71 @retval RETURN_UNSUPPORTED An attempt was made to call this function\r
3e3ae634 72 after ExitBootServices().\r
73 @retval RETURN_UNSUPPORTED The resources required to access the PCI device\r
74 at runtime could not be mapped.\r
75 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to\r
76 complete the registration.\r
77\r
78**/\r
79RETURN_STATUS\r
80EFIAPI\r
81PciCf8RegisterForRuntimeAccess (\r
82 IN UINTN Address\r
83 )\r
84{\r
59ceeabe 85 ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
3e3ae634 86 return RETURN_SUCCESS;\r
87}\r
88\r
e1f414b6 89/**\r
90 Reads an 8-bit PCI configuration register.\r
91\r
92 Reads and returns the 8-bit PCI configuration register specified by Address.\r
93 This function must guarantee that all PCI read and write operations are\r
94 serialized.\r
95\r
96 If Address > 0x0FFFFFFF, then ASSERT().\r
97 If the register specified by Address >= 0x100, then ASSERT().\r
98\r
2fc59a00 99 @param Address The address that encodes the PCI Bus, Device, Function and\r
e1f414b6 100 Register.\r
101\r
102 @return The read value from the PCI configuration register.\r
103\r
104**/\r
105UINT8\r
106EFIAPI\r
107PciCf8Read8 (\r
108 IN UINTN Address\r
109 )\r
110{\r
96dd57ee 111 BOOLEAN InterruptState;\r
112 UINT32 AddressPort;\r
113 UINT8 Result;\r
9095d37b 114\r
e1f414b6 115 ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
96dd57ee 116 InterruptState = SaveAndDisableInterrupts ();\r
117 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 118 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 119 Result = IoRead8 (PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3));\r
120 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
121 SetInterruptState (InterruptState);\r
122 return Result;\r
e1f414b6 123}\r
124\r
125/**\r
126 Writes an 8-bit PCI configuration register.\r
127\r
128 Writes the 8-bit PCI configuration register specified by Address with the\r
129 value specified by Value. Value is returned. This function must guarantee\r
130 that all PCI read and write operations are serialized.\r
131\r
132 If Address > 0x0FFFFFFF, then ASSERT().\r
133 If the register specified by Address >= 0x100, then ASSERT().\r
134\r
2fc59a00 135 @param Address The address that encodes the PCI Bus, Device, Function and\r
e1f414b6 136 Register.\r
137 @param Value The value to write.\r
138\r
139 @return The value written to the PCI configuration register.\r
140\r
141**/\r
142UINT8\r
143EFIAPI\r
144PciCf8Write8 (\r
145 IN UINTN Address,\r
146 IN UINT8 Value\r
147 )\r
148{\r
96dd57ee 149 BOOLEAN InterruptState;\r
150 UINT32 AddressPort;\r
151 UINT8 Result;\r
9095d37b 152\r
e1f414b6 153 ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
96dd57ee 154 InterruptState = SaveAndDisableInterrupts ();\r
155 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 156 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 157 Result = IoWrite8 (\r
158 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r
159 Value\r
160 );\r
161 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
162 SetInterruptState (InterruptState);\r
163 return Result;\r
e1f414b6 164}\r
165\r
166/**\r
62991af2 167 Performs a bitwise OR of an 8-bit PCI configuration register with\r
e1f414b6 168 an 8-bit value.\r
169\r
170 Reads the 8-bit PCI configuration register specified by Address, performs a\r
62991af2 171 bitwise OR between the read result and the value specified by\r
e1f414b6 172 OrData, and writes the result to the 8-bit PCI configuration register\r
173 specified by Address. The value written to the PCI configuration register is\r
174 returned. This function must guarantee that all PCI read and write operations\r
175 are serialized.\r
176\r
177 If Address > 0x0FFFFFFF, then ASSERT().\r
178 If the register specified by Address >= 0x100, then ASSERT().\r
179\r
2fc59a00 180 @param Address The address that encodes the PCI Bus, Device, Function and\r
e1f414b6 181 Register.\r
182 @param OrData The value to OR with the PCI configuration register.\r
183\r
184 @return The value written back to the PCI configuration register.\r
185\r
186**/\r
187UINT8\r
188EFIAPI\r
189PciCf8Or8 (\r
190 IN UINTN Address,\r
191 IN UINT8 OrData\r
192 )\r
193{\r
96dd57ee 194 BOOLEAN InterruptState;\r
195 UINT32 AddressPort;\r
196 UINT8 Result;\r
9095d37b 197\r
e1f414b6 198 ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
96dd57ee 199 InterruptState = SaveAndDisableInterrupts ();\r
200 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 201 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 202 Result = IoOr8 (\r
203 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r
204 OrData\r
205 );\r
206 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
207 SetInterruptState (InterruptState);\r
208 return Result;\r
e1f414b6 209}\r
210\r
211/**\r
212 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit\r
213 value.\r
214\r
215 Reads the 8-bit PCI configuration register specified by Address, performs a\r
216 bitwise AND between the read result and the value specified by AndData, and\r
217 writes the result to the 8-bit PCI configuration register specified by\r
218 Address. The value written to the PCI configuration register is returned.\r
219 This function must guarantee that all PCI read and write operations are\r
220 serialized.\r
221\r
222 If Address > 0x0FFFFFFF, then ASSERT().\r
223 If the register specified by Address >= 0x100, then ASSERT().\r
224\r
2fc59a00 225 @param Address The address that encodes the PCI Bus, Device, Function and\r
e1f414b6 226 Register.\r
227 @param AndData The value to AND with the PCI configuration register.\r
228\r
229 @return The value written back to the PCI configuration register.\r
230\r
231**/\r
232UINT8\r
233EFIAPI\r
234PciCf8And8 (\r
235 IN UINTN Address,\r
236 IN UINT8 AndData\r
237 )\r
238{\r
96dd57ee 239 BOOLEAN InterruptState;\r
240 UINT32 AddressPort;\r
241 UINT8 Result;\r
9095d37b 242\r
e1f414b6 243 ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
96dd57ee 244 InterruptState = SaveAndDisableInterrupts ();\r
245 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 246 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 247 Result = IoAnd8 (\r
248 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r
249 AndData\r
250 );\r
251 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
252 SetInterruptState (InterruptState);\r
253 return Result;\r
e1f414b6 254}\r
255\r
256/**\r
257 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit\r
62991af2 258 value, followed a bitwise OR with another 8-bit value.\r
e1f414b6 259\r
260 Reads the 8-bit PCI configuration register specified by Address, performs a\r
261 bitwise AND between the read result and the value specified by AndData,\r
62991af2 262 performs a bitwise OR between the result of the AND operation and\r
e1f414b6 263 the value specified by OrData, and writes the result to the 8-bit PCI\r
264 configuration register specified by Address. The value written to the PCI\r
265 configuration register is returned. This function must guarantee that all PCI\r
266 read and write operations are serialized.\r
267\r
268 If Address > 0x0FFFFFFF, then ASSERT().\r
269 If the register specified by Address >= 0x100, then ASSERT().\r
270\r
2fc59a00 271 @param Address The address that encodes the PCI Bus, Device, Function and\r
e1f414b6 272 Register.\r
273 @param AndData The value to AND with the PCI configuration register.\r
274 @param OrData The value to OR with the result of the AND operation.\r
275\r
276 @return The value written back to the PCI configuration register.\r
277\r
278**/\r
279UINT8\r
280EFIAPI\r
281PciCf8AndThenOr8 (\r
282 IN UINTN Address,\r
283 IN UINT8 AndData,\r
284 IN UINT8 OrData\r
285 )\r
286{\r
96dd57ee 287 BOOLEAN InterruptState;\r
288 UINT32 AddressPort;\r
289 UINT8 Result;\r
9095d37b 290\r
e1f414b6 291 ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
96dd57ee 292 InterruptState = SaveAndDisableInterrupts ();\r
293 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 294 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 295 Result = IoAndThenOr8 (\r
296 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r
297 AndData,\r
298 OrData\r
299 );\r
300 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
301 SetInterruptState (InterruptState);\r
302 return Result;\r
e1f414b6 303}\r
304\r
305/**\r
306 Reads a bit field of a PCI configuration register.\r
307\r
308 Reads the bit field in an 8-bit PCI configuration register. The bit field is\r
309 specified by the StartBit and the EndBit. The value of the bit field is\r
310 returned.\r
311\r
312 If Address > 0x0FFFFFFF, then ASSERT().\r
313 If the register specified by Address >= 0x100, then ASSERT().\r
314 If StartBit is greater than 7, then ASSERT().\r
315 If EndBit is greater than 7, then ASSERT().\r
316 If EndBit is less than StartBit, then ASSERT().\r
317\r
2fc59a00 318 @param Address The PCI configuration register to read.\r
e1f414b6 319 @param StartBit The ordinal of the least significant bit in the bit field.\r
320 Range 0..7.\r
321 @param EndBit The ordinal of the most significant bit in the bit field.\r
322 Range 0..7.\r
323\r
324 @return The value of the bit field read from the PCI configuration register.\r
325\r
326**/\r
327UINT8\r
328EFIAPI\r
329PciCf8BitFieldRead8 (\r
330 IN UINTN Address,\r
331 IN UINTN StartBit,\r
332 IN UINTN EndBit\r
333 )\r
334{\r
96dd57ee 335 BOOLEAN InterruptState;\r
336 UINT32 AddressPort;\r
337 UINT8 Result;\r
9095d37b 338\r
e1f414b6 339 ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
96dd57ee 340 InterruptState = SaveAndDisableInterrupts ();\r
341 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 342 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 343 Result = IoBitFieldRead8 (\r
344 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r
345 StartBit,\r
346 EndBit\r
347 );\r
348 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
349 SetInterruptState (InterruptState);\r
350 return Result;\r
e1f414b6 351}\r
352\r
353/**\r
354 Writes a bit field to a PCI configuration register.\r
355\r
356 Writes Value to the bit field of the PCI configuration register. The bit\r
357 field is specified by the StartBit and the EndBit. All other bits in the\r
358 destination PCI configuration register are preserved. The new value of the\r
359 8-bit register is returned.\r
360\r
361 If Address > 0x0FFFFFFF, then ASSERT().\r
362 If the register specified by Address >= 0x100, then ASSERT().\r
363 If StartBit is greater than 7, then ASSERT().\r
364 If EndBit is greater than 7, then ASSERT().\r
365 If EndBit is less than StartBit, then ASSERT().\r
94952554 366 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 367\r
2fc59a00 368 @param Address The PCI configuration register to write.\r
e1f414b6 369 @param StartBit The ordinal of the least significant bit in the bit field.\r
370 Range 0..7.\r
371 @param EndBit The ordinal of the most significant bit in the bit field.\r
372 Range 0..7.\r
2fc59a00 373 @param Value The new value of the bit field.\r
e1f414b6 374\r
375 @return The value written back to the PCI configuration register.\r
376\r
377**/\r
378UINT8\r
379EFIAPI\r
380PciCf8BitFieldWrite8 (\r
381 IN UINTN Address,\r
382 IN UINTN StartBit,\r
383 IN UINTN EndBit,\r
384 IN UINT8 Value\r
385 )\r
386{\r
96dd57ee 387 BOOLEAN InterruptState;\r
388 UINT32 AddressPort;\r
389 UINT8 Result;\r
9095d37b 390\r
e1f414b6 391 ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
96dd57ee 392 InterruptState = SaveAndDisableInterrupts ();\r
393 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 394 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 395 Result = IoBitFieldWrite8 (\r
396 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r
397 StartBit,\r
398 EndBit,\r
399 Value\r
400 );\r
401 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
402 SetInterruptState (InterruptState);\r
403 return Result;\r
e1f414b6 404}\r
405\r
406/**\r
407 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and\r
408 writes the result back to the bit field in the 8-bit port.\r
409\r
410 Reads the 8-bit PCI configuration register specified by Address, performs a\r
62991af2 411 bitwise OR between the read result and the value specified by\r
e1f414b6 412 OrData, and writes the result to the 8-bit PCI configuration register\r
413 specified by Address. The value written to the PCI configuration register is\r
414 returned. This function must guarantee that all PCI read and write operations\r
415 are serialized. Extra left bits in OrData are stripped.\r
416\r
417 If Address > 0x0FFFFFFF, then ASSERT().\r
418 If the register specified by Address >= 0x100, then ASSERT().\r
419 If StartBit is greater than 7, then ASSERT().\r
420 If EndBit is greater than 7, then ASSERT().\r
421 If EndBit is less than StartBit, then ASSERT().\r
94952554 422 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 423\r
2fc59a00 424 @param Address The PCI configuration register to write.\r
e1f414b6 425 @param StartBit The ordinal of the least significant bit in the bit field.\r
426 Range 0..7.\r
427 @param EndBit The ordinal of the most significant bit in the bit field.\r
428 Range 0..7.\r
429 @param OrData The value to OR with the PCI configuration register.\r
430\r
431 @return The value written back to the PCI configuration register.\r
432\r
433**/\r
434UINT8\r
435EFIAPI\r
436PciCf8BitFieldOr8 (\r
437 IN UINTN Address,\r
438 IN UINTN StartBit,\r
439 IN UINTN EndBit,\r
440 IN UINT8 OrData\r
441 )\r
442{\r
96dd57ee 443 BOOLEAN InterruptState;\r
444 UINT32 AddressPort;\r
445 UINT8 Result;\r
9095d37b 446\r
e1f414b6 447 ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
96dd57ee 448 InterruptState = SaveAndDisableInterrupts ();\r
449 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 450 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 451 Result = IoBitFieldOr8 (\r
452 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r
453 StartBit,\r
454 EndBit,\r
455 OrData\r
456 );\r
457 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
458 SetInterruptState (InterruptState);\r
459 return Result;\r
e1f414b6 460}\r
461\r
462/**\r
463 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise\r
464 AND, and writes the result back to the bit field in the 8-bit register.\r
465\r
466 Reads the 8-bit PCI configuration register specified by Address, performs a\r
467 bitwise AND between the read result and the value specified by AndData, and\r
468 writes the result to the 8-bit PCI configuration register specified by\r
469 Address. The value written to the PCI configuration register is returned.\r
470 This function must guarantee that all PCI read and write operations are\r
471 serialized. Extra left bits in AndData are stripped.\r
472\r
473 If Address > 0x0FFFFFFF, then ASSERT().\r
474 If the register specified by Address >= 0x100, then ASSERT().\r
475 If StartBit is greater than 7, then ASSERT().\r
476 If EndBit is greater than 7, then ASSERT().\r
477 If EndBit is less than StartBit, then ASSERT().\r
94952554 478 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 479\r
2fc59a00 480 @param Address The PCI configuration register to write.\r
e1f414b6 481 @param StartBit The ordinal of the least significant bit in the bit field.\r
482 Range 0..7.\r
483 @param EndBit The ordinal of the most significant bit in the bit field.\r
484 Range 0..7.\r
485 @param AndData The value to AND with the PCI configuration register.\r
486\r
487 @return The value written back to the PCI configuration register.\r
488\r
489**/\r
490UINT8\r
491EFIAPI\r
492PciCf8BitFieldAnd8 (\r
493 IN UINTN Address,\r
494 IN UINTN StartBit,\r
495 IN UINTN EndBit,\r
496 IN UINT8 AndData\r
497 )\r
498{\r
96dd57ee 499 BOOLEAN InterruptState;\r
500 UINT32 AddressPort;\r
501 UINT8 Result;\r
9095d37b 502\r
e1f414b6 503 ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
96dd57ee 504 InterruptState = SaveAndDisableInterrupts ();\r
505 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 506 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 507 Result = IoBitFieldAnd8 (\r
508 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r
509 StartBit,\r
510 EndBit,\r
511 AndData\r
512 );\r
513 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
514 SetInterruptState (InterruptState);\r
515 return Result;\r
e1f414b6 516}\r
517\r
518/**\r
519 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a\r
62991af2 520 bitwise OR, and writes the result back to the bit field in the\r
e1f414b6 521 8-bit port.\r
522\r
523 Reads the 8-bit PCI configuration register specified by Address, performs a\r
62991af2 524 bitwise AND followed by a bitwise OR between the read result and\r
e1f414b6 525 the value specified by AndData, and writes the result to the 8-bit PCI\r
526 configuration register specified by Address. The value written to the PCI\r
527 configuration register is returned. This function must guarantee that all PCI\r
528 read and write operations are serialized. Extra left bits in both AndData and\r
529 OrData are stripped.\r
530\r
531 If Address > 0x0FFFFFFF, then ASSERT().\r
532 If the register specified by Address >= 0x100, then ASSERT().\r
533 If StartBit is greater than 7, then ASSERT().\r
534 If EndBit is greater than 7, then ASSERT().\r
535 If EndBit is less than StartBit, then ASSERT().\r
94952554
LG
536 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
537 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 538\r
2fc59a00 539 @param Address The PCI configuration register to write.\r
e1f414b6 540 @param StartBit The ordinal of the least significant bit in the bit field.\r
541 Range 0..7.\r
542 @param EndBit The ordinal of the most significant bit in the bit field.\r
543 Range 0..7.\r
544 @param AndData The value to AND with the PCI configuration register.\r
545 @param OrData The value to OR with the result of the AND operation.\r
546\r
547 @return The value written back to the PCI configuration register.\r
548\r
549**/\r
550UINT8\r
551EFIAPI\r
552PciCf8BitFieldAndThenOr8(\r
553 IN UINTN Address,\r
554 IN UINTN StartBit,\r
555 IN UINTN EndBit,\r
556 IN UINT8 AndData,\r
557 IN UINT8 OrData\r
558 )\r
559{\r
96dd57ee 560 BOOLEAN InterruptState;\r
561 UINT32 AddressPort;\r
562 UINT8 Result;\r
9095d37b 563\r
e1f414b6 564 ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
96dd57ee 565 InterruptState = SaveAndDisableInterrupts ();\r
566 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 567 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 568 Result = IoBitFieldAndThenOr8 (\r
569 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r
570 StartBit,\r
571 EndBit,\r
572 AndData,\r
573 OrData\r
574 );\r
575 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
576 SetInterruptState (InterruptState);\r
577 return Result;\r
e1f414b6 578}\r
579\r
580/**\r
581 Reads a 16-bit PCI configuration register.\r
582\r
583 Reads and returns the 16-bit PCI configuration register specified by Address.\r
584 This function must guarantee that all PCI read and write operations are\r
585 serialized.\r
586\r
587 If Address > 0x0FFFFFFF, then ASSERT().\r
588 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
589 If the register specified by Address >= 0x100, then ASSERT().\r
590\r
2fc59a00 591 @param Address The address that encodes the PCI Bus, Device, Function and\r
e1f414b6 592 Register.\r
593\r
594 @return The read value from the PCI configuration register.\r
595\r
596**/\r
597UINT16\r
598EFIAPI\r
599PciCf8Read16 (\r
600 IN UINTN Address\r
601 )\r
602{\r
96dd57ee 603 BOOLEAN InterruptState;\r
604 UINT32 AddressPort;\r
605 UINT16 Result;\r
9095d37b 606\r
e1f414b6 607 ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
96dd57ee 608 InterruptState = SaveAndDisableInterrupts ();\r
609 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 610 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 611 Result = IoRead16 (PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2));\r
612 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
613 SetInterruptState (InterruptState);\r
614 return Result;\r
e1f414b6 615}\r
616\r
617/**\r
618 Writes a 16-bit PCI configuration register.\r
619\r
620 Writes the 16-bit PCI configuration register specified by Address with the\r
621 value specified by Value. Value is returned. This function must guarantee\r
622 that all PCI read and write operations are serialized.\r
623\r
624 If Address > 0x0FFFFFFF, then ASSERT().\r
625 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
626 If the register specified by Address >= 0x100, then ASSERT().\r
627\r
2fc59a00 628 @param Address The address that encodes the PCI Bus, Device, Function and\r
e1f414b6 629 Register.\r
630 @param Value The value to write.\r
631\r
632 @return The value written to the PCI configuration register.\r
633\r
634**/\r
635UINT16\r
636EFIAPI\r
637PciCf8Write16 (\r
638 IN UINTN Address,\r
639 IN UINT16 Value\r
640 )\r
641{\r
96dd57ee 642 BOOLEAN InterruptState;\r
643 UINT32 AddressPort;\r
644 UINT16 Result;\r
9095d37b 645\r
e1f414b6 646 ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
96dd57ee 647 InterruptState = SaveAndDisableInterrupts ();\r
648 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 649 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 650 Result = IoWrite16 (\r
651 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
652 Value\r
653 );\r
654 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
655 SetInterruptState (InterruptState);\r
656 return Result;\r
e1f414b6 657}\r
658\r
659/**\r
62991af2 660 Performs a bitwise OR of a 16-bit PCI configuration register with\r
e1f414b6 661 a 16-bit value.\r
662\r
663 Reads the 16-bit PCI configuration register specified by Address, performs a\r
62991af2 664 bitwise OR between the read result and the value specified by\r
e1f414b6 665 OrData, and writes the result to the 16-bit PCI configuration register\r
666 specified by Address. The value written to the PCI configuration register is\r
667 returned. This function must guarantee that all PCI read and write operations\r
668 are serialized.\r
669\r
670 If Address > 0x0FFFFFFF, then ASSERT().\r
671 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
672 If the register specified by Address >= 0x100, then ASSERT().\r
673\r
2fc59a00 674 @param Address The address that encodes the PCI Bus, Device, Function and\r
e1f414b6 675 Register.\r
676 @param OrData The value to OR with the PCI configuration register.\r
677\r
678 @return The value written back to the PCI configuration register.\r
679\r
680**/\r
681UINT16\r
682EFIAPI\r
683PciCf8Or16 (\r
684 IN UINTN Address,\r
685 IN UINT16 OrData\r
686 )\r
687{\r
96dd57ee 688 BOOLEAN InterruptState;\r
689 UINT32 AddressPort;\r
690 UINT16 Result;\r
9095d37b 691\r
e1f414b6 692 ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
96dd57ee 693 InterruptState = SaveAndDisableInterrupts ();\r
694 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 695 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 696 Result = IoOr16 (\r
697 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
698 OrData\r
699 );\r
700 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
701 SetInterruptState (InterruptState);\r
702 return Result;\r
e1f414b6 703}\r
704\r
705/**\r
706 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit\r
707 value.\r
708\r
709 Reads the 16-bit PCI configuration register specified by Address, performs a\r
710 bitwise AND between the read result and the value specified by AndData, and\r
711 writes the result to the 16-bit PCI configuration register specified by\r
712 Address. The value written to the PCI configuration register is returned.\r
713 This function must guarantee that all PCI read and write operations are\r
714 serialized.\r
715\r
716 If Address > 0x0FFFFFFF, then ASSERT().\r
717 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
718 If the register specified by Address >= 0x100, then ASSERT().\r
719\r
2fc59a00 720 @param Address The address that encodes the PCI Bus, Device, Function and\r
e1f414b6 721 Register.\r
722 @param AndData The value to AND with the PCI configuration register.\r
723\r
724 @return The value written back to the PCI configuration register.\r
725\r
726**/\r
727UINT16\r
728EFIAPI\r
729PciCf8And16 (\r
730 IN UINTN Address,\r
731 IN UINT16 AndData\r
732 )\r
733{\r
96dd57ee 734 BOOLEAN InterruptState;\r
735 UINT32 AddressPort;\r
736 UINT16 Result;\r
9095d37b 737\r
e1f414b6 738 ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
96dd57ee 739 InterruptState = SaveAndDisableInterrupts ();\r
740 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 741 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 742 Result = IoAnd16 (\r
743 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
744 AndData\r
745 );\r
746 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
747 SetInterruptState (InterruptState);\r
748 return Result;\r
e1f414b6 749}\r
750\r
751/**\r
752 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit\r
62991af2 753 value, followed a bitwise OR with another 16-bit value.\r
e1f414b6 754\r
755 Reads the 16-bit PCI configuration register specified by Address, performs a\r
756 bitwise AND between the read result and the value specified by AndData,\r
62991af2 757 performs a bitwise OR between the result of the AND operation and\r
e1f414b6 758 the value specified by OrData, and writes the result to the 16-bit PCI\r
759 configuration register specified by Address. The value written to the PCI\r
760 configuration register is returned. This function must guarantee that all PCI\r
761 read and write operations are serialized.\r
762\r
763 If Address > 0x0FFFFFFF, then ASSERT().\r
764 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
765 If the register specified by Address >= 0x100, then ASSERT().\r
766\r
2fc59a00 767 @param Address The address that encodes the PCI Bus, Device, Function and\r
e1f414b6 768 Register.\r
769 @param AndData The value to AND with the PCI configuration register.\r
770 @param OrData The value to OR with the result of the AND operation.\r
771\r
772 @return The value written back to the PCI configuration register.\r
773\r
774**/\r
775UINT16\r
776EFIAPI\r
777PciCf8AndThenOr16 (\r
778 IN UINTN Address,\r
779 IN UINT16 AndData,\r
780 IN UINT16 OrData\r
781 )\r
782{\r
96dd57ee 783 BOOLEAN InterruptState;\r
784 UINT32 AddressPort;\r
785 UINT16 Result;\r
9095d37b 786\r
e1f414b6 787 ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
96dd57ee 788 InterruptState = SaveAndDisableInterrupts ();\r
789 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 790 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 791 Result = IoAndThenOr16 (\r
792 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
793 AndData,\r
794 OrData\r
795 );\r
796 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
797 SetInterruptState (InterruptState);\r
798 return Result;\r
e1f414b6 799}\r
800\r
801/**\r
802 Reads a bit field of a PCI configuration register.\r
803\r
804 Reads the bit field in a 16-bit PCI configuration register. The bit field is\r
805 specified by the StartBit and the EndBit. The value of the bit field is\r
806 returned.\r
807\r
808 If Address > 0x0FFFFFFF, then ASSERT().\r
809 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
810 If the register specified by Address >= 0x100, then ASSERT().\r
811 If StartBit is greater than 15, then ASSERT().\r
812 If EndBit is greater than 15, then ASSERT().\r
813 If EndBit is less than StartBit, then ASSERT().\r
814\r
2fc59a00 815 @param Address The PCI configuration register to read.\r
e1f414b6 816 @param StartBit The ordinal of the least significant bit in the bit field.\r
817 Range 0..15.\r
818 @param EndBit The ordinal of the most significant bit in the bit field.\r
819 Range 0..15.\r
820\r
821 @return The value of the bit field read from the PCI configuration register.\r
822\r
823**/\r
824UINT16\r
825EFIAPI\r
826PciCf8BitFieldRead16 (\r
827 IN UINTN Address,\r
828 IN UINTN StartBit,\r
829 IN UINTN EndBit\r
830 )\r
831{\r
96dd57ee 832 BOOLEAN InterruptState;\r
833 UINT32 AddressPort;\r
834 UINT16 Result;\r
9095d37b 835\r
e1f414b6 836 ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
96dd57ee 837 InterruptState = SaveAndDisableInterrupts ();\r
838 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 839 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 840 Result = IoBitFieldRead16 (\r
841 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
842 StartBit,\r
843 EndBit\r
844 );\r
845 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
846 SetInterruptState (InterruptState);\r
847 return Result;\r
e1f414b6 848}\r
849\r
850/**\r
851 Writes a bit field to a PCI configuration register.\r
852\r
853 Writes Value to the bit field of the PCI configuration register. The bit\r
854 field is specified by the StartBit and the EndBit. All other bits in the\r
855 destination PCI configuration register are preserved. The new value of the\r
856 16-bit register is returned.\r
857\r
858 If Address > 0x0FFFFFFF, then ASSERT().\r
859 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
860 If the register specified by Address >= 0x100, then ASSERT().\r
861 If StartBit is greater than 15, then ASSERT().\r
862 If EndBit is greater than 15, then ASSERT().\r
863 If EndBit is less than StartBit, then ASSERT().\r
94952554 864 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 865\r
2fc59a00 866 @param Address The PCI configuration register to write.\r
e1f414b6 867 @param StartBit The ordinal of the least significant bit in the bit field.\r
868 Range 0..15.\r
869 @param EndBit The ordinal of the most significant bit in the bit field.\r
870 Range 0..15.\r
2fc59a00 871 @param Value The new value of the bit field.\r
e1f414b6 872\r
873 @return The value written back to the PCI configuration register.\r
874\r
875**/\r
876UINT16\r
877EFIAPI\r
878PciCf8BitFieldWrite16 (\r
879 IN UINTN Address,\r
880 IN UINTN StartBit,\r
881 IN UINTN EndBit,\r
882 IN UINT16 Value\r
883 )\r
884{\r
96dd57ee 885 BOOLEAN InterruptState;\r
886 UINT32 AddressPort;\r
887 UINT16 Result;\r
9095d37b 888\r
e1f414b6 889 ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
96dd57ee 890 InterruptState = SaveAndDisableInterrupts ();\r
891 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 892 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 893 Result = IoBitFieldWrite16 (\r
894 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
895 StartBit,\r
896 EndBit,\r
897 Value\r
898 );\r
899 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
900 SetInterruptState (InterruptState);\r
901 return Result;\r
e1f414b6 902}\r
903\r
904/**\r
905 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and\r
906 writes the result back to the bit field in the 16-bit port.\r
907\r
908 Reads the 16-bit PCI configuration register specified by Address, performs a\r
62991af2 909 bitwise OR between the read result and the value specified by\r
e1f414b6 910 OrData, and writes the result to the 16-bit PCI configuration register\r
911 specified by Address. The value written to the PCI configuration register is\r
912 returned. This function must guarantee that all PCI read and write operations\r
913 are serialized. Extra left bits in OrData are stripped.\r
914\r
915 If Address > 0x0FFFFFFF, then ASSERT().\r
916 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
917 If the register specified by Address >= 0x100, then ASSERT().\r
918 If StartBit is greater than 15, then ASSERT().\r
919 If EndBit is greater than 15, then ASSERT().\r
920 If EndBit is less than StartBit, then ASSERT().\r
94952554 921 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 922\r
2fc59a00 923 @param Address The PCI configuration register to write.\r
e1f414b6 924 @param StartBit The ordinal of the least significant bit in the bit field.\r
925 Range 0..15.\r
926 @param EndBit The ordinal of the most significant bit in the bit field.\r
927 Range 0..15.\r
928 @param OrData The value to OR with the PCI configuration register.\r
929\r
930 @return The value written back to the PCI configuration register.\r
931\r
932**/\r
933UINT16\r
934EFIAPI\r
935PciCf8BitFieldOr16 (\r
936 IN UINTN Address,\r
937 IN UINTN StartBit,\r
938 IN UINTN EndBit,\r
939 IN UINT16 OrData\r
940 )\r
941{\r
96dd57ee 942 BOOLEAN InterruptState;\r
943 UINT32 AddressPort;\r
944 UINT16 Result;\r
9095d37b 945\r
e1f414b6 946 ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
96dd57ee 947 InterruptState = SaveAndDisableInterrupts ();\r
948 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 949 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 950 Result = IoBitFieldOr16 (\r
951 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
952 StartBit,\r
953 EndBit,\r
954 OrData\r
955 );\r
956 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
957 SetInterruptState (InterruptState);\r
958 return Result;\r
e1f414b6 959}\r
960\r
961/**\r
962 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise\r
963 AND, and writes the result back to the bit field in the 16-bit register.\r
964\r
965 Reads the 16-bit PCI configuration register specified by Address, performs a\r
966 bitwise AND between the read result and the value specified by AndData, and\r
967 writes the result to the 16-bit PCI configuration register specified by\r
968 Address. The value written to the PCI configuration register is returned.\r
969 This function must guarantee that all PCI read and write operations are\r
970 serialized. Extra left bits in AndData are stripped.\r
971\r
972 If Address > 0x0FFFFFFF, then ASSERT().\r
973 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
974 If the register specified by Address >= 0x100, then ASSERT().\r
975 If StartBit is greater than 15, then ASSERT().\r
976 If EndBit is greater than 15, then ASSERT().\r
977 If EndBit is less than StartBit, then ASSERT().\r
94952554 978 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 979\r
2fc59a00 980 @param Address The PCI configuration register to write.\r
e1f414b6 981 @param StartBit The ordinal of the least significant bit in the bit field.\r
982 Range 0..15.\r
983 @param EndBit The ordinal of the most significant bit in the bit field.\r
984 Range 0..15.\r
985 @param AndData The value to AND with the PCI configuration register.\r
986\r
987 @return The value written back to the PCI configuration register.\r
988\r
989**/\r
990UINT16\r
991EFIAPI\r
992PciCf8BitFieldAnd16 (\r
993 IN UINTN Address,\r
994 IN UINTN StartBit,\r
995 IN UINTN EndBit,\r
996 IN UINT16 AndData\r
997 )\r
998{\r
96dd57ee 999 BOOLEAN InterruptState;\r
1000 UINT32 AddressPort;\r
1001 UINT16 Result;\r
9095d37b 1002\r
e1f414b6 1003 ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
96dd57ee 1004 InterruptState = SaveAndDisableInterrupts ();\r
1005 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 1006 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 1007 Result = IoBitFieldAnd16 (\r
1008 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
1009 StartBit,\r
1010 EndBit,\r
1011 AndData\r
1012 );\r
1013 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
1014 SetInterruptState (InterruptState);\r
1015 return Result;\r
e1f414b6 1016}\r
1017\r
1018/**\r
1019 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a\r
62991af2 1020 bitwise OR, and writes the result back to the bit field in the\r
e1f414b6 1021 16-bit port.\r
1022\r
1023 Reads the 16-bit PCI configuration register specified by Address, performs a\r
62991af2 1024 bitwise AND followed by a bitwise OR between the read result and\r
e1f414b6 1025 the value specified by AndData, and writes the result to the 16-bit PCI\r
1026 configuration register specified by Address. The value written to the PCI\r
1027 configuration register is returned. This function must guarantee that all PCI\r
1028 read and write operations are serialized. Extra left bits in both AndData and\r
1029 OrData are stripped.\r
1030\r
1031 If Address > 0x0FFFFFFF, then ASSERT().\r
1032 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
1033 If the register specified by Address >= 0x100, then ASSERT().\r
1034 If StartBit is greater than 15, then ASSERT().\r
1035 If EndBit is greater than 15, then ASSERT().\r
1036 If EndBit is less than StartBit, then ASSERT().\r
94952554
LG
1037 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
1038 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 1039\r
2fc59a00 1040 @param Address The PCI configuration register to write.\r
e1f414b6 1041 @param StartBit The ordinal of the least significant bit in the bit field.\r
1042 Range 0..15.\r
1043 @param EndBit The ordinal of the most significant bit in the bit field.\r
1044 Range 0..15.\r
1045 @param AndData The value to AND with the PCI configuration register.\r
1046 @param OrData The value to OR with the result of the AND operation.\r
1047\r
1048 @return The value written back to the PCI configuration register.\r
1049\r
1050**/\r
1051UINT16\r
1052EFIAPI\r
1053PciCf8BitFieldAndThenOr16(\r
1054 IN UINTN Address,\r
1055 IN UINTN StartBit,\r
1056 IN UINTN EndBit,\r
1057 IN UINT16 AndData,\r
1058 IN UINT16 OrData\r
1059 )\r
1060{\r
96dd57ee 1061 BOOLEAN InterruptState;\r
1062 UINT32 AddressPort;\r
1063 UINT16 Result;\r
9095d37b 1064\r
e1f414b6 1065 ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
96dd57ee 1066 InterruptState = SaveAndDisableInterrupts ();\r
1067 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 1068 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 1069 Result = IoBitFieldAndThenOr16 (\r
1070 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
1071 StartBit,\r
1072 EndBit,\r
1073 AndData,\r
1074 OrData\r
1075 );\r
1076 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
1077 SetInterruptState (InterruptState);\r
1078 return Result;\r
e1f414b6 1079}\r
1080\r
1081/**\r
1082 Reads a 32-bit PCI configuration register.\r
1083\r
1084 Reads and returns the 32-bit PCI configuration register specified by Address.\r
1085 This function must guarantee that all PCI read and write operations are\r
1086 serialized.\r
1087\r
1088 If Address > 0x0FFFFFFF, then ASSERT().\r
1089 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1090 If the register specified by Address >= 0x100, then ASSERT().\r
1091\r
2fc59a00 1092 @param Address The address that encodes the PCI Bus, Device, Function and\r
e1f414b6 1093 Register.\r
1094\r
1095 @return The read value from the PCI configuration register.\r
1096\r
1097**/\r
1098UINT32\r
1099EFIAPI\r
1100PciCf8Read32 (\r
1101 IN UINTN Address\r
1102 )\r
1103{\r
96dd57ee 1104 BOOLEAN InterruptState;\r
1105 UINT32 AddressPort;\r
1106 UINT32 Result;\r
9095d37b 1107\r
e1f414b6 1108 ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
96dd57ee 1109 InterruptState = SaveAndDisableInterrupts ();\r
1110 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 1111 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 1112 Result = IoRead32 (PCI_CONFIGURATION_DATA_PORT);\r
1113 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
1114 SetInterruptState (InterruptState);\r
1115 return Result;\r
e1f414b6 1116}\r
1117\r
1118/**\r
1119 Writes a 32-bit PCI configuration register.\r
1120\r
1121 Writes the 32-bit PCI configuration register specified by Address with the\r
1122 value specified by Value. Value is returned. This function must guarantee\r
1123 that all PCI read and write operations are serialized.\r
1124\r
1125 If Address > 0x0FFFFFFF, then ASSERT().\r
1126 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1127 If the register specified by Address >= 0x100, then ASSERT().\r
1128\r
2fc59a00 1129 @param Address The address that encodes the PCI Bus, Device, Function and\r
e1f414b6 1130 Register.\r
1131 @param Value The value to write.\r
1132\r
1133 @return The value written to the PCI configuration register.\r
1134\r
1135**/\r
1136UINT32\r
1137EFIAPI\r
1138PciCf8Write32 (\r
1139 IN UINTN Address,\r
1140 IN UINT32 Value\r
1141 )\r
1142{\r
96dd57ee 1143 BOOLEAN InterruptState;\r
1144 UINT32 AddressPort;\r
1145 UINT32 Result;\r
9095d37b 1146\r
e1f414b6 1147 ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
96dd57ee 1148 InterruptState = SaveAndDisableInterrupts ();\r
1149 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 1150 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 1151 Result = IoWrite32 (\r
1152 PCI_CONFIGURATION_DATA_PORT,\r
1153 Value\r
1154 );\r
1155 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
1156 SetInterruptState (InterruptState);\r
1157 return Result;\r
e1f414b6 1158}\r
1159\r
1160/**\r
62991af2 1161 Performs a bitwise OR of a 32-bit PCI configuration register with\r
e1f414b6 1162 a 32-bit value.\r
1163\r
1164 Reads the 32-bit PCI configuration register specified by Address, performs a\r
62991af2 1165 bitwise OR between the read result and the value specified by\r
e1f414b6 1166 OrData, and writes the result to the 32-bit PCI configuration register\r
1167 specified by Address. The value written to the PCI configuration register is\r
1168 returned. This function must guarantee that all PCI read and write operations\r
1169 are serialized.\r
1170\r
1171 If Address > 0x0FFFFFFF, then ASSERT().\r
1172 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1173 If the register specified by Address >= 0x100, then ASSERT().\r
1174\r
2fc59a00 1175 @param Address The address that encodes the PCI Bus, Device, Function and\r
e1f414b6 1176 Register.\r
1177 @param OrData The value to OR with the PCI configuration register.\r
1178\r
1179 @return The value written back to the PCI configuration register.\r
1180\r
1181**/\r
1182UINT32\r
1183EFIAPI\r
1184PciCf8Or32 (\r
1185 IN UINTN Address,\r
1186 IN UINT32 OrData\r
1187 )\r
1188{\r
96dd57ee 1189 BOOLEAN InterruptState;\r
1190 UINT32 AddressPort;\r
1191 UINT32 Result;\r
9095d37b 1192\r
e1f414b6 1193 ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
96dd57ee 1194 InterruptState = SaveAndDisableInterrupts ();\r
1195 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 1196 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 1197 Result = IoOr32 (\r
1198 PCI_CONFIGURATION_DATA_PORT,\r
1199 OrData\r
1200 );\r
1201 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
1202 SetInterruptState (InterruptState);\r
1203 return Result;\r
e1f414b6 1204}\r
1205\r
1206/**\r
1207 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit\r
1208 value.\r
1209\r
1210 Reads the 32-bit PCI configuration register specified by Address, performs a\r
1211 bitwise AND between the read result and the value specified by AndData, and\r
1212 writes the result to the 32-bit PCI configuration register specified by\r
1213 Address. The value written to the PCI configuration register is returned.\r
1214 This function must guarantee that all PCI read and write operations are\r
1215 serialized.\r
1216\r
1217 If Address > 0x0FFFFFFF, then ASSERT().\r
1218 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1219 If the register specified by Address >= 0x100, then ASSERT().\r
1220\r
2fc59a00 1221 @param Address The address that encodes the PCI Bus, Device, Function and\r
e1f414b6 1222 Register.\r
1223 @param AndData The value to AND with the PCI configuration register.\r
1224\r
1225 @return The value written back to the PCI configuration register.\r
1226\r
1227**/\r
1228UINT32\r
1229EFIAPI\r
1230PciCf8And32 (\r
1231 IN UINTN Address,\r
1232 IN UINT32 AndData\r
1233 )\r
1234{\r
96dd57ee 1235 BOOLEAN InterruptState;\r
1236 UINT32 AddressPort;\r
1237 UINT32 Result;\r
9095d37b 1238\r
e1f414b6 1239 ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
96dd57ee 1240 InterruptState = SaveAndDisableInterrupts ();\r
1241 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 1242 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 1243 Result = IoAnd32 (\r
1244 PCI_CONFIGURATION_DATA_PORT,\r
1245 AndData\r
1246 );\r
1247 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
1248 SetInterruptState (InterruptState);\r
1249 return Result;\r
e1f414b6 1250}\r
1251\r
1252/**\r
1253 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit\r
62991af2 1254 value, followed a bitwise OR with another 32-bit value.\r
e1f414b6 1255\r
1256 Reads the 32-bit PCI configuration register specified by Address, performs a\r
1257 bitwise AND between the read result and the value specified by AndData,\r
62991af2 1258 performs a bitwise OR between the result of the AND operation and\r
e1f414b6 1259 the value specified by OrData, and writes the result to the 32-bit PCI\r
1260 configuration register specified by Address. The value written to the PCI\r
1261 configuration register is returned. This function must guarantee that all PCI\r
1262 read and write operations are serialized.\r
1263\r
1264 If Address > 0x0FFFFFFF, then ASSERT().\r
1265 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1266 If the register specified by Address >= 0x100, then ASSERT().\r
1267\r
2fc59a00 1268 @param Address The address that encodes the PCI Bus, Device, Function and\r
e1f414b6 1269 Register.\r
1270 @param AndData The value to AND with the PCI configuration register.\r
1271 @param OrData The value to OR with the result of the AND operation.\r
1272\r
1273 @return The value written back to the PCI configuration register.\r
1274\r
1275**/\r
1276UINT32\r
1277EFIAPI\r
1278PciCf8AndThenOr32 (\r
1279 IN UINTN Address,\r
1280 IN UINT32 AndData,\r
1281 IN UINT32 OrData\r
1282 )\r
1283{\r
96dd57ee 1284 BOOLEAN InterruptState;\r
1285 UINT32 AddressPort;\r
1286 UINT32 Result;\r
9095d37b 1287\r
e1f414b6 1288 ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
96dd57ee 1289 InterruptState = SaveAndDisableInterrupts ();\r
1290 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 1291 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 1292 Result = IoAndThenOr32 (\r
1293 PCI_CONFIGURATION_DATA_PORT,\r
1294 AndData,\r
1295 OrData\r
1296 );\r
1297 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
1298 SetInterruptState (InterruptState);\r
1299 return Result;\r
e1f414b6 1300}\r
1301\r
1302/**\r
1303 Reads a bit field of a PCI configuration register.\r
1304\r
1305 Reads the bit field in a 32-bit PCI configuration register. The bit field is\r
1306 specified by the StartBit and the EndBit. The value of the bit field is\r
1307 returned.\r
1308\r
1309 If Address > 0x0FFFFFFF, then ASSERT().\r
1310 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1311 If the register specified by Address >= 0x100, then ASSERT().\r
1312 If StartBit is greater than 31, then ASSERT().\r
1313 If EndBit is greater than 31, then ASSERT().\r
1314 If EndBit is less than StartBit, then ASSERT().\r
1315\r
2fc59a00 1316 @param Address The PCI configuration register to read.\r
e1f414b6 1317 @param StartBit The ordinal of the least significant bit in the bit field.\r
1318 Range 0..31.\r
1319 @param EndBit The ordinal of the most significant bit in the bit field.\r
1320 Range 0..31.\r
1321\r
1322 @return The value of the bit field read from the PCI configuration register.\r
1323\r
1324**/\r
1325UINT32\r
1326EFIAPI\r
1327PciCf8BitFieldRead32 (\r
1328 IN UINTN Address,\r
1329 IN UINTN StartBit,\r
1330 IN UINTN EndBit\r
1331 )\r
1332{\r
96dd57ee 1333 BOOLEAN InterruptState;\r
1334 UINT32 AddressPort;\r
1335 UINT32 Result;\r
9095d37b 1336\r
e1f414b6 1337 ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
96dd57ee 1338 InterruptState = SaveAndDisableInterrupts ();\r
1339 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 1340 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 1341 Result = IoBitFieldRead32 (\r
1342 PCI_CONFIGURATION_DATA_PORT,\r
1343 StartBit,\r
1344 EndBit\r
1345 );\r
1346 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
1347 SetInterruptState (InterruptState);\r
1348 return Result;\r
e1f414b6 1349}\r
1350\r
1351/**\r
1352 Writes a bit field to a PCI configuration register.\r
1353\r
1354 Writes Value to the bit field of the PCI configuration register. The bit\r
1355 field is specified by the StartBit and the EndBit. All other bits in the\r
1356 destination PCI configuration register are preserved. The new value of the\r
1357 32-bit register is returned.\r
1358\r
1359 If Address > 0x0FFFFFFF, then ASSERT().\r
1360 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1361 If the register specified by Address >= 0x100, then ASSERT().\r
1362 If StartBit is greater than 31, then ASSERT().\r
1363 If EndBit is greater than 31, then ASSERT().\r
1364 If EndBit is less than StartBit, then ASSERT().\r
94952554 1365 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 1366\r
2fc59a00 1367 @param Address The PCI configuration register to write.\r
e1f414b6 1368 @param StartBit The ordinal of the least significant bit in the bit field.\r
1369 Range 0..31.\r
1370 @param EndBit The ordinal of the most significant bit in the bit field.\r
1371 Range 0..31.\r
2fc59a00 1372 @param Value The new value of the bit field.\r
e1f414b6 1373\r
1374 @return The value written back to the PCI configuration register.\r
1375\r
1376**/\r
1377UINT32\r
1378EFIAPI\r
1379PciCf8BitFieldWrite32 (\r
1380 IN UINTN Address,\r
1381 IN UINTN StartBit,\r
1382 IN UINTN EndBit,\r
1383 IN UINT32 Value\r
1384 )\r
1385{\r
96dd57ee 1386 BOOLEAN InterruptState;\r
1387 UINT32 AddressPort;\r
1388 UINT32 Result;\r
9095d37b 1389\r
e1f414b6 1390 ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
96dd57ee 1391 InterruptState = SaveAndDisableInterrupts ();\r
1392 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 1393 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 1394 Result = IoBitFieldWrite32 (\r
1395 PCI_CONFIGURATION_DATA_PORT,\r
1396 StartBit,\r
1397 EndBit,\r
1398 Value\r
1399 );\r
1400 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
1401 SetInterruptState (InterruptState);\r
1402 return Result;\r
e1f414b6 1403}\r
1404\r
1405/**\r
1406 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and\r
1407 writes the result back to the bit field in the 32-bit port.\r
1408\r
1409 Reads the 32-bit PCI configuration register specified by Address, performs a\r
62991af2 1410 bitwise OR between the read result and the value specified by\r
e1f414b6 1411 OrData, and writes the result to the 32-bit PCI configuration register\r
1412 specified by Address. The value written to the PCI configuration register is\r
1413 returned. This function must guarantee that all PCI read and write operations\r
1414 are serialized. Extra left bits in OrData are stripped.\r
1415\r
1416 If Address > 0x0FFFFFFF, then ASSERT().\r
1417 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1418 If the register specified by Address >= 0x100, then ASSERT().\r
1419 If StartBit is greater than 31, then ASSERT().\r
1420 If EndBit is greater than 31, then ASSERT().\r
1421 If EndBit is less than StartBit, then ASSERT().\r
94952554 1422 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 1423\r
2fc59a00 1424 @param Address The PCI configuration register to write.\r
e1f414b6 1425 @param StartBit The ordinal of the least significant bit in the bit field.\r
1426 Range 0..31.\r
1427 @param EndBit The ordinal of the most significant bit in the bit field.\r
1428 Range 0..31.\r
1429 @param OrData The value to OR with the PCI configuration register.\r
1430\r
1431 @return The value written back to the PCI configuration register.\r
1432\r
1433**/\r
1434UINT32\r
1435EFIAPI\r
1436PciCf8BitFieldOr32 (\r
1437 IN UINTN Address,\r
1438 IN UINTN StartBit,\r
1439 IN UINTN EndBit,\r
1440 IN UINT32 OrData\r
1441 )\r
1442{\r
96dd57ee 1443 BOOLEAN InterruptState;\r
1444 UINT32 AddressPort;\r
1445 UINT32 Result;\r
9095d37b 1446\r
e1f414b6 1447 ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
96dd57ee 1448 InterruptState = SaveAndDisableInterrupts ();\r
1449 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 1450 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 1451 Result = IoBitFieldOr32 (\r
1452 PCI_CONFIGURATION_DATA_PORT,\r
1453 StartBit,\r
1454 EndBit,\r
1455 OrData\r
1456 );\r
1457 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
1458 SetInterruptState (InterruptState);\r
1459 return Result;\r
e1f414b6 1460}\r
1461\r
1462/**\r
1463 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise\r
1464 AND, and writes the result back to the bit field in the 32-bit register.\r
1465\r
1466 Reads the 32-bit PCI configuration register specified by Address, performs a\r
1467 bitwise AND between the read result and the value specified by AndData, and\r
1468 writes the result to the 32-bit PCI configuration register specified by\r
1469 Address. The value written to the PCI configuration register is returned.\r
1470 This function must guarantee that all PCI read and write operations are\r
1471 serialized. Extra left bits in AndData are stripped.\r
1472\r
1473 If Address > 0x0FFFFFFF, then ASSERT().\r
1474 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1475 If the register specified by Address >= 0x100, then ASSERT().\r
1476 If StartBit is greater than 31, then ASSERT().\r
1477 If EndBit is greater than 31, then ASSERT().\r
1478 If EndBit is less than StartBit, then ASSERT().\r
94952554 1479 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 1480\r
2fc59a00 1481 @param Address The PCI configuration register to write.\r
e1f414b6 1482 @param StartBit The ordinal of the least significant bit in the bit field.\r
1483 Range 0..31.\r
1484 @param EndBit The ordinal of the most significant bit in the bit field.\r
1485 Range 0..31.\r
1486 @param AndData The value to AND with the PCI configuration register.\r
1487\r
1488 @return The value written back to the PCI configuration register.\r
1489\r
1490**/\r
1491UINT32\r
1492EFIAPI\r
1493PciCf8BitFieldAnd32 (\r
1494 IN UINTN Address,\r
1495 IN UINTN StartBit,\r
1496 IN UINTN EndBit,\r
1497 IN UINT32 AndData\r
1498 )\r
1499{\r
96dd57ee 1500 BOOLEAN InterruptState;\r
1501 UINT32 AddressPort;\r
1502 UINT32 Result;\r
9095d37b 1503\r
e1f414b6 1504 ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
96dd57ee 1505 InterruptState = SaveAndDisableInterrupts ();\r
1506 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 1507 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 1508 Result = IoBitFieldAnd32 (\r
1509 PCI_CONFIGURATION_DATA_PORT,\r
1510 StartBit,\r
1511 EndBit,\r
1512 AndData\r
1513 );\r
1514 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
1515 SetInterruptState (InterruptState);\r
1516 return Result;\r
e1f414b6 1517}\r
1518\r
1519/**\r
1520 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a\r
62991af2 1521 bitwise OR, and writes the result back to the bit field in the\r
e1f414b6 1522 32-bit port.\r
1523\r
1524 Reads the 32-bit PCI configuration register specified by Address, performs a\r
62991af2 1525 bitwise AND followed by a bitwise OR between the read result and\r
e1f414b6 1526 the value specified by AndData, and writes the result to the 32-bit PCI\r
1527 configuration register specified by Address. The value written to the PCI\r
1528 configuration register is returned. This function must guarantee that all PCI\r
1529 read and write operations are serialized. Extra left bits in both AndData and\r
1530 OrData are stripped.\r
1531\r
1532 If Address > 0x0FFFFFFF, then ASSERT().\r
1533 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1534 If the register specified by Address >= 0x100, then ASSERT().\r
1535 If StartBit is greater than 31, then ASSERT().\r
1536 If EndBit is greater than 31, then ASSERT().\r
1537 If EndBit is less than StartBit, then ASSERT().\r
94952554
LG
1538 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
1539 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 1540\r
2fc59a00 1541 @param Address The PCI configuration register to write.\r
e1f414b6 1542 @param StartBit The ordinal of the least significant bit in the bit field.\r
1543 Range 0..31.\r
1544 @param EndBit The ordinal of the most significant bit in the bit field.\r
1545 Range 0..31.\r
1546 @param AndData The value to AND with the PCI configuration register.\r
1547 @param OrData The value to OR with the result of the AND operation.\r
1548\r
1549 @return The value written back to the PCI configuration register.\r
1550\r
1551**/\r
1552UINT32\r
1553EFIAPI\r
1554PciCf8BitFieldAndThenOr32(\r
1555 IN UINTN Address,\r
1556 IN UINTN StartBit,\r
1557 IN UINTN EndBit,\r
1558 IN UINT32 AndData,\r
1559 IN UINT32 OrData\r
1560 )\r
1561{\r
96dd57ee 1562 BOOLEAN InterruptState;\r
1563 UINT32 AddressPort;\r
1564 UINT32 Result;\r
9095d37b 1565\r
e1f414b6 1566 ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
96dd57ee 1567 InterruptState = SaveAndDisableInterrupts ();\r
1568 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 1569 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 1570 Result = IoBitFieldAndThenOr32 (\r
1571 PCI_CONFIGURATION_DATA_PORT,\r
1572 StartBit,\r
1573 EndBit,\r
1574 AndData,\r
1575 OrData\r
1576 );\r
1577 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
1578 SetInterruptState (InterruptState);\r
1579 return Result;\r
e1f414b6 1580}\r
1581\r
1582/**\r
1583 Reads a range of PCI configuration registers into a caller supplied buffer.\r
1584\r
1585 Reads the range of PCI configuration registers specified by StartAddress and\r
1586 Size into the buffer specified by Buffer. This function only allows the PCI\r
1587 configuration registers from a single PCI function to be read. Size is\r
1588 returned. When possible 32-bit PCI configuration read cycles are used to read\r
1589 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit\r
1590 and 16-bit PCI configuration read cycles may be used at the beginning and the\r
1591 end of the range.\r
1592\r
1593 If StartAddress > 0x0FFFFFFF, then ASSERT().\r
1594 If the register specified by StartAddress >= 0x100, then ASSERT().\r
1595 If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().\r
1596 If Size > 0 and Buffer is NULL, then ASSERT().\r
1597\r
2fc59a00 1598 @param StartAddress The starting address that encodes the PCI Bus, Device,\r
e1f414b6 1599 Function and Register.\r
2fc59a00 1600 @param Size The size in bytes of the transfer.\r
1601 @param Buffer The pointer to a buffer receiving the data read.\r
e1f414b6 1602\r
9638ba6d 1603 @return Size read from StartAddress.\r
e1f414b6 1604\r
1605**/\r
1606UINTN\r
1607EFIAPI\r
1608PciCf8ReadBuffer (\r
1609 IN UINTN StartAddress,\r
1610 IN UINTN Size,\r
1611 OUT VOID *Buffer\r
1612 )\r
1613{\r
0c62737d 1614 UINTN ReturnValue;\r
e1f414b6 1615\r
1616 ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);\r
1617 ASSERT (((StartAddress & 0xFFF) + Size) <= 0x100);\r
1618\r
1619 if (Size == 0) {\r
1620 return Size;\r
1621 }\r
1622\r
1623 ASSERT (Buffer != NULL);\r
1624\r
1625 //\r
1626 // Save Size for return\r
1627 //\r
1628 ReturnValue = Size;\r
1629\r
1630 if ((StartAddress & 1) != 0) {\r
1631 //\r
1632 // Read a byte if StartAddress is byte aligned\r
1633 //\r
1634 *(volatile UINT8 *)Buffer = PciCf8Read8 (StartAddress);\r
1635 StartAddress += sizeof (UINT8);\r
1636 Size -= sizeof (UINT8);\r
1637 Buffer = (UINT8*)Buffer + 1;\r
1638 }\r
1639\r
1640 if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {\r
1641 //\r
1642 // Read a word if StartAddress is word aligned\r
1643 //\r
af2bb549 1644 WriteUnaligned16 ((UINT16 *)Buffer, (UINT16) PciCf8Read16 (StartAddress));\r
0c62737d 1645\r
e1f414b6 1646 StartAddress += sizeof (UINT16);\r
1647 Size -= sizeof (UINT16);\r
1648 Buffer = (UINT16*)Buffer + 1;\r
1649 }\r
1650\r
1651 while (Size >= sizeof (UINT32)) {\r
1652 //\r
1653 // Read as many double words as possible\r
1654 //\r
af2bb549 1655 WriteUnaligned32 ((UINT32 *)Buffer, (UINT32) PciCf8Read32 (StartAddress));\r
e1f414b6 1656 StartAddress += sizeof (UINT32);\r
1657 Size -= sizeof (UINT32);\r
1658 Buffer = (UINT32*)Buffer + 1;\r
1659 }\r
1660\r
1661 if (Size >= sizeof (UINT16)) {\r
1662 //\r
1663 // Read the last remaining word if exist\r
1664 //\r
af2bb549 1665 WriteUnaligned16 ((UINT16 *)Buffer, (UINT16) PciCf8Read16 (StartAddress));\r
e1f414b6 1666 StartAddress += sizeof (UINT16);\r
1667 Size -= sizeof (UINT16);\r
1668 Buffer = (UINT16*)Buffer + 1;\r
1669 }\r
1670\r
1671 if (Size >= sizeof (UINT8)) {\r
1672 //\r
1673 // Read the last remaining byte if exist\r
1674 //\r
1675 *(volatile UINT8 *)Buffer = PciCf8Read8 (StartAddress);\r
1676 }\r
1677\r
1678 return ReturnValue;\r
1679}\r
1680\r
1681/**\r
1682 Copies the data in a caller supplied buffer to a specified range of PCI\r
1683 configuration space.\r
1684\r
1685 Writes the range of PCI configuration registers specified by StartAddress and\r
1686 Size from the buffer specified by Buffer. This function only allows the PCI\r
1687 configuration registers from a single PCI function to be written. Size is\r
1688 returned. When possible 32-bit PCI configuration write cycles are used to\r
1689 write from StartAdress to StartAddress + Size. Due to alignment restrictions,\r
1690 8-bit and 16-bit PCI configuration write cycles may be used at the beginning\r
1691 and the end of the range.\r
1692\r
1693 If StartAddress > 0x0FFFFFFF, then ASSERT().\r
1694 If the register specified by StartAddress >= 0x100, then ASSERT().\r
1695 If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().\r
1696 If Size > 0 and Buffer is NULL, then ASSERT().\r
1697\r
2fc59a00 1698 @param StartAddress The starting address that encodes the PCI Bus, Device,\r
e1f414b6 1699 Function and Register.\r
2fc59a00 1700 @param Size The size in bytes of the transfer.\r
1701 @param Buffer The pointer to a buffer containing the data to write.\r
e1f414b6 1702\r
9638ba6d 1703 @return Size written to StartAddress.\r
e1f414b6 1704\r
1705**/\r
1706UINTN\r
1707EFIAPI\r
1708PciCf8WriteBuffer (\r
1709 IN UINTN StartAddress,\r
1710 IN UINTN Size,\r
1711 IN VOID *Buffer\r
1712 )\r
1713{\r
0c62737d 1714 UINTN ReturnValue;\r
e1f414b6 1715\r
1716 ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);\r
1717 ASSERT (((StartAddress & 0xFFF) + Size) <= 0x100);\r
1718\r
1719 if (Size == 0) {\r
1720 return 0;\r
1721 }\r
1722\r
1723 ASSERT (Buffer != NULL);\r
1724\r
1725 //\r
1726 // Save Size for return\r
1727 //\r
1728 ReturnValue = Size;\r
1729\r
1730 if ((StartAddress & 1) != 0) {\r
1731 //\r
1732 // Write a byte if StartAddress is byte aligned\r
1733 //\r
1734 PciCf8Write8 (StartAddress, *(UINT8*)Buffer);\r
1735 StartAddress += sizeof (UINT8);\r
1736 Size -= sizeof (UINT8);\r
1737 Buffer = (UINT8*)Buffer + 1;\r
1738 }\r
1739\r
1740 if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {\r
1741 //\r
1742 // Write a word if StartAddress is word aligned\r
1743 //\r
0c62737d 1744 PciCf8Write16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer));\r
e1f414b6 1745 StartAddress += sizeof (UINT16);\r
1746 Size -= sizeof (UINT16);\r
1747 Buffer = (UINT16*)Buffer + 1;\r
1748 }\r
1749\r
1750 while (Size >= sizeof (UINT32)) {\r
1751 //\r
1752 // Write as many double words as possible\r
1753 //\r
0c62737d 1754 PciCf8Write32 (StartAddress, ReadUnaligned32 ((UINT32*)Buffer));\r
e1f414b6 1755 StartAddress += sizeof (UINT32);\r
1756 Size -= sizeof (UINT32);\r
1757 Buffer = (UINT32*)Buffer + 1;\r
1758 }\r
1759\r
1760 if (Size >= sizeof (UINT16)) {\r
1761 //\r
1762 // Write the last remaining word if exist\r
1763 //\r
0c62737d 1764 PciCf8Write16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer));\r
e1f414b6 1765 StartAddress += sizeof (UINT16);\r
1766 Size -= sizeof (UINT16);\r
1767 Buffer = (UINT16*)Buffer + 1;\r
1768 }\r
1769\r
1770 if (Size >= sizeof (UINT8)) {\r
1771 //\r
1772 // Write the last remaining byte if exist\r
1773 //\r
1774 PciCf8Write8 (StartAddress, *(UINT8*)Buffer);\r
1775 }\r
1776\r
1777 return ReturnValue;\r
1778}\r