]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BasePciCf8Lib/PciCf8Lib.c
Add ASSERT() for BitField operations to make sure the input value is valid.
[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
94952554 5 Copyright (c) 2006 - 2012, 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
94952554 372 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 373\r
2fc59a00 374 @param Address The PCI configuration register to write.\r
e1f414b6 375 @param StartBit The ordinal of the least significant bit in the bit field.\r
376 Range 0..7.\r
377 @param EndBit The ordinal of the most significant bit in the bit field.\r
378 Range 0..7.\r
2fc59a00 379 @param Value The new value of the bit field.\r
e1f414b6 380\r
381 @return The value written back to the PCI configuration register.\r
382\r
383**/\r
384UINT8\r
385EFIAPI\r
386PciCf8BitFieldWrite8 (\r
387 IN UINTN Address,\r
388 IN UINTN StartBit,\r
389 IN UINTN EndBit,\r
390 IN UINT8 Value\r
391 )\r
392{\r
96dd57ee 393 BOOLEAN InterruptState;\r
394 UINT32 AddressPort;\r
395 UINT8 Result;\r
396 \r
e1f414b6 397 ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
96dd57ee 398 InterruptState = SaveAndDisableInterrupts ();\r
399 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 400 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 401 Result = IoBitFieldWrite8 (\r
402 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r
403 StartBit,\r
404 EndBit,\r
405 Value\r
406 );\r
407 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
408 SetInterruptState (InterruptState);\r
409 return Result;\r
e1f414b6 410}\r
411\r
412/**\r
413 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and\r
414 writes the result back to the bit field in the 8-bit port.\r
415\r
416 Reads the 8-bit PCI configuration register specified by Address, performs a\r
62991af2 417 bitwise OR between the read result and the value specified by\r
e1f414b6 418 OrData, and writes the result to the 8-bit PCI configuration register\r
419 specified by Address. The value written to the PCI configuration register is\r
420 returned. This function must guarantee that all PCI read and write operations\r
421 are serialized. Extra left bits in OrData are stripped.\r
422\r
423 If Address > 0x0FFFFFFF, then ASSERT().\r
424 If the register specified by Address >= 0x100, then ASSERT().\r
425 If StartBit is greater than 7, then ASSERT().\r
426 If EndBit is greater than 7, then ASSERT().\r
427 If EndBit is less than StartBit, then ASSERT().\r
94952554 428 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 429\r
2fc59a00 430 @param Address The PCI configuration register to write.\r
e1f414b6 431 @param StartBit The ordinal of the least significant bit in the bit field.\r
432 Range 0..7.\r
433 @param EndBit The ordinal of the most significant bit in the bit field.\r
434 Range 0..7.\r
435 @param OrData The value to OR with the PCI configuration register.\r
436\r
437 @return The value written back to the PCI configuration register.\r
438\r
439**/\r
440UINT8\r
441EFIAPI\r
442PciCf8BitFieldOr8 (\r
443 IN UINTN Address,\r
444 IN UINTN StartBit,\r
445 IN UINTN EndBit,\r
446 IN UINT8 OrData\r
447 )\r
448{\r
96dd57ee 449 BOOLEAN InterruptState;\r
450 UINT32 AddressPort;\r
451 UINT8 Result;\r
452 \r
e1f414b6 453 ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
96dd57ee 454 InterruptState = SaveAndDisableInterrupts ();\r
455 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 456 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 457 Result = IoBitFieldOr8 (\r
458 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r
459 StartBit,\r
460 EndBit,\r
461 OrData\r
462 );\r
463 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
464 SetInterruptState (InterruptState);\r
465 return Result;\r
e1f414b6 466}\r
467\r
468/**\r
469 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise\r
470 AND, and writes the result back to the bit field in the 8-bit register.\r
471\r
472 Reads the 8-bit PCI configuration register specified by Address, performs a\r
473 bitwise AND between the read result and the value specified by AndData, and\r
474 writes the result to the 8-bit PCI configuration register specified by\r
475 Address. The value written to the PCI configuration register is returned.\r
476 This function must guarantee that all PCI read and write operations are\r
477 serialized. Extra left bits in AndData are stripped.\r
478\r
479 If Address > 0x0FFFFFFF, then ASSERT().\r
480 If the register specified by Address >= 0x100, then ASSERT().\r
481 If StartBit is greater than 7, then ASSERT().\r
482 If EndBit is greater than 7, then ASSERT().\r
483 If EndBit is less than StartBit, then ASSERT().\r
94952554 484 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 485\r
2fc59a00 486 @param Address The PCI configuration register to write.\r
e1f414b6 487 @param StartBit The ordinal of the least significant bit in the bit field.\r
488 Range 0..7.\r
489 @param EndBit The ordinal of the most significant bit in the bit field.\r
490 Range 0..7.\r
491 @param AndData The value to AND with the PCI configuration register.\r
492\r
493 @return The value written back to the PCI configuration register.\r
494\r
495**/\r
496UINT8\r
497EFIAPI\r
498PciCf8BitFieldAnd8 (\r
499 IN UINTN Address,\r
500 IN UINTN StartBit,\r
501 IN UINTN EndBit,\r
502 IN UINT8 AndData\r
503 )\r
504{\r
96dd57ee 505 BOOLEAN InterruptState;\r
506 UINT32 AddressPort;\r
507 UINT8 Result;\r
508 \r
e1f414b6 509 ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
96dd57ee 510 InterruptState = SaveAndDisableInterrupts ();\r
511 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 512 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 513 Result = IoBitFieldAnd8 (\r
514 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r
515 StartBit,\r
516 EndBit,\r
517 AndData\r
518 );\r
519 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
520 SetInterruptState (InterruptState);\r
521 return Result;\r
e1f414b6 522}\r
523\r
524/**\r
525 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a\r
62991af2 526 bitwise OR, and writes the result back to the bit field in the\r
e1f414b6 527 8-bit port.\r
528\r
529 Reads the 8-bit PCI configuration register specified by Address, performs a\r
62991af2 530 bitwise AND followed by a bitwise OR between the read result and\r
e1f414b6 531 the value specified by AndData, and writes the result to the 8-bit PCI\r
532 configuration register specified by Address. The value written to the PCI\r
533 configuration register is returned. This function must guarantee that all PCI\r
534 read and write operations are serialized. Extra left bits in both AndData and\r
535 OrData are stripped.\r
536\r
537 If Address > 0x0FFFFFFF, then ASSERT().\r
538 If the register specified by Address >= 0x100, then ASSERT().\r
539 If StartBit is greater than 7, then ASSERT().\r
540 If EndBit is greater than 7, then ASSERT().\r
541 If EndBit is less than StartBit, then ASSERT().\r
94952554
LG
542 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
543 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 544\r
2fc59a00 545 @param Address The PCI configuration register to write.\r
e1f414b6 546 @param StartBit The ordinal of the least significant bit in the bit field.\r
547 Range 0..7.\r
548 @param EndBit The ordinal of the most significant bit in the bit field.\r
549 Range 0..7.\r
550 @param AndData The value to AND with the PCI configuration register.\r
551 @param OrData The value to OR with the result of the AND operation.\r
552\r
553 @return The value written back to the PCI configuration register.\r
554\r
555**/\r
556UINT8\r
557EFIAPI\r
558PciCf8BitFieldAndThenOr8(\r
559 IN UINTN Address,\r
560 IN UINTN StartBit,\r
561 IN UINTN EndBit,\r
562 IN UINT8 AndData,\r
563 IN UINT8 OrData\r
564 )\r
565{\r
96dd57ee 566 BOOLEAN InterruptState;\r
567 UINT32 AddressPort;\r
568 UINT8 Result;\r
569 \r
e1f414b6 570 ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
96dd57ee 571 InterruptState = SaveAndDisableInterrupts ();\r
572 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 573 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 574 Result = IoBitFieldAndThenOr8 (\r
575 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),\r
576 StartBit,\r
577 EndBit,\r
578 AndData,\r
579 OrData\r
580 );\r
581 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
582 SetInterruptState (InterruptState);\r
583 return Result;\r
e1f414b6 584}\r
585\r
586/**\r
587 Reads a 16-bit PCI configuration register.\r
588\r
589 Reads and returns the 16-bit PCI configuration register specified by Address.\r
590 This function must guarantee that all PCI read and write operations are\r
591 serialized.\r
592\r
593 If Address > 0x0FFFFFFF, then ASSERT().\r
594 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
595 If the register specified by Address >= 0x100, then ASSERT().\r
596\r
2fc59a00 597 @param Address The address that encodes the PCI Bus, Device, Function and\r
e1f414b6 598 Register.\r
599\r
600 @return The read value from the PCI configuration register.\r
601\r
602**/\r
603UINT16\r
604EFIAPI\r
605PciCf8Read16 (\r
606 IN UINTN Address\r
607 )\r
608{\r
96dd57ee 609 BOOLEAN InterruptState;\r
610 UINT32 AddressPort;\r
611 UINT16 Result;\r
612 \r
e1f414b6 613 ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
96dd57ee 614 InterruptState = SaveAndDisableInterrupts ();\r
615 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 616 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 617 Result = IoRead16 (PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2));\r
618 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
619 SetInterruptState (InterruptState);\r
620 return Result;\r
e1f414b6 621}\r
622\r
623/**\r
624 Writes a 16-bit PCI configuration register.\r
625\r
626 Writes the 16-bit PCI configuration register specified by Address with the\r
627 value specified by Value. Value is returned. This function must guarantee\r
628 that all PCI read and write operations are serialized.\r
629\r
630 If Address > 0x0FFFFFFF, then ASSERT().\r
631 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
632 If the register specified by Address >= 0x100, then ASSERT().\r
633\r
2fc59a00 634 @param Address The address that encodes the PCI Bus, Device, Function and\r
e1f414b6 635 Register.\r
636 @param Value The value to write.\r
637\r
638 @return The value written to the PCI configuration register.\r
639\r
640**/\r
641UINT16\r
642EFIAPI\r
643PciCf8Write16 (\r
644 IN UINTN Address,\r
645 IN UINT16 Value\r
646 )\r
647{\r
96dd57ee 648 BOOLEAN InterruptState;\r
649 UINT32 AddressPort;\r
650 UINT16 Result;\r
651 \r
e1f414b6 652 ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
96dd57ee 653 InterruptState = SaveAndDisableInterrupts ();\r
654 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 655 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 656 Result = IoWrite16 (\r
657 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
658 Value\r
659 );\r
660 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
661 SetInterruptState (InterruptState);\r
662 return Result;\r
e1f414b6 663}\r
664\r
665/**\r
62991af2 666 Performs a bitwise OR of a 16-bit PCI configuration register with\r
e1f414b6 667 a 16-bit value.\r
668\r
669 Reads the 16-bit PCI configuration register specified by Address, performs a\r
62991af2 670 bitwise OR between the read result and the value specified by\r
e1f414b6 671 OrData, and writes the result to the 16-bit PCI configuration register\r
672 specified by Address. The value written to the PCI configuration register is\r
673 returned. This function must guarantee that all PCI read and write operations\r
674 are serialized.\r
675\r
676 If Address > 0x0FFFFFFF, then ASSERT().\r
677 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
678 If the register specified by Address >= 0x100, then ASSERT().\r
679\r
2fc59a00 680 @param Address The address that encodes the PCI Bus, Device, Function and\r
e1f414b6 681 Register.\r
682 @param OrData The value to OR with the PCI configuration register.\r
683\r
684 @return The value written back to the PCI configuration register.\r
685\r
686**/\r
687UINT16\r
688EFIAPI\r
689PciCf8Or16 (\r
690 IN UINTN Address,\r
691 IN UINT16 OrData\r
692 )\r
693{\r
96dd57ee 694 BOOLEAN InterruptState;\r
695 UINT32 AddressPort;\r
696 UINT16 Result;\r
697 \r
e1f414b6 698 ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
96dd57ee 699 InterruptState = SaveAndDisableInterrupts ();\r
700 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 701 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 702 Result = IoOr16 (\r
703 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
704 OrData\r
705 );\r
706 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
707 SetInterruptState (InterruptState);\r
708 return Result;\r
e1f414b6 709}\r
710\r
711/**\r
712 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit\r
713 value.\r
714\r
715 Reads the 16-bit PCI configuration register specified by Address, performs a\r
716 bitwise AND between the read result and the value specified by AndData, and\r
717 writes the result to the 16-bit PCI configuration register specified by\r
718 Address. The value written to the PCI configuration register is returned.\r
719 This function must guarantee that all PCI read and write operations are\r
720 serialized.\r
721\r
722 If Address > 0x0FFFFFFF, then ASSERT().\r
723 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
724 If the register specified by Address >= 0x100, then ASSERT().\r
725\r
2fc59a00 726 @param Address The address that encodes the PCI Bus, Device, Function and\r
e1f414b6 727 Register.\r
728 @param AndData The value to AND with the PCI configuration register.\r
729\r
730 @return The value written back to the PCI configuration register.\r
731\r
732**/\r
733UINT16\r
734EFIAPI\r
735PciCf8And16 (\r
736 IN UINTN Address,\r
737 IN UINT16 AndData\r
738 )\r
739{\r
96dd57ee 740 BOOLEAN InterruptState;\r
741 UINT32 AddressPort;\r
742 UINT16 Result;\r
743 \r
e1f414b6 744 ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
96dd57ee 745 InterruptState = SaveAndDisableInterrupts ();\r
746 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 747 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 748 Result = IoAnd16 (\r
749 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
750 AndData\r
751 );\r
752 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
753 SetInterruptState (InterruptState);\r
754 return Result;\r
e1f414b6 755}\r
756\r
757/**\r
758 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit\r
62991af2 759 value, followed a bitwise OR with another 16-bit value.\r
e1f414b6 760\r
761 Reads the 16-bit PCI configuration register specified by Address, performs a\r
762 bitwise AND between the read result and the value specified by AndData,\r
62991af2 763 performs a bitwise OR between the result of the AND operation and\r
e1f414b6 764 the value specified by OrData, and writes the result to the 16-bit PCI\r
765 configuration register specified by Address. The value written to the PCI\r
766 configuration register is returned. This function must guarantee that all PCI\r
767 read and write operations are serialized.\r
768\r
769 If Address > 0x0FFFFFFF, then ASSERT().\r
770 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
771 If the register specified by Address >= 0x100, then ASSERT().\r
772\r
2fc59a00 773 @param Address The address that encodes the PCI Bus, Device, Function and\r
e1f414b6 774 Register.\r
775 @param AndData The value to AND with the PCI configuration register.\r
776 @param OrData The value to OR with the result of the AND operation.\r
777\r
778 @return The value written back to the PCI configuration register.\r
779\r
780**/\r
781UINT16\r
782EFIAPI\r
783PciCf8AndThenOr16 (\r
784 IN UINTN Address,\r
785 IN UINT16 AndData,\r
786 IN UINT16 OrData\r
787 )\r
788{\r
96dd57ee 789 BOOLEAN InterruptState;\r
790 UINT32 AddressPort;\r
791 UINT16 Result;\r
792 \r
e1f414b6 793 ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
96dd57ee 794 InterruptState = SaveAndDisableInterrupts ();\r
795 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 796 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 797 Result = IoAndThenOr16 (\r
798 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
799 AndData,\r
800 OrData\r
801 );\r
802 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
803 SetInterruptState (InterruptState);\r
804 return Result;\r
e1f414b6 805}\r
806\r
807/**\r
808 Reads a bit field of a PCI configuration register.\r
809\r
810 Reads the bit field in a 16-bit PCI configuration register. The bit field is\r
811 specified by the StartBit and the EndBit. The value of the bit field is\r
812 returned.\r
813\r
814 If Address > 0x0FFFFFFF, then ASSERT().\r
815 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
816 If the register specified by Address >= 0x100, then ASSERT().\r
817 If StartBit is greater than 15, then ASSERT().\r
818 If EndBit is greater than 15, then ASSERT().\r
819 If EndBit is less than StartBit, then ASSERT().\r
820\r
2fc59a00 821 @param Address The PCI configuration register to read.\r
e1f414b6 822 @param StartBit The ordinal of the least significant bit in the bit field.\r
823 Range 0..15.\r
824 @param EndBit The ordinal of the most significant bit in the bit field.\r
825 Range 0..15.\r
826\r
827 @return The value of the bit field read from the PCI configuration register.\r
828\r
829**/\r
830UINT16\r
831EFIAPI\r
832PciCf8BitFieldRead16 (\r
833 IN UINTN Address,\r
834 IN UINTN StartBit,\r
835 IN UINTN EndBit\r
836 )\r
837{\r
96dd57ee 838 BOOLEAN InterruptState;\r
839 UINT32 AddressPort;\r
840 UINT16 Result;\r
841 \r
e1f414b6 842 ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
96dd57ee 843 InterruptState = SaveAndDisableInterrupts ();\r
844 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 845 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 846 Result = IoBitFieldRead16 (\r
847 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
848 StartBit,\r
849 EndBit\r
850 );\r
851 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
852 SetInterruptState (InterruptState);\r
853 return Result;\r
e1f414b6 854}\r
855\r
856/**\r
857 Writes a bit field to a PCI configuration register.\r
858\r
859 Writes Value to the bit field of the PCI configuration register. The bit\r
860 field is specified by the StartBit and the EndBit. All other bits in the\r
861 destination PCI configuration register are preserved. The new value of the\r
862 16-bit register is returned.\r
863\r
864 If Address > 0x0FFFFFFF, then ASSERT().\r
865 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
866 If the register specified by Address >= 0x100, then ASSERT().\r
867 If StartBit is greater than 15, then ASSERT().\r
868 If EndBit is greater than 15, then ASSERT().\r
869 If EndBit is less than StartBit, then ASSERT().\r
94952554 870 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 871\r
2fc59a00 872 @param Address The PCI configuration register to write.\r
e1f414b6 873 @param StartBit The ordinal of the least significant bit in the bit field.\r
874 Range 0..15.\r
875 @param EndBit The ordinal of the most significant bit in the bit field.\r
876 Range 0..15.\r
2fc59a00 877 @param Value The new value of the bit field.\r
e1f414b6 878\r
879 @return The value written back to the PCI configuration register.\r
880\r
881**/\r
882UINT16\r
883EFIAPI\r
884PciCf8BitFieldWrite16 (\r
885 IN UINTN Address,\r
886 IN UINTN StartBit,\r
887 IN UINTN EndBit,\r
888 IN UINT16 Value\r
889 )\r
890{\r
96dd57ee 891 BOOLEAN InterruptState;\r
892 UINT32 AddressPort;\r
893 UINT16 Result;\r
894 \r
e1f414b6 895 ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
96dd57ee 896 InterruptState = SaveAndDisableInterrupts ();\r
897 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 898 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 899 Result = IoBitFieldWrite16 (\r
900 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
901 StartBit,\r
902 EndBit,\r
903 Value\r
904 );\r
905 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
906 SetInterruptState (InterruptState);\r
907 return Result;\r
e1f414b6 908}\r
909\r
910/**\r
911 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and\r
912 writes the result back to the bit field in the 16-bit port.\r
913\r
914 Reads the 16-bit PCI configuration register specified by Address, performs a\r
62991af2 915 bitwise OR between the read result and the value specified by\r
e1f414b6 916 OrData, and writes the result to the 16-bit PCI configuration register\r
917 specified by Address. The value written to the PCI configuration register is\r
918 returned. This function must guarantee that all PCI read and write operations\r
919 are serialized. Extra left bits in OrData are stripped.\r
920\r
921 If Address > 0x0FFFFFFF, then ASSERT().\r
922 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
923 If the register specified by Address >= 0x100, then ASSERT().\r
924 If StartBit is greater than 15, then ASSERT().\r
925 If EndBit is greater than 15, then ASSERT().\r
926 If EndBit is less than StartBit, then ASSERT().\r
94952554 927 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 928\r
2fc59a00 929 @param Address The PCI configuration register to write.\r
e1f414b6 930 @param StartBit The ordinal of the least significant bit in the bit field.\r
931 Range 0..15.\r
932 @param EndBit The ordinal of the most significant bit in the bit field.\r
933 Range 0..15.\r
934 @param OrData The value to OR with the PCI configuration register.\r
935\r
936 @return The value written back to the PCI configuration register.\r
937\r
938**/\r
939UINT16\r
940EFIAPI\r
941PciCf8BitFieldOr16 (\r
942 IN UINTN Address,\r
943 IN UINTN StartBit,\r
944 IN UINTN EndBit,\r
945 IN UINT16 OrData\r
946 )\r
947{\r
96dd57ee 948 BOOLEAN InterruptState;\r
949 UINT32 AddressPort;\r
950 UINT16 Result;\r
951 \r
e1f414b6 952 ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
96dd57ee 953 InterruptState = SaveAndDisableInterrupts ();\r
954 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 955 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 956 Result = IoBitFieldOr16 (\r
957 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
958 StartBit,\r
959 EndBit,\r
960 OrData\r
961 );\r
962 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
963 SetInterruptState (InterruptState);\r
964 return Result;\r
e1f414b6 965}\r
966\r
967/**\r
968 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise\r
969 AND, and writes the result back to the bit field in the 16-bit register.\r
970\r
971 Reads the 16-bit PCI configuration register specified by Address, performs a\r
972 bitwise AND between the read result and the value specified by AndData, and\r
973 writes the result to the 16-bit PCI configuration register specified by\r
974 Address. The value written to the PCI configuration register is returned.\r
975 This function must guarantee that all PCI read and write operations are\r
976 serialized. Extra left bits in AndData are stripped.\r
977\r
978 If Address > 0x0FFFFFFF, then ASSERT().\r
979 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
980 If the register specified by Address >= 0x100, then ASSERT().\r
981 If StartBit is greater than 15, then ASSERT().\r
982 If EndBit is greater than 15, then ASSERT().\r
983 If EndBit is less than StartBit, then ASSERT().\r
94952554 984 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 985\r
2fc59a00 986 @param Address The PCI configuration register to write.\r
e1f414b6 987 @param StartBit The ordinal of the least significant bit in the bit field.\r
988 Range 0..15.\r
989 @param EndBit The ordinal of the most significant bit in the bit field.\r
990 Range 0..15.\r
991 @param AndData The value to AND with the PCI configuration register.\r
992\r
993 @return The value written back to the PCI configuration register.\r
994\r
995**/\r
996UINT16\r
997EFIAPI\r
998PciCf8BitFieldAnd16 (\r
999 IN UINTN Address,\r
1000 IN UINTN StartBit,\r
1001 IN UINTN EndBit,\r
1002 IN UINT16 AndData\r
1003 )\r
1004{\r
96dd57ee 1005 BOOLEAN InterruptState;\r
1006 UINT32 AddressPort;\r
1007 UINT16 Result;\r
1008 \r
e1f414b6 1009 ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
96dd57ee 1010 InterruptState = SaveAndDisableInterrupts ();\r
1011 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 1012 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 1013 Result = IoBitFieldAnd16 (\r
1014 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
1015 StartBit,\r
1016 EndBit,\r
1017 AndData\r
1018 );\r
1019 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
1020 SetInterruptState (InterruptState);\r
1021 return Result;\r
e1f414b6 1022}\r
1023\r
1024/**\r
1025 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a\r
62991af2 1026 bitwise OR, and writes the result back to the bit field in the\r
e1f414b6 1027 16-bit port.\r
1028\r
1029 Reads the 16-bit PCI configuration register specified by Address, performs a\r
62991af2 1030 bitwise AND followed by a bitwise OR between the read result and\r
e1f414b6 1031 the value specified by AndData, and writes the result to the 16-bit PCI\r
1032 configuration register specified by Address. The value written to the PCI\r
1033 configuration register is returned. This function must guarantee that all PCI\r
1034 read and write operations are serialized. Extra left bits in both AndData and\r
1035 OrData are stripped.\r
1036\r
1037 If Address > 0x0FFFFFFF, then ASSERT().\r
1038 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
1039 If the register specified by Address >= 0x100, then ASSERT().\r
1040 If StartBit is greater than 15, then ASSERT().\r
1041 If EndBit is greater than 15, then ASSERT().\r
1042 If EndBit is less than StartBit, then ASSERT().\r
94952554
LG
1043 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
1044 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 1045\r
2fc59a00 1046 @param Address The PCI configuration register to write.\r
e1f414b6 1047 @param StartBit The ordinal of the least significant bit in the bit field.\r
1048 Range 0..15.\r
1049 @param EndBit The ordinal of the most significant bit in the bit field.\r
1050 Range 0..15.\r
1051 @param AndData The value to AND with the PCI configuration register.\r
1052 @param OrData The value to OR with the result of the AND operation.\r
1053\r
1054 @return The value written back to the PCI configuration register.\r
1055\r
1056**/\r
1057UINT16\r
1058EFIAPI\r
1059PciCf8BitFieldAndThenOr16(\r
1060 IN UINTN Address,\r
1061 IN UINTN StartBit,\r
1062 IN UINTN EndBit,\r
1063 IN UINT16 AndData,\r
1064 IN UINT16 OrData\r
1065 )\r
1066{\r
96dd57ee 1067 BOOLEAN InterruptState;\r
1068 UINT32 AddressPort;\r
1069 UINT16 Result;\r
1070 \r
e1f414b6 1071 ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
96dd57ee 1072 InterruptState = SaveAndDisableInterrupts ();\r
1073 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 1074 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 1075 Result = IoBitFieldAndThenOr16 (\r
1076 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),\r
1077 StartBit,\r
1078 EndBit,\r
1079 AndData,\r
1080 OrData\r
1081 );\r
1082 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
1083 SetInterruptState (InterruptState);\r
1084 return Result;\r
e1f414b6 1085}\r
1086\r
1087/**\r
1088 Reads a 32-bit PCI configuration register.\r
1089\r
1090 Reads and returns the 32-bit PCI configuration register specified by Address.\r
1091 This function must guarantee that all PCI read and write operations are\r
1092 serialized.\r
1093\r
1094 If Address > 0x0FFFFFFF, then ASSERT().\r
1095 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1096 If the register specified by Address >= 0x100, then ASSERT().\r
1097\r
2fc59a00 1098 @param Address The address that encodes the PCI Bus, Device, Function and\r
e1f414b6 1099 Register.\r
1100\r
1101 @return The read value from the PCI configuration register.\r
1102\r
1103**/\r
1104UINT32\r
1105EFIAPI\r
1106PciCf8Read32 (\r
1107 IN UINTN Address\r
1108 )\r
1109{\r
96dd57ee 1110 BOOLEAN InterruptState;\r
1111 UINT32 AddressPort;\r
1112 UINT32 Result;\r
1113 \r
e1f414b6 1114 ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
96dd57ee 1115 InterruptState = SaveAndDisableInterrupts ();\r
1116 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 1117 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 1118 Result = IoRead32 (PCI_CONFIGURATION_DATA_PORT);\r
1119 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
1120 SetInterruptState (InterruptState);\r
1121 return Result;\r
e1f414b6 1122}\r
1123\r
1124/**\r
1125 Writes a 32-bit PCI configuration register.\r
1126\r
1127 Writes the 32-bit PCI configuration register specified by Address with the\r
1128 value specified by Value. Value is returned. This function must guarantee\r
1129 that all PCI read and write operations are serialized.\r
1130\r
1131 If Address > 0x0FFFFFFF, then ASSERT().\r
1132 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1133 If the register specified by Address >= 0x100, then ASSERT().\r
1134\r
2fc59a00 1135 @param Address The address that encodes the PCI Bus, Device, Function and\r
e1f414b6 1136 Register.\r
1137 @param Value The value to write.\r
1138\r
1139 @return The value written to the PCI configuration register.\r
1140\r
1141**/\r
1142UINT32\r
1143EFIAPI\r
1144PciCf8Write32 (\r
1145 IN UINTN Address,\r
1146 IN UINT32 Value\r
1147 )\r
1148{\r
96dd57ee 1149 BOOLEAN InterruptState;\r
1150 UINT32 AddressPort;\r
1151 UINT32 Result;\r
1152 \r
e1f414b6 1153 ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
96dd57ee 1154 InterruptState = SaveAndDisableInterrupts ();\r
1155 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 1156 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 1157 Result = IoWrite32 (\r
1158 PCI_CONFIGURATION_DATA_PORT,\r
1159 Value\r
1160 );\r
1161 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
1162 SetInterruptState (InterruptState);\r
1163 return Result;\r
e1f414b6 1164}\r
1165\r
1166/**\r
62991af2 1167 Performs a bitwise OR of a 32-bit PCI configuration register with\r
e1f414b6 1168 a 32-bit value.\r
1169\r
1170 Reads the 32-bit PCI configuration register specified by Address, performs a\r
62991af2 1171 bitwise OR between the read result and the value specified by\r
e1f414b6 1172 OrData, and writes the result to the 32-bit PCI configuration register\r
1173 specified by Address. The value written to the PCI configuration register is\r
1174 returned. This function must guarantee that all PCI read and write operations\r
1175 are serialized.\r
1176\r
1177 If Address > 0x0FFFFFFF, then ASSERT().\r
1178 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1179 If the register specified by Address >= 0x100, then ASSERT().\r
1180\r
2fc59a00 1181 @param Address The address that encodes the PCI Bus, Device, Function and\r
e1f414b6 1182 Register.\r
1183 @param OrData The value to OR with the PCI configuration register.\r
1184\r
1185 @return The value written back to the PCI configuration register.\r
1186\r
1187**/\r
1188UINT32\r
1189EFIAPI\r
1190PciCf8Or32 (\r
1191 IN UINTN Address,\r
1192 IN UINT32 OrData\r
1193 )\r
1194{\r
96dd57ee 1195 BOOLEAN InterruptState;\r
1196 UINT32 AddressPort;\r
1197 UINT32 Result;\r
1198 \r
e1f414b6 1199 ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
96dd57ee 1200 InterruptState = SaveAndDisableInterrupts ();\r
1201 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 1202 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 1203 Result = IoOr32 (\r
1204 PCI_CONFIGURATION_DATA_PORT,\r
1205 OrData\r
1206 );\r
1207 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
1208 SetInterruptState (InterruptState);\r
1209 return Result;\r
e1f414b6 1210}\r
1211\r
1212/**\r
1213 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit\r
1214 value.\r
1215\r
1216 Reads the 32-bit PCI configuration register specified by Address, performs a\r
1217 bitwise AND between the read result and the value specified by AndData, and\r
1218 writes the result to the 32-bit PCI configuration register specified by\r
1219 Address. The value written to the PCI configuration register is returned.\r
1220 This function must guarantee that all PCI read and write operations are\r
1221 serialized.\r
1222\r
1223 If Address > 0x0FFFFFFF, then ASSERT().\r
1224 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1225 If the register specified by Address >= 0x100, then ASSERT().\r
1226\r
2fc59a00 1227 @param Address The address that encodes the PCI Bus, Device, Function and\r
e1f414b6 1228 Register.\r
1229 @param AndData The value to AND with the PCI configuration register.\r
1230\r
1231 @return The value written back to the PCI configuration register.\r
1232\r
1233**/\r
1234UINT32\r
1235EFIAPI\r
1236PciCf8And32 (\r
1237 IN UINTN Address,\r
1238 IN UINT32 AndData\r
1239 )\r
1240{\r
96dd57ee 1241 BOOLEAN InterruptState;\r
1242 UINT32 AddressPort;\r
1243 UINT32 Result;\r
1244 \r
e1f414b6 1245 ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
96dd57ee 1246 InterruptState = SaveAndDisableInterrupts ();\r
1247 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 1248 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 1249 Result = IoAnd32 (\r
1250 PCI_CONFIGURATION_DATA_PORT,\r
1251 AndData\r
1252 );\r
1253 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
1254 SetInterruptState (InterruptState);\r
1255 return Result;\r
e1f414b6 1256}\r
1257\r
1258/**\r
1259 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit\r
62991af2 1260 value, followed a bitwise OR with another 32-bit value.\r
e1f414b6 1261\r
1262 Reads the 32-bit PCI configuration register specified by Address, performs a\r
1263 bitwise AND between the read result and the value specified by AndData,\r
62991af2 1264 performs a bitwise OR between the result of the AND operation and\r
e1f414b6 1265 the value specified by OrData, and writes the result to the 32-bit PCI\r
1266 configuration register specified by Address. The value written to the PCI\r
1267 configuration register is returned. This function must guarantee that all PCI\r
1268 read and write operations are serialized.\r
1269\r
1270 If Address > 0x0FFFFFFF, then ASSERT().\r
1271 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1272 If the register specified by Address >= 0x100, then ASSERT().\r
1273\r
2fc59a00 1274 @param Address The address that encodes the PCI Bus, Device, Function and\r
e1f414b6 1275 Register.\r
1276 @param AndData The value to AND with the PCI configuration register.\r
1277 @param OrData The value to OR with the result of the AND operation.\r
1278\r
1279 @return The value written back to the PCI configuration register.\r
1280\r
1281**/\r
1282UINT32\r
1283EFIAPI\r
1284PciCf8AndThenOr32 (\r
1285 IN UINTN Address,\r
1286 IN UINT32 AndData,\r
1287 IN UINT32 OrData\r
1288 )\r
1289{\r
96dd57ee 1290 BOOLEAN InterruptState;\r
1291 UINT32 AddressPort;\r
1292 UINT32 Result;\r
1293 \r
e1f414b6 1294 ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
96dd57ee 1295 InterruptState = SaveAndDisableInterrupts ();\r
1296 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 1297 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 1298 Result = IoAndThenOr32 (\r
1299 PCI_CONFIGURATION_DATA_PORT,\r
1300 AndData,\r
1301 OrData\r
1302 );\r
1303 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
1304 SetInterruptState (InterruptState);\r
1305 return Result;\r
e1f414b6 1306}\r
1307\r
1308/**\r
1309 Reads a bit field of a PCI configuration register.\r
1310\r
1311 Reads the bit field in a 32-bit PCI configuration register. The bit field is\r
1312 specified by the StartBit and the EndBit. The value of the bit field is\r
1313 returned.\r
1314\r
1315 If Address > 0x0FFFFFFF, then ASSERT().\r
1316 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1317 If the register specified by Address >= 0x100, then ASSERT().\r
1318 If StartBit is greater than 31, then ASSERT().\r
1319 If EndBit is greater than 31, then ASSERT().\r
1320 If EndBit is less than StartBit, then ASSERT().\r
1321\r
2fc59a00 1322 @param Address The PCI configuration register to read.\r
e1f414b6 1323 @param StartBit The ordinal of the least significant bit in the bit field.\r
1324 Range 0..31.\r
1325 @param EndBit The ordinal of the most significant bit in the bit field.\r
1326 Range 0..31.\r
1327\r
1328 @return The value of the bit field read from the PCI configuration register.\r
1329\r
1330**/\r
1331UINT32\r
1332EFIAPI\r
1333PciCf8BitFieldRead32 (\r
1334 IN UINTN Address,\r
1335 IN UINTN StartBit,\r
1336 IN UINTN EndBit\r
1337 )\r
1338{\r
96dd57ee 1339 BOOLEAN InterruptState;\r
1340 UINT32 AddressPort;\r
1341 UINT32 Result;\r
1342 \r
e1f414b6 1343 ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
96dd57ee 1344 InterruptState = SaveAndDisableInterrupts ();\r
1345 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 1346 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 1347 Result = IoBitFieldRead32 (\r
1348 PCI_CONFIGURATION_DATA_PORT,\r
1349 StartBit,\r
1350 EndBit\r
1351 );\r
1352 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
1353 SetInterruptState (InterruptState);\r
1354 return Result;\r
e1f414b6 1355}\r
1356\r
1357/**\r
1358 Writes a bit field to a PCI configuration register.\r
1359\r
1360 Writes Value to the bit field of the PCI configuration register. The bit\r
1361 field is specified by the StartBit and the EndBit. All other bits in the\r
1362 destination PCI configuration register are preserved. The new value of the\r
1363 32-bit register is returned.\r
1364\r
1365 If Address > 0x0FFFFFFF, then ASSERT().\r
1366 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1367 If the register specified by Address >= 0x100, then ASSERT().\r
1368 If StartBit is greater than 31, then ASSERT().\r
1369 If EndBit is greater than 31, then ASSERT().\r
1370 If EndBit is less than StartBit, then ASSERT().\r
94952554 1371 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 1372\r
2fc59a00 1373 @param Address The PCI configuration register to write.\r
e1f414b6 1374 @param StartBit The ordinal of the least significant bit in the bit field.\r
1375 Range 0..31.\r
1376 @param EndBit The ordinal of the most significant bit in the bit field.\r
1377 Range 0..31.\r
2fc59a00 1378 @param Value The new value of the bit field.\r
e1f414b6 1379\r
1380 @return The value written back to the PCI configuration register.\r
1381\r
1382**/\r
1383UINT32\r
1384EFIAPI\r
1385PciCf8BitFieldWrite32 (\r
1386 IN UINTN Address,\r
1387 IN UINTN StartBit,\r
1388 IN UINTN EndBit,\r
1389 IN UINT32 Value\r
1390 )\r
1391{\r
96dd57ee 1392 BOOLEAN InterruptState;\r
1393 UINT32 AddressPort;\r
1394 UINT32 Result;\r
1395 \r
e1f414b6 1396 ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
96dd57ee 1397 InterruptState = SaveAndDisableInterrupts ();\r
1398 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 1399 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 1400 Result = IoBitFieldWrite32 (\r
1401 PCI_CONFIGURATION_DATA_PORT,\r
1402 StartBit,\r
1403 EndBit,\r
1404 Value\r
1405 );\r
1406 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
1407 SetInterruptState (InterruptState);\r
1408 return Result;\r
e1f414b6 1409}\r
1410\r
1411/**\r
1412 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and\r
1413 writes the result back to the bit field in the 32-bit port.\r
1414\r
1415 Reads the 32-bit PCI configuration register specified by Address, performs a\r
62991af2 1416 bitwise OR between the read result and the value specified by\r
e1f414b6 1417 OrData, and writes the result to the 32-bit PCI configuration register\r
1418 specified by Address. The value written to the PCI configuration register is\r
1419 returned. This function must guarantee that all PCI read and write operations\r
1420 are serialized. Extra left bits in OrData are stripped.\r
1421\r
1422 If Address > 0x0FFFFFFF, then ASSERT().\r
1423 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1424 If the register specified by Address >= 0x100, then ASSERT().\r
1425 If StartBit is greater than 31, then ASSERT().\r
1426 If EndBit is greater than 31, then ASSERT().\r
1427 If EndBit is less than StartBit, then ASSERT().\r
94952554 1428 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 1429\r
2fc59a00 1430 @param Address The PCI configuration register to write.\r
e1f414b6 1431 @param StartBit The ordinal of the least significant bit in the bit field.\r
1432 Range 0..31.\r
1433 @param EndBit The ordinal of the most significant bit in the bit field.\r
1434 Range 0..31.\r
1435 @param OrData The value to OR with the PCI configuration register.\r
1436\r
1437 @return The value written back to the PCI configuration register.\r
1438\r
1439**/\r
1440UINT32\r
1441EFIAPI\r
1442PciCf8BitFieldOr32 (\r
1443 IN UINTN Address,\r
1444 IN UINTN StartBit,\r
1445 IN UINTN EndBit,\r
1446 IN UINT32 OrData\r
1447 )\r
1448{\r
96dd57ee 1449 BOOLEAN InterruptState;\r
1450 UINT32 AddressPort;\r
1451 UINT32 Result;\r
1452 \r
e1f414b6 1453 ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
96dd57ee 1454 InterruptState = SaveAndDisableInterrupts ();\r
1455 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 1456 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 1457 Result = IoBitFieldOr32 (\r
1458 PCI_CONFIGURATION_DATA_PORT,\r
1459 StartBit,\r
1460 EndBit,\r
1461 OrData\r
1462 );\r
1463 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
1464 SetInterruptState (InterruptState);\r
1465 return Result;\r
e1f414b6 1466}\r
1467\r
1468/**\r
1469 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise\r
1470 AND, and writes the result back to the bit field in the 32-bit register.\r
1471\r
1472 Reads the 32-bit PCI configuration register specified by Address, performs a\r
1473 bitwise AND between the read result and the value specified by AndData, and\r
1474 writes the result to the 32-bit PCI configuration register specified by\r
1475 Address. The value written to the PCI configuration register is returned.\r
1476 This function must guarantee that all PCI read and write operations are\r
1477 serialized. Extra left bits in AndData are stripped.\r
1478\r
1479 If Address > 0x0FFFFFFF, then ASSERT().\r
1480 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1481 If the register specified by Address >= 0x100, then ASSERT().\r
1482 If StartBit is greater than 31, then ASSERT().\r
1483 If EndBit is greater than 31, then ASSERT().\r
1484 If EndBit is less than StartBit, then ASSERT().\r
94952554 1485 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 1486\r
2fc59a00 1487 @param Address The PCI configuration register to write.\r
e1f414b6 1488 @param StartBit The ordinal of the least significant bit in the bit field.\r
1489 Range 0..31.\r
1490 @param EndBit The ordinal of the most significant bit in the bit field.\r
1491 Range 0..31.\r
1492 @param AndData The value to AND with the PCI configuration register.\r
1493\r
1494 @return The value written back to the PCI configuration register.\r
1495\r
1496**/\r
1497UINT32\r
1498EFIAPI\r
1499PciCf8BitFieldAnd32 (\r
1500 IN UINTN Address,\r
1501 IN UINTN StartBit,\r
1502 IN UINTN EndBit,\r
1503 IN UINT32 AndData\r
1504 )\r
1505{\r
96dd57ee 1506 BOOLEAN InterruptState;\r
1507 UINT32 AddressPort;\r
1508 UINT32 Result;\r
1509 \r
e1f414b6 1510 ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
96dd57ee 1511 InterruptState = SaveAndDisableInterrupts ();\r
1512 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 1513 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 1514 Result = IoBitFieldAnd32 (\r
1515 PCI_CONFIGURATION_DATA_PORT,\r
1516 StartBit,\r
1517 EndBit,\r
1518 AndData\r
1519 );\r
1520 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
1521 SetInterruptState (InterruptState);\r
1522 return Result;\r
e1f414b6 1523}\r
1524\r
1525/**\r
1526 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a\r
62991af2 1527 bitwise OR, and writes the result back to the bit field in the\r
e1f414b6 1528 32-bit port.\r
1529\r
1530 Reads the 32-bit PCI configuration register specified by Address, performs a\r
62991af2 1531 bitwise AND followed by a bitwise OR between the read result and\r
e1f414b6 1532 the value specified by AndData, and writes the result to the 32-bit PCI\r
1533 configuration register specified by Address. The value written to the PCI\r
1534 configuration register is returned. This function must guarantee that all PCI\r
1535 read and write operations are serialized. Extra left bits in both AndData and\r
1536 OrData are stripped.\r
1537\r
1538 If Address > 0x0FFFFFFF, then ASSERT().\r
1539 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1540 If the register specified by Address >= 0x100, then ASSERT().\r
1541 If StartBit is greater than 31, then ASSERT().\r
1542 If EndBit is greater than 31, then ASSERT().\r
1543 If EndBit is less than StartBit, then ASSERT().\r
94952554
LG
1544 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
1545 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
e1f414b6 1546\r
2fc59a00 1547 @param Address The PCI configuration register to write.\r
e1f414b6 1548 @param StartBit The ordinal of the least significant bit in the bit field.\r
1549 Range 0..31.\r
1550 @param EndBit The ordinal of the most significant bit in the bit field.\r
1551 Range 0..31.\r
1552 @param AndData The value to AND with the PCI configuration register.\r
1553 @param OrData The value to OR with the result of the AND operation.\r
1554\r
1555 @return The value written back to the PCI configuration register.\r
1556\r
1557**/\r
1558UINT32\r
1559EFIAPI\r
1560PciCf8BitFieldAndThenOr32(\r
1561 IN UINTN Address,\r
1562 IN UINTN StartBit,\r
1563 IN UINTN EndBit,\r
1564 IN UINT32 AndData,\r
1565 IN UINT32 OrData\r
1566 )\r
1567{\r
96dd57ee 1568 BOOLEAN InterruptState;\r
1569 UINT32 AddressPort;\r
1570 UINT32 Result;\r
1571 \r
e1f414b6 1572 ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
96dd57ee 1573 InterruptState = SaveAndDisableInterrupts ();\r
1574 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);\r
e1f414b6 1575 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));\r
96dd57ee 1576 Result = IoBitFieldAndThenOr32 (\r
1577 PCI_CONFIGURATION_DATA_PORT,\r
1578 StartBit,\r
1579 EndBit,\r
1580 AndData,\r
1581 OrData\r
1582 );\r
1583 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);\r
1584 SetInterruptState (InterruptState);\r
1585 return Result;\r
e1f414b6 1586}\r
1587\r
1588/**\r
1589 Reads a range of PCI configuration registers into a caller supplied buffer.\r
1590\r
1591 Reads the range of PCI configuration registers specified by StartAddress and\r
1592 Size into the buffer specified by Buffer. This function only allows the PCI\r
1593 configuration registers from a single PCI function to be read. Size is\r
1594 returned. When possible 32-bit PCI configuration read cycles are used to read\r
1595 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit\r
1596 and 16-bit PCI configuration read cycles may be used at the beginning and the\r
1597 end of the range.\r
1598\r
1599 If StartAddress > 0x0FFFFFFF, then ASSERT().\r
1600 If the register specified by StartAddress >= 0x100, then ASSERT().\r
1601 If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().\r
1602 If Size > 0 and Buffer is NULL, then ASSERT().\r
1603\r
2fc59a00 1604 @param StartAddress The starting address that encodes the PCI Bus, Device,\r
e1f414b6 1605 Function and Register.\r
2fc59a00 1606 @param Size The size in bytes of the transfer.\r
1607 @param Buffer The pointer to a buffer receiving the data read.\r
e1f414b6 1608\r
9638ba6d 1609 @return Size read from StartAddress.\r
e1f414b6 1610\r
1611**/\r
1612UINTN\r
1613EFIAPI\r
1614PciCf8ReadBuffer (\r
1615 IN UINTN StartAddress,\r
1616 IN UINTN Size,\r
1617 OUT VOID *Buffer\r
1618 )\r
1619{\r
0c62737d 1620 UINTN ReturnValue;\r
e1f414b6 1621\r
1622 ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);\r
1623 ASSERT (((StartAddress & 0xFFF) + Size) <= 0x100);\r
1624\r
1625 if (Size == 0) {\r
1626 return Size;\r
1627 }\r
1628\r
1629 ASSERT (Buffer != NULL);\r
1630\r
1631 //\r
1632 // Save Size for return\r
1633 //\r
1634 ReturnValue = Size;\r
1635\r
1636 if ((StartAddress & 1) != 0) {\r
1637 //\r
1638 // Read a byte if StartAddress is byte aligned\r
1639 //\r
1640 *(volatile UINT8 *)Buffer = PciCf8Read8 (StartAddress);\r
1641 StartAddress += sizeof (UINT8);\r
1642 Size -= sizeof (UINT8);\r
1643 Buffer = (UINT8*)Buffer + 1;\r
1644 }\r
1645\r
1646 if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {\r
1647 //\r
1648 // Read a word if StartAddress is word aligned\r
1649 //\r
af2bb549 1650 WriteUnaligned16 ((UINT16 *)Buffer, (UINT16) PciCf8Read16 (StartAddress));\r
0c62737d 1651\r
e1f414b6 1652 StartAddress += sizeof (UINT16);\r
1653 Size -= sizeof (UINT16);\r
1654 Buffer = (UINT16*)Buffer + 1;\r
1655 }\r
1656\r
1657 while (Size >= sizeof (UINT32)) {\r
1658 //\r
1659 // Read as many double words as possible\r
1660 //\r
af2bb549 1661 WriteUnaligned32 ((UINT32 *)Buffer, (UINT32) PciCf8Read32 (StartAddress));\r
e1f414b6 1662 StartAddress += sizeof (UINT32);\r
1663 Size -= sizeof (UINT32);\r
1664 Buffer = (UINT32*)Buffer + 1;\r
1665 }\r
1666\r
1667 if (Size >= sizeof (UINT16)) {\r
1668 //\r
1669 // Read the last remaining word if exist\r
1670 //\r
af2bb549 1671 WriteUnaligned16 ((UINT16 *)Buffer, (UINT16) PciCf8Read16 (StartAddress));\r
e1f414b6 1672 StartAddress += sizeof (UINT16);\r
1673 Size -= sizeof (UINT16);\r
1674 Buffer = (UINT16*)Buffer + 1;\r
1675 }\r
1676\r
1677 if (Size >= sizeof (UINT8)) {\r
1678 //\r
1679 // Read the last remaining byte if exist\r
1680 //\r
1681 *(volatile UINT8 *)Buffer = PciCf8Read8 (StartAddress);\r
1682 }\r
1683\r
1684 return ReturnValue;\r
1685}\r
1686\r
1687/**\r
1688 Copies the data in a caller supplied buffer to a specified range of PCI\r
1689 configuration space.\r
1690\r
1691 Writes the range of PCI configuration registers specified by StartAddress and\r
1692 Size from the buffer specified by Buffer. This function only allows the PCI\r
1693 configuration registers from a single PCI function to be written. Size is\r
1694 returned. When possible 32-bit PCI configuration write cycles are used to\r
1695 write from StartAdress to StartAddress + Size. Due to alignment restrictions,\r
1696 8-bit and 16-bit PCI configuration write cycles may be used at the beginning\r
1697 and the end of the range.\r
1698\r
1699 If StartAddress > 0x0FFFFFFF, then ASSERT().\r
1700 If the register specified by StartAddress >= 0x100, then ASSERT().\r
1701 If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().\r
1702 If Size > 0 and Buffer is NULL, then ASSERT().\r
1703\r
2fc59a00 1704 @param StartAddress The starting address that encodes the PCI Bus, Device,\r
e1f414b6 1705 Function and Register.\r
2fc59a00 1706 @param Size The size in bytes of the transfer.\r
1707 @param Buffer The pointer to a buffer containing the data to write.\r
e1f414b6 1708\r
9638ba6d 1709 @return Size written to StartAddress.\r
e1f414b6 1710\r
1711**/\r
1712UINTN\r
1713EFIAPI\r
1714PciCf8WriteBuffer (\r
1715 IN UINTN StartAddress,\r
1716 IN UINTN Size,\r
1717 IN VOID *Buffer\r
1718 )\r
1719{\r
0c62737d 1720 UINTN ReturnValue;\r
e1f414b6 1721\r
1722 ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);\r
1723 ASSERT (((StartAddress & 0xFFF) + Size) <= 0x100);\r
1724\r
1725 if (Size == 0) {\r
1726 return 0;\r
1727 }\r
1728\r
1729 ASSERT (Buffer != NULL);\r
1730\r
1731 //\r
1732 // Save Size for return\r
1733 //\r
1734 ReturnValue = Size;\r
1735\r
1736 if ((StartAddress & 1) != 0) {\r
1737 //\r
1738 // Write a byte if StartAddress is byte aligned\r
1739 //\r
1740 PciCf8Write8 (StartAddress, *(UINT8*)Buffer);\r
1741 StartAddress += sizeof (UINT8);\r
1742 Size -= sizeof (UINT8);\r
1743 Buffer = (UINT8*)Buffer + 1;\r
1744 }\r
1745\r
1746 if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {\r
1747 //\r
1748 // Write a word if StartAddress is word aligned\r
1749 //\r
0c62737d 1750 PciCf8Write16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer));\r
e1f414b6 1751 StartAddress += sizeof (UINT16);\r
1752 Size -= sizeof (UINT16);\r
1753 Buffer = (UINT16*)Buffer + 1;\r
1754 }\r
1755\r
1756 while (Size >= sizeof (UINT32)) {\r
1757 //\r
1758 // Write as many double words as possible\r
1759 //\r
0c62737d 1760 PciCf8Write32 (StartAddress, ReadUnaligned32 ((UINT32*)Buffer));\r
e1f414b6 1761 StartAddress += sizeof (UINT32);\r
1762 Size -= sizeof (UINT32);\r
1763 Buffer = (UINT32*)Buffer + 1;\r
1764 }\r
1765\r
1766 if (Size >= sizeof (UINT16)) {\r
1767 //\r
1768 // Write the last remaining word if exist\r
1769 //\r
0c62737d 1770 PciCf8Write16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer));\r
e1f414b6 1771 StartAddress += sizeof (UINT16);\r
1772 Size -= sizeof (UINT16);\r
1773 Buffer = (UINT16*)Buffer + 1;\r
1774 }\r
1775\r
1776 if (Size >= sizeof (UINT8)) {\r
1777 //\r
1778 // Write the last remaining byte if exist\r
1779 //\r
1780 PciCf8Write8 (StartAddress, *(UINT8*)Buffer);\r
1781 }\r
1782\r
1783 return ReturnValue;\r
1784}\r