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