2 Produces the CPU I/O PPI.
4 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
5 Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
7 SPDX-License-Identifier: BSD-2-Clause-Patent
14 // Instance of CPU I/O PPI
16 EFI_PEI_CPU_IO_PPI gCpuIoPpi
= {
44 // PPI Descriptor used to install the CPU I/O PPI
46 EFI_PEI_PPI_DESCRIPTOR gPpiList
= {
47 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
48 &gEfiPeiCpuIoPpiInstalledGuid
,
53 // Lookup table for increment values based on transfer widths
56 1, // EfiPeiCpuIoWidthUint8
57 2, // EfiPeiCpuIoWidthUint16
58 4, // EfiPeiCpuIoWidthUint32
59 8, // EfiPeiCpuIoWidthUint64
60 0, // EfiPeiCpuIoWidthFifoUint8
61 0, // EfiPeiCpuIoWidthFifoUint16
62 0, // EfiPeiCpuIoWidthFifoUint32
63 0, // EfiPeiCpuIoWidthFifoUint64
64 1, // EfiPeiCpuIoWidthFillUint8
65 2, // EfiPeiCpuIoWidthFillUint16
66 4, // EfiPeiCpuIoWidthFillUint32
67 8 // EfiPeiCpuIoWidthFillUint64
71 // Lookup table for increment values based on transfer widths
73 UINT8 mOutStride
[] = {
74 1, // EfiPeiCpuIoWidthUint8
75 2, // EfiPeiCpuIoWidthUint16
76 4, // EfiPeiCpuIoWidthUint32
77 8, // EfiPeiCpuIoWidthUint64
78 1, // EfiPeiCpuIoWidthFifoUint8
79 2, // EfiPeiCpuIoWidthFifoUint16
80 4, // EfiPeiCpuIoWidthFifoUint32
81 8, // EfiPeiCpuIoWidthFifoUint64
82 0, // EfiPeiCpuIoWidthFillUint8
83 0, // EfiPeiCpuIoWidthFillUint16
84 0, // EfiPeiCpuIoWidthFillUint32
85 0 // EfiPeiCpuIoWidthFillUint64
89 Check parameters to a CPU I/O PPI service request.
91 @param[in] MmioOperation TRUE for an MMIO operation, FALSE for I/O Port operation.
92 @param[in] Width The width of the access. Enumerated in bytes.
93 @param[in] Address The physical address of the access.
94 @param[in] Count The number of accesses to perform.
95 @param[in] Buffer A pointer to the buffer of data.
97 @retval EFI_SUCCESS The parameters for this request pass the checks.
98 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system.
99 @retval EFI_INVALID_PARAMETER Buffer is NULL.
100 @retval EFI_UNSUPPORTED The address range specified by Address, Width,
101 and Count is not valid for this EFI system.
105 CpuIoCheckParameter (
106 IN BOOLEAN MmioOperation
,
107 IN EFI_PEI_CPU_IO_PPI_WIDTH Width
,
117 // Check to see if Buffer is NULL
119 if (Buffer
== NULL
) {
120 return EFI_INVALID_PARAMETER
;
124 // Check to see if Width is in the valid range
126 if ((UINT32
)Width
>= EfiPeiCpuIoWidthMaximum
) {
127 return EFI_INVALID_PARAMETER
;
131 // For FIFO type, the target address won't increase during the access,
132 // so treat Count as 1
134 if ((Width
>= EfiPeiCpuIoWidthFifoUint8
) && (Width
<= EfiPeiCpuIoWidthFifoUint64
)) {
139 // Check to see if Width is in the valid range for I/O Port operations
141 Width
= (EFI_PEI_CPU_IO_PPI_WIDTH
)(Width
& 0x03);
142 if (!MmioOperation
&& (Width
== EfiPeiCpuIoWidthUint64
)) {
143 return EFI_INVALID_PARAMETER
;
147 // Check to see if any address associated with this transfer exceeds the maximum
148 // allowed address. The maximum address implied by the parameters passed in is
149 // Address + Size * Count. If the following condition is met, then the transfer
152 // Address + Size * Count > (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS) + 1
154 // Since MAX_ADDRESS can be the maximum integer value supported by the CPU and Count
155 // can also be the maximum integer value supported by the CPU, this range
156 // check must be adjusted to avoid all overflow conditions.
158 // The following form of the range check is equivalent but assumes that
159 // MAX_ADDRESS and MAX_IO_PORT_ADDRESS are of the form (2^n - 1).
161 Limit
= (MmioOperation
? MAX_ADDRESS
: MAX_IO_PORT_ADDRESS
);
163 if (Address
> Limit
) {
164 return EFI_UNSUPPORTED
;
167 MaxCount
= RShiftU64 (Limit
, Width
);
168 if (MaxCount
< (Count
- 1)) {
169 return EFI_UNSUPPORTED
;
172 if (Address
> LShiftU64 (MaxCount
- Count
+ 1, Width
)) {
173 return EFI_UNSUPPORTED
;
181 Reads memory-mapped registers.
183 @param[in] PeiServices An indirect pointer to the PEI Services Table
184 published by the PEI Foundation.
185 @param[in] This Pointer to local data for the interface.
186 @param[in] Width The width of the access. Enumerated in bytes.
187 @param[in] Address The physical address of the access.
188 @param[in] Count The number of accesses to perform.
189 @param[out] Buffer A pointer to the buffer of data.
191 @retval EFI_SUCCESS The function completed successfully.
192 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system.
193 @retval EFI_INVALID_PARAMETER Buffer is NULL.
194 @retval EFI_UNSUPPORTED The address range specified by Address, Width,
195 and Count is not valid for this EFI system.
200 CpuMemoryServiceRead (
201 IN CONST EFI_PEI_SERVICES
**PeiServices
,
202 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
203 IN EFI_PEI_CPU_IO_PPI_WIDTH Width
,
212 EFI_PEI_CPU_IO_PPI_WIDTH OperationWidth
;
216 Status
= CpuIoCheckParameter (TRUE
, Width
, Address
, Count
, Buffer
);
217 if (EFI_ERROR (Status
)) {
222 // Select loop based on the width of the transfer
224 InStride
= mInStride
[Width
];
225 OutStride
= mOutStride
[Width
];
226 OperationWidth
= (EFI_PEI_CPU_IO_PPI_WIDTH
)(Width
& 0x03);
227 Aligned
= (BOOLEAN
)(((UINTN
)Buffer
& (mInStride
[OperationWidth
] - 1)) == 0x00);
228 for (Uint8Buffer
= Buffer
; Count
> 0; Address
+= InStride
, Uint8Buffer
+= OutStride
, Count
--) {
229 if (OperationWidth
== EfiPeiCpuIoWidthUint8
) {
230 *Uint8Buffer
= MmioRead8 ((UINTN
)Address
);
231 } else if (OperationWidth
== EfiPeiCpuIoWidthUint16
) {
233 *((UINT16
*)Uint8Buffer
) = MmioRead16 ((UINTN
)Address
);
235 WriteUnaligned16 ((UINT16
*)Uint8Buffer
, MmioRead16 ((UINTN
)Address
));
237 } else if (OperationWidth
== EfiPeiCpuIoWidthUint32
) {
239 *((UINT32
*)Uint8Buffer
) = MmioRead32 ((UINTN
)Address
);
241 WriteUnaligned32 ((UINT32
*)Uint8Buffer
, MmioRead32 ((UINTN
)Address
));
243 } else if (OperationWidth
== EfiPeiCpuIoWidthUint64
) {
245 *((UINT64
*)Uint8Buffer
) = MmioRead64 ((UINTN
)Address
);
247 WriteUnaligned64 ((UINT64
*)Uint8Buffer
, MmioRead64 ((UINTN
)Address
));
256 Writes memory-mapped registers.
258 @param[in] PeiServices An indirect pointer to the PEI Services Table
259 published by the PEI Foundation.
260 @param[in] This Pointer to local data for the interface.
261 @param[in] Width The width of the access. Enumerated in bytes.
262 @param[in] Address The physical address of the access.
263 @param[in] Count The number of accesses to perform.
264 @param[in] Buffer A pointer to the buffer of data.
266 @retval EFI_SUCCESS The function completed successfully.
267 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system.
268 @retval EFI_INVALID_PARAMETER Buffer is NULL.
269 @retval EFI_UNSUPPORTED The address range specified by Address, Width,
270 and Count is not valid for this EFI system.
275 CpuMemoryServiceWrite (
276 IN CONST EFI_PEI_SERVICES
**PeiServices
,
277 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
278 IN EFI_PEI_CPU_IO_PPI_WIDTH Width
,
287 EFI_PEI_CPU_IO_PPI_WIDTH OperationWidth
;
291 Status
= CpuIoCheckParameter (TRUE
, Width
, Address
, Count
, Buffer
);
292 if (EFI_ERROR (Status
)) {
297 // Select loop based on the width of the transfer
299 InStride
= mInStride
[Width
];
300 OutStride
= mOutStride
[Width
];
301 OperationWidth
= (EFI_PEI_CPU_IO_PPI_WIDTH
)(Width
& 0x03);
302 Aligned
= (BOOLEAN
)(((UINTN
)Buffer
& (mInStride
[OperationWidth
] - 1)) == 0x00);
303 for (Uint8Buffer
= Buffer
; Count
> 0; Address
+= InStride
, Uint8Buffer
+= OutStride
, Count
--) {
304 if (OperationWidth
== EfiPeiCpuIoWidthUint8
) {
305 MmioWrite8 ((UINTN
)Address
, *Uint8Buffer
);
306 } else if (OperationWidth
== EfiPeiCpuIoWidthUint16
) {
308 MmioWrite16 ((UINTN
)Address
, *((UINT16
*)Uint8Buffer
));
310 MmioWrite16 ((UINTN
)Address
, ReadUnaligned16 ((UINT16
*)Uint8Buffer
));
312 } else if (OperationWidth
== EfiPeiCpuIoWidthUint32
) {
314 MmioWrite32 ((UINTN
)Address
, *((UINT32
*)Uint8Buffer
));
316 MmioWrite32 ((UINTN
)Address
, ReadUnaligned32 ((UINT32
*)Uint8Buffer
));
318 } else if (OperationWidth
== EfiPeiCpuIoWidthUint64
) {
320 MmioWrite64 ((UINTN
)Address
, *((UINT64
*)Uint8Buffer
));
322 MmioWrite64 ((UINTN
)Address
, ReadUnaligned64 ((UINT64
*)Uint8Buffer
));
333 @param[in] PeiServices An indirect pointer to the PEI Services Table
334 published by the PEI Foundation.
335 @param[in] This Pointer to local data for the interface.
336 @param[in] Width The width of the access. Enumerated in bytes.
337 @param[in] Address The physical address of the access.
338 @param[in] Count The number of accesses to perform.
339 @param[out] Buffer A pointer to the buffer of data.
341 @retval EFI_SUCCESS The function completed successfully.
342 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system.
343 @retval EFI_INVALID_PARAMETER Buffer is NULL.
344 @retval EFI_UNSUPPORTED The address range specified by Address, Width,
345 and Count is not valid for this EFI system.
351 IN CONST EFI_PEI_SERVICES
**PeiServices
,
352 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
353 IN EFI_PEI_CPU_IO_PPI_WIDTH Width
,
362 EFI_PEI_CPU_IO_PPI_WIDTH OperationWidth
;
366 Status
= CpuIoCheckParameter (FALSE
, Width
, Address
, Count
, Buffer
);
367 if (EFI_ERROR (Status
)) {
372 // Select loop based on the width of the transfer
374 InStride
= mInStride
[Width
];
375 OutStride
= mOutStride
[Width
];
376 OperationWidth
= (EFI_PEI_CPU_IO_PPI_WIDTH
)(Width
& 0x03);
379 // Fifo operations supported for (mInStride[Width] == 0)
382 switch (OperationWidth
) {
383 case EfiPeiCpuIoWidthUint8
:
384 IoReadFifo8 ((UINTN
)Address
, Count
, Buffer
);
386 case EfiPeiCpuIoWidthUint16
:
387 IoReadFifo16 ((UINTN
)Address
, Count
, Buffer
);
389 case EfiPeiCpuIoWidthUint32
:
390 IoReadFifo32 ((UINTN
)Address
, Count
, Buffer
);
394 // The CpuIoCheckParameter call above will ensure that this
395 // path is not taken.
402 Aligned
= (BOOLEAN
)(((UINTN
)Buffer
& (mInStride
[OperationWidth
] - 1)) == 0x00);
403 for (Uint8Buffer
= Buffer
; Count
> 0; Address
+= InStride
, Uint8Buffer
+= OutStride
, Count
--) {
404 if (OperationWidth
== EfiPeiCpuIoWidthUint8
) {
405 *Uint8Buffer
= IoRead8 ((UINTN
)Address
);
406 } else if (OperationWidth
== EfiPeiCpuIoWidthUint16
) {
408 *((UINT16
*)Uint8Buffer
) = IoRead16 ((UINTN
)Address
);
410 WriteUnaligned16 ((UINT16
*)Uint8Buffer
, IoRead16 ((UINTN
)Address
));
412 } else if (OperationWidth
== EfiPeiCpuIoWidthUint32
) {
414 *((UINT32
*)Uint8Buffer
) = IoRead32 ((UINTN
)Address
);
416 WriteUnaligned32 ((UINT32
*)Uint8Buffer
, IoRead32 ((UINTN
)Address
));
427 @param[in] PeiServices An indirect pointer to the PEI Services Table
428 published by the PEI Foundation.
429 @param[in] This Pointer to local data for the interface.
430 @param[in] Width The width of the access. Enumerated in bytes.
431 @param[in] Address The physical address of the access.
432 @param[in] Count The number of accesses to perform.
433 @param[in] Buffer A pointer to the buffer of data.
435 @retval EFI_SUCCESS The function completed successfully.
436 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system.
437 @retval EFI_INVALID_PARAMETER Buffer is NULL.
438 @retval EFI_UNSUPPORTED The address range specified by Address, Width,
439 and Count is not valid for this EFI system.
445 IN CONST EFI_PEI_SERVICES
**PeiServices
,
446 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
447 IN EFI_PEI_CPU_IO_PPI_WIDTH Width
,
456 EFI_PEI_CPU_IO_PPI_WIDTH OperationWidth
;
461 // Make sure the parameters are valid
463 Status
= CpuIoCheckParameter (FALSE
, Width
, Address
, Count
, Buffer
);
464 if (EFI_ERROR (Status
)) {
469 // Select loop based on the width of the transfer
471 InStride
= mInStride
[Width
];
472 OutStride
= mOutStride
[Width
];
473 OperationWidth
= (EFI_PEI_CPU_IO_PPI_WIDTH
)(Width
& 0x03);
476 // Fifo operations supported for (mInStride[Width] == 0)
479 switch (OperationWidth
) {
480 case EfiPeiCpuIoWidthUint8
:
481 IoWriteFifo8 ((UINTN
)Address
, Count
, Buffer
);
483 case EfiPeiCpuIoWidthUint16
:
484 IoWriteFifo16 ((UINTN
)Address
, Count
, Buffer
);
486 case EfiPeiCpuIoWidthUint32
:
487 IoWriteFifo32 ((UINTN
)Address
, Count
, Buffer
);
491 // The CpuIoCheckParameter call above will ensure that this
492 // path is not taken.
499 Aligned
= (BOOLEAN
)(((UINTN
)Buffer
& (mInStride
[OperationWidth
] - 1)) == 0x00);
500 for (Uint8Buffer
= (UINT8
*)Buffer
; Count
> 0; Address
+= InStride
, Uint8Buffer
+= OutStride
, Count
--) {
501 if (OperationWidth
== EfiPeiCpuIoWidthUint8
) {
502 IoWrite8 ((UINTN
)Address
, *Uint8Buffer
);
503 } else if (OperationWidth
== EfiPeiCpuIoWidthUint16
) {
505 IoWrite16 ((UINTN
)Address
, *((UINT16
*)Uint8Buffer
));
507 IoWrite16 ((UINTN
)Address
, ReadUnaligned16 ((UINT16
*)Uint8Buffer
));
509 } else if (OperationWidth
== EfiPeiCpuIoWidthUint32
) {
511 IoWrite32 ((UINTN
)Address
, *((UINT32
*)Uint8Buffer
));
513 IoWrite32 ((UINTN
)Address
, ReadUnaligned32 ((UINT32
*)Uint8Buffer
));
522 8-bit I/O read operations.
524 @param[in] PeiServices An indirect pointer to the PEI Services Table published
525 by the PEI Foundation.
526 @param[in] This Pointer to local data for the interface.
527 @param[in] Address The physical address of the access.
529 @return An 8-bit value returned from the I/O space.
534 IN CONST EFI_PEI_SERVICES
**PeiServices
,
535 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
539 return IoRead8 ((UINTN
)Address
);
543 16-bit I/O read operations.
545 @param[in] PeiServices An indirect pointer to the PEI Services Table published
546 by the PEI Foundation.
547 @param[in] This Pointer to local data for the interface.
548 @param[in] Address The physical address of the access.
550 @return A 16-bit value returned from the I/O space.
556 IN CONST EFI_PEI_SERVICES
**PeiServices
,
557 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
561 return IoRead16 ((UINTN
)Address
);
565 32-bit I/O read operations.
567 @param[in] PeiServices An indirect pointer to the PEI Services Table published
568 by the PEI Foundation.
569 @param[in] This Pointer to local data for the interface.
570 @param[in] Address The physical address of the access.
572 @return A 32-bit value returned from the I/O space.
578 IN CONST EFI_PEI_SERVICES
**PeiServices
,
579 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
583 return IoRead32 ((UINTN
)Address
);
587 64-bit I/O read operations.
589 @param[in] PeiServices An indirect pointer to the PEI Services Table published
590 by the PEI Foundation.
591 @param[in] This Pointer to local data for the interface.
592 @param[in] Address The physical address of the access.
594 @return A 64-bit value returned from the I/O space.
600 IN CONST EFI_PEI_SERVICES
**PeiServices
,
601 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
605 return IoRead64 ((UINTN
)Address
);
609 8-bit I/O write operations.
611 @param[in] PeiServices An indirect pointer to the PEI Services Table published
612 by the PEI Foundation.
613 @param[in] This Pointer to local data for the interface.
614 @param[in] Address The physical address of the access.
615 @param[in] Data The data to write.
621 IN CONST EFI_PEI_SERVICES
**PeiServices
,
622 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
627 IoWrite8 ((UINTN
)Address
, Data
);
631 16-bit I/O write operations.
633 @param[in] PeiServices An indirect pointer to the PEI Services Table published
634 by the PEI Foundation.
635 @param[in] This Pointer to local data for the interface.
636 @param[in] Address The physical address of the access.
637 @param[in] Data The data to write.
643 IN CONST EFI_PEI_SERVICES
**PeiServices
,
644 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
649 IoWrite16 ((UINTN
)Address
, Data
);
653 32-bit I/O write operations.
655 @param[in] PeiServices An indirect pointer to the PEI Services Table published
656 by the PEI Foundation.
657 @param[in] This Pointer to local data for the interface.
658 @param[in] Address The physical address of the access.
659 @param[in] Data The data to write.
665 IN CONST EFI_PEI_SERVICES
**PeiServices
,
666 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
671 IoWrite32 ((UINTN
)Address
, Data
);
675 64-bit I/O write operations.
677 @param[in] PeiServices An indirect pointer to the PEI Services Table published
678 by the PEI Foundation.
679 @param[in] This Pointer to local data for the interface.
680 @param[in] Address The physical address of the access.
681 @param[in] Data The data to write.
687 IN CONST EFI_PEI_SERVICES
**PeiServices
,
688 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
693 IoWrite64 ((UINTN
)Address
, Data
);
697 8-bit memory read operations.
699 @param[in] PeiServices An indirect pointer to the PEI Services Table published
700 by the PEI Foundation.
701 @param[in] This Pointer to local data for the interface.
702 @param[in] Address The physical address of the access.
704 @return An 8-bit value returned from the memory space.
710 IN CONST EFI_PEI_SERVICES
**PeiServices
,
711 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
715 return MmioRead8 ((UINTN
)Address
);
719 16-bit memory read operations.
721 @param[in] PeiServices An indirect pointer to the PEI Services Table published
722 by the PEI Foundation.
723 @param[in] This Pointer to local data for the interface.
724 @param[in] Address The physical address of the access.
726 @return A 16-bit value returned from the memory space.
732 IN CONST EFI_PEI_SERVICES
**PeiServices
,
733 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
737 return MmioRead16 ((UINTN
)Address
);
741 32-bit memory read operations.
743 @param[in] PeiServices An indirect pointer to the PEI Services Table published
744 by the PEI Foundation.
745 @param[in] This Pointer to local data for the interface.
746 @param[in] Address The physical address of the access.
748 @return A 32-bit value returned from the memory space.
754 IN CONST EFI_PEI_SERVICES
**PeiServices
,
755 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
759 return MmioRead32 ((UINTN
)Address
);
763 64-bit memory read operations.
765 @param[in] PeiServices An indirect pointer to the PEI Services Table published
766 by the PEI Foundation.
767 @param[in] This Pointer to local data for the interface.
768 @param[in] Address The physical address of the access.
770 @return A 64-bit value returned from the memory space.
776 IN CONST EFI_PEI_SERVICES
**PeiServices
,
777 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
781 return MmioRead64 ((UINTN
)Address
);
785 8-bit memory write operations.
787 @param[in] PeiServices An indirect pointer to the PEI Services Table published
788 by the PEI Foundation.
789 @param[in] This Pointer to local data for the interface.
790 @param[in] Address The physical address of the access.
791 @param[in] Data The data to write.
797 IN CONST EFI_PEI_SERVICES
**PeiServices
,
798 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
803 MmioWrite8 ((UINTN
)Address
, Data
);
807 16-bit memory write operations.
809 @param[in] PeiServices An indirect pointer to the PEI Services Table published
810 by the PEI Foundation.
811 @param[in] This Pointer to local data for the interface.
812 @param[in] Address The physical address of the access.
813 @param[in] Data The data to write.
819 IN CONST EFI_PEI_SERVICES
**PeiServices
,
820 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
825 MmioWrite16 ((UINTN
)Address
, Data
);
829 32-bit memory write operations.
831 @param[in] PeiServices An indirect pointer to the PEI Services Table published
832 by the PEI Foundation.
833 @param[in] This Pointer to local data for the interface.
834 @param[in] Address The physical address of the access.
835 @param[in] Data The data to write.
841 IN CONST EFI_PEI_SERVICES
**PeiServices
,
842 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
847 MmioWrite32 ((UINTN
)Address
, Data
);
851 64-bit memory write operations.
853 @param[in] PeiServices An indirect pointer to the PEI Services Table published
854 by the PEI Foundation.
855 @param[in] This Pointer to local data for the interface.
856 @param[in] Address The physical address of the access.
857 @param[in] Data The data to write.
863 IN CONST EFI_PEI_SERVICES
**PeiServices
,
864 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
869 MmioWrite64 ((UINTN
)Address
, Data
);
873 The Entry point of the CPU I/O PEIM
875 This function is the Entry point of the CPU I/O PEIM which installs CpuIoPpi.
877 @param[in] FileHandle Pointer to image file handle.
878 @param[in] PeiServices Pointer to PEI Services Table
880 @retval EFI_SUCCESS CPU I/O PPI successfully installed
886 IN EFI_PEI_FILE_HANDLE FileHandle
,
887 IN CONST EFI_PEI_SERVICES
**PeiServices
893 // Register so it will be automatically shadowed to memory
895 Status
= PeiServicesRegisterForShadow (FileHandle
);
898 // Make CpuIo pointer in PeiService table point to gCpuIoPpi
900 (*((EFI_PEI_SERVICES
**)PeiServices
))->CpuIo
= &gCpuIoPpi
;
902 if (Status
== EFI_ALREADY_STARTED
) {
904 // Shadow completed and running from memory
906 DEBUG ((DEBUG_INFO
, "CpuIO PPI has been loaded into memory. Reinstalled PPI=0x%x\n", &gCpuIoPpi
));
908 Status
= PeiServicesInstallPpi (&gPpiList
);
909 ASSERT_EFI_ERROR (Status
);