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