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
;
171 if (Address
> LShiftU64 (MaxCount
- Count
+ 1, Width
)) {
172 return EFI_UNSUPPORTED
;
180 Reads memory-mapped registers.
182 @param[in] PeiServices An indirect pointer to the PEI Services Table
183 published by the PEI Foundation.
184 @param[in] This Pointer to local data for the interface.
185 @param[in] Width The width of the access. Enumerated in bytes.
186 @param[in] Address The physical address of the access.
187 @param[in] Count The number of accesses to perform.
188 @param[out] Buffer A pointer to the buffer of data.
190 @retval EFI_SUCCESS The function completed successfully.
191 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system.
192 @retval EFI_INVALID_PARAMETER Buffer is NULL.
193 @retval EFI_UNSUPPORTED The address range specified by Address, Width,
194 and Count is not valid for this EFI system.
199 CpuMemoryServiceRead (
200 IN CONST EFI_PEI_SERVICES
**PeiServices
,
201 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
202 IN EFI_PEI_CPU_IO_PPI_WIDTH Width
,
211 EFI_PEI_CPU_IO_PPI_WIDTH OperationWidth
;
215 Status
= CpuIoCheckParameter (TRUE
, Width
, Address
, Count
, Buffer
);
216 if (EFI_ERROR (Status
)) {
221 // Select loop based on the width of the transfer
223 InStride
= mInStride
[Width
];
224 OutStride
= mOutStride
[Width
];
225 OperationWidth
= (EFI_PEI_CPU_IO_PPI_WIDTH
) (Width
& 0x03);
226 Aligned
= (BOOLEAN
)(((UINTN
)Buffer
& (mInStride
[OperationWidth
] - 1)) == 0x00);
227 for (Uint8Buffer
= Buffer
; Count
> 0; Address
+= InStride
, Uint8Buffer
+= OutStride
, Count
--) {
228 if (OperationWidth
== EfiPeiCpuIoWidthUint8
) {
229 *Uint8Buffer
= MmioRead8 ((UINTN
)Address
);
230 } else if (OperationWidth
== EfiPeiCpuIoWidthUint16
) {
232 *((UINT16
*)Uint8Buffer
) = MmioRead16 ((UINTN
)Address
);
234 WriteUnaligned16 ((UINT16
*)Uint8Buffer
, MmioRead16 ((UINTN
)Address
));
236 } else if (OperationWidth
== EfiPeiCpuIoWidthUint32
) {
238 *((UINT32
*)Uint8Buffer
) = MmioRead32 ((UINTN
)Address
);
240 WriteUnaligned32 ((UINT32
*)Uint8Buffer
, MmioRead32 ((UINTN
)Address
));
242 } else if (OperationWidth
== EfiPeiCpuIoWidthUint64
) {
244 *((UINT64
*)Uint8Buffer
) = MmioRead64 ((UINTN
)Address
);
246 WriteUnaligned64 ((UINT64
*)Uint8Buffer
, MmioRead64 ((UINTN
)Address
));
254 Writes memory-mapped registers.
256 @param[in] PeiServices An indirect pointer to the PEI Services Table
257 published by the PEI Foundation.
258 @param[in] This Pointer to local data for the interface.
259 @param[in] Width The width of the access. Enumerated in bytes.
260 @param[in] Address The physical address of the access.
261 @param[in] Count The number of accesses to perform.
262 @param[in] Buffer A pointer to the buffer of data.
264 @retval EFI_SUCCESS The function completed successfully.
265 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system.
266 @retval EFI_INVALID_PARAMETER Buffer is NULL.
267 @retval EFI_UNSUPPORTED The address range specified by Address, Width,
268 and Count is not valid for this EFI system.
273 CpuMemoryServiceWrite (
274 IN CONST EFI_PEI_SERVICES
**PeiServices
,
275 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
276 IN EFI_PEI_CPU_IO_PPI_WIDTH Width
,
285 EFI_PEI_CPU_IO_PPI_WIDTH OperationWidth
;
289 Status
= CpuIoCheckParameter (TRUE
, Width
, Address
, Count
, Buffer
);
290 if (EFI_ERROR (Status
)) {
295 // Select loop based on the width of the transfer
297 InStride
= mInStride
[Width
];
298 OutStride
= mOutStride
[Width
];
299 OperationWidth
= (EFI_PEI_CPU_IO_PPI_WIDTH
) (Width
& 0x03);
300 Aligned
= (BOOLEAN
)(((UINTN
)Buffer
& (mInStride
[OperationWidth
] - 1)) == 0x00);
301 for (Uint8Buffer
= Buffer
; Count
> 0; Address
+= InStride
, Uint8Buffer
+= OutStride
, Count
--) {
302 if (OperationWidth
== EfiPeiCpuIoWidthUint8
) {
303 MmioWrite8 ((UINTN
)Address
, *Uint8Buffer
);
304 } else if (OperationWidth
== EfiPeiCpuIoWidthUint16
) {
306 MmioWrite16 ((UINTN
)Address
, *((UINT16
*)Uint8Buffer
));
308 MmioWrite16 ((UINTN
)Address
, ReadUnaligned16 ((UINT16
*)Uint8Buffer
));
310 } else if (OperationWidth
== EfiPeiCpuIoWidthUint32
) {
312 MmioWrite32 ((UINTN
)Address
, *((UINT32
*)Uint8Buffer
));
314 MmioWrite32 ((UINTN
)Address
, ReadUnaligned32 ((UINT32
*)Uint8Buffer
));
316 } else if (OperationWidth
== EfiPeiCpuIoWidthUint64
) {
318 MmioWrite64 ((UINTN
)Address
, *((UINT64
*)Uint8Buffer
));
320 MmioWrite64 ((UINTN
)Address
, ReadUnaligned64 ((UINT64
*)Uint8Buffer
));
330 @param[in] PeiServices An indirect pointer to the PEI Services Table
331 published by the PEI Foundation.
332 @param[in] This Pointer to local data for the interface.
333 @param[in] Width The width of the access. Enumerated in bytes.
334 @param[in] Address The physical address of the access.
335 @param[in] Count The number of accesses to perform.
336 @param[out] Buffer A pointer to the buffer of data.
338 @retval EFI_SUCCESS The function completed successfully.
339 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system.
340 @retval EFI_INVALID_PARAMETER Buffer is NULL.
341 @retval EFI_UNSUPPORTED The address range specified by Address, Width,
342 and Count is not valid for this EFI system.
348 IN CONST EFI_PEI_SERVICES
**PeiServices
,
349 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
350 IN EFI_PEI_CPU_IO_PPI_WIDTH Width
,
359 EFI_PEI_CPU_IO_PPI_WIDTH OperationWidth
;
363 Status
= CpuIoCheckParameter (FALSE
, Width
, Address
, Count
, Buffer
);
364 if (EFI_ERROR (Status
)) {
369 // Select loop based on the width of the transfer
371 InStride
= mInStride
[Width
];
372 OutStride
= mOutStride
[Width
];
373 OperationWidth
= (EFI_PEI_CPU_IO_PPI_WIDTH
) (Width
& 0x03);
376 // Fifo operations supported for (mInStride[Width] == 0)
379 switch (OperationWidth
) {
380 case EfiPeiCpuIoWidthUint8
:
381 IoReadFifo8 ((UINTN
)Address
, Count
, Buffer
);
383 case EfiPeiCpuIoWidthUint16
:
384 IoReadFifo16 ((UINTN
)Address
, Count
, Buffer
);
386 case EfiPeiCpuIoWidthUint32
:
387 IoReadFifo32 ((UINTN
)Address
, Count
, Buffer
);
391 // The CpuIoCheckParameter call above will ensure that this
392 // path is not taken.
399 Aligned
= (BOOLEAN
)(((UINTN
)Buffer
& (mInStride
[OperationWidth
] - 1)) == 0x00);
400 for (Uint8Buffer
= Buffer
; Count
> 0; Address
+= InStride
, Uint8Buffer
+= OutStride
, Count
--) {
401 if (OperationWidth
== EfiPeiCpuIoWidthUint8
) {
402 *Uint8Buffer
= IoRead8 ((UINTN
)Address
);
403 } else if (OperationWidth
== EfiPeiCpuIoWidthUint16
) {
405 *((UINT16
*)Uint8Buffer
) = IoRead16 ((UINTN
)Address
);
407 WriteUnaligned16 ((UINT16
*)Uint8Buffer
, IoRead16 ((UINTN
)Address
));
409 } else if (OperationWidth
== EfiPeiCpuIoWidthUint32
) {
411 *((UINT32
*)Uint8Buffer
) = IoRead32 ((UINTN
)Address
);
413 WriteUnaligned32 ((UINT32
*)Uint8Buffer
, IoRead32 ((UINTN
)Address
));
424 @param[in] PeiServices An indirect pointer to the PEI Services Table
425 published by the PEI Foundation.
426 @param[in] This Pointer to local data for the interface.
427 @param[in] Width The width of the access. Enumerated in bytes.
428 @param[in] Address The physical address of the access.
429 @param[in] Count The number of accesses to perform.
430 @param[in] Buffer A pointer to the buffer of data.
432 @retval EFI_SUCCESS The function completed successfully.
433 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system.
434 @retval EFI_INVALID_PARAMETER Buffer is NULL.
435 @retval EFI_UNSUPPORTED The address range specified by Address, Width,
436 and Count is not valid for this EFI system.
442 IN CONST EFI_PEI_SERVICES
**PeiServices
,
443 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
444 IN EFI_PEI_CPU_IO_PPI_WIDTH Width
,
453 EFI_PEI_CPU_IO_PPI_WIDTH OperationWidth
;
458 // Make sure the parameters are valid
460 Status
= CpuIoCheckParameter (FALSE
, Width
, Address
, Count
, Buffer
);
461 if (EFI_ERROR (Status
)) {
466 // Select loop based on the width of the transfer
468 InStride
= mInStride
[Width
];
469 OutStride
= mOutStride
[Width
];
470 OperationWidth
= (EFI_PEI_CPU_IO_PPI_WIDTH
) (Width
& 0x03);
473 // Fifo operations supported for (mInStride[Width] == 0)
476 switch (OperationWidth
) {
477 case EfiPeiCpuIoWidthUint8
:
478 IoWriteFifo8 ((UINTN
)Address
, Count
, Buffer
);
480 case EfiPeiCpuIoWidthUint16
:
481 IoWriteFifo16 ((UINTN
)Address
, Count
, Buffer
);
483 case EfiPeiCpuIoWidthUint32
:
484 IoWriteFifo32 ((UINTN
)Address
, Count
, Buffer
);
488 // The CpuIoCheckParameter call above will ensure that this
489 // path is not taken.
496 Aligned
= (BOOLEAN
)(((UINTN
)Buffer
& (mInStride
[OperationWidth
] - 1)) == 0x00);
497 for (Uint8Buffer
= (UINT8
*)Buffer
; Count
> 0; Address
+= InStride
, Uint8Buffer
+= OutStride
, Count
--) {
498 if (OperationWidth
== EfiPeiCpuIoWidthUint8
) {
499 IoWrite8 ((UINTN
)Address
, *Uint8Buffer
);
500 } else if (OperationWidth
== EfiPeiCpuIoWidthUint16
) {
502 IoWrite16 ((UINTN
)Address
, *((UINT16
*)Uint8Buffer
));
504 IoWrite16 ((UINTN
)Address
, ReadUnaligned16 ((UINT16
*)Uint8Buffer
));
506 } else if (OperationWidth
== EfiPeiCpuIoWidthUint32
) {
508 IoWrite32 ((UINTN
)Address
, *((UINT32
*)Uint8Buffer
));
510 IoWrite32 ((UINTN
)Address
, ReadUnaligned32 ((UINT32
*)Uint8Buffer
));
519 8-bit I/O read operations.
521 @param[in] PeiServices An indirect pointer to the PEI Services Table published
522 by the PEI Foundation.
523 @param[in] This Pointer to local data for the interface.
524 @param[in] Address The physical address of the access.
526 @return An 8-bit value returned from the I/O space.
531 IN CONST EFI_PEI_SERVICES
**PeiServices
,
532 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
536 return IoRead8 ((UINTN
)Address
);
540 16-bit I/O read operations.
542 @param[in] PeiServices An indirect pointer to the PEI Services Table published
543 by the PEI Foundation.
544 @param[in] This Pointer to local data for the interface.
545 @param[in] Address The physical address of the access.
547 @return A 16-bit value returned from the I/O space.
553 IN CONST EFI_PEI_SERVICES
**PeiServices
,
554 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
558 return IoRead16 ((UINTN
)Address
);
562 32-bit I/O read operations.
564 @param[in] PeiServices An indirect pointer to the PEI Services Table published
565 by the PEI Foundation.
566 @param[in] This Pointer to local data for the interface.
567 @param[in] Address The physical address of the access.
569 @return A 32-bit value returned from the I/O space.
575 IN CONST EFI_PEI_SERVICES
**PeiServices
,
576 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
580 return IoRead32 ((UINTN
)Address
);
584 64-bit I/O read operations.
586 @param[in] PeiServices An indirect pointer to the PEI Services Table published
587 by the PEI Foundation.
588 @param[in] This Pointer to local data for the interface.
589 @param[in] Address The physical address of the access.
591 @return A 64-bit value returned from the I/O space.
597 IN CONST EFI_PEI_SERVICES
**PeiServices
,
598 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
602 return IoRead64 ((UINTN
)Address
);
606 8-bit I/O write operations.
608 @param[in] PeiServices An indirect pointer to the PEI Services Table published
609 by the PEI Foundation.
610 @param[in] This Pointer to local data for the interface.
611 @param[in] Address The physical address of the access.
612 @param[in] Data The data to write.
618 IN CONST EFI_PEI_SERVICES
**PeiServices
,
619 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
624 IoWrite8 ((UINTN
)Address
, Data
);
628 16-bit I/O write operations.
630 @param[in] PeiServices An indirect pointer to the PEI Services Table published
631 by the PEI Foundation.
632 @param[in] This Pointer to local data for the interface.
633 @param[in] Address The physical address of the access.
634 @param[in] Data The data to write.
640 IN CONST EFI_PEI_SERVICES
**PeiServices
,
641 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
646 IoWrite16 ((UINTN
)Address
, Data
);
650 32-bit I/O write operations.
652 @param[in] PeiServices An indirect pointer to the PEI Services Table published
653 by the PEI Foundation.
654 @param[in] This Pointer to local data for the interface.
655 @param[in] Address The physical address of the access.
656 @param[in] Data The data to write.
662 IN CONST EFI_PEI_SERVICES
**PeiServices
,
663 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
668 IoWrite32 ((UINTN
)Address
, Data
);
672 64-bit I/O write operations.
674 @param[in] PeiServices An indirect pointer to the PEI Services Table published
675 by the PEI Foundation.
676 @param[in] This Pointer to local data for the interface.
677 @param[in] Address The physical address of the access.
678 @param[in] Data The data to write.
684 IN CONST EFI_PEI_SERVICES
**PeiServices
,
685 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
690 IoWrite64 ((UINTN
)Address
, Data
);
694 8-bit memory read operations.
696 @param[in] PeiServices An indirect pointer to the PEI Services Table published
697 by the PEI Foundation.
698 @param[in] This Pointer to local data for the interface.
699 @param[in] Address The physical address of the access.
701 @return An 8-bit value returned from the memory space.
707 IN CONST EFI_PEI_SERVICES
**PeiServices
,
708 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
712 return MmioRead8 ((UINTN
)Address
);
716 16-bit memory read operations.
718 @param[in] PeiServices An indirect pointer to the PEI Services Table published
719 by the PEI Foundation.
720 @param[in] This Pointer to local data for the interface.
721 @param[in] Address The physical address of the access.
723 @return A 16-bit value returned from the memory space.
729 IN CONST EFI_PEI_SERVICES
**PeiServices
,
730 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
734 return MmioRead16 ((UINTN
)Address
);
738 32-bit memory read operations.
740 @param[in] PeiServices An indirect pointer to the PEI Services Table published
741 by the PEI Foundation.
742 @param[in] This Pointer to local data for the interface.
743 @param[in] Address The physical address of the access.
745 @return A 32-bit value returned from the memory space.
751 IN CONST EFI_PEI_SERVICES
**PeiServices
,
752 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
756 return MmioRead32 ((UINTN
)Address
);
760 64-bit memory read operations.
762 @param[in] PeiServices An indirect pointer to the PEI Services Table published
763 by the PEI Foundation.
764 @param[in] This Pointer to local data for the interface.
765 @param[in] Address The physical address of the access.
767 @return A 64-bit value returned from the memory space.
773 IN CONST EFI_PEI_SERVICES
**PeiServices
,
774 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
778 return MmioRead64 ((UINTN
)Address
);
782 8-bit memory write operations.
784 @param[in] PeiServices An indirect pointer to the PEI Services Table published
785 by the PEI Foundation.
786 @param[in] This Pointer to local data for the interface.
787 @param[in] Address The physical address of the access.
788 @param[in] Data The data to write.
794 IN CONST EFI_PEI_SERVICES
**PeiServices
,
795 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
800 MmioWrite8 ((UINTN
)Address
, Data
);
804 16-bit memory write operations.
806 @param[in] PeiServices An indirect pointer to the PEI Services Table published
807 by the PEI Foundation.
808 @param[in] This Pointer to local data for the interface.
809 @param[in] Address The physical address of the access.
810 @param[in] Data The data to write.
816 IN CONST EFI_PEI_SERVICES
**PeiServices
,
817 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
822 MmioWrite16 ((UINTN
)Address
, Data
);
826 32-bit memory write operations.
828 @param[in] PeiServices An indirect pointer to the PEI Services Table published
829 by the PEI Foundation.
830 @param[in] This Pointer to local data for the interface.
831 @param[in] Address The physical address of the access.
832 @param[in] Data The data to write.
838 IN CONST EFI_PEI_SERVICES
**PeiServices
,
839 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
844 MmioWrite32 ((UINTN
)Address
, Data
);
848 64-bit memory write operations.
850 @param[in] PeiServices An indirect pointer to the PEI Services Table published
851 by the PEI Foundation.
852 @param[in] This Pointer to local data for the interface.
853 @param[in] Address The physical address of the access.
854 @param[in] Data The data to write.
860 IN CONST EFI_PEI_SERVICES
**PeiServices
,
861 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
866 MmioWrite64 ((UINTN
)Address
, Data
);
870 The Entry point of the CPU I/O PEIM
872 This function is the Entry point of the CPU I/O PEIM which installs CpuIoPpi.
874 @param[in] FileHandle Pointer to image file handle.
875 @param[in] PeiServices Pointer to PEI Services Table
877 @retval EFI_SUCCESS CPU I/O PPI successfully installed
883 IN EFI_PEI_FILE_HANDLE FileHandle
,
884 IN CONST EFI_PEI_SERVICES
**PeiServices
890 // Register so it will be automatically shadowed to memory
892 Status
= PeiServicesRegisterForShadow (FileHandle
);
895 // Make CpuIo pointer in PeiService table point to gCpuIoPpi
897 (*((EFI_PEI_SERVICES
**)PeiServices
))->CpuIo
= &gCpuIoPpi
;
899 if (Status
== EFI_ALREADY_STARTED
) {
901 // Shadow completed and running from memory
903 DEBUG ((EFI_D_INFO
, "CpuIO PPI has been loaded into memory. Reinstalled PPI=0x%x\n", &gCpuIoPpi
));
905 Status
= PeiServicesInstallPpi (&gPpiList
);
906 ASSERT_EFI_ERROR (Status
);