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