2 Produces the CPU I/O PPI.
4 Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
5 Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20 // Instance of CPU I/O PPI
22 EFI_PEI_CPU_IO_PPI gCpuIoPpi
= {
50 // PPI Descriptor used to install the CPU I/O PPI
52 EFI_PEI_PPI_DESCRIPTOR gPpiList
= {
53 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
54 &gEfiPeiCpuIoPpiInstalledGuid
,
59 // Lookup table for increment values based on transfer widths
62 1, // EfiPeiCpuIoWidthUint8
63 2, // EfiPeiCpuIoWidthUint16
64 4, // EfiPeiCpuIoWidthUint32
65 8, // EfiPeiCpuIoWidthUint64
66 0, // EfiPeiCpuIoWidthFifoUint8
67 0, // EfiPeiCpuIoWidthFifoUint16
68 0, // EfiPeiCpuIoWidthFifoUint32
69 0, // EfiPeiCpuIoWidthFifoUint64
70 1, // EfiPeiCpuIoWidthFillUint8
71 2, // EfiPeiCpuIoWidthFillUint16
72 4, // EfiPeiCpuIoWidthFillUint32
73 8 // EfiPeiCpuIoWidthFillUint64
77 // Lookup table for increment values based on transfer widths
79 UINT8 mOutStride
[] = {
80 1, // EfiPeiCpuIoWidthUint8
81 2, // EfiPeiCpuIoWidthUint16
82 4, // EfiPeiCpuIoWidthUint32
83 8, // EfiPeiCpuIoWidthUint64
84 1, // EfiPeiCpuIoWidthFifoUint8
85 2, // EfiPeiCpuIoWidthFifoUint16
86 4, // EfiPeiCpuIoWidthFifoUint32
87 8, // EfiPeiCpuIoWidthFifoUint64
88 0, // EfiPeiCpuIoWidthFillUint8
89 0, // EfiPeiCpuIoWidthFillUint16
90 0, // EfiPeiCpuIoWidthFillUint32
91 0 // EfiPeiCpuIoWidthFillUint64
95 Check parameters to a CPU I/O PPI service request.
97 @param[in] MmioOperation TRUE for an MMIO operation, FALSE for I/O Port operation.
98 @param[in] Width The width of the access. Enumerated in bytes.
99 @param[in] Address The physical address of the access.
100 @param[in] Count The number of accesses to perform.
101 @param[in] Buffer A pointer to the buffer of data.
103 @retval EFI_SUCCESS The parameters for this request pass the checks.
104 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system.
105 @retval EFI_INVALID_PARAMETER Buffer is NULL.
106 @retval EFI_UNSUPPORTED The address range specified by Address, Width,
107 and Count is not valid for this EFI system.
111 CpuIoCheckParameter (
112 IN BOOLEAN MmioOperation
,
113 IN EFI_PEI_CPU_IO_PPI_WIDTH Width
,
123 // Check to see if Buffer is NULL
125 if (Buffer
== NULL
) {
126 return EFI_INVALID_PARAMETER
;
130 // Check to see if Width is in the valid range
132 if ((UINT32
)Width
>= EfiPeiCpuIoWidthMaximum
) {
133 return EFI_INVALID_PARAMETER
;
137 // For FIFO type, the target address won't increase during the access,
138 // so treat Count as 1
140 if (Width
>= EfiPeiCpuIoWidthFifoUint8
&& Width
<= EfiPeiCpuIoWidthFifoUint64
) {
145 // Check to see if Width is in the valid range for I/O Port operations
147 Width
= (EFI_PEI_CPU_IO_PPI_WIDTH
) (Width
& 0x03);
148 if (!MmioOperation
&& (Width
== EfiPeiCpuIoWidthUint64
)) {
149 return EFI_INVALID_PARAMETER
;
153 // Check to see if any address associated with this transfer exceeds the maximum
154 // allowed address. The maximum address implied by the parameters passed in is
155 // Address + Size * Count. If the following condition is met, then the transfer
158 // Address + Size * Count > (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS) + 1
160 // Since MAX_ADDRESS can be the maximum integer value supported by the CPU and Count
161 // can also be the maximum integer value supported by the CPU, this range
162 // check must be adjusted to avoid all overflow conditions.
164 // The following form of the range check is equivalent but assumes that
165 // MAX_ADDRESS and MAX_IO_PORT_ADDRESS are of the form (2^n - 1).
167 Limit
= (MmioOperation
? MAX_ADDRESS
: MAX_IO_PORT_ADDRESS
);
169 if (Address
> Limit
) {
170 return EFI_UNSUPPORTED
;
173 MaxCount
= RShiftU64 (Limit
, Width
);
174 if (MaxCount
< (Count
- 1)) {
175 return EFI_UNSUPPORTED
;
177 if (Address
> LShiftU64 (MaxCount
- Count
+ 1, Width
)) {
178 return EFI_UNSUPPORTED
;
186 Reads memory-mapped registers.
188 @param[in] PeiServices An indirect pointer to the PEI Services Table
189 published by the PEI Foundation.
190 @param[in] This Pointer to local data for the interface.
191 @param[in] Width The width of the access. Enumerated in bytes.
192 @param[in] Address The physical address of the access.
193 @param[in] Count The number of accesses to perform.
194 @param[out] Buffer A pointer to the buffer of data.
196 @retval EFI_SUCCESS The function completed successfully.
197 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system.
198 @retval EFI_INVALID_PARAMETER Buffer is NULL.
199 @retval EFI_UNSUPPORTED The address range specified by Address, Width,
200 and Count is not valid for this EFI system.
205 CpuMemoryServiceRead (
206 IN CONST EFI_PEI_SERVICES
**PeiServices
,
207 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
208 IN EFI_PEI_CPU_IO_PPI_WIDTH Width
,
217 EFI_PEI_CPU_IO_PPI_WIDTH OperationWidth
;
221 Status
= CpuIoCheckParameter (TRUE
, Width
, Address
, Count
, Buffer
);
222 if (EFI_ERROR (Status
)) {
227 // Select loop based on the width of the transfer
229 InStride
= mInStride
[Width
];
230 OutStride
= mOutStride
[Width
];
231 OperationWidth
= (EFI_PEI_CPU_IO_PPI_WIDTH
) (Width
& 0x03);
232 Aligned
= (BOOLEAN
)(((UINTN
)Buffer
& (mInStride
[OperationWidth
] - 1)) == 0x00);
233 for (Uint8Buffer
= Buffer
; Count
> 0; Address
+= InStride
, Uint8Buffer
+= OutStride
, Count
--) {
234 if (OperationWidth
== EfiPeiCpuIoWidthUint8
) {
235 *Uint8Buffer
= MmioRead8 ((UINTN
)Address
);
236 } else if (OperationWidth
== EfiPeiCpuIoWidthUint16
) {
238 *((UINT16
*)Uint8Buffer
) = MmioRead16 ((UINTN
)Address
);
240 WriteUnaligned16 ((UINT16
*)Uint8Buffer
, MmioRead16 ((UINTN
)Address
));
242 } else if (OperationWidth
== EfiPeiCpuIoWidthUint32
) {
244 *((UINT32
*)Uint8Buffer
) = MmioRead32 ((UINTN
)Address
);
246 WriteUnaligned32 ((UINT32
*)Uint8Buffer
, MmioRead32 ((UINTN
)Address
));
248 } else if (OperationWidth
== EfiPeiCpuIoWidthUint64
) {
250 *((UINT64
*)Uint8Buffer
) = MmioRead64 ((UINTN
)Address
);
252 WriteUnaligned64 ((UINT64
*)Uint8Buffer
, MmioRead64 ((UINTN
)Address
));
260 Writes memory-mapped registers.
262 @param[in] PeiServices An indirect pointer to the PEI Services Table
263 published by the PEI Foundation.
264 @param[in] This Pointer to local data for the interface.
265 @param[in] Width The width of the access. Enumerated in bytes.
266 @param[in] Address The physical address of the access.
267 @param[in] Count The number of accesses to perform.
268 @param[in] Buffer A pointer to the buffer of data.
270 @retval EFI_SUCCESS The function completed successfully.
271 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system.
272 @retval EFI_INVALID_PARAMETER Buffer is NULL.
273 @retval EFI_UNSUPPORTED The address range specified by Address, Width,
274 and Count is not valid for this EFI system.
279 CpuMemoryServiceWrite (
280 IN CONST EFI_PEI_SERVICES
**PeiServices
,
281 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
282 IN EFI_PEI_CPU_IO_PPI_WIDTH Width
,
291 EFI_PEI_CPU_IO_PPI_WIDTH OperationWidth
;
295 Status
= CpuIoCheckParameter (TRUE
, Width
, Address
, Count
, Buffer
);
296 if (EFI_ERROR (Status
)) {
301 // Select loop based on the width of the transfer
303 InStride
= mInStride
[Width
];
304 OutStride
= mOutStride
[Width
];
305 OperationWidth
= (EFI_PEI_CPU_IO_PPI_WIDTH
) (Width
& 0x03);
306 Aligned
= (BOOLEAN
)(((UINTN
)Buffer
& (mInStride
[OperationWidth
] - 1)) == 0x00);
307 for (Uint8Buffer
= Buffer
; Count
> 0; Address
+= InStride
, Uint8Buffer
+= OutStride
, Count
--) {
308 if (OperationWidth
== EfiPeiCpuIoWidthUint8
) {
309 MmioWrite8 ((UINTN
)Address
, *Uint8Buffer
);
310 } else if (OperationWidth
== EfiPeiCpuIoWidthUint16
) {
312 MmioWrite16 ((UINTN
)Address
, *((UINT16
*)Uint8Buffer
));
314 MmioWrite16 ((UINTN
)Address
, ReadUnaligned16 ((UINT16
*)Uint8Buffer
));
316 } else if (OperationWidth
== EfiPeiCpuIoWidthUint32
) {
318 MmioWrite32 ((UINTN
)Address
, *((UINT32
*)Uint8Buffer
));
320 MmioWrite32 ((UINTN
)Address
, ReadUnaligned32 ((UINT32
*)Uint8Buffer
));
322 } else if (OperationWidth
== EfiPeiCpuIoWidthUint64
) {
324 MmioWrite64 ((UINTN
)Address
, *((UINT64
*)Uint8Buffer
));
326 MmioWrite64 ((UINTN
)Address
, ReadUnaligned64 ((UINT64
*)Uint8Buffer
));
336 @param[in] PeiServices An indirect pointer to the PEI Services Table
337 published by the PEI Foundation.
338 @param[in] This Pointer to local data for the interface.
339 @param[in] Width The width of the access. Enumerated in bytes.
340 @param[in] Address The physical address of the access.
341 @param[in] Count The number of accesses to perform.
342 @param[out] Buffer A pointer to the buffer of data.
344 @retval EFI_SUCCESS The function completed successfully.
345 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system.
346 @retval EFI_INVALID_PARAMETER Buffer is NULL.
347 @retval EFI_UNSUPPORTED The address range specified by Address, Width,
348 and Count is not valid for this EFI system.
354 IN CONST EFI_PEI_SERVICES
**PeiServices
,
355 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
356 IN EFI_PEI_CPU_IO_PPI_WIDTH Width
,
365 EFI_PEI_CPU_IO_PPI_WIDTH OperationWidth
;
369 Status
= CpuIoCheckParameter (FALSE
, Width
, Address
, Count
, Buffer
);
370 if (EFI_ERROR (Status
)) {
375 // Select loop based on the width of the transfer
377 InStride
= mInStride
[Width
];
378 OutStride
= mOutStride
[Width
];
379 OperationWidth
= (EFI_PEI_CPU_IO_PPI_WIDTH
) (Width
& 0x03);
382 // Fifo operations supported for (mInStride[Width] == 0)
385 switch (OperationWidth
) {
386 case EfiPeiCpuIoWidthUint8
:
387 IoReadFifo8 ((UINTN
)Address
, Count
, Buffer
);
389 case EfiPeiCpuIoWidthUint16
:
390 IoReadFifo16 ((UINTN
)Address
, Count
, Buffer
);
392 case EfiPeiCpuIoWidthUint32
:
393 IoReadFifo32 ((UINTN
)Address
, Count
, Buffer
);
397 // The CpuIoCheckParameter call above will ensure that this
398 // path is not taken.
405 Aligned
= (BOOLEAN
)(((UINTN
)Buffer
& (mInStride
[OperationWidth
] - 1)) == 0x00);
406 for (Uint8Buffer
= Buffer
; Count
> 0; Address
+= InStride
, Uint8Buffer
+= OutStride
, Count
--) {
407 if (OperationWidth
== EfiPeiCpuIoWidthUint8
) {
408 *Uint8Buffer
= IoRead8 ((UINTN
)Address
);
409 } else if (OperationWidth
== EfiPeiCpuIoWidthUint16
) {
411 *((UINT16
*)Uint8Buffer
) = IoRead16 ((UINTN
)Address
);
413 WriteUnaligned16 ((UINT16
*)Uint8Buffer
, IoRead16 ((UINTN
)Address
));
415 } else if (OperationWidth
== EfiPeiCpuIoWidthUint32
) {
417 *((UINT32
*)Uint8Buffer
) = IoRead32 ((UINTN
)Address
);
419 WriteUnaligned32 ((UINT32
*)Uint8Buffer
, IoRead32 ((UINTN
)Address
));
430 @param[in] PeiServices An indirect pointer to the PEI Services Table
431 published by the PEI Foundation.
432 @param[in] This Pointer to local data for the interface.
433 @param[in] Width The width of the access. Enumerated in bytes.
434 @param[in] Address The physical address of the access.
435 @param[in] Count The number of accesses to perform.
436 @param[in] Buffer A pointer to the buffer of data.
438 @retval EFI_SUCCESS The function completed successfully.
439 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system.
440 @retval EFI_INVALID_PARAMETER Buffer is NULL.
441 @retval EFI_UNSUPPORTED The address range specified by Address, Width,
442 and Count is not valid for this EFI system.
448 IN CONST EFI_PEI_SERVICES
**PeiServices
,
449 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
450 IN EFI_PEI_CPU_IO_PPI_WIDTH Width
,
459 EFI_PEI_CPU_IO_PPI_WIDTH OperationWidth
;
464 // Make sure the parameters are valid
466 Status
= CpuIoCheckParameter (FALSE
, Width
, Address
, Count
, Buffer
);
467 if (EFI_ERROR (Status
)) {
472 // Select loop based on the width of the transfer
474 InStride
= mInStride
[Width
];
475 OutStride
= mOutStride
[Width
];
476 OperationWidth
= (EFI_PEI_CPU_IO_PPI_WIDTH
) (Width
& 0x03);
479 // Fifo operations supported for (mInStride[Width] == 0)
482 switch (OperationWidth
) {
483 case EfiPeiCpuIoWidthUint8
:
484 IoWriteFifo8 ((UINTN
)Address
, Count
, Buffer
);
486 case EfiPeiCpuIoWidthUint16
:
487 IoWriteFifo16 ((UINTN
)Address
, Count
, Buffer
);
489 case EfiPeiCpuIoWidthUint32
:
490 IoWriteFifo32 ((UINTN
)Address
, Count
, Buffer
);
494 // The CpuIoCheckParameter call above will ensure that this
495 // path is not taken.
502 Aligned
= (BOOLEAN
)(((UINTN
)Buffer
& (mInStride
[OperationWidth
] - 1)) == 0x00);
503 for (Uint8Buffer
= (UINT8
*)Buffer
; Count
> 0; Address
+= InStride
, Uint8Buffer
+= OutStride
, Count
--) {
504 if (OperationWidth
== EfiPeiCpuIoWidthUint8
) {
505 IoWrite8 ((UINTN
)Address
, *Uint8Buffer
);
506 } else if (OperationWidth
== EfiPeiCpuIoWidthUint16
) {
508 IoWrite16 ((UINTN
)Address
, *((UINT16
*)Uint8Buffer
));
510 IoWrite16 ((UINTN
)Address
, ReadUnaligned16 ((UINT16
*)Uint8Buffer
));
512 } else if (OperationWidth
== EfiPeiCpuIoWidthUint32
) {
514 IoWrite32 ((UINTN
)Address
, *((UINT32
*)Uint8Buffer
));
516 IoWrite32 ((UINTN
)Address
, ReadUnaligned32 ((UINT32
*)Uint8Buffer
));
525 8-bit I/O read operations.
527 @param[in] PeiServices An indirect pointer to the PEI Services Table published
528 by the PEI Foundation.
529 @param[in] This Pointer to local data for the interface.
530 @param[in] Address The physical address of the access.
532 @return An 8-bit value returned from the I/O space.
537 IN CONST EFI_PEI_SERVICES
**PeiServices
,
538 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
542 return IoRead8 ((UINTN
)Address
);
546 16-bit I/O read operations.
548 @param[in] PeiServices An indirect pointer to the PEI Services Table published
549 by the PEI Foundation.
550 @param[in] This Pointer to local data for the interface.
551 @param[in] Address The physical address of the access.
553 @return A 16-bit value returned from the I/O space.
559 IN CONST EFI_PEI_SERVICES
**PeiServices
,
560 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
564 return IoRead16 ((UINTN
)Address
);
568 32-bit I/O read operations.
570 @param[in] PeiServices An indirect pointer to the PEI Services Table published
571 by the PEI Foundation.
572 @param[in] This Pointer to local data for the interface.
573 @param[in] Address The physical address of the access.
575 @return A 32-bit value returned from the I/O space.
581 IN CONST EFI_PEI_SERVICES
**PeiServices
,
582 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
586 return IoRead32 ((UINTN
)Address
);
590 64-bit I/O read operations.
592 @param[in] PeiServices An indirect pointer to the PEI Services Table published
593 by the PEI Foundation.
594 @param[in] This Pointer to local data for the interface.
595 @param[in] Address The physical address of the access.
597 @return A 64-bit value returned from the I/O space.
603 IN CONST EFI_PEI_SERVICES
**PeiServices
,
604 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
608 return IoRead64 ((UINTN
)Address
);
612 8-bit I/O write operations.
614 @param[in] PeiServices An indirect pointer to the PEI Services Table published
615 by the PEI Foundation.
616 @param[in] This Pointer to local data for the interface.
617 @param[in] Address The physical address of the access.
618 @param[in] Data The data to write.
624 IN CONST EFI_PEI_SERVICES
**PeiServices
,
625 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
630 IoWrite8 ((UINTN
)Address
, Data
);
634 16-bit I/O write operations.
636 @param[in] PeiServices An indirect pointer to the PEI Services Table published
637 by the PEI Foundation.
638 @param[in] This Pointer to local data for the interface.
639 @param[in] Address The physical address of the access.
640 @param[in] Data The data to write.
646 IN CONST EFI_PEI_SERVICES
**PeiServices
,
647 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
652 IoWrite16 ((UINTN
)Address
, Data
);
656 32-bit I/O write operations.
658 @param[in] PeiServices An indirect pointer to the PEI Services Table published
659 by the PEI Foundation.
660 @param[in] This Pointer to local data for the interface.
661 @param[in] Address The physical address of the access.
662 @param[in] Data The data to write.
668 IN CONST EFI_PEI_SERVICES
**PeiServices
,
669 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
674 IoWrite32 ((UINTN
)Address
, Data
);
678 64-bit I/O write operations.
680 @param[in] PeiServices An indirect pointer to the PEI Services Table published
681 by the PEI Foundation.
682 @param[in] This Pointer to local data for the interface.
683 @param[in] Address The physical address of the access.
684 @param[in] Data The data to write.
690 IN CONST EFI_PEI_SERVICES
**PeiServices
,
691 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
696 IoWrite64 ((UINTN
)Address
, Data
);
700 8-bit memory read operations.
702 @param[in] PeiServices An indirect pointer to the PEI Services Table published
703 by the PEI Foundation.
704 @param[in] This Pointer to local data for the interface.
705 @param[in] Address The physical address of the access.
707 @return An 8-bit value returned from the memory space.
713 IN CONST EFI_PEI_SERVICES
**PeiServices
,
714 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
718 return MmioRead8 ((UINTN
)Address
);
722 16-bit memory read operations.
724 @param[in] PeiServices An indirect pointer to the PEI Services Table published
725 by the PEI Foundation.
726 @param[in] This Pointer to local data for the interface.
727 @param[in] Address The physical address of the access.
729 @return A 16-bit value returned from the memory space.
735 IN CONST EFI_PEI_SERVICES
**PeiServices
,
736 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
740 return MmioRead16 ((UINTN
)Address
);
744 32-bit memory read operations.
746 @param[in] PeiServices An indirect pointer to the PEI Services Table published
747 by the PEI Foundation.
748 @param[in] This Pointer to local data for the interface.
749 @param[in] Address The physical address of the access.
751 @return A 32-bit value returned from the memory space.
757 IN CONST EFI_PEI_SERVICES
**PeiServices
,
758 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
762 return MmioRead32 ((UINTN
)Address
);
766 64-bit memory read operations.
768 @param[in] PeiServices An indirect pointer to the PEI Services Table published
769 by the PEI Foundation.
770 @param[in] This Pointer to local data for the interface.
771 @param[in] Address The physical address of the access.
773 @return A 64-bit value returned from the memory space.
779 IN CONST EFI_PEI_SERVICES
**PeiServices
,
780 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
784 return MmioRead64 ((UINTN
)Address
);
788 8-bit memory write operations.
790 @param[in] PeiServices An indirect pointer to the PEI Services Table published
791 by the PEI Foundation.
792 @param[in] This Pointer to local data for the interface.
793 @param[in] Address The physical address of the access.
794 @param[in] Data The data to write.
800 IN CONST EFI_PEI_SERVICES
**PeiServices
,
801 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
806 MmioWrite8 ((UINTN
)Address
, Data
);
810 16-bit memory write operations.
812 @param[in] PeiServices An indirect pointer to the PEI Services Table published
813 by the PEI Foundation.
814 @param[in] This Pointer to local data for the interface.
815 @param[in] Address The physical address of the access.
816 @param[in] Data The data to write.
822 IN CONST EFI_PEI_SERVICES
**PeiServices
,
823 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
828 MmioWrite16 ((UINTN
)Address
, Data
);
832 32-bit memory write operations.
834 @param[in] PeiServices An indirect pointer to the PEI Services Table published
835 by the PEI Foundation.
836 @param[in] This Pointer to local data for the interface.
837 @param[in] Address The physical address of the access.
838 @param[in] Data The data to write.
844 IN CONST EFI_PEI_SERVICES
**PeiServices
,
845 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
850 MmioWrite32 ((UINTN
)Address
, Data
);
854 64-bit memory write operations.
856 @param[in] PeiServices An indirect pointer to the PEI Services Table published
857 by the PEI Foundation.
858 @param[in] This Pointer to local data for the interface.
859 @param[in] Address The physical address of the access.
860 @param[in] Data The data to write.
866 IN CONST EFI_PEI_SERVICES
**PeiServices
,
867 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
872 MmioWrite64 ((UINTN
)Address
, Data
);
876 The Entry point of the CPU I/O PEIM
878 This function is the Entry point of the CPU I/O PEIM which installs CpuIoPpi.
880 @param[in] FileHandle Pointer to image file handle.
881 @param[in] PeiServices Pointer to PEI Services Table
883 @retval EFI_SUCCESS CPU I/O PPI successfully installed
889 IN EFI_PEI_FILE_HANDLE FileHandle
,
890 IN CONST EFI_PEI_SERVICES
**PeiServices
896 // Register so it will be automatically shadowed to memory
898 Status
= PeiServicesRegisterForShadow (FileHandle
);
901 // Make CpuIo pointer in PeiService table point to gCpuIoPpi
903 (*((EFI_PEI_SERVICES
**)PeiServices
))->CpuIo
= &gCpuIoPpi
;
905 if (Status
== EFI_ALREADY_STARTED
) {
907 // Shadow completed and running from memory
909 DEBUG ((EFI_D_INFO
, "CpuIO PPI has been loaded into memory. Reinstalled PPI=0x%x\n", &gCpuIoPpi
));
911 Status
= PeiServicesInstallPpi (&gPpiList
);
912 ASSERT_EFI_ERROR (Status
);