2 Produces the CPU I/O PPI.
4 Copyright (c) 2009 - 2010, Intel Corporation
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include <Ppi/CpuIo.h>
19 #include <Library/BaseLib.h>
20 #include <Library/DebugLib.h>
21 #include <Library/IoLib.h>
22 #include <Library/PeiServicesLib.h>
24 #define MAX_IO_PORT_ADDRESS 0xFFFF
27 // Function Prototypes
31 CpuMemoryServiceRead (
32 IN CONST EFI_PEI_SERVICES
**PeiServices
,
33 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
34 IN EFI_PEI_CPU_IO_PPI_WIDTH Width
,
42 CpuMemoryServiceWrite (
43 IN CONST EFI_PEI_SERVICES
**PeiServices
,
44 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
45 IN EFI_PEI_CPU_IO_PPI_WIDTH Width
,
54 IN CONST EFI_PEI_SERVICES
**PeiServices
,
55 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
56 IN EFI_PEI_CPU_IO_PPI_WIDTH Width
,
65 IN CONST EFI_PEI_SERVICES
**PeiServices
,
66 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
67 IN EFI_PEI_CPU_IO_PPI_WIDTH Width
,
76 IN CONST EFI_PEI_SERVICES
**PeiServices
,
77 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
84 IN CONST EFI_PEI_SERVICES
**PeiServices
,
85 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
92 IN CONST EFI_PEI_SERVICES
**PeiServices
,
93 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
100 IN CONST EFI_PEI_SERVICES
**PeiServices
,
101 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
108 IN CONST EFI_PEI_SERVICES
**PeiServices
,
109 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
117 IN CONST EFI_PEI_SERVICES
**PeiServices
,
118 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
126 IN CONST EFI_PEI_SERVICES
**PeiServices
,
127 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
135 IN CONST EFI_PEI_SERVICES
**PeiServices
,
136 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
144 IN CONST EFI_PEI_SERVICES
**PeiServices
,
145 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
152 IN CONST EFI_PEI_SERVICES
**PeiServices
,
153 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
160 IN CONST EFI_PEI_SERVICES
**PeiServices
,
161 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
168 IN CONST EFI_PEI_SERVICES
**PeiServices
,
169 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
176 IN CONST EFI_PEI_SERVICES
**PeiServices
,
177 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
185 IN CONST EFI_PEI_SERVICES
**PeiServices
,
186 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
194 IN CONST EFI_PEI_SERVICES
**PeiServices
,
195 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
203 IN CONST EFI_PEI_SERVICES
**PeiServices
,
204 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
210 // Instance of CPU I/O PPI
212 EFI_PEI_CPU_IO_PPI gCpuIoPpi
= {
214 CpuMemoryServiceRead
,
215 CpuMemoryServiceWrite
240 // PPI Descriptor used to install the CPU I/O PPI
242 EFI_PEI_PPI_DESCRIPTOR gPpiList
= {
243 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
244 &gEfiPeiCpuIoPpiInstalledGuid
,
249 // Lookup table for increment values based on transfer widths
251 UINT8 mInStride
[] = {
252 1, // EfiPeiCpuIoWidthUint8
253 2, // EfiPeiCpuIoWidthUint16
254 4, // EfiPeiCpuIoWidthUint32
255 8, // EfiPeiCpuIoWidthUint64
256 0, // EfiPeiCpuIoWidthFifoUint8
257 0, // EfiPeiCpuIoWidthFifoUint16
258 0, // EfiPeiCpuIoWidthFifoUint32
259 0, // EfiPeiCpuIoWidthFifoUint64
260 1, // EfiPeiCpuIoWidthFillUint8
261 2, // EfiPeiCpuIoWidthFillUint16
262 4, // EfiPeiCpuIoWidthFillUint32
263 8 // EfiPeiCpuIoWidthFillUint64
267 // Lookup table for increment values based on transfer widths
269 UINT8 mOutStride
[] = {
270 1, // EfiPeiCpuIoWidthUint8
271 2, // EfiPeiCpuIoWidthUint16
272 4, // EfiPeiCpuIoWidthUint32
273 8, // EfiPeiCpuIoWidthUint64
274 1, // EfiPeiCpuIoWidthFifoUint8
275 2, // EfiPeiCpuIoWidthFifoUint16
276 4, // EfiPeiCpuIoWidthFifoUint32
277 8, // EfiPeiCpuIoWidthFifoUint64
278 0, // EfiPeiCpuIoWidthFillUint8
279 0, // EfiPeiCpuIoWidthFillUint16
280 0, // EfiPeiCpuIoWidthFillUint32
281 0 // EfiPeiCpuIoWidthFillUint64
285 Check parameters to a CPU I/O PPI service request.
287 @param[in] MmioOperation TRUE for an MMIO operation, FALSE for I/O Port operation.
288 @param[in] Width The width of the access. Enumerated in bytes.
289 @param[in] Address The physical address of the access.
290 @param[in] Count The number of accesses to perform.
291 @param[in] Buffer A pointer to the buffer of data.
293 @retval EFI_SUCCESS The parameters for this request pass the checks.
294 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system.
295 @retval EFI_INVALID_PARAMETER Buffer is NULL.
296 @retval EFI_UNSUPPORTED The address range specified by Address, Width,
297 and Count is not valid for this EFI system.
301 CpuIoCheckParameter (
302 IN BOOLEAN MmioOperation
,
303 IN EFI_PEI_CPU_IO_PPI_WIDTH Width
,
313 // Check to see if Buffer is NULL
315 if (Buffer
== NULL
) {
316 return EFI_INVALID_PARAMETER
;
320 // Check to see if Width is in the valid range
322 if (Width
< 0 || Width
>= EfiPeiCpuIoWidthMaximum
) {
323 return EFI_INVALID_PARAMETER
;
327 // For FIFO type, the target address won't increase during the access,
328 // so treat Count as 1
330 if (Width
>= EfiPeiCpuIoWidthFifoUint8
&& Width
<= EfiPeiCpuIoWidthFifoUint64
) {
335 // Check to see if Width is in the valid range for I/O Port operations
337 Width
= Width
& 0x03;
338 if (!MmioOperation
&& (Width
== EfiPeiCpuIoWidthUint64
)) {
339 return EFI_INVALID_PARAMETER
;
343 // Check to see if any address associated with this transfer exceeds the maximum
344 // allowed address. The maximum address implied by the parameters passed in is
345 // Address + Size * Count. If the following condition is met, then the transfer
348 // Address + Size * Count > (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS) + 1
350 // Since MAX_ADDRESS can be the maximum integer value supported by the CPU and Count
351 // can also be the maximum integer value supported by the CPU, this range
352 // check must be adjusted to avoid all oveflow conditions.
354 // The follwing form of the range check is equivalent but assumes that
355 // MAX_ADDRESS and MAX_IO_PORT_ADDRESS are of the form (2^n - 1).
357 Limit
= (MmioOperation
? MAX_ADDRESS
: MAX_IO_PORT_ADDRESS
);
359 if (Address
> Limit
) {
360 return EFI_UNSUPPORTED
;
363 MaxCount
= RShiftU64 (Limit
, Width
);
364 if (MaxCount
< (Count
- 1)) {
365 return EFI_UNSUPPORTED
;
367 if (Address
> LShiftU64 (MaxCount
- Count
+ 1, Width
)) {
368 return EFI_UNSUPPORTED
;
376 Reads memory-mapped registers.
378 @param[in] PeiServices An indirect pointer to the PEI Services Table
379 published by the PEI Foundation.
380 @param[in] This Pointer to local data for the interface.
381 @param[in] Width The width of the access. Enumerated in bytes.
382 @param[in] Address The physical address of the access.
383 @param[in] Count The number of accesses to perform.
384 @param[out] Buffer A pointer to the buffer of data.
386 @retval EFI_SUCCESS The function completed successfully.
387 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system.
388 @retval EFI_INVALID_PARAMETER Buffer is NULL.
389 @retval EFI_UNSUPPORTED The address range specified by Address, Width,
390 and Count is not valid for this EFI system.
395 CpuMemoryServiceRead (
396 IN CONST EFI_PEI_SERVICES
**PeiServices
,
397 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
398 IN EFI_PEI_CPU_IO_PPI_WIDTH Width
,
407 EFI_PEI_CPU_IO_PPI_WIDTH OperationWidth
;
411 Status
= CpuIoCheckParameter (TRUE
, Width
, Address
, Count
, Buffer
);
412 if (EFI_ERROR (Status
)) {
417 // Select loop based on the width of the transfer
419 InStride
= mInStride
[Width
];
420 OutStride
= mOutStride
[Width
];
421 OperationWidth
= Width
& 0x03;
422 Aligned
= (BOOLEAN
)(((UINTN
)Buffer
& (mInStride
[OperationWidth
] - 1)) == 0x00);
423 for (Uint8Buffer
= Buffer
; Count
> 0; Address
+= InStride
, Uint8Buffer
+= OutStride
, Count
--) {
424 if (OperationWidth
== EfiPeiCpuIoWidthUint8
) {
425 *Uint8Buffer
= MmioRead8 ((UINTN
)Address
);
426 } else if (OperationWidth
== EfiPeiCpuIoWidthUint16
) {
428 *((UINT16
*)Uint8Buffer
) = MmioRead16 ((UINTN
)Address
);
430 WriteUnaligned16 ((UINT16
*)Uint8Buffer
, MmioRead16 ((UINTN
)Address
));
432 } else if (OperationWidth
== EfiPeiCpuIoWidthUint32
) {
434 *((UINT32
*)Uint8Buffer
) = MmioRead32 ((UINTN
)Address
);
436 WriteUnaligned32 ((UINT32
*)Uint8Buffer
, MmioRead32 ((UINTN
)Address
));
438 } else if (OperationWidth
== EfiPeiCpuIoWidthUint64
) {
440 *((UINT64
*)Uint8Buffer
) = MmioRead64 ((UINTN
)Address
);
442 WriteUnaligned64 ((UINT64
*)Uint8Buffer
, MmioRead64 ((UINTN
)Address
));
450 Writes memory-mapped registers.
452 @param[in] PeiServices An indirect pointer to the PEI Services Table
453 published by the PEI Foundation.
454 @param[in] This Pointer to local data for the interface.
455 @param[in] Width The width of the access. Enumerated in bytes.
456 @param[in] Address The physical address of the access.
457 @param[in] Count The number of accesses to perform.
458 @param[in] Buffer A pointer to the buffer of data.
460 @retval EFI_SUCCESS The function completed successfully.
461 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system.
462 @retval EFI_INVALID_PARAMETER Buffer is NULL.
463 @retval EFI_UNSUPPORTED The address range specified by Address, Width,
464 and Count is not valid for this EFI system.
469 CpuMemoryServiceWrite (
470 IN CONST EFI_PEI_SERVICES
**PeiServices
,
471 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
472 IN EFI_PEI_CPU_IO_PPI_WIDTH Width
,
481 EFI_PEI_CPU_IO_PPI_WIDTH OperationWidth
;
485 Status
= CpuIoCheckParameter (TRUE
, Width
, Address
, Count
, Buffer
);
486 if (EFI_ERROR (Status
)) {
491 // Select loop based on the width of the transfer
493 InStride
= mInStride
[Width
];
494 OutStride
= mOutStride
[Width
];
495 OperationWidth
= Width
& 0x03;
496 Aligned
= (BOOLEAN
)(((UINTN
)Buffer
& (mInStride
[OperationWidth
] - 1)) == 0x00);
497 for (Uint8Buffer
= Buffer
; Count
> 0; Address
+= InStride
, Uint8Buffer
+= OutStride
, Count
--) {
498 if (OperationWidth
== EfiPeiCpuIoWidthUint8
) {
499 MmioWrite8 ((UINTN
)Address
, *Uint8Buffer
);
500 } else if (OperationWidth
== EfiPeiCpuIoWidthUint16
) {
502 MmioWrite16 ((UINTN
)Address
, *((UINT16
*)Uint8Buffer
));
504 MmioWrite16 ((UINTN
)Address
, ReadUnaligned16 ((UINT16
*)Uint8Buffer
));
506 } else if (OperationWidth
== EfiPeiCpuIoWidthUint32
) {
508 MmioWrite32 ((UINTN
)Address
, *((UINT32
*)Uint8Buffer
));
510 MmioWrite32 ((UINTN
)Address
, ReadUnaligned32 ((UINT32
*)Uint8Buffer
));
512 } else if (OperationWidth
== EfiPeiCpuIoWidthUint64
) {
514 MmioWrite64 ((UINTN
)Address
, *((UINT64
*)Uint8Buffer
));
516 MmioWrite64 ((UINTN
)Address
, ReadUnaligned64 ((UINT64
*)Uint8Buffer
));
526 @param[in] PeiServices An indirect pointer to the PEI Services Table
527 published by the PEI Foundation.
528 @param[in] This Pointer to local data for the interface.
529 @param[in] Width The width of the access. Enumerated in bytes.
530 @param[in] Address The physical address of the access.
531 @param[in] Count The number of accesses to perform.
532 @param[out] Buffer A pointer to the buffer of data.
534 @retval EFI_SUCCESS The function completed successfully.
535 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system.
536 @retval EFI_INVALID_PARAMETER Buffer is NULL.
537 @retval EFI_UNSUPPORTED The address range specified by Address, Width,
538 and Count is not valid for this EFI system.
544 IN CONST EFI_PEI_SERVICES
**PeiServices
,
545 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
546 IN EFI_PEI_CPU_IO_PPI_WIDTH Width
,
555 EFI_PEI_CPU_IO_PPI_WIDTH OperationWidth
;
559 Status
= CpuIoCheckParameter (FALSE
, Width
, Address
, Count
, Buffer
);
560 if (EFI_ERROR (Status
)) {
565 // Select loop based on the width of the transfer
567 InStride
= mInStride
[Width
];
568 OutStride
= mOutStride
[Width
];
569 OperationWidth
= Width
& 0x03;
570 Aligned
= (BOOLEAN
)(((UINTN
)Buffer
& (mInStride
[OperationWidth
] - 1)) == 0x00);
571 for (Uint8Buffer
= Buffer
; Count
> 0; Address
+= InStride
, Uint8Buffer
+= OutStride
, Count
--) {
572 if (OperationWidth
== EfiPeiCpuIoWidthUint8
) {
573 *Uint8Buffer
= IoRead8 ((UINTN
)Address
);
574 } else if (OperationWidth
== EfiPeiCpuIoWidthUint16
) {
576 *((UINT16
*)Uint8Buffer
) = IoRead16 ((UINTN
)Address
);
578 WriteUnaligned16 ((UINT16
*)Uint8Buffer
, IoRead16 ((UINTN
)Address
));
580 } else if (OperationWidth
== EfiPeiCpuIoWidthUint32
) {
582 *((UINT32
*)Uint8Buffer
) = IoRead32 ((UINTN
)Address
);
584 WriteUnaligned32 ((UINT32
*)Uint8Buffer
, IoRead32 ((UINTN
)Address
));
595 @param[in] PeiServices An indirect pointer to the PEI Services Table
596 published by the PEI Foundation.
597 @param[in] This Pointer to local data for the interface.
598 @param[in] Width The width of the access. Enumerated in bytes.
599 @param[in] Address The physical address of the access.
600 @param[in] Count The number of accesses to perform.
601 @param[in] Buffer A pointer to the buffer of data.
603 @retval EFI_SUCCESS The function completed successfully.
604 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system.
605 @retval EFI_INVALID_PARAMETER Buffer is NULL.
606 @retval EFI_UNSUPPORTED The address range specified by Address, Width,
607 and Count is not valid for this EFI system.
613 IN CONST EFI_PEI_SERVICES
**PeiServices
,
614 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
615 IN EFI_PEI_CPU_IO_PPI_WIDTH Width
,
624 EFI_PEI_CPU_IO_PPI_WIDTH OperationWidth
;
629 // Make sure the parameters are valid
631 Status
= CpuIoCheckParameter (FALSE
, Width
, Address
, Count
, Buffer
);
632 if (EFI_ERROR (Status
)) {
637 // Select loop based on the width of the transfer
639 InStride
= mInStride
[Width
];
640 OutStride
= mOutStride
[Width
];
641 OperationWidth
= Width
& 0x03;
642 Aligned
= (BOOLEAN
)(((UINTN
)Buffer
& (mInStride
[OperationWidth
] - 1)) == 0x00);
643 for (Uint8Buffer
= (UINT8
*)Buffer
; Count
> 0; Address
+= InStride
, Uint8Buffer
+= OutStride
, Count
--) {
644 if (OperationWidth
== EfiPeiCpuIoWidthUint8
) {
645 IoWrite8 ((UINTN
)Address
, *Uint8Buffer
);
646 } else if (OperationWidth
== EfiPeiCpuIoWidthUint16
) {
648 IoWrite16 ((UINTN
)Address
, *((UINT16
*)Uint8Buffer
));
650 IoWrite16 ((UINTN
)Address
, ReadUnaligned16 ((UINT16
*)Uint8Buffer
));
652 } else if (OperationWidth
== EfiPeiCpuIoWidthUint32
) {
654 IoWrite32 ((UINTN
)Address
, *((UINT32
*)Uint8Buffer
));
656 IoWrite32 ((UINTN
)Address
, ReadUnaligned32 ((UINT32
*)Uint8Buffer
));
665 8-bit I/O read operations.
667 @param[in] PeiServices An indirect pointer to the PEI Services Table published
668 by the PEI Foundation.
669 @param[in] This Pointer to local data for the interface.
670 @param[in] Address The physical address of the access.
672 @return An 8-bit value returned from the I/O space.
677 IN CONST EFI_PEI_SERVICES
**PeiServices
,
678 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
682 return IoRead8 ((UINTN
)Address
);
686 16-bit I/O read operations.
688 @param[in] PeiServices An indirect pointer to the PEI Services Table published
689 by the PEI Foundation.
690 @param[in] This Pointer to local data for the interface.
691 @param[in] Address The physical address of the access.
693 @return A 16-bit value returned from the I/O space.
699 IN CONST EFI_PEI_SERVICES
**PeiServices
,
700 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
704 return IoRead16 ((UINTN
)Address
);
708 32-bit I/O read operations.
710 @param[in] PeiServices An indirect pointer to the PEI Services Table published
711 by the PEI Foundation.
712 @param[in] This Pointer to local data for the interface.
713 @param[in] Address The physical address of the access.
715 @return A 32-bit value returned from the I/O space.
721 IN CONST EFI_PEI_SERVICES
**PeiServices
,
722 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
726 return IoRead32 ((UINTN
)Address
);
730 64-bit I/O read operations.
732 @param[in] PeiServices An indirect pointer to the PEI Services Table published
733 by the PEI Foundation.
734 @param[in] This Pointer to local data for the interface.
735 @param[in] Address The physical address of the access.
737 @return A 64-bit value returned from the I/O space.
743 IN CONST EFI_PEI_SERVICES
**PeiServices
,
744 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
748 return IoRead64 ((UINTN
)Address
);
752 8-bit I/O write operations.
754 @param[in] PeiServices An indirect pointer to the PEI Services Table published
755 by the PEI Foundation.
756 @param[in] This Pointer to local data for the interface.
757 @param[in] Address The physical address of the access.
758 @param[in] Data The data to write.
764 IN CONST EFI_PEI_SERVICES
**PeiServices
,
765 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
770 IoWrite8 ((UINTN
)Address
, Data
);
774 16-bit I/O write operations.
776 @param[in] PeiServices An indirect pointer to the PEI Services Table published
777 by the PEI Foundation.
778 @param[in] This Pointer to local data for the interface.
779 @param[in] Address The physical address of the access.
780 @param[in] Data The data to write.
786 IN CONST EFI_PEI_SERVICES
**PeiServices
,
787 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
792 IoWrite16 ((UINTN
)Address
, Data
);
796 32-bit I/O write operations.
798 @param[in] PeiServices An indirect pointer to the PEI Services Table published
799 by the PEI Foundation.
800 @param[in] This Pointer to local data for the interface.
801 @param[in] Address The physical address of the access.
802 @param[in] Data The data to write.
808 IN CONST EFI_PEI_SERVICES
**PeiServices
,
809 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
814 IoWrite32 ((UINTN
)Address
, Data
);
818 64-bit I/O write operations.
820 @param[in] PeiServices An indirect pointer to the PEI Services Table published
821 by the PEI Foundation.
822 @param[in] This Pointer to local data for the interface.
823 @param[in] Address The physical address of the access.
824 @param[in] Data The data to write.
830 IN CONST EFI_PEI_SERVICES
**PeiServices
,
831 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
836 IoWrite64 ((UINTN
)Address
, Data
);
840 8-bit memory read operations.
842 @param[in] PeiServices An indirect pointer to the PEI Services Table published
843 by the PEI Foundation.
844 @param[in] This Pointer to local data for the interface.
845 @param[in] Address The physical address of the access.
847 @return An 8-bit value returned from the memory space.
853 IN CONST EFI_PEI_SERVICES
**PeiServices
,
854 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
858 return MmioRead8 ((UINTN
)Address
);
862 16-bit memory read operations.
864 @param[in] PeiServices An indirect pointer to the PEI Services Table published
865 by the PEI Foundation.
866 @param[in] This Pointer to local data for the interface.
867 @param[in] Address The physical address of the access.
869 @return A 16-bit value returned from the memory space.
875 IN CONST EFI_PEI_SERVICES
**PeiServices
,
876 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
880 return MmioRead16 ((UINTN
)Address
);
884 32-bit memory read operations.
886 @param[in] PeiServices An indirect pointer to the PEI Services Table published
887 by the PEI Foundation.
888 @param[in] This Pointer to local data for the interface.
889 @param[in] Address The physical address of the access.
891 @return A 32-bit value returned from the memory space.
897 IN CONST EFI_PEI_SERVICES
**PeiServices
,
898 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
902 return MmioRead32 ((UINTN
)Address
);
906 64-bit memory read operations.
908 @param[in] PeiServices An indirect pointer to the PEI Services Table published
909 by the PEI Foundation.
910 @param[in] This Pointer to local data for the interface.
911 @param[in] Address The physical address of the access.
913 @return A 64-bit value returned from the memory space.
919 IN CONST EFI_PEI_SERVICES
**PeiServices
,
920 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
924 return MmioRead64 ((UINTN
)Address
);
928 8-bit memory write operations.
930 @param[in] PeiServices An indirect pointer to the PEI Services Table published
931 by the PEI Foundation.
932 @param[in] This Pointer to local data for the interface.
933 @param[in] Address The physical address of the access.
934 @param[in] Data The data to write.
940 IN CONST EFI_PEI_SERVICES
**PeiServices
,
941 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
946 MmioWrite8 ((UINTN
)Address
, Data
);
950 16-bit memory write operations.
952 @param[in] PeiServices An indirect pointer to the PEI Services Table published
953 by the PEI Foundation.
954 @param[in] This Pointer to local data for the interface.
955 @param[in] Address The physical address of the access.
956 @param[in] Data The data to write.
962 IN CONST EFI_PEI_SERVICES
**PeiServices
,
963 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
968 MmioWrite16 ((UINTN
)Address
, Data
);
972 32-bit memory write operations.
974 @param[in] PeiServices An indirect pointer to the PEI Services Table published
975 by the PEI Foundation.
976 @param[in] This Pointer to local data for the interface.
977 @param[in] Address The physical address of the access.
978 @param[in] Data The data to write.
984 IN CONST EFI_PEI_SERVICES
**PeiServices
,
985 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
990 MmioWrite32 ((UINTN
)Address
, Data
);
994 64-bit memory write operations.
996 @param[in] PeiServices An indirect pointer to the PEI Services Table published
997 by the PEI Foundation.
998 @param[in] This Pointer to local data for the interface.
999 @param[in] Address The physical address of the access.
1000 @param[in] Data The data to write.
1006 IN CONST EFI_PEI_SERVICES
**PeiServices
,
1007 IN CONST EFI_PEI_CPU_IO_PPI
*This
,
1012 MmioWrite64 ((UINTN
)Address
, Data
);
1016 The Entry point of the CPU I/O PEIM
1018 This function is the Entry point of the CPU I/O PEIM which installs CpuIoPpi.
1020 @param[in] FileHandle Pointer to image file handle.
1021 @param[in] PeiServices Pointer to PEI Services Table
1023 @retval EFI_SUCCESS CPU I/O PPI successfully installed
1029 IN EFI_PEI_FILE_HANDLE FileHandle
,
1030 IN CONST EFI_PEI_SERVICES
**PeiServices
1036 // Register so it will be automatically shadowed to memory
1038 Status
= PeiServicesRegisterForShadow (FileHandle
);
1041 // Make CpuIo pointer in PeiService table point to gCpuIoPpi
1043 (*((EFI_PEI_SERVICES
**)PeiServices
))->CpuIo
= &gCpuIoPpi
;
1045 if (Status
== EFI_ALREADY_STARTED
) {
1047 // Shadow completed and running from memory
1049 DEBUG ((EFI_D_INFO
, "CpuIO PPI has been loaded into memory. Reinstalled PPI=0x%x\n", &gCpuIoPpi
));
1051 Status
= PeiServicesInstallPpi (&gPpiList
);
1052 ASSERT_EFI_ERROR (Status
);