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