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