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