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