]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/DxeRuntimePciExpressLib/PciExpressLib.c
4231614595b07efb37e9e4a0dec7156a85bc31e4
[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 - 2009, Intel Corporation<BR>
9 All rights reserved. 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 ///
37 typedef struct {
38 UINTN PhysicalAddress;
39 UINTN VirtualAddress;
40 } PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE;
41
42 ///
43 /// Set Virtual Address Map Event
44 ///
45 EFI_EVENT mDxeRuntimePciExpressLibVirtualNotifyEvent = NULL;
46
47 ///
48 /// Module global that contains the base physical address of the PCI Express MMIO range
49 ///
50 UINTN mDxeRuntimePciExpressLibPciExpressBaseAddress = 0;
51
52 ///
53 /// The number of PCI devices that have been registered for runtime access
54 ///
55 UINTN mDxeRuntimePciExpressLibNumberOfRuntimeRanges = 0;
56
57 ///
58 /// The table of PCI devices that have been registered for runtime access
59 ///
60 PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE *mDxeRuntimePciExpressLibRegistrationTable = NULL;
61
62 ///
63 /// The table index of the most recent virtual address lookup
64 ///
65 UINTN 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 Event Context
74 **/
75 VOID
76 EFIAPI
77 DxeRuntimePciExpressLibVirtualNotify (
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 **/
116 EFI_STATUS
117 EFIAPI
118 DxeRuntimePciExpressLibConstructor (
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 **/
157 EFI_STATUS
158 EFIAPI
159 DxeRuntimePciExpressLibDestructor (
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 Address that encodes the PCI Bus, Device, Function and Register.
190 @return The base address of PCI Express.
191
192 **/
193 UINTN
194 GetPciExpressAddress (
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 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 **/
277 RETURN_STATUS
278 EFIAPI
279 PciExpressRegisterForRuntimeAccess (
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 Address that encodes the PCI Bus, Device, Function and
363 Register.
364
365 @return The read value from the PCI configuration register.
366
367 **/
368 UINT8
369 EFIAPI
370 PciExpressRead8 (
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 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 **/
393 UINT8
394 EFIAPI
395 PciExpressWrite8 (
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 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 **/
423 UINT8
424 EFIAPI
425 PciExpressOr8 (
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 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 **/
453 UINT8
454 EFIAPI
455 PciExpressAnd8 (
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 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 **/
485 UINT8
486 EFIAPI
487 PciExpressAndThenOr8 (
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 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 **/
521 UINT8
522 EFIAPI
523 PciExpressBitFieldRead8 (
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
549 @param Address PCI configuration register to write.
550 @param StartBit The ordinal of the least significant bit in the bit field.
551 Range 0..7.
552 @param EndBit The ordinal of the most significant bit in the bit field.
553 Range 0..7.
554 @param Value New value of the bit field.
555
556 @return The value written back to the PCI configuration register.
557
558 **/
559 UINT8
560 EFIAPI
561 PciExpressBitFieldWrite8 (
562 IN UINTN Address,
563 IN UINTN StartBit,
564 IN UINTN EndBit,
565 IN UINT8 Value
566 )
567 {
568 return MmioBitFieldWrite8 (
569 GetPciExpressAddress (Address),
570 StartBit,
571 EndBit,
572 Value
573 );
574 }
575
576 /**
577 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
578 writes the result back to the bit field in the 8-bit port.
579
580 Reads the 8-bit PCI configuration register specified by Address, performs a
581 bitwise OR between the read result and the value specified by
582 OrData, and writes the result to the 8-bit PCI configuration register
583 specified by Address. The value written to the PCI configuration register is
584 returned. This function must guarantee that all PCI read and write operations
585 are serialized. Extra left bits in OrData are stripped.
586
587 If Address > 0x0FFFFFFF, then ASSERT().
588 If StartBit is greater than 7, then ASSERT().
589 If EndBit is greater than 7, then ASSERT().
590 If EndBit is less than StartBit, then ASSERT().
591
592 @param Address PCI configuration register to write.
593 @param StartBit The ordinal of the least significant bit in the bit field.
594 Range 0..7.
595 @param EndBit The ordinal of the most significant bit in the bit field.
596 Range 0..7.
597 @param OrData The value to OR with the PCI configuration register.
598
599 @return The value written back to the PCI configuration register.
600
601 **/
602 UINT8
603 EFIAPI
604 PciExpressBitFieldOr8 (
605 IN UINTN Address,
606 IN UINTN StartBit,
607 IN UINTN EndBit,
608 IN UINT8 OrData
609 )
610 {
611 return MmioBitFieldOr8 (
612 GetPciExpressAddress (Address),
613 StartBit,
614 EndBit,
615 OrData
616 );
617 }
618
619 /**
620 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
621 AND, and writes the result back to the bit field in the 8-bit register.
622
623 Reads the 8-bit PCI configuration register specified by Address, performs a
624 bitwise AND between the read result and the value specified by AndData, and
625 writes the result to the 8-bit PCI configuration register specified by
626 Address. The value written to the PCI configuration register is returned.
627 This function must guarantee that all PCI read and write operations are
628 serialized. Extra left bits in AndData are stripped.
629
630 If Address > 0x0FFFFFFF, then ASSERT().
631 If StartBit is greater than 7, then ASSERT().
632 If EndBit is greater than 7, then ASSERT().
633 If EndBit is less than StartBit, then ASSERT().
634
635 @param Address PCI configuration register to write.
636 @param StartBit The ordinal of the least significant bit in the bit field.
637 Range 0..7.
638 @param EndBit The ordinal of the most significant bit in the bit field.
639 Range 0..7.
640 @param AndData The value to AND with the PCI configuration register.
641
642 @return The value written back to the PCI configuration register.
643
644 **/
645 UINT8
646 EFIAPI
647 PciExpressBitFieldAnd8 (
648 IN UINTN Address,
649 IN UINTN StartBit,
650 IN UINTN EndBit,
651 IN UINT8 AndData
652 )
653 {
654 return MmioBitFieldAnd8 (
655 GetPciExpressAddress (Address),
656 StartBit,
657 EndBit,
658 AndData
659 );
660 }
661
662 /**
663 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
664 bitwise OR, and writes the result back to the bit field in the
665 8-bit port.
666
667 Reads the 8-bit PCI configuration register specified by Address, performs a
668 bitwise AND followed by a bitwise OR between the read result and
669 the value specified by AndData, and writes the result to the 8-bit PCI
670 configuration register specified by Address. The value written to the PCI
671 configuration register is returned. This function must guarantee that all PCI
672 read and write operations are serialized. Extra left bits in both AndData and
673 OrData are stripped.
674
675 If Address > 0x0FFFFFFF, then ASSERT().
676 If StartBit is greater than 7, then ASSERT().
677 If EndBit is greater than 7, then ASSERT().
678 If EndBit is less than StartBit, then ASSERT().
679
680 @param Address PCI configuration register to write.
681 @param StartBit The ordinal of the least significant bit in the bit field.
682 Range 0..7.
683 @param EndBit The ordinal of the most significant bit in the bit field.
684 Range 0..7.
685 @param AndData The value to AND with the PCI configuration register.
686 @param OrData The value to OR with the result of the AND operation.
687
688 @return The value written back to the PCI configuration register.
689
690 **/
691 UINT8
692 EFIAPI
693 PciExpressBitFieldAndThenOr8 (
694 IN UINTN Address,
695 IN UINTN StartBit,
696 IN UINTN EndBit,
697 IN UINT8 AndData,
698 IN UINT8 OrData
699 )
700 {
701 return MmioBitFieldAndThenOr8 (
702 GetPciExpressAddress (Address),
703 StartBit,
704 EndBit,
705 AndData,
706 OrData
707 );
708 }
709
710 /**
711 Reads a 16-bit PCI configuration register.
712
713 Reads and returns the 16-bit PCI configuration register specified by Address.
714 This function must guarantee that all PCI read and write operations are
715 serialized.
716
717 If Address > 0x0FFFFFFF, then ASSERT().
718 If Address is not aligned on a 16-bit boundary, then ASSERT().
719
720 @param Address Address that encodes the PCI Bus, Device, Function and
721 Register.
722
723 @return The read value from the PCI configuration register.
724
725 **/
726 UINT16
727 EFIAPI
728 PciExpressRead16 (
729 IN UINTN Address
730 )
731 {
732 return MmioRead16 (GetPciExpressAddress (Address));
733 }
734
735 /**
736 Writes a 16-bit PCI configuration register.
737
738 Writes the 16-bit PCI configuration register specified by Address with the
739 value specified by Value. Value is returned. This function must guarantee
740 that all PCI read and write operations are serialized.
741
742 If Address > 0x0FFFFFFF, then ASSERT().
743 If Address is not aligned on a 16-bit boundary, then ASSERT().
744
745 @param Address Address that encodes the PCI Bus, Device, Function and
746 Register.
747 @param Value The value to write.
748
749 @return The value written to the PCI configuration register.
750
751 **/
752 UINT16
753 EFIAPI
754 PciExpressWrite16 (
755 IN UINTN Address,
756 IN UINT16 Value
757 )
758 {
759 return MmioWrite16 (GetPciExpressAddress (Address), Value);
760 }
761
762 /**
763 Performs a bitwise OR of a 16-bit PCI configuration register with
764 a 16-bit value.
765
766 Reads the 16-bit PCI configuration register specified by Address, performs a
767 bitwise OR between the read result and the value specified by
768 OrData, and writes the result to the 16-bit PCI configuration register
769 specified by Address. The value written to the PCI configuration register is
770 returned. This function must guarantee that all PCI read and write operations
771 are serialized.
772
773 If Address > 0x0FFFFFFF, then ASSERT().
774 If Address is not aligned on a 16-bit boundary, then ASSERT().
775
776 @param Address Address that encodes the PCI Bus, Device, Function and
777 Register.
778 @param OrData The value to OR with the PCI configuration register.
779
780 @return The value written back to the PCI configuration register.
781
782 **/
783 UINT16
784 EFIAPI
785 PciExpressOr16 (
786 IN UINTN Address,
787 IN UINT16 OrData
788 )
789 {
790 return MmioOr16 (GetPciExpressAddress (Address), OrData);
791 }
792
793 /**
794 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
795 value.
796
797 Reads the 16-bit PCI configuration register specified by Address, performs a
798 bitwise AND between the read result and the value specified by AndData, and
799 writes the result to the 16-bit PCI configuration register specified by
800 Address. The value written to the PCI configuration register is returned.
801 This function must guarantee that all PCI read and write operations are
802 serialized.
803
804 If Address > 0x0FFFFFFF, then ASSERT().
805 If Address is not aligned on a 16-bit boundary, then ASSERT().
806
807 @param Address Address that encodes the PCI Bus, Device, Function and
808 Register.
809 @param AndData The value to AND with the PCI configuration register.
810
811 @return The value written back to the PCI configuration register.
812
813 **/
814 UINT16
815 EFIAPI
816 PciExpressAnd16 (
817 IN UINTN Address,
818 IN UINT16 AndData
819 )
820 {
821 return MmioAnd16 (GetPciExpressAddress (Address), AndData);
822 }
823
824 /**
825 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
826 value, followed a bitwise OR with another 16-bit value.
827
828 Reads the 16-bit PCI configuration register specified by Address, performs a
829 bitwise AND between the read result and the value specified by AndData,
830 performs a bitwise OR between the result of the AND operation and
831 the value specified by OrData, and writes the result to the 16-bit PCI
832 configuration register specified by Address. The value written to the PCI
833 configuration register is returned. This function must guarantee that all PCI
834 read and write operations are serialized.
835
836 If Address > 0x0FFFFFFF, then ASSERT().
837 If Address is not aligned on a 16-bit boundary, then ASSERT().
838
839 @param Address Address that encodes the PCI Bus, Device, Function and
840 Register.
841 @param AndData The value to AND with the PCI configuration register.
842 @param OrData The value to OR with the result of the AND operation.
843
844 @return The value written back to the PCI configuration register.
845
846 **/
847 UINT16
848 EFIAPI
849 PciExpressAndThenOr16 (
850 IN UINTN Address,
851 IN UINT16 AndData,
852 IN UINT16 OrData
853 )
854 {
855 return MmioAndThenOr16 (
856 GetPciExpressAddress (Address),
857 AndData,
858 OrData
859 );
860 }
861
862 /**
863 Reads a bit field of a PCI configuration register.
864
865 Reads the bit field in a 16-bit PCI configuration register. The bit field is
866 specified by the StartBit and the EndBit. The value of the bit field is
867 returned.
868
869 If Address > 0x0FFFFFFF, then ASSERT().
870 If Address is not aligned on a 16-bit boundary, then ASSERT().
871 If StartBit is greater than 15, then ASSERT().
872 If EndBit is greater than 15, then ASSERT().
873 If EndBit is less than StartBit, then ASSERT().
874
875 @param Address PCI configuration register to read.
876 @param StartBit The ordinal of the least significant bit in the bit field.
877 Range 0..15.
878 @param EndBit The ordinal of the most significant bit in the bit field.
879 Range 0..15.
880
881 @return The value of the bit field read from the PCI configuration register.
882
883 **/
884 UINT16
885 EFIAPI
886 PciExpressBitFieldRead16 (
887 IN UINTN Address,
888 IN UINTN StartBit,
889 IN UINTN EndBit
890 )
891 {
892 return MmioBitFieldRead16 (
893 GetPciExpressAddress (Address),
894 StartBit,
895 EndBit
896 );
897 }
898
899 /**
900 Writes a bit field to a PCI configuration register.
901
902 Writes Value to the bit field of the PCI configuration register. The bit
903 field is specified by the StartBit and the EndBit. All other bits in the
904 destination PCI configuration register are preserved. The new value of the
905 16-bit register is returned.
906
907 If Address > 0x0FFFFFFF, then ASSERT().
908 If Address is not aligned on a 16-bit boundary, then ASSERT().
909 If StartBit is greater than 15, then ASSERT().
910 If EndBit is greater than 15, then ASSERT().
911 If EndBit is less than StartBit, then ASSERT().
912
913 @param Address PCI configuration register to write.
914 @param StartBit The ordinal of the least significant bit in the bit field.
915 Range 0..15.
916 @param EndBit The ordinal of the most significant bit in the bit field.
917 Range 0..15.
918 @param Value New value of the bit field.
919
920 @return The value written back to the PCI configuration register.
921
922 **/
923 UINT16
924 EFIAPI
925 PciExpressBitFieldWrite16 (
926 IN UINTN Address,
927 IN UINTN StartBit,
928 IN UINTN EndBit,
929 IN UINT16 Value
930 )
931 {
932 return MmioBitFieldWrite16 (
933 GetPciExpressAddress (Address),
934 StartBit,
935 EndBit,
936 Value
937 );
938 }
939
940 /**
941 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
942 writes the result back to the bit field in the 16-bit port.
943
944 Reads the 16-bit PCI configuration register specified by Address, performs a
945 bitwise OR between the read result and the value specified by
946 OrData, and writes the result to the 16-bit PCI configuration register
947 specified by Address. The value written to the PCI configuration register is
948 returned. This function must guarantee that all PCI read and write operations
949 are serialized. Extra left bits in OrData are stripped.
950
951 If Address > 0x0FFFFFFF, then ASSERT().
952 If Address is not aligned on a 16-bit boundary, then ASSERT().
953 If StartBit is greater than 15, then ASSERT().
954 If EndBit is greater than 15, then ASSERT().
955 If EndBit is less than StartBit, then ASSERT().
956
957 @param Address PCI configuration register to write.
958 @param StartBit The ordinal of the least significant bit in the bit field.
959 Range 0..15.
960 @param EndBit The ordinal of the most significant bit in the bit field.
961 Range 0..15.
962 @param OrData The value to OR with the PCI configuration register.
963
964 @return The value written back to the PCI configuration register.
965
966 **/
967 UINT16
968 EFIAPI
969 PciExpressBitFieldOr16 (
970 IN UINTN Address,
971 IN UINTN StartBit,
972 IN UINTN EndBit,
973 IN UINT16 OrData
974 )
975 {
976 return MmioBitFieldOr16 (
977 GetPciExpressAddress (Address),
978 StartBit,
979 EndBit,
980 OrData
981 );
982 }
983
984 /**
985 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
986 AND, and writes the result back to the bit field in the 16-bit register.
987
988 Reads the 16-bit PCI configuration register specified by Address, performs a
989 bitwise AND between the read result and the value specified by AndData, and
990 writes the result to the 16-bit PCI configuration register specified by
991 Address. The value written to the PCI configuration register is returned.
992 This function must guarantee that all PCI read and write operations are
993 serialized. Extra left bits in AndData are stripped.
994
995 If Address > 0x0FFFFFFF, then ASSERT().
996 If Address is not aligned on a 16-bit boundary, then ASSERT().
997 If StartBit is greater than 15, then ASSERT().
998 If EndBit is greater than 15, then ASSERT().
999 If EndBit is less than StartBit, then ASSERT().
1000
1001 @param Address PCI configuration register to write.
1002 @param StartBit The ordinal of the least significant bit in the bit field.
1003 Range 0..15.
1004 @param EndBit The ordinal of the most significant bit in the bit field.
1005 Range 0..15.
1006 @param AndData The value to AND with the PCI configuration register.
1007
1008 @return The value written back to the PCI configuration register.
1009
1010 **/
1011 UINT16
1012 EFIAPI
1013 PciExpressBitFieldAnd16 (
1014 IN UINTN Address,
1015 IN UINTN StartBit,
1016 IN UINTN EndBit,
1017 IN UINT16 AndData
1018 )
1019 {
1020 return MmioBitFieldAnd16 (
1021 GetPciExpressAddress (Address),
1022 StartBit,
1023 EndBit,
1024 AndData
1025 );
1026 }
1027
1028 /**
1029 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
1030 bitwise OR, and writes the result back to the bit field in the
1031 16-bit port.
1032
1033 Reads the 16-bit PCI configuration register specified by Address, performs a
1034 bitwise AND followed by a bitwise OR between the read result and
1035 the value specified by AndData, and writes the result to the 16-bit PCI
1036 configuration register specified by Address. The value written to the PCI
1037 configuration register is returned. This function must guarantee that all PCI
1038 read and write operations are serialized. Extra left bits in both AndData and
1039 OrData are stripped.
1040
1041 If Address > 0x0FFFFFFF, then ASSERT().
1042 If Address is not aligned on a 16-bit boundary, then ASSERT().
1043 If StartBit is greater than 15, then ASSERT().
1044 If EndBit is greater than 15, then ASSERT().
1045 If EndBit is less than StartBit, then ASSERT().
1046
1047 @param Address PCI configuration register to write.
1048 @param StartBit The ordinal of the least significant bit in the bit field.
1049 Range 0..15.
1050 @param EndBit The ordinal of the most significant bit in the bit field.
1051 Range 0..15.
1052 @param AndData The value to AND with the PCI configuration register.
1053 @param OrData The value to OR with the result of the AND operation.
1054
1055 @return The value written back to the PCI configuration register.
1056
1057 **/
1058 UINT16
1059 EFIAPI
1060 PciExpressBitFieldAndThenOr16 (
1061 IN UINTN Address,
1062 IN UINTN StartBit,
1063 IN UINTN EndBit,
1064 IN UINT16 AndData,
1065 IN UINT16 OrData
1066 )
1067 {
1068 return MmioBitFieldAndThenOr16 (
1069 GetPciExpressAddress (Address),
1070 StartBit,
1071 EndBit,
1072 AndData,
1073 OrData
1074 );
1075 }
1076
1077 /**
1078 Reads a 32-bit PCI configuration register.
1079
1080 Reads and returns the 32-bit PCI configuration register specified by Address.
1081 This function must guarantee that all PCI read and write operations are
1082 serialized.
1083
1084 If Address > 0x0FFFFFFF, then ASSERT().
1085 If Address is not aligned on a 32-bit boundary, then ASSERT().
1086
1087 @param Address Address that encodes the PCI Bus, Device, Function and
1088 Register.
1089
1090 @return The read value from the PCI configuration register.
1091
1092 **/
1093 UINT32
1094 EFIAPI
1095 PciExpressRead32 (
1096 IN UINTN Address
1097 )
1098 {
1099 return MmioRead32 (GetPciExpressAddress (Address));
1100 }
1101
1102 /**
1103 Writes a 32-bit PCI configuration register.
1104
1105 Writes the 32-bit PCI configuration register specified by Address with the
1106 value specified by Value. Value is returned. This function must guarantee
1107 that all PCI read and write operations are serialized.
1108
1109 If Address > 0x0FFFFFFF, then ASSERT().
1110 If Address is not aligned on a 32-bit boundary, then ASSERT().
1111
1112 @param Address Address that encodes the PCI Bus, Device, Function and
1113 Register.
1114 @param Value The value to write.
1115
1116 @return The value written to the PCI configuration register.
1117
1118 **/
1119 UINT32
1120 EFIAPI
1121 PciExpressWrite32 (
1122 IN UINTN Address,
1123 IN UINT32 Value
1124 )
1125 {
1126 return MmioWrite32 (GetPciExpressAddress (Address), Value);
1127 }
1128
1129 /**
1130 Performs a bitwise OR of a 32-bit PCI configuration register with
1131 a 32-bit value.
1132
1133 Reads the 32-bit PCI configuration register specified by Address, performs a
1134 bitwise OR between the read result and the value specified by
1135 OrData, and writes the result to the 32-bit PCI configuration register
1136 specified by Address. The value written to the PCI configuration register is
1137 returned. This function must guarantee that all PCI read and write operations
1138 are serialized.
1139
1140 If Address > 0x0FFFFFFF, then ASSERT().
1141 If Address is not aligned on a 32-bit boundary, then ASSERT().
1142
1143 @param Address Address that encodes the PCI Bus, Device, Function and
1144 Register.
1145 @param OrData The value to OR with the PCI configuration register.
1146
1147 @return The value written back to the PCI configuration register.
1148
1149 **/
1150 UINT32
1151 EFIAPI
1152 PciExpressOr32 (
1153 IN UINTN Address,
1154 IN UINT32 OrData
1155 )
1156 {
1157 return MmioOr32 (GetPciExpressAddress (Address), OrData);
1158 }
1159
1160 /**
1161 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1162 value.
1163
1164 Reads the 32-bit PCI configuration register specified by Address, performs a
1165 bitwise AND between the read result and the value specified by AndData, and
1166 writes the result to the 32-bit PCI configuration register specified by
1167 Address. The value written to the PCI configuration register is returned.
1168 This function must guarantee that all PCI read and write operations are
1169 serialized.
1170
1171 If Address > 0x0FFFFFFF, then ASSERT().
1172 If Address is not aligned on a 32-bit boundary, then ASSERT().
1173
1174 @param Address Address that encodes the PCI Bus, Device, Function and
1175 Register.
1176 @param AndData The value to AND with the PCI configuration register.
1177
1178 @return The value written back to the PCI configuration register.
1179
1180 **/
1181 UINT32
1182 EFIAPI
1183 PciExpressAnd32 (
1184 IN UINTN Address,
1185 IN UINT32 AndData
1186 )
1187 {
1188 return MmioAnd32 (GetPciExpressAddress (Address), AndData);
1189 }
1190
1191 /**
1192 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1193 value, followed a bitwise OR with another 32-bit value.
1194
1195 Reads the 32-bit PCI configuration register specified by Address, performs a
1196 bitwise AND between the read result and the value specified by AndData,
1197 performs a bitwise OR between the result of the AND operation and
1198 the value specified by OrData, and writes the result to the 32-bit PCI
1199 configuration register specified by Address. The value written to the PCI
1200 configuration register is returned. This function must guarantee that all PCI
1201 read and write operations are serialized.
1202
1203 If Address > 0x0FFFFFFF, then ASSERT().
1204 If Address is not aligned on a 32-bit boundary, then ASSERT().
1205
1206 @param Address Address that encodes the PCI Bus, Device, Function and
1207 Register.
1208 @param AndData The value to AND with the PCI configuration register.
1209 @param OrData The value to OR with the result of the AND operation.
1210
1211 @return The value written back to the PCI configuration register.
1212
1213 **/
1214 UINT32
1215 EFIAPI
1216 PciExpressAndThenOr32 (
1217 IN UINTN Address,
1218 IN UINT32 AndData,
1219 IN UINT32 OrData
1220 )
1221 {
1222 return MmioAndThenOr32 (
1223 GetPciExpressAddress (Address),
1224 AndData,
1225 OrData
1226 );
1227 }
1228
1229 /**
1230 Reads a bit field of a PCI configuration register.
1231
1232 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1233 specified by the StartBit and the EndBit. The value of the bit field is
1234 returned.
1235
1236 If Address > 0x0FFFFFFF, then ASSERT().
1237 If Address is not aligned on a 32-bit boundary, then ASSERT().
1238 If StartBit is greater than 31, then ASSERT().
1239 If EndBit is greater than 31, then ASSERT().
1240 If EndBit is less than StartBit, then ASSERT().
1241
1242 @param Address PCI configuration register to read.
1243 @param StartBit The ordinal of the least significant bit in the bit field.
1244 Range 0..31.
1245 @param EndBit The ordinal of the most significant bit in the bit field.
1246 Range 0..31.
1247
1248 @return The value of the bit field read from the PCI configuration register.
1249
1250 **/
1251 UINT32
1252 EFIAPI
1253 PciExpressBitFieldRead32 (
1254 IN UINTN Address,
1255 IN UINTN StartBit,
1256 IN UINTN EndBit
1257 )
1258 {
1259 return MmioBitFieldRead32 (
1260 GetPciExpressAddress (Address),
1261 StartBit,
1262 EndBit
1263 );
1264 }
1265
1266 /**
1267 Writes a bit field to a PCI configuration register.
1268
1269 Writes Value to the bit field of the PCI configuration register. The bit
1270 field is specified by the StartBit and the EndBit. All other bits in the
1271 destination PCI configuration register are preserved. The new value of the
1272 32-bit register is returned.
1273
1274 If Address > 0x0FFFFFFF, then ASSERT().
1275 If Address is not aligned on a 32-bit boundary, then ASSERT().
1276 If StartBit is greater than 31, then ASSERT().
1277 If EndBit is greater than 31, then ASSERT().
1278 If EndBit is less than StartBit, then ASSERT().
1279
1280 @param Address PCI configuration register to write.
1281 @param StartBit The ordinal of the least significant bit in the bit field.
1282 Range 0..31.
1283 @param EndBit The ordinal of the most significant bit in the bit field.
1284 Range 0..31.
1285 @param Value New value of the bit field.
1286
1287 @return The value written back to the PCI configuration register.
1288
1289 **/
1290 UINT32
1291 EFIAPI
1292 PciExpressBitFieldWrite32 (
1293 IN UINTN Address,
1294 IN UINTN StartBit,
1295 IN UINTN EndBit,
1296 IN UINT32 Value
1297 )
1298 {
1299 return MmioBitFieldWrite32 (
1300 GetPciExpressAddress (Address),
1301 StartBit,
1302 EndBit,
1303 Value
1304 );
1305 }
1306
1307 /**
1308 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1309 writes the result back to the bit field in the 32-bit port.
1310
1311 Reads the 32-bit PCI configuration register specified by Address, performs a
1312 bitwise OR between the read result and the value specified by
1313 OrData, and writes the result to the 32-bit PCI configuration register
1314 specified by Address. The value written to the PCI configuration register is
1315 returned. This function must guarantee that all PCI read and write operations
1316 are serialized. Extra left bits in OrData are stripped.
1317
1318 If Address > 0x0FFFFFFF, then ASSERT().
1319 If Address is not aligned on a 32-bit boundary, then ASSERT().
1320 If StartBit is greater than 31, then ASSERT().
1321 If EndBit is greater than 31, then ASSERT().
1322 If EndBit is less than StartBit, then ASSERT().
1323
1324 @param Address PCI configuration register to write.
1325 @param StartBit The ordinal of the least significant bit in the bit field.
1326 Range 0..31.
1327 @param EndBit The ordinal of the most significant bit in the bit field.
1328 Range 0..31.
1329 @param OrData The value to OR with the PCI configuration register.
1330
1331 @return The value written back to the PCI configuration register.
1332
1333 **/
1334 UINT32
1335 EFIAPI
1336 PciExpressBitFieldOr32 (
1337 IN UINTN Address,
1338 IN UINTN StartBit,
1339 IN UINTN EndBit,
1340 IN UINT32 OrData
1341 )
1342 {
1343 return MmioBitFieldOr32 (
1344 GetPciExpressAddress (Address),
1345 StartBit,
1346 EndBit,
1347 OrData
1348 );
1349 }
1350
1351 /**
1352 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1353 AND, and writes the result back to the bit field in the 32-bit register.
1354
1355 Reads the 32-bit PCI configuration register specified by Address, performs a
1356 bitwise AND between the read result and the value specified by AndData, and
1357 writes the result to the 32-bit PCI configuration register specified by
1358 Address. The value written to the PCI configuration register is returned.
1359 This function must guarantee that all PCI read and write operations are
1360 serialized. Extra left bits in AndData are stripped.
1361
1362 If Address > 0x0FFFFFFF, then ASSERT().
1363 If Address is not aligned on a 32-bit boundary, then ASSERT().
1364 If StartBit is greater than 31, then ASSERT().
1365 If EndBit is greater than 31, then ASSERT().
1366 If EndBit is less than StartBit, then ASSERT().
1367
1368 @param Address PCI configuration register to write.
1369 @param StartBit The ordinal of the least significant bit in the bit field.
1370 Range 0..31.
1371 @param EndBit The ordinal of the most significant bit in the bit field.
1372 Range 0..31.
1373 @param AndData The value to AND with the PCI configuration register.
1374
1375 @return The value written back to the PCI configuration register.
1376
1377 **/
1378 UINT32
1379 EFIAPI
1380 PciExpressBitFieldAnd32 (
1381 IN UINTN Address,
1382 IN UINTN StartBit,
1383 IN UINTN EndBit,
1384 IN UINT32 AndData
1385 )
1386 {
1387 return MmioBitFieldAnd32 (
1388 GetPciExpressAddress (Address),
1389 StartBit,
1390 EndBit,
1391 AndData
1392 );
1393 }
1394
1395 /**
1396 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1397 bitwise OR, and writes the result back to the bit field in the
1398 32-bit port.
1399
1400 Reads the 32-bit PCI configuration register specified by Address, performs a
1401 bitwise AND followed by a bitwise OR between the read result and
1402 the value specified by AndData, and writes the result to the 32-bit PCI
1403 configuration register specified by Address. The value written to the PCI
1404 configuration register is returned. This function must guarantee that all PCI
1405 read and write operations are serialized. Extra left bits in both AndData and
1406 OrData are stripped.
1407
1408 If Address > 0x0FFFFFFF, then ASSERT().
1409 If Address is not aligned on a 32-bit boundary, then ASSERT().
1410 If StartBit is greater than 31, then ASSERT().
1411 If EndBit is greater than 31, then ASSERT().
1412 If EndBit is less than StartBit, then ASSERT().
1413
1414 @param Address PCI configuration register to write.
1415 @param StartBit The ordinal of the least significant bit in the bit field.
1416 Range 0..31.
1417 @param EndBit The ordinal of the most significant bit in the bit field.
1418 Range 0..31.
1419 @param AndData The value to AND with the PCI configuration register.
1420 @param OrData The value to OR with the result of the AND operation.
1421
1422 @return The value written back to the PCI configuration register.
1423
1424 **/
1425 UINT32
1426 EFIAPI
1427 PciExpressBitFieldAndThenOr32 (
1428 IN UINTN Address,
1429 IN UINTN StartBit,
1430 IN UINTN EndBit,
1431 IN UINT32 AndData,
1432 IN UINT32 OrData
1433 )
1434 {
1435 return MmioBitFieldAndThenOr32 (
1436 GetPciExpressAddress (Address),
1437 StartBit,
1438 EndBit,
1439 AndData,
1440 OrData
1441 );
1442 }
1443
1444 /**
1445 Reads a range of PCI configuration registers into a caller supplied buffer.
1446
1447 Reads the range of PCI configuration registers specified by StartAddress and
1448 Size into the buffer specified by Buffer. This function only allows the PCI
1449 configuration registers from a single PCI function to be read. Size is
1450 returned. When possible 32-bit PCI configuration read cycles are used to read
1451 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1452 and 16-bit PCI configuration read cycles may be used at the beginning and the
1453 end of the range.
1454
1455 If StartAddress > 0x0FFFFFFF, then ASSERT().
1456 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1457 If Size > 0 and Buffer is NULL, then ASSERT().
1458
1459 @param StartAddress Starting address that encodes the PCI Bus, Device,
1460 Function and Register.
1461 @param Size Size in bytes of the transfer.
1462 @param Buffer Pointer to a buffer receiving the data read.
1463
1464 @return Size read data from StartAddress.
1465
1466 **/
1467 UINTN
1468 EFIAPI
1469 PciExpressReadBuffer (
1470 IN UINTN StartAddress,
1471 IN UINTN Size,
1472 OUT VOID *Buffer
1473 )
1474 {
1475 UINTN ReturnValue;
1476
1477 //
1478 // Make sure Address is valid
1479 //
1480 ASSERT (((StartAddress) & ~0xfffffff) == 0);
1481 ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);
1482
1483 if (Size == 0) {
1484 return Size;
1485 }
1486
1487 ASSERT (Buffer != NULL);
1488
1489 //
1490 // Save Size for return
1491 //
1492 ReturnValue = Size;
1493
1494 if ((StartAddress & 1) != 0) {
1495 //
1496 // Read a byte if StartAddress is byte aligned
1497 //
1498 *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress);
1499 StartAddress += sizeof (UINT8);
1500 Size -= sizeof (UINT8);
1501 Buffer = (UINT8*)Buffer + 1;
1502 }
1503
1504 if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {
1505 //
1506 // Read a word if StartAddress is word aligned
1507 //
1508 WriteUnaligned16 ((UINT16 *) Buffer, (UINT16) PciExpressRead16 (StartAddress));
1509
1510 StartAddress += sizeof (UINT16);
1511 Size -= sizeof (UINT16);
1512 Buffer = (UINT16*)Buffer + 1;
1513 }
1514
1515 while (Size >= sizeof (UINT32)) {
1516 //
1517 // Read as many double words as possible
1518 //
1519 WriteUnaligned32 ((UINT32 *) Buffer, (UINT32) PciExpressRead32 (StartAddress));
1520
1521 StartAddress += sizeof (UINT32);
1522 Size -= sizeof (UINT32);
1523 Buffer = (UINT32*)Buffer + 1;
1524 }
1525
1526 if (Size >= sizeof (UINT16)) {
1527 //
1528 // Read the last remaining word if exist
1529 //
1530 WriteUnaligned16 ((UINT16 *) Buffer, (UINT16) PciExpressRead16 (StartAddress));
1531 StartAddress += sizeof (UINT16);
1532 Size -= sizeof (UINT16);
1533 Buffer = (UINT16*)Buffer + 1;
1534 }
1535
1536 if (Size >= sizeof (UINT8)) {
1537 //
1538 // Read the last remaining byte if exist
1539 //
1540 *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress);
1541 }
1542
1543 return ReturnValue;
1544 }
1545
1546 /**
1547 Copies the data in a caller supplied buffer to a specified range of PCI
1548 configuration space.
1549
1550 Writes the range of PCI configuration registers specified by StartAddress and
1551 Size from the buffer specified by Buffer. This function only allows the PCI
1552 configuration registers from a single PCI function to be written. Size is
1553 returned. When possible 32-bit PCI configuration write cycles are used to
1554 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1555 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1556 and the end of the range.
1557
1558 If StartAddress > 0x0FFFFFFF, then ASSERT().
1559 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1560 If Size > 0 and Buffer is NULL, then ASSERT().
1561
1562 @param StartAddress Starting address that encodes the PCI Bus, Device,
1563 Function and Register.
1564 @param Size Size in bytes of the transfer.
1565 @param Buffer Pointer to a buffer containing the data to write.
1566
1567 @return Size written to StartAddress.
1568
1569 **/
1570 UINTN
1571 EFIAPI
1572 PciExpressWriteBuffer (
1573 IN UINTN StartAddress,
1574 IN UINTN Size,
1575 IN VOID *Buffer
1576 )
1577 {
1578 UINTN ReturnValue;
1579
1580 //
1581 // Make sure Address is valid
1582 //
1583 ASSERT (((StartAddress) & ~0xfffffff) == 0);
1584 ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);
1585
1586 if (Size == 0) {
1587 return 0;
1588 }
1589
1590 ASSERT (Buffer != NULL);
1591
1592 //
1593 // Save Size for return
1594 //
1595 ReturnValue = Size;
1596
1597 if ((StartAddress & 1) != 0) {
1598 //
1599 // Write a byte if StartAddress is byte aligned
1600 //
1601 PciExpressWrite8 (StartAddress, *(UINT8*)Buffer);
1602 StartAddress += sizeof (UINT8);
1603 Size -= sizeof (UINT8);
1604 Buffer = (UINT8*)Buffer + 1;
1605 }
1606
1607 if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {
1608 //
1609 // Write a word if StartAddress is word aligned
1610 //
1611 PciExpressWrite16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer));
1612 StartAddress += sizeof (UINT16);
1613 Size -= sizeof (UINT16);
1614 Buffer = (UINT16*)Buffer + 1;
1615 }
1616
1617 while (Size >= sizeof (UINT32)) {
1618 //
1619 // Write as many double words as possible
1620 //
1621 PciExpressWrite32 (StartAddress, ReadUnaligned32 ((UINT32*)Buffer));
1622 StartAddress += sizeof (UINT32);
1623 Size -= sizeof (UINT32);
1624 Buffer = (UINT32*)Buffer + 1;
1625 }
1626
1627 if (Size >= sizeof (UINT16)) {
1628 //
1629 // Write the last remaining word if exist
1630 //
1631 PciExpressWrite16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer));
1632 StartAddress += sizeof (UINT16);
1633 Size -= sizeof (UINT16);
1634 Buffer = (UINT16*)Buffer + 1;
1635 }
1636
1637 if (Size >= sizeof (UINT8)) {
1638 //
1639 // Write the last remaining byte if exist
1640 //
1641 PciExpressWrite8 (StartAddress, *(UINT8*)Buffer);
1642 }
1643
1644 return ReturnValue;
1645 }