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