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