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