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