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