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