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