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