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