]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/DxeRuntimePciExpressLib/PciExpressLib.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdePkg / Library / DxeRuntimePciExpressLib / PciExpressLib.c
1 /** @file
2 Functions in this library instance make use of MMIO functions in IoLib to
3 access memory mapped PCI configuration space.
4
5 All assertions for I/O operations are handled in MMIO functions in the IoLib
6 Library.
7
8 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
9 SPDX-License-Identifier: BSD-2-Clause-Patent
10
11 **/
12
13
14 #include <PiDxe.h>
15
16 #include <Guid/EventGroup.h>
17
18 #include <Library/BaseLib.h>
19 #include <Library/PciExpressLib.h>
20 #include <Library/IoLib.h>
21 #include <Library/DebugLib.h>
22 #include <Library/PcdLib.h>
23 #include <Library/MemoryAllocationLib.h>
24 #include <Library/UefiBootServicesTableLib.h>
25 #include <Library/DxeServicesTableLib.h>
26 #include <Library/UefiRuntimeLib.h>
27
28 ///
29 /// Define table for mapping PCI Express MMIO physical addresses to virtual addresses at OS runtime
30 ///
31 typedef struct {
32 UINTN PhysicalAddress;
33 UINTN VirtualAddress;
34 } PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE;
35
36 ///
37 /// Set Virtual Address Map Event
38 ///
39 EFI_EVENT mDxeRuntimePciExpressLibVirtualNotifyEvent = NULL;
40
41 ///
42 /// Module global that contains the base physical address of the PCI Express MMIO range.
43 ///
44 UINTN mDxeRuntimePciExpressLibPciExpressBaseAddress = 0;
45
46 ///
47 /// The number of PCI devices that have been registered for runtime access.
48 ///
49 UINTN mDxeRuntimePciExpressLibNumberOfRuntimeRanges = 0;
50
51 ///
52 /// The table of PCI devices that have been registered for runtime access.
53 ///
54 PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE *mDxeRuntimePciExpressLibRegistrationTable = NULL;
55
56 ///
57 /// The table index of the most recent virtual address lookup.
58 ///
59 UINTN mDxeRuntimePciExpressLibLastRuntimeRange = 0;
60
61
62 /**
63 Convert the physical PCI Express MMIO addresses for all registered PCI devices
64 to virtual addresses.
65
66 @param[in] Event The event that is being processed.
67 @param[in] Context The Event Context.
68 **/
69 VOID
70 EFIAPI
71 DxeRuntimePciExpressLibVirtualNotify (
72 IN EFI_EVENT Event,
73 IN VOID *Context
74 )
75 {
76 UINTN Index;
77
78 //
79 // If there have been no runtime registrations, then just return
80 //
81 if (mDxeRuntimePciExpressLibRegistrationTable == NULL) {
82 return;
83 }
84
85 //
86 // Convert physical addresses associated with the set of registered PCI devices to
87 // virtual addresses.
88 //
89 for (Index = 0; Index < mDxeRuntimePciExpressLibNumberOfRuntimeRanges; Index++) {
90 EfiConvertPointer (0, (VOID **) &(mDxeRuntimePciExpressLibRegistrationTable[Index].VirtualAddress));
91 }
92
93 //
94 // Convert table pointer that is allocated from EfiRuntimeServicesData to a virtual address.
95 //
96 EfiConvertPointer (0, (VOID **) &mDxeRuntimePciExpressLibRegistrationTable);
97 }
98
99 /**
100 The constructor function caches the PCI Express Base Address and creates a
101 Set Virtual Address Map event to convert physical address to virtual addresses.
102
103 @param ImageHandle The firmware allocated handle for the EFI image.
104 @param SystemTable A pointer to the EFI System Table.
105
106 @retval EFI_SUCCESS The constructor completed successfully.
107 @retval Other value The constructor did not complete successfully.
108
109 **/
110 EFI_STATUS
111 EFIAPI
112 DxeRuntimePciExpressLibConstructor (
113 IN EFI_HANDLE ImageHandle,
114 IN EFI_SYSTEM_TABLE *SystemTable
115 )
116 {
117 EFI_STATUS Status;
118
119 //
120 // Cache the physical address of the PCI Express MMIO range into a module global variable
121 //
122 mDxeRuntimePciExpressLibPciExpressBaseAddress = (UINTN) PcdGet64 (PcdPciExpressBaseAddress);
123
124 //
125 // Register SetVirtualAddressMap () notify function
126 //
127 Status = gBS->CreateEvent (
128 EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
129 TPL_NOTIFY,
130 DxeRuntimePciExpressLibVirtualNotify,
131 NULL,
132 &mDxeRuntimePciExpressLibVirtualNotifyEvent
133 );
134 ASSERT_EFI_ERROR (Status);
135
136 return Status;
137 }
138
139 /**
140 The destructor function frees any allocated buffers and closes the Set Virtual
141 Address Map event.
142
143 @param ImageHandle The firmware allocated handle for the EFI image.
144 @param SystemTable A pointer to the EFI System Table.
145
146 @retval EFI_SUCCESS The destructor completed successfully.
147 @retval Other value The destructor did not complete successfully.
148
149 **/
150 EFI_STATUS
151 EFIAPI
152 DxeRuntimePciExpressLibDestructor (
153 IN EFI_HANDLE ImageHandle,
154 IN EFI_SYSTEM_TABLE *SystemTable
155 )
156 {
157 EFI_STATUS Status;
158
159 //
160 // If one or more PCI devices have been registered for runtime access, then
161 // free the registration table.
162 //
163 if (mDxeRuntimePciExpressLibRegistrationTable != NULL) {
164 FreePool (mDxeRuntimePciExpressLibRegistrationTable);
165 }
166
167 //
168 // Close the Set Virtual Address Map event
169 //
170 Status = gBS->CloseEvent (mDxeRuntimePciExpressLibVirtualNotifyEvent);
171 ASSERT_EFI_ERROR (Status);
172
173 return Status;
174 }
175
176 /**
177 Gets the base address of PCI Express.
178
179 This internal functions retrieves PCI Express Base Address via a PCD entry
180 PcdPciExpressBaseAddress.
181
182 @param Address The address that encodes the PCI Bus, Device, Function and Register.
183 @return The base address of PCI Express.
184
185 **/
186 UINTN
187 GetPciExpressAddress (
188 IN UINTN Address
189 )
190 {
191 UINTN Index;
192
193 //
194 // Make sure Address is valid
195 //
196 ASSERT (((Address) & ~0xfffffff) == 0);
197
198 //
199 // Convert Address to a physical address in the MMIO PCI Express range
200 //
201 Address += mDxeRuntimePciExpressLibPciExpressBaseAddress;
202
203 //
204 // If SetVirtualAddressMap() has not been called, then just return the physical address
205 //
206 if (!EfiGoneVirtual ()) {
207 return Address;
208 }
209
210 //
211 // See if there is a physical address match at the exact same index as the last address match
212 //
213 if (mDxeRuntimePciExpressLibRegistrationTable[mDxeRuntimePciExpressLibLastRuntimeRange].PhysicalAddress == (Address & (~0x00000fff))) {
214 //
215 // Convert the physical address to a virtual address and return the virtual address
216 //
217 return (Address & 0x00000fff) + mDxeRuntimePciExpressLibRegistrationTable[mDxeRuntimePciExpressLibLastRuntimeRange].VirtualAddress;
218 }
219
220 //
221 // Search the entire table for a physical address match
222 //
223 for (Index = 0; Index < mDxeRuntimePciExpressLibNumberOfRuntimeRanges; Index++) {
224 if (mDxeRuntimePciExpressLibRegistrationTable[Index].PhysicalAddress == (Address & (~0x00000fff))) {
225 //
226 // Cache the matching index value
227 //
228 mDxeRuntimePciExpressLibLastRuntimeRange = Index;
229 //
230 // Convert the physical address to a virtual address and return the virtual address
231 //
232 return (Address & 0x00000fff) + mDxeRuntimePciExpressLibRegistrationTable[Index].VirtualAddress;
233 }
234 }
235
236 //
237 // No match was found. This is a critical error at OS runtime, so ASSERT() and force a breakpoint.
238 //
239 ASSERT (FALSE);
240 CpuBreakpoint();
241
242 //
243 // Return the physical address
244 //
245 return Address;
246 }
247
248 /**
249 Registers a PCI device so PCI configuration registers may be accessed after
250 SetVirtualAddressMap().
251
252 Registers the PCI device specified by Address so all the PCI configuration
253 registers associated with that PCI device may be accessed after SetVirtualAddressMap()
254 is called.
255
256 If Address > 0x0FFFFFFF, then ASSERT().
257
258 @param Address The address that encodes the PCI Bus, Device, Function and
259 Register.
260
261 @retval RETURN_SUCCESS The PCI device was registered for runtime access.
262 @retval RETURN_UNSUPPORTED An attempt was made to call this function
263 after ExitBootServices().
264 @retval RETURN_UNSUPPORTED The resources required to access the PCI device
265 at runtime could not be mapped.
266 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
267 complete the registration.
268
269 **/
270 RETURN_STATUS
271 EFIAPI
272 PciExpressRegisterForRuntimeAccess (
273 IN UINTN Address
274 )
275 {
276 EFI_STATUS Status;
277 EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;
278 UINTN Index;
279 VOID *NewTable;
280
281 //
282 // Return an error if this function is called after ExitBootServices().
283 //
284 if (EfiAtRuntime ()) {
285 return RETURN_UNSUPPORTED;
286 }
287
288 //
289 // Make sure Address is valid
290 //
291 ASSERT (((Address) & ~0xfffffff) == 0);
292
293 //
294 // Convert Address to a physical address in the MMIO PCI Express range
295 // at the beginning of the PCI Configuration header for the specified
296 // PCI Bus/Dev/Func
297 //
298 Address = GetPciExpressAddress (Address & 0x0ffff000);
299
300 //
301 // See if Address has already been registered for runtime access
302 //
303 for (Index = 0; Index < mDxeRuntimePciExpressLibNumberOfRuntimeRanges; Index++) {
304 if (mDxeRuntimePciExpressLibRegistrationTable[Index].PhysicalAddress == Address) {
305 return RETURN_SUCCESS;
306 }
307 }
308
309 //
310 // Get the GCD Memory Descriptor for the PCI Express Bus/Dev/Func specified by Address
311 //
312 Status = gDS->GetMemorySpaceDescriptor (Address, &Descriptor);
313 if (EFI_ERROR (Status)) {
314 return RETURN_UNSUPPORTED;
315 }
316
317 //
318 // Mark the 4KB region for the PCI Express Bus/Dev/Func as EFI_RUNTIME_MEMORY so the OS
319 // will allocate a virtual address range for the 4KB PCI Configuration Header.
320 //
321 Status = gDS->SetMemorySpaceAttributes (Address, 0x1000, Descriptor.Attributes | EFI_MEMORY_RUNTIME);
322 if (EFI_ERROR (Status)) {
323 return RETURN_UNSUPPORTED;
324 }
325
326 //
327 // Grow the size of the registration table
328 //
329 NewTable = ReallocateRuntimePool (
330 (mDxeRuntimePciExpressLibNumberOfRuntimeRanges + 0) * sizeof (PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE),
331 (mDxeRuntimePciExpressLibNumberOfRuntimeRanges + 1) * sizeof (PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE),
332 mDxeRuntimePciExpressLibRegistrationTable
333 );
334 if (NewTable == NULL) {
335 return RETURN_OUT_OF_RESOURCES;
336 }
337 mDxeRuntimePciExpressLibRegistrationTable = NewTable;
338 mDxeRuntimePciExpressLibRegistrationTable[mDxeRuntimePciExpressLibNumberOfRuntimeRanges].PhysicalAddress = Address;
339 mDxeRuntimePciExpressLibRegistrationTable[mDxeRuntimePciExpressLibNumberOfRuntimeRanges].VirtualAddress = Address;
340 mDxeRuntimePciExpressLibNumberOfRuntimeRanges++;
341
342 return RETURN_SUCCESS;
343 }
344
345
346 /**
347 Reads an 8-bit PCI configuration register.
348
349 Reads and returns the 8-bit PCI configuration register specified by Address.
350 This function must guarantee that all PCI read and write operations are
351 serialized.
352
353 If Address > 0x0FFFFFFF, then ASSERT().
354
355 @param Address The address that encodes the PCI Bus, Device, Function and
356 Register.
357
358 @return The read value from the PCI configuration register.
359
360 **/
361 UINT8
362 EFIAPI
363 PciExpressRead8 (
364 IN UINTN Address
365 )
366 {
367 return MmioRead8 (GetPciExpressAddress (Address));
368 }
369
370 /**
371 Writes an 8-bit PCI configuration register.
372
373 Writes the 8-bit PCI configuration register specified by Address with the
374 value specified by Value. Value is returned. This function must guarantee
375 that all PCI read and write operations are serialized.
376
377 If Address > 0x0FFFFFFF, then ASSERT().
378
379 @param Address The address that encodes the PCI Bus, Device, Function and
380 Register.
381 @param Value The value to write.
382
383 @return The value written to the PCI configuration register.
384
385 **/
386 UINT8
387 EFIAPI
388 PciExpressWrite8 (
389 IN UINTN Address,
390 IN UINT8 Value
391 )
392 {
393 return MmioWrite8 (GetPciExpressAddress (Address), Value);
394 }
395
396 /**
397 Performs a bitwise OR of an 8-bit PCI configuration register with
398 an 8-bit value.
399
400 Reads the 8-bit PCI configuration register specified by Address, performs a
401 bitwise OR between the read result and the value specified by
402 OrData, and writes the result to the 8-bit PCI configuration register
403 specified by Address. The value written to the PCI configuration register is
404 returned. This function must guarantee that all PCI read and write operations
405 are serialized.
406
407 If Address > 0x0FFFFFFF, then ASSERT().
408
409 @param Address The address that encodes the PCI Bus, Device, Function and
410 Register.
411 @param OrData The value to OR with the PCI configuration register.
412
413 @return The value written back to the PCI configuration register.
414
415 **/
416 UINT8
417 EFIAPI
418 PciExpressOr8 (
419 IN UINTN Address,
420 IN UINT8 OrData
421 )
422 {
423 return MmioOr8 (GetPciExpressAddress (Address), OrData);
424 }
425
426 /**
427 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
428 value.
429
430 Reads the 8-bit PCI configuration register specified by Address, performs a
431 bitwise AND between the read result and the value specified by AndData, and
432 writes the result to the 8-bit PCI configuration register specified by
433 Address. The value written to the PCI configuration register is returned.
434 This function must guarantee that all PCI read and write operations are
435 serialized.
436
437 If Address > 0x0FFFFFFF, then ASSERT().
438
439 @param Address The address that encodes the PCI Bus, Device, Function and
440 Register.
441 @param AndData The value to AND with the PCI configuration register.
442
443 @return The value written back to the PCI configuration register.
444
445 **/
446 UINT8
447 EFIAPI
448 PciExpressAnd8 (
449 IN UINTN Address,
450 IN UINT8 AndData
451 )
452 {
453 return MmioAnd8 (GetPciExpressAddress (Address), AndData);
454 }
455
456 /**
457 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
458 value, followed a bitwise OR with another 8-bit value.
459
460 Reads the 8-bit PCI configuration register specified by Address, performs a
461 bitwise AND between the read result and the value specified by AndData,
462 performs a bitwise OR between the result of the AND operation and
463 the value specified by OrData, and writes the result to the 8-bit PCI
464 configuration register specified by Address. The value written to the PCI
465 configuration register is returned. This function must guarantee that all PCI
466 read and write operations are serialized.
467
468 If Address > 0x0FFFFFFF, then ASSERT().
469
470 @param Address The address that encodes the PCI Bus, Device, Function and
471 Register.
472 @param AndData The value to AND with the PCI configuration register.
473 @param OrData The value to OR with the result of the AND operation.
474
475 @return The value written back to the PCI configuration register.
476
477 **/
478 UINT8
479 EFIAPI
480 PciExpressAndThenOr8 (
481 IN UINTN Address,
482 IN UINT8 AndData,
483 IN UINT8 OrData
484 )
485 {
486 return MmioAndThenOr8 (
487 GetPciExpressAddress (Address),
488 AndData,
489 OrData
490 );
491 }
492
493 /**
494 Reads a bit field of a PCI configuration register.
495
496 Reads the bit field in an 8-bit PCI configuration register. The bit field is
497 specified by the StartBit and the EndBit. The value of the bit field is
498 returned.
499
500 If Address > 0x0FFFFFFF, then ASSERT().
501 If StartBit is greater than 7, then ASSERT().
502 If EndBit is greater than 7, then ASSERT().
503 If EndBit is less than StartBit, then ASSERT().
504
505 @param Address The PCI configuration register to read.
506 @param StartBit The ordinal of the least significant bit in the bit field.
507 Range 0..7.
508 @param EndBit The ordinal of the most significant bit in the bit field.
509 Range 0..7.
510
511 @return The value of the bit field read from the PCI configuration register.
512
513 **/
514 UINT8
515 EFIAPI
516 PciExpressBitFieldRead8 (
517 IN UINTN Address,
518 IN UINTN StartBit,
519 IN UINTN EndBit
520 )
521 {
522 return MmioBitFieldRead8 (
523 GetPciExpressAddress (Address),
524 StartBit,
525 EndBit
526 );
527 }
528
529 /**
530 Writes a bit field to a PCI configuration register.
531
532 Writes Value to the bit field of the PCI configuration register. The bit
533 field is specified by the StartBit and the EndBit. All other bits in the
534 destination PCI configuration register are preserved. The new value of the
535 8-bit register is returned.
536
537 If Address > 0x0FFFFFFF, then ASSERT().
538 If StartBit is greater than 7, then ASSERT().
539 If EndBit is greater than 7, then ASSERT().
540 If EndBit is less than StartBit, then ASSERT().
541 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
542
543 @param Address The PCI configuration register to write.
544 @param StartBit The ordinal of the least significant bit in the bit field.
545 Range 0..7.
546 @param EndBit The ordinal of the most significant bit in the bit field.
547 Range 0..7.
548 @param Value The new value of the bit field.
549
550 @return The value written back to the PCI configuration register.
551
552 **/
553 UINT8
554 EFIAPI
555 PciExpressBitFieldWrite8 (
556 IN UINTN Address,
557 IN UINTN StartBit,
558 IN UINTN EndBit,
559 IN UINT8 Value
560 )
561 {
562 return MmioBitFieldWrite8 (
563 GetPciExpressAddress (Address),
564 StartBit,
565 EndBit,
566 Value
567 );
568 }
569
570 /**
571 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
572 writes the result back to the bit field in the 8-bit port.
573
574 Reads the 8-bit PCI configuration register specified by Address, performs a
575 bitwise OR between the read result and the value specified by
576 OrData, and writes the result to the 8-bit PCI configuration register
577 specified by Address. The value written to the PCI configuration register is
578 returned. This function must guarantee that all PCI read and write operations
579 are serialized. Extra left bits in OrData are stripped.
580
581 If Address > 0x0FFFFFFF, then ASSERT().
582 If StartBit is greater than 7, then ASSERT().
583 If EndBit is greater than 7, then ASSERT().
584 If EndBit is less than StartBit, then ASSERT().
585 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
586
587 @param Address The PCI configuration register to write.
588 @param StartBit The ordinal of the least significant bit in the bit field.
589 Range 0..7.
590 @param EndBit The ordinal of the most significant bit in the bit field.
591 Range 0..7.
592 @param OrData The value to OR with the PCI configuration register.
593
594 @return The value written back to the PCI configuration register.
595
596 **/
597 UINT8
598 EFIAPI
599 PciExpressBitFieldOr8 (
600 IN UINTN Address,
601 IN UINTN StartBit,
602 IN UINTN EndBit,
603 IN UINT8 OrData
604 )
605 {
606 return MmioBitFieldOr8 (
607 GetPciExpressAddress (Address),
608 StartBit,
609 EndBit,
610 OrData
611 );
612 }
613
614 /**
615 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
616 AND, and writes the result back to the bit field in the 8-bit register.
617
618 Reads the 8-bit PCI configuration register specified by Address, performs a
619 bitwise AND between the read result and the value specified by AndData, and
620 writes the result to the 8-bit PCI configuration register specified by
621 Address. The value written to the PCI configuration register is returned.
622 This function must guarantee that all PCI read and write operations are
623 serialized. Extra left bits in AndData are stripped.
624
625 If Address > 0x0FFFFFFF, then ASSERT().
626 If StartBit is greater than 7, then ASSERT().
627 If EndBit is greater than 7, then ASSERT().
628 If EndBit is less than StartBit, then ASSERT().
629 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
630
631 @param Address The PCI configuration register to write.
632 @param StartBit The ordinal of the least significant bit in the bit field.
633 Range 0..7.
634 @param EndBit The ordinal of the most significant bit in the bit field.
635 Range 0..7.
636 @param AndData The value to AND with the PCI configuration register.
637
638 @return The value written back to the PCI configuration register.
639
640 **/
641 UINT8
642 EFIAPI
643 PciExpressBitFieldAnd8 (
644 IN UINTN Address,
645 IN UINTN StartBit,
646 IN UINTN EndBit,
647 IN UINT8 AndData
648 )
649 {
650 return MmioBitFieldAnd8 (
651 GetPciExpressAddress (Address),
652 StartBit,
653 EndBit,
654 AndData
655 );
656 }
657
658 /**
659 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
660 bitwise OR, and writes the result back to the bit field in the
661 8-bit port.
662
663 Reads the 8-bit PCI configuration register specified by Address, performs a
664 bitwise AND followed by a bitwise OR between the read result and
665 the value specified by AndData, and writes the result to the 8-bit PCI
666 configuration register specified by Address. The value written to the PCI
667 configuration register is returned. This function must guarantee that all PCI
668 read and write operations are serialized. Extra left bits in both AndData and
669 OrData are stripped.
670
671 If Address > 0x0FFFFFFF, then ASSERT().
672 If StartBit is greater than 7, then ASSERT().
673 If EndBit is greater than 7, then ASSERT().
674 If EndBit is less than StartBit, then ASSERT().
675 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
676 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
677
678 @param Address The PCI configuration register to write.
679 @param StartBit The ordinal of the least significant bit in the bit field.
680 Range 0..7.
681 @param EndBit The ordinal of the most significant bit in the bit field.
682 Range 0..7.
683 @param AndData The value to AND with the PCI configuration register.
684 @param OrData The value to OR with the result of the AND operation.
685
686 @return The value written back to the PCI configuration register.
687
688 **/
689 UINT8
690 EFIAPI
691 PciExpressBitFieldAndThenOr8 (
692 IN UINTN Address,
693 IN UINTN StartBit,
694 IN UINTN EndBit,
695 IN UINT8 AndData,
696 IN UINT8 OrData
697 )
698 {
699 return MmioBitFieldAndThenOr8 (
700 GetPciExpressAddress (Address),
701 StartBit,
702 EndBit,
703 AndData,
704 OrData
705 );
706 }
707
708 /**
709 Reads a 16-bit PCI configuration register.
710
711 Reads and returns the 16-bit PCI configuration register specified by Address.
712 This function must guarantee that all PCI read and write operations are
713 serialized.
714
715 If Address > 0x0FFFFFFF, then ASSERT().
716 If Address is not aligned on a 16-bit boundary, then ASSERT().
717
718 @param Address The address that encodes the PCI Bus, Device, Function and
719 Register.
720
721 @return The read value from the PCI configuration register.
722
723 **/
724 UINT16
725 EFIAPI
726 PciExpressRead16 (
727 IN UINTN Address
728 )
729 {
730 return MmioRead16 (GetPciExpressAddress (Address));
731 }
732
733 /**
734 Writes a 16-bit PCI configuration register.
735
736 Writes the 16-bit PCI configuration register specified by Address with the
737 value specified by Value. Value is returned. This function must guarantee
738 that all PCI read and write operations are serialized.
739
740 If Address > 0x0FFFFFFF, then ASSERT().
741 If Address is not aligned on a 16-bit boundary, then ASSERT().
742
743 @param Address The address that encodes the PCI Bus, Device, Function and
744 Register.
745 @param Value The value to write.
746
747 @return The value written to the PCI configuration register.
748
749 **/
750 UINT16
751 EFIAPI
752 PciExpressWrite16 (
753 IN UINTN Address,
754 IN UINT16 Value
755 )
756 {
757 return MmioWrite16 (GetPciExpressAddress (Address), Value);
758 }
759
760 /**
761 Performs a bitwise OR of a 16-bit PCI configuration register with
762 a 16-bit value.
763
764 Reads the 16-bit PCI configuration register specified by Address, performs a
765 bitwise OR between the read result and the value specified by
766 OrData, and writes the result to the 16-bit PCI configuration register
767 specified by Address. The value written to the PCI configuration register is
768 returned. This function must guarantee that all PCI read and write operations
769 are serialized.
770
771 If Address > 0x0FFFFFFF, then ASSERT().
772 If Address is not aligned on a 16-bit boundary, then ASSERT().
773
774 @param Address The address that encodes the PCI Bus, Device, Function and
775 Register.
776 @param OrData The value to OR with the PCI configuration register.
777
778 @return The value written back to the PCI configuration register.
779
780 **/
781 UINT16
782 EFIAPI
783 PciExpressOr16 (
784 IN UINTN Address,
785 IN UINT16 OrData
786 )
787 {
788 return MmioOr16 (GetPciExpressAddress (Address), OrData);
789 }
790
791 /**
792 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
793 value.
794
795 Reads the 16-bit PCI configuration register specified by Address, performs a
796 bitwise AND between the read result and the value specified by AndData, and
797 writes the result to the 16-bit PCI configuration register specified by
798 Address. The value written to the PCI configuration register is returned.
799 This function must guarantee that all PCI read and write operations are
800 serialized.
801
802 If Address > 0x0FFFFFFF, then ASSERT().
803 If Address is not aligned on a 16-bit boundary, then ASSERT().
804
805 @param Address The address that encodes the PCI Bus, Device, Function and
806 Register.
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 PciExpressAnd16 (
815 IN UINTN Address,
816 IN UINT16 AndData
817 )
818 {
819 return MmioAnd16 (GetPciExpressAddress (Address), AndData);
820 }
821
822 /**
823 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
824 value, followed a bitwise OR with another 16-bit value.
825
826 Reads the 16-bit PCI configuration register specified by Address, performs a
827 bitwise AND between the read result and the value specified by AndData,
828 performs a bitwise OR between the result of the AND operation and
829 the value specified by OrData, and writes the result to the 16-bit PCI
830 configuration register specified by Address. The value written to the PCI
831 configuration register is returned. This function must guarantee that all PCI
832 read and write operations are serialized.
833
834 If Address > 0x0FFFFFFF, then ASSERT().
835 If Address is not aligned on a 16-bit boundary, then ASSERT().
836
837 @param Address The address that encodes the PCI Bus, Device, Function and
838 Register.
839 @param AndData The value to AND with the PCI configuration register.
840 @param OrData The value to OR with the result of the AND operation.
841
842 @return The value written back to the PCI configuration register.
843
844 **/
845 UINT16
846 EFIAPI
847 PciExpressAndThenOr16 (
848 IN UINTN Address,
849 IN UINT16 AndData,
850 IN UINT16 OrData
851 )
852 {
853 return MmioAndThenOr16 (
854 GetPciExpressAddress (Address),
855 AndData,
856 OrData
857 );
858 }
859
860 /**
861 Reads a bit field of a PCI configuration register.
862
863 Reads the bit field in a 16-bit PCI configuration register. The bit field is
864 specified by the StartBit and the EndBit. The value of the bit field is
865 returned.
866
867 If Address > 0x0FFFFFFF, then ASSERT().
868 If Address is not aligned on a 16-bit boundary, then ASSERT().
869 If StartBit is greater than 15, then ASSERT().
870 If EndBit is greater than 15, then ASSERT().
871 If EndBit is less than StartBit, then ASSERT().
872
873 @param Address The PCI configuration register to read.
874 @param StartBit The ordinal of the least significant bit in the bit field.
875 Range 0..15.
876 @param EndBit The ordinal of the most significant bit in the bit field.
877 Range 0..15.
878
879 @return The value of the bit field read from the PCI configuration register.
880
881 **/
882 UINT16
883 EFIAPI
884 PciExpressBitFieldRead16 (
885 IN UINTN Address,
886 IN UINTN StartBit,
887 IN UINTN EndBit
888 )
889 {
890 return MmioBitFieldRead16 (
891 GetPciExpressAddress (Address),
892 StartBit,
893 EndBit
894 );
895 }
896
897 /**
898 Writes a bit field to a PCI configuration register.
899
900 Writes Value to the bit field of the PCI configuration register. The bit
901 field is specified by the StartBit and the EndBit. All other bits in the
902 destination PCI configuration register are preserved. The new value of the
903 16-bit register is returned.
904
905 If Address > 0x0FFFFFFF, then ASSERT().
906 If Address is not aligned on a 16-bit boundary, then ASSERT().
907 If StartBit is greater than 15, then ASSERT().
908 If EndBit is greater than 15, then ASSERT().
909 If EndBit is less than StartBit, then ASSERT().
910 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
911
912 @param Address The PCI configuration register to write.
913 @param StartBit The ordinal of the least significant bit in the bit field.
914 Range 0..15.
915 @param EndBit The ordinal of the most significant bit in the bit field.
916 Range 0..15.
917 @param Value The new value of the bit field.
918
919 @return The value written back to the PCI configuration register.
920
921 **/
922 UINT16
923 EFIAPI
924 PciExpressBitFieldWrite16 (
925 IN UINTN Address,
926 IN UINTN StartBit,
927 IN UINTN EndBit,
928 IN UINT16 Value
929 )
930 {
931 return MmioBitFieldWrite16 (
932 GetPciExpressAddress (Address),
933 StartBit,
934 EndBit,
935 Value
936 );
937 }
938
939 /**
940 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
941 writes the result back to the bit field in the 16-bit port.
942
943 Reads the 16-bit PCI configuration register specified by Address, performs a
944 bitwise OR between the read result and the value specified by
945 OrData, and writes the result to the 16-bit PCI configuration register
946 specified by Address. The value written to the PCI configuration register is
947 returned. This function must guarantee that all PCI read and write operations
948 are serialized. Extra left bits in OrData are stripped.
949
950 If Address > 0x0FFFFFFF, then ASSERT().
951 If Address is not aligned on a 16-bit boundary, then ASSERT().
952 If StartBit is greater than 15, then ASSERT().
953 If EndBit is greater than 15, then ASSERT().
954 If EndBit is less than StartBit, then ASSERT().
955 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
956
957 @param Address The PCI configuration register to write.
958 @param StartBit The ordinal of the least significant bit in the bit field.
959 Range 0..15.
960 @param EndBit The ordinal of the most significant bit in the bit field.
961 Range 0..15.
962 @param OrData The value to OR with the PCI configuration register.
963
964 @return The value written back to the PCI configuration register.
965
966 **/
967 UINT16
968 EFIAPI
969 PciExpressBitFieldOr16 (
970 IN UINTN Address,
971 IN UINTN StartBit,
972 IN UINTN EndBit,
973 IN UINT16 OrData
974 )
975 {
976 return MmioBitFieldOr16 (
977 GetPciExpressAddress (Address),
978 StartBit,
979 EndBit,
980 OrData
981 );
982 }
983
984 /**
985 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
986 AND, and writes the result back to the bit field in the 16-bit register.
987
988 Reads the 16-bit PCI configuration register specified by Address, performs a
989 bitwise AND between the read result and the value specified by AndData, and
990 writes the result to the 16-bit PCI configuration register specified by
991 Address. The value written to the PCI configuration register is returned.
992 This function must guarantee that all PCI read and write operations are
993 serialized. Extra left bits in AndData are stripped.
994
995 If Address > 0x0FFFFFFF, then ASSERT().
996 If Address is not aligned on a 16-bit boundary, then ASSERT().
997 If StartBit is greater than 15, then ASSERT().
998 If EndBit is greater than 15, then ASSERT().
999 If EndBit is less than StartBit, then ASSERT().
1000 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1001
1002 @param Address The PCI configuration register to write.
1003 @param StartBit The ordinal of the least significant bit in the bit field.
1004 Range 0..15.
1005 @param EndBit The ordinal of the most significant bit in the bit field.
1006 Range 0..15.
1007 @param AndData The value to AND with the PCI configuration register.
1008
1009 @return The value written back to the PCI configuration register.
1010
1011 **/
1012 UINT16
1013 EFIAPI
1014 PciExpressBitFieldAnd16 (
1015 IN UINTN Address,
1016 IN UINTN StartBit,
1017 IN UINTN EndBit,
1018 IN UINT16 AndData
1019 )
1020 {
1021 return MmioBitFieldAnd16 (
1022 GetPciExpressAddress (Address),
1023 StartBit,
1024 EndBit,
1025 AndData
1026 );
1027 }
1028
1029 /**
1030 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
1031 bitwise OR, and writes the result back to the bit field in the
1032 16-bit port.
1033
1034 Reads the 16-bit PCI configuration register specified by Address, performs a
1035 bitwise AND followed by a bitwise OR between the read result and
1036 the value specified by AndData, and writes the result to the 16-bit PCI
1037 configuration register specified by Address. The value written to the PCI
1038 configuration register is returned. This function must guarantee that all PCI
1039 read and write operations are serialized. Extra left bits in both AndData and
1040 OrData are stripped.
1041
1042 If Address > 0x0FFFFFFF, then ASSERT().
1043 If Address is not aligned on a 16-bit boundary, then ASSERT().
1044 If StartBit is greater than 15, then ASSERT().
1045 If EndBit is greater than 15, then ASSERT().
1046 If EndBit is less than StartBit, then ASSERT().
1047 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1048 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1049
1050 @param Address The PCI configuration register to write.
1051 @param StartBit The ordinal of the least significant bit in the bit field.
1052 Range 0..15.
1053 @param EndBit The ordinal of the most significant bit in the bit field.
1054 Range 0..15.
1055 @param AndData The value to AND with the PCI configuration register.
1056 @param OrData The value to OR with the result of the AND operation.
1057
1058 @return The value written back to the PCI configuration register.
1059
1060 **/
1061 UINT16
1062 EFIAPI
1063 PciExpressBitFieldAndThenOr16 (
1064 IN UINTN Address,
1065 IN UINTN StartBit,
1066 IN UINTN EndBit,
1067 IN UINT16 AndData,
1068 IN UINT16 OrData
1069 )
1070 {
1071 return MmioBitFieldAndThenOr16 (
1072 GetPciExpressAddress (Address),
1073 StartBit,
1074 EndBit,
1075 AndData,
1076 OrData
1077 );
1078 }
1079
1080 /**
1081 Reads a 32-bit PCI configuration register.
1082
1083 Reads and returns the 32-bit PCI configuration register specified by Address.
1084 This function must guarantee that all PCI read and write operations are
1085 serialized.
1086
1087 If Address > 0x0FFFFFFF, then ASSERT().
1088 If Address is not aligned on a 32-bit boundary, then ASSERT().
1089
1090 @param Address The address that encodes the PCI Bus, Device, Function and
1091 Register.
1092
1093 @return The read value from the PCI configuration register.
1094
1095 **/
1096 UINT32
1097 EFIAPI
1098 PciExpressRead32 (
1099 IN UINTN Address
1100 )
1101 {
1102 return MmioRead32 (GetPciExpressAddress (Address));
1103 }
1104
1105 /**
1106 Writes a 32-bit PCI configuration register.
1107
1108 Writes the 32-bit PCI configuration register specified by Address with the
1109 value specified by Value. Value is returned. This function must guarantee
1110 that all PCI read and write operations are serialized.
1111
1112 If Address > 0x0FFFFFFF, then ASSERT().
1113 If Address is not aligned on a 32-bit boundary, then ASSERT().
1114
1115 @param Address The address that encodes the PCI Bus, Device, Function and
1116 Register.
1117 @param Value The value to write.
1118
1119 @return The value written to the PCI configuration register.
1120
1121 **/
1122 UINT32
1123 EFIAPI
1124 PciExpressWrite32 (
1125 IN UINTN Address,
1126 IN UINT32 Value
1127 )
1128 {
1129 return MmioWrite32 (GetPciExpressAddress (Address), Value);
1130 }
1131
1132 /**
1133 Performs a bitwise OR of a 32-bit PCI configuration register with
1134 a 32-bit value.
1135
1136 Reads the 32-bit PCI configuration register specified by Address, performs a
1137 bitwise OR between the read result and the value specified by
1138 OrData, and writes the result to the 32-bit PCI configuration register
1139 specified by Address. The value written to the PCI configuration register is
1140 returned. This function must guarantee that all PCI read and write operations
1141 are serialized.
1142
1143 If Address > 0x0FFFFFFF, then ASSERT().
1144 If Address is not aligned on a 32-bit boundary, then ASSERT().
1145
1146 @param Address The address that encodes the PCI Bus, Device, Function and
1147 Register.
1148 @param OrData The value to OR with the PCI configuration register.
1149
1150 @return The value written back to the PCI configuration register.
1151
1152 **/
1153 UINT32
1154 EFIAPI
1155 PciExpressOr32 (
1156 IN UINTN Address,
1157 IN UINT32 OrData
1158 )
1159 {
1160 return MmioOr32 (GetPciExpressAddress (Address), OrData);
1161 }
1162
1163 /**
1164 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1165 value.
1166
1167 Reads the 32-bit PCI configuration register specified by Address, performs a
1168 bitwise AND between the read result and the value specified by AndData, and
1169 writes the result to the 32-bit PCI configuration register specified by
1170 Address. The value written to the PCI configuration register is returned.
1171 This function must guarantee that all PCI read and write operations are
1172 serialized.
1173
1174 If Address > 0x0FFFFFFF, then ASSERT().
1175 If Address is not aligned on a 32-bit boundary, then ASSERT().
1176
1177 @param Address The address that encodes the PCI Bus, Device, Function and
1178 Register.
1179 @param AndData The value to AND with the PCI configuration register.
1180
1181 @return The value written back to the PCI configuration register.
1182
1183 **/
1184 UINT32
1185 EFIAPI
1186 PciExpressAnd32 (
1187 IN UINTN Address,
1188 IN UINT32 AndData
1189 )
1190 {
1191 return MmioAnd32 (GetPciExpressAddress (Address), AndData);
1192 }
1193
1194 /**
1195 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1196 value, followed a bitwise OR with another 32-bit value.
1197
1198 Reads the 32-bit PCI configuration register specified by Address, performs a
1199 bitwise AND between the read result and the value specified by AndData,
1200 performs a bitwise OR between the result of the AND operation and
1201 the value specified by OrData, and writes the result to the 32-bit PCI
1202 configuration register specified by Address. The value written to the PCI
1203 configuration register is returned. This function must guarantee that all PCI
1204 read and write operations are serialized.
1205
1206 If Address > 0x0FFFFFFF, then ASSERT().
1207 If Address is not aligned on a 32-bit boundary, then ASSERT().
1208
1209 @param Address The address that encodes the PCI Bus, Device, Function and
1210 Register.
1211 @param AndData The value to AND with the PCI configuration register.
1212 @param OrData The value to OR with the result of the AND operation.
1213
1214 @return The value written back to the PCI configuration register.
1215
1216 **/
1217 UINT32
1218 EFIAPI
1219 PciExpressAndThenOr32 (
1220 IN UINTN Address,
1221 IN UINT32 AndData,
1222 IN UINT32 OrData
1223 )
1224 {
1225 return MmioAndThenOr32 (
1226 GetPciExpressAddress (Address),
1227 AndData,
1228 OrData
1229 );
1230 }
1231
1232 /**
1233 Reads a bit field of a PCI configuration register.
1234
1235 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1236 specified by the StartBit and the EndBit. The value of the bit field is
1237 returned.
1238
1239 If Address > 0x0FFFFFFF, then ASSERT().
1240 If Address is not aligned on a 32-bit boundary, then ASSERT().
1241 If StartBit is greater than 31, then ASSERT().
1242 If EndBit is greater than 31, then ASSERT().
1243 If EndBit is less than StartBit, then ASSERT().
1244
1245 @param Address The PCI configuration register to read.
1246 @param StartBit The ordinal of the least significant bit in the bit field.
1247 Range 0..31.
1248 @param EndBit The ordinal of the most significant bit in the bit field.
1249 Range 0..31.
1250
1251 @return The value of the bit field read from the PCI configuration register.
1252
1253 **/
1254 UINT32
1255 EFIAPI
1256 PciExpressBitFieldRead32 (
1257 IN UINTN Address,
1258 IN UINTN StartBit,
1259 IN UINTN EndBit
1260 )
1261 {
1262 return MmioBitFieldRead32 (
1263 GetPciExpressAddress (Address),
1264 StartBit,
1265 EndBit
1266 );
1267 }
1268
1269 /**
1270 Writes a bit field to a PCI configuration register.
1271
1272 Writes Value to the bit field of the PCI configuration register. The bit
1273 field is specified by the StartBit and the EndBit. All other bits in the
1274 destination PCI configuration register are preserved. The new value of the
1275 32-bit register is returned.
1276
1277 If Address > 0x0FFFFFFF, then ASSERT().
1278 If Address is not aligned on a 32-bit boundary, then ASSERT().
1279 If StartBit is greater than 31, then ASSERT().
1280 If EndBit is greater than 31, then ASSERT().
1281 If EndBit is less than StartBit, then ASSERT().
1282 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1283
1284 @param Address The PCI configuration register to write.
1285 @param StartBit The ordinal of the least significant bit in the bit field.
1286 Range 0..31.
1287 @param EndBit The ordinal of the most significant bit in the bit field.
1288 Range 0..31.
1289 @param Value The new value of the bit field.
1290
1291 @return The value written back to the PCI configuration register.
1292
1293 **/
1294 UINT32
1295 EFIAPI
1296 PciExpressBitFieldWrite32 (
1297 IN UINTN Address,
1298 IN UINTN StartBit,
1299 IN UINTN EndBit,
1300 IN UINT32 Value
1301 )
1302 {
1303 return MmioBitFieldWrite32 (
1304 GetPciExpressAddress (Address),
1305 StartBit,
1306 EndBit,
1307 Value
1308 );
1309 }
1310
1311 /**
1312 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1313 writes the result back to the bit field in the 32-bit port.
1314
1315 Reads the 32-bit PCI configuration register specified by Address, performs a
1316 bitwise OR between the read result and the value specified by
1317 OrData, and writes the result to the 32-bit PCI configuration register
1318 specified by Address. The value written to the PCI configuration register is
1319 returned. This function must guarantee that all PCI read and write operations
1320 are serialized. Extra left bits in OrData are stripped.
1321
1322 If Address > 0x0FFFFFFF, then ASSERT().
1323 If Address is not aligned on a 32-bit boundary, then ASSERT().
1324 If StartBit is greater than 31, then ASSERT().
1325 If EndBit is greater than 31, then ASSERT().
1326 If EndBit is less than StartBit, then ASSERT().
1327 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1328
1329 @param Address The PCI configuration register to write.
1330 @param StartBit The ordinal of the least significant bit in the bit field.
1331 Range 0..31.
1332 @param EndBit The ordinal of the most significant bit in the bit field.
1333 Range 0..31.
1334 @param OrData The value to OR with the PCI configuration register.
1335
1336 @return The value written back to the PCI configuration register.
1337
1338 **/
1339 UINT32
1340 EFIAPI
1341 PciExpressBitFieldOr32 (
1342 IN UINTN Address,
1343 IN UINTN StartBit,
1344 IN UINTN EndBit,
1345 IN UINT32 OrData
1346 )
1347 {
1348 return MmioBitFieldOr32 (
1349 GetPciExpressAddress (Address),
1350 StartBit,
1351 EndBit,
1352 OrData
1353 );
1354 }
1355
1356 /**
1357 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1358 AND, and writes the result back to the bit field in the 32-bit register.
1359
1360 Reads the 32-bit PCI configuration register specified by Address, performs a
1361 bitwise AND between the read result and the value specified by AndData, and
1362 writes the result to the 32-bit PCI configuration register specified by
1363 Address. The value written to the PCI configuration register is returned.
1364 This function must guarantee that all PCI read and write operations are
1365 serialized. Extra left bits in AndData are stripped.
1366
1367 If Address > 0x0FFFFFFF, then ASSERT().
1368 If Address is not aligned on a 32-bit boundary, then ASSERT().
1369 If StartBit is greater than 31, then ASSERT().
1370 If EndBit is greater than 31, then ASSERT().
1371 If EndBit is less than StartBit, then ASSERT().
1372 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1373
1374 @param Address The PCI configuration register to write.
1375 @param StartBit The ordinal of the least significant bit in the bit field.
1376 Range 0..31.
1377 @param EndBit The ordinal of the most significant bit in the bit field.
1378 Range 0..31.
1379 @param AndData The value to AND with the PCI configuration register.
1380
1381 @return The value written back to the PCI configuration register.
1382
1383 **/
1384 UINT32
1385 EFIAPI
1386 PciExpressBitFieldAnd32 (
1387 IN UINTN Address,
1388 IN UINTN StartBit,
1389 IN UINTN EndBit,
1390 IN UINT32 AndData
1391 )
1392 {
1393 return MmioBitFieldAnd32 (
1394 GetPciExpressAddress (Address),
1395 StartBit,
1396 EndBit,
1397 AndData
1398 );
1399 }
1400
1401 /**
1402 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1403 bitwise OR, and writes the result back to the bit field in the
1404 32-bit port.
1405
1406 Reads the 32-bit PCI configuration register specified by Address, performs a
1407 bitwise AND followed by a bitwise OR between the read result and
1408 the value specified by AndData, and writes the result to the 32-bit PCI
1409 configuration register specified by Address. The value written to the PCI
1410 configuration register is returned. This function must guarantee that all PCI
1411 read and write operations are serialized. Extra left bits in both AndData and
1412 OrData are stripped.
1413
1414 If Address > 0x0FFFFFFF, then ASSERT().
1415 If Address is not aligned on a 32-bit boundary, then ASSERT().
1416 If StartBit is greater than 31, then ASSERT().
1417 If EndBit is greater than 31, then ASSERT().
1418 If EndBit is less than StartBit, then ASSERT().
1419 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1420 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1421
1422 @param Address The PCI configuration register to write.
1423 @param StartBit The ordinal of the least significant bit in the bit field.
1424 Range 0..31.
1425 @param EndBit The ordinal of the most significant bit in the bit field.
1426 Range 0..31.
1427 @param AndData The value to AND with the PCI configuration register.
1428 @param OrData The value to OR with the result of the AND operation.
1429
1430 @return The value written back to the PCI configuration register.
1431
1432 **/
1433 UINT32
1434 EFIAPI
1435 PciExpressBitFieldAndThenOr32 (
1436 IN UINTN Address,
1437 IN UINTN StartBit,
1438 IN UINTN EndBit,
1439 IN UINT32 AndData,
1440 IN UINT32 OrData
1441 )
1442 {
1443 return MmioBitFieldAndThenOr32 (
1444 GetPciExpressAddress (Address),
1445 StartBit,
1446 EndBit,
1447 AndData,
1448 OrData
1449 );
1450 }
1451
1452 /**
1453 Reads a range of PCI configuration registers into a caller supplied buffer.
1454
1455 Reads the range of PCI configuration registers specified by StartAddress and
1456 Size into the buffer specified by Buffer. This function only allows the PCI
1457 configuration registers from a single PCI function to be read. Size is
1458 returned. When possible 32-bit PCI configuration read cycles are used to read
1459 from StartAddress to StartAddress + Size. Due to alignment restrictions, 8-bit
1460 and 16-bit PCI configuration read cycles may be used at the beginning and the
1461 end of the range.
1462
1463 If StartAddress > 0x0FFFFFFF, then ASSERT().
1464 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1465 If Size > 0 and Buffer is NULL, then ASSERT().
1466
1467 @param StartAddress The starting address that encodes the PCI Bus, Device,
1468 Function and Register.
1469 @param Size The size in bytes of the transfer.
1470 @param Buffer The pointer to a buffer receiving the data read.
1471
1472 @return Size read data from StartAddress.
1473
1474 **/
1475 UINTN
1476 EFIAPI
1477 PciExpressReadBuffer (
1478 IN UINTN StartAddress,
1479 IN UINTN Size,
1480 OUT VOID *Buffer
1481 )
1482 {
1483 UINTN ReturnValue;
1484
1485 //
1486 // Make sure Address is valid
1487 //
1488 ASSERT (((StartAddress) & ~0xfffffff) == 0);
1489 ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);
1490
1491 if (Size == 0) {
1492 return Size;
1493 }
1494
1495 ASSERT (Buffer != NULL);
1496
1497 //
1498 // Save Size for return
1499 //
1500 ReturnValue = Size;
1501
1502 if ((StartAddress & 1) != 0) {
1503 //
1504 // Read a byte if StartAddress is byte aligned
1505 //
1506 *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress);
1507 StartAddress += sizeof (UINT8);
1508 Size -= sizeof (UINT8);
1509 Buffer = (UINT8*)Buffer + 1;
1510 }
1511
1512 if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {
1513 //
1514 // Read a word if StartAddress is word aligned
1515 //
1516 WriteUnaligned16 ((UINT16 *) Buffer, (UINT16) PciExpressRead16 (StartAddress));
1517
1518 StartAddress += sizeof (UINT16);
1519 Size -= sizeof (UINT16);
1520 Buffer = (UINT16*)Buffer + 1;
1521 }
1522
1523 while (Size >= sizeof (UINT32)) {
1524 //
1525 // Read as many double words as possible
1526 //
1527 WriteUnaligned32 ((UINT32 *) Buffer, (UINT32) PciExpressRead32 (StartAddress));
1528
1529 StartAddress += sizeof (UINT32);
1530 Size -= sizeof (UINT32);
1531 Buffer = (UINT32*)Buffer + 1;
1532 }
1533
1534 if (Size >= sizeof (UINT16)) {
1535 //
1536 // Read the last remaining word if exist
1537 //
1538 WriteUnaligned16 ((UINT16 *) Buffer, (UINT16) PciExpressRead16 (StartAddress));
1539 StartAddress += sizeof (UINT16);
1540 Size -= sizeof (UINT16);
1541 Buffer = (UINT16*)Buffer + 1;
1542 }
1543
1544 if (Size >= sizeof (UINT8)) {
1545 //
1546 // Read the last remaining byte if exist
1547 //
1548 *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress);
1549 }
1550
1551 return ReturnValue;
1552 }
1553
1554 /**
1555 Copies the data in a caller supplied buffer to a specified range of PCI
1556 configuration space.
1557
1558 Writes the range of PCI configuration registers specified by StartAddress and
1559 Size from the buffer specified by Buffer. This function only allows the PCI
1560 configuration registers from a single PCI function to be written. Size is
1561 returned. When possible 32-bit PCI configuration write cycles are used to
1562 write from StartAddress to StartAddress + Size. Due to alignment restrictions,
1563 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1564 and the end of the range.
1565
1566 If StartAddress > 0x0FFFFFFF, then ASSERT().
1567 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1568 If Size > 0 and Buffer is NULL, then ASSERT().
1569
1570 @param StartAddress The starting address that encodes the PCI Bus, Device,
1571 Function and Register.
1572 @param Size The size in bytes of the transfer.
1573 @param Buffer The pointer to a buffer containing the data to write.
1574
1575 @return Size written to StartAddress.
1576
1577 **/
1578 UINTN
1579 EFIAPI
1580 PciExpressWriteBuffer (
1581 IN UINTN StartAddress,
1582 IN UINTN Size,
1583 IN VOID *Buffer
1584 )
1585 {
1586 UINTN ReturnValue;
1587
1588 //
1589 // Make sure Address is valid
1590 //
1591 ASSERT (((StartAddress) & ~0xfffffff) == 0);
1592 ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);
1593
1594 if (Size == 0) {
1595 return 0;
1596 }
1597
1598 ASSERT (Buffer != NULL);
1599
1600 //
1601 // Save Size for return
1602 //
1603 ReturnValue = Size;
1604
1605 if ((StartAddress & 1) != 0) {
1606 //
1607 // Write a byte if StartAddress is byte aligned
1608 //
1609 PciExpressWrite8 (StartAddress, *(UINT8*)Buffer);
1610 StartAddress += sizeof (UINT8);
1611 Size -= sizeof (UINT8);
1612 Buffer = (UINT8*)Buffer + 1;
1613 }
1614
1615 if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {
1616 //
1617 // Write a word if StartAddress is word aligned
1618 //
1619 PciExpressWrite16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer));
1620 StartAddress += sizeof (UINT16);
1621 Size -= sizeof (UINT16);
1622 Buffer = (UINT16*)Buffer + 1;
1623 }
1624
1625 while (Size >= sizeof (UINT32)) {
1626 //
1627 // Write as many double words as possible
1628 //
1629 PciExpressWrite32 (StartAddress, ReadUnaligned32 ((UINT32*)Buffer));
1630 StartAddress += sizeof (UINT32);
1631 Size -= sizeof (UINT32);
1632 Buffer = (UINT32*)Buffer + 1;
1633 }
1634
1635 if (Size >= sizeof (UINT16)) {
1636 //
1637 // Write the last remaining word if exist
1638 //
1639 PciExpressWrite16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer));
1640 StartAddress += sizeof (UINT16);
1641 Size -= sizeof (UINT16);
1642 Buffer = (UINT16*)Buffer + 1;
1643 }
1644
1645 if (Size >= sizeof (UINT8)) {
1646 //
1647 // Write the last remaining byte if exist
1648 //
1649 PciExpressWrite8 (StartAddress, *(UINT8*)Buffer);
1650 }
1651
1652 return ReturnValue;
1653 }