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