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