/** @file Produces the CPU I/O PPI. Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ #include #include #include #include #include #include #define MAX_IO_PORT_ADDRESS 0xFFFF // // Function Prototypes // EFI_STATUS EFIAPI CpuMemoryServiceRead ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN EFI_PEI_CPU_IO_PPI_WIDTH Width, IN UINT64 Address, IN UINTN Count, OUT VOID *Buffer ); EFI_STATUS EFIAPI CpuMemoryServiceWrite ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN EFI_PEI_CPU_IO_PPI_WIDTH Width, IN UINT64 Address, IN UINTN Count, IN VOID *Buffer ); EFI_STATUS EFIAPI CpuIoServiceRead ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN EFI_PEI_CPU_IO_PPI_WIDTH Width, IN UINT64 Address, IN UINTN Count, OUT VOID *Buffer ); EFI_STATUS EFIAPI CpuIoServiceWrite ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN EFI_PEI_CPU_IO_PPI_WIDTH Width, IN UINT64 Address, IN UINTN Count, IN VOID *Buffer ); UINT8 EFIAPI CpuIoRead8 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN UINT64 Address ); UINT16 EFIAPI CpuIoRead16 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN UINT64 Address ); UINT32 EFIAPI CpuIoRead32 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN UINT64 Address ); UINT64 EFIAPI CpuIoRead64 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN UINT64 Address ); VOID EFIAPI CpuIoWrite8 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN UINT64 Address, IN UINT8 Data ); VOID EFIAPI CpuIoWrite16 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN UINT64 Address, IN UINT16 Data ); VOID EFIAPI CpuIoWrite32 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN UINT64 Address, IN UINT32 Data ); VOID EFIAPI CpuIoWrite64 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN UINT64 Address, IN UINT64 Data ); UINT8 EFIAPI CpuMemRead8 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN UINT64 Address ); UINT16 EFIAPI CpuMemRead16 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN UINT64 Address ); UINT32 EFIAPI CpuMemRead32 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN UINT64 Address ); UINT64 EFIAPI CpuMemRead64 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN UINT64 Address ); VOID EFIAPI CpuMemWrite8 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN UINT64 Address, IN UINT8 Data ); VOID EFIAPI CpuMemWrite16 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN UINT64 Address, IN UINT16 Data ); VOID EFIAPI CpuMemWrite32 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN UINT64 Address, IN UINT32 Data ); VOID EFIAPI CpuMemWrite64 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN UINT64 Address, IN UINT64 Data ); // // Instance of CPU I/O PPI // EFI_PEI_CPU_IO_PPI gCpuIoPpi = { { CpuMemoryServiceRead, CpuMemoryServiceWrite }, { CpuIoServiceRead, CpuIoServiceWrite }, CpuIoRead8, CpuIoRead16, CpuIoRead32, CpuIoRead64, CpuIoWrite8, CpuIoWrite16, CpuIoWrite32, CpuIoWrite64, CpuMemRead8, CpuMemRead16, CpuMemRead32, CpuMemRead64, CpuMemWrite8, CpuMemWrite16, CpuMemWrite32, CpuMemWrite64 }; // // PPI Descriptor used to install the CPU I/O PPI // EFI_PEI_PPI_DESCRIPTOR gPpiList = { (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), &gEfiPeiCpuIoPpiInstalledGuid, NULL }; // // Lookup table for increment values based on transfer widths // UINT8 mInStride[] = { 1, // EfiPeiCpuIoWidthUint8 2, // EfiPeiCpuIoWidthUint16 4, // EfiPeiCpuIoWidthUint32 8, // EfiPeiCpuIoWidthUint64 0, // EfiPeiCpuIoWidthFifoUint8 0, // EfiPeiCpuIoWidthFifoUint16 0, // EfiPeiCpuIoWidthFifoUint32 0, // EfiPeiCpuIoWidthFifoUint64 1, // EfiPeiCpuIoWidthFillUint8 2, // EfiPeiCpuIoWidthFillUint16 4, // EfiPeiCpuIoWidthFillUint32 8 // EfiPeiCpuIoWidthFillUint64 }; // // Lookup table for increment values based on transfer widths // UINT8 mOutStride[] = { 1, // EfiPeiCpuIoWidthUint8 2, // EfiPeiCpuIoWidthUint16 4, // EfiPeiCpuIoWidthUint32 8, // EfiPeiCpuIoWidthUint64 1, // EfiPeiCpuIoWidthFifoUint8 2, // EfiPeiCpuIoWidthFifoUint16 4, // EfiPeiCpuIoWidthFifoUint32 8, // EfiPeiCpuIoWidthFifoUint64 0, // EfiPeiCpuIoWidthFillUint8 0, // EfiPeiCpuIoWidthFillUint16 0, // EfiPeiCpuIoWidthFillUint32 0 // EfiPeiCpuIoWidthFillUint64 }; /** Check parameters to a CPU I/O PPI service request. @param[in] MmioOperation TRUE for an MMIO operation, FALSE for I/O Port operation. @param[in] Width The width of the access. Enumerated in bytes. @param[in] Address The physical address of the access. @param[in] Count The number of accesses to perform. @param[in] Buffer A pointer to the buffer of data. @retval EFI_SUCCESS The parameters for this request pass the checks. @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system. @retval EFI_INVALID_PARAMETER Buffer is NULL. @retval EFI_UNSUPPORTED The address range specified by Address, Width, and Count is not valid for this EFI system. **/ EFI_STATUS CpuIoCheckParameter ( IN BOOLEAN MmioOperation, IN EFI_PEI_CPU_IO_PPI_WIDTH Width, IN UINT64 Address, IN UINTN Count, IN VOID *Buffer ) { UINT64 MaxCount; UINT64 Limit; // // Check to see if Buffer is NULL // if (Buffer == NULL) { return EFI_INVALID_PARAMETER; } // // Check to see if Width is in the valid range // if (Width < 0 || Width >= EfiPeiCpuIoWidthMaximum) { return EFI_INVALID_PARAMETER; } // // For FIFO type, the target address won't increase during the access, // so treat Count as 1 // if (Width >= EfiPeiCpuIoWidthFifoUint8 && Width <= EfiPeiCpuIoWidthFifoUint64) { Count = 1; } // // Check to see if Width is in the valid range for I/O Port operations // Width = (EFI_PEI_CPU_IO_PPI_WIDTH) (Width & 0x03); if (!MmioOperation && (Width == EfiPeiCpuIoWidthUint64)) { return EFI_INVALID_PARAMETER; } // // Check to see if any address associated with this transfer exceeds the maximum // allowed address. The maximum address implied by the parameters passed in is // Address + Size * Count. If the following condition is met, then the transfer // is not supported. // // Address + Size * Count > (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS) + 1 // // Since MAX_ADDRESS can be the maximum integer value supported by the CPU and Count // can also be the maximum integer value supported by the CPU, this range // check must be adjusted to avoid all overflow conditions. // // The following form of the range check is equivalent but assumes that // MAX_ADDRESS and MAX_IO_PORT_ADDRESS are of the form (2^n - 1). // Limit = (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS); if (Count == 0) { if (Address > Limit) { return EFI_UNSUPPORTED; } } else { MaxCount = RShiftU64 (Limit, Width); if (MaxCount < (Count - 1)) { return EFI_UNSUPPORTED; } if (Address > LShiftU64 (MaxCount - Count + 1, Width)) { return EFI_UNSUPPORTED; } } return EFI_SUCCESS; } /** Reads memory-mapped registers. @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Width The width of the access. Enumerated in bytes. @param[in] Address The physical address of the access. @param[in] Count The number of accesses to perform. @param[out] Buffer A pointer to the buffer of data. @retval EFI_SUCCESS The function completed successfully. @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system. @retval EFI_INVALID_PARAMETER Buffer is NULL. @retval EFI_UNSUPPORTED The address range specified by Address, Width, and Count is not valid for this EFI system. **/ EFI_STATUS EFIAPI CpuMemoryServiceRead ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN EFI_PEI_CPU_IO_PPI_WIDTH Width, IN UINT64 Address, IN UINTN Count, OUT VOID *Buffer ) { EFI_STATUS Status; UINT8 InStride; UINT8 OutStride; EFI_PEI_CPU_IO_PPI_WIDTH OperationWidth; BOOLEAN Aligned; UINT8 *Uint8Buffer; Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer); if (EFI_ERROR (Status)) { return Status; } // // Select loop based on the width of the transfer // InStride = mInStride[Width]; OutStride = mOutStride[Width]; OperationWidth = (EFI_PEI_CPU_IO_PPI_WIDTH) (Width & 0x03); Aligned = (BOOLEAN)(((UINTN)Buffer & (mInStride[OperationWidth] - 1)) == 0x00); for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) { if (OperationWidth == EfiPeiCpuIoWidthUint8) { *Uint8Buffer = MmioRead8 ((UINTN)Address); } else if (OperationWidth == EfiPeiCpuIoWidthUint16) { if (Aligned) { *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address); } else { WriteUnaligned16 ((UINT16 *)Uint8Buffer, MmioRead16 ((UINTN)Address)); } } else if (OperationWidth == EfiPeiCpuIoWidthUint32) { if (Aligned) { *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address); } else { WriteUnaligned32 ((UINT32 *)Uint8Buffer, MmioRead32 ((UINTN)Address)); } } else if (OperationWidth == EfiPeiCpuIoWidthUint64) { if (Aligned) { *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address); } else { WriteUnaligned64 ((UINT64 *)Uint8Buffer, MmioRead64 ((UINTN)Address)); } } } return EFI_SUCCESS; } /** Writes memory-mapped registers. @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Width The width of the access. Enumerated in bytes. @param[in] Address The physical address of the access. @param[in] Count The number of accesses to perform. @param[in] Buffer A pointer to the buffer of data. @retval EFI_SUCCESS The function completed successfully. @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system. @retval EFI_INVALID_PARAMETER Buffer is NULL. @retval EFI_UNSUPPORTED The address range specified by Address, Width, and Count is not valid for this EFI system. **/ EFI_STATUS EFIAPI CpuMemoryServiceWrite ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN EFI_PEI_CPU_IO_PPI_WIDTH Width, IN UINT64 Address, IN UINTN Count, IN VOID *Buffer ) { EFI_STATUS Status; UINT8 InStride; UINT8 OutStride; EFI_PEI_CPU_IO_PPI_WIDTH OperationWidth; BOOLEAN Aligned; UINT8 *Uint8Buffer; Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer); if (EFI_ERROR (Status)) { return Status; } // // Select loop based on the width of the transfer // InStride = mInStride[Width]; OutStride = mOutStride[Width]; OperationWidth = (EFI_PEI_CPU_IO_PPI_WIDTH) (Width & 0x03); Aligned = (BOOLEAN)(((UINTN)Buffer & (mInStride[OperationWidth] - 1)) == 0x00); for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) { if (OperationWidth == EfiPeiCpuIoWidthUint8) { MmioWrite8 ((UINTN)Address, *Uint8Buffer); } else if (OperationWidth == EfiPeiCpuIoWidthUint16) { if (Aligned) { MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer)); } else { MmioWrite16 ((UINTN)Address, ReadUnaligned16 ((UINT16 *)Uint8Buffer)); } } else if (OperationWidth == EfiPeiCpuIoWidthUint32) { if (Aligned) { MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer)); } else { MmioWrite32 ((UINTN)Address, ReadUnaligned32 ((UINT32 *)Uint8Buffer)); } } else if (OperationWidth == EfiPeiCpuIoWidthUint64) { if (Aligned) { MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer)); } else { MmioWrite64 ((UINTN)Address, ReadUnaligned64 ((UINT64 *)Uint8Buffer)); } } } return EFI_SUCCESS; } /** Reads I/O registers. @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Width The width of the access. Enumerated in bytes. @param[in] Address The physical address of the access. @param[in] Count The number of accesses to perform. @param[out] Buffer A pointer to the buffer of data. @retval EFI_SUCCESS The function completed successfully. @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system. @retval EFI_INVALID_PARAMETER Buffer is NULL. @retval EFI_UNSUPPORTED The address range specified by Address, Width, and Count is not valid for this EFI system. **/ EFI_STATUS EFIAPI CpuIoServiceRead ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN EFI_PEI_CPU_IO_PPI_WIDTH Width, IN UINT64 Address, IN UINTN Count, OUT VOID *Buffer ) { EFI_STATUS Status; UINT8 InStride; UINT8 OutStride; EFI_PEI_CPU_IO_PPI_WIDTH OperationWidth; BOOLEAN Aligned; UINT8 *Uint8Buffer; Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer); if (EFI_ERROR (Status)) { return Status; } // // Select loop based on the width of the transfer // InStride = mInStride[Width]; OutStride = mOutStride[Width]; OperationWidth = (EFI_PEI_CPU_IO_PPI_WIDTH) (Width & 0x03); Aligned = (BOOLEAN)(((UINTN)Buffer & (mInStride[OperationWidth] - 1)) == 0x00); for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) { if (OperationWidth == EfiPeiCpuIoWidthUint8) { *Uint8Buffer = IoRead8 ((UINTN)Address); } else if (OperationWidth == EfiPeiCpuIoWidthUint16) { if (Aligned) { *((UINT16 *)Uint8Buffer) = IoRead16 ((UINTN)Address); } else { WriteUnaligned16 ((UINT16 *)Uint8Buffer, IoRead16 ((UINTN)Address)); } } else if (OperationWidth == EfiPeiCpuIoWidthUint32) { if (Aligned) { *((UINT32 *)Uint8Buffer) = IoRead32 ((UINTN)Address); } else { WriteUnaligned32 ((UINT32 *)Uint8Buffer, IoRead32 ((UINTN)Address)); } } } return EFI_SUCCESS; } /** Write I/O registers. @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Width The width of the access. Enumerated in bytes. @param[in] Address The physical address of the access. @param[in] Count The number of accesses to perform. @param[in] Buffer A pointer to the buffer of data. @retval EFI_SUCCESS The function completed successfully. @retval EFI_INVALID_PARAMETER Width is invalid for this EFI system. @retval EFI_INVALID_PARAMETER Buffer is NULL. @retval EFI_UNSUPPORTED The address range specified by Address, Width, and Count is not valid for this EFI system. **/ EFI_STATUS EFIAPI CpuIoServiceWrite ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN EFI_PEI_CPU_IO_PPI_WIDTH Width, IN UINT64 Address, IN UINTN Count, IN VOID *Buffer ) { EFI_STATUS Status; UINT8 InStride; UINT8 OutStride; EFI_PEI_CPU_IO_PPI_WIDTH OperationWidth; BOOLEAN Aligned; UINT8 *Uint8Buffer; // // Make sure the parameters are valid // Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer); if (EFI_ERROR (Status)) { return Status; } // // Select loop based on the width of the transfer // InStride = mInStride[Width]; OutStride = mOutStride[Width]; OperationWidth = (EFI_PEI_CPU_IO_PPI_WIDTH) (Width & 0x03); Aligned = (BOOLEAN)(((UINTN)Buffer & (mInStride[OperationWidth] - 1)) == 0x00); for (Uint8Buffer = (UINT8 *)Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) { if (OperationWidth == EfiPeiCpuIoWidthUint8) { IoWrite8 ((UINTN)Address, *Uint8Buffer); } else if (OperationWidth == EfiPeiCpuIoWidthUint16) { if (Aligned) { IoWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer)); } else { IoWrite16 ((UINTN)Address, ReadUnaligned16 ((UINT16 *)Uint8Buffer)); } } else if (OperationWidth == EfiPeiCpuIoWidthUint32) { if (Aligned) { IoWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer)); } else { IoWrite32 ((UINTN)Address, ReadUnaligned32 ((UINT32 *)Uint8Buffer)); } } } return EFI_SUCCESS; } /** 8-bit I/O read operations. @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @return An 8-bit value returned from the I/O space. **/ UINT8 EFIAPI CpuIoRead8 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN UINT64 Address ) { return IoRead8 ((UINTN)Address); } /** 16-bit I/O read operations. @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @return A 16-bit value returned from the I/O space. **/ UINT16 EFIAPI CpuIoRead16 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN UINT64 Address ) { return IoRead16 ((UINTN)Address); } /** 32-bit I/O read operations. @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @return A 32-bit value returned from the I/O space. **/ UINT32 EFIAPI CpuIoRead32 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN UINT64 Address ) { return IoRead32 ((UINTN)Address); } /** 64-bit I/O read operations. @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @return A 64-bit value returned from the I/O space. **/ UINT64 EFIAPI CpuIoRead64 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN UINT64 Address ) { return IoRead64 ((UINTN)Address); } /** 8-bit I/O write operations. @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @param[in] Data The data to write. **/ VOID EFIAPI CpuIoWrite8 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN UINT64 Address, IN UINT8 Data ) { IoWrite8 ((UINTN)Address, Data); } /** 16-bit I/O write operations. @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @param[in] Data The data to write. **/ VOID EFIAPI CpuIoWrite16 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN UINT64 Address, IN UINT16 Data ) { IoWrite16 ((UINTN)Address, Data); } /** 32-bit I/O write operations. @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @param[in] Data The data to write. **/ VOID EFIAPI CpuIoWrite32 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN UINT64 Address, IN UINT32 Data ) { IoWrite32 ((UINTN)Address, Data); } /** 64-bit I/O write operations. @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @param[in] Data The data to write. **/ VOID EFIAPI CpuIoWrite64 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN UINT64 Address, IN UINT64 Data ) { IoWrite64 ((UINTN)Address, Data); } /** 8-bit memory read operations. @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @return An 8-bit value returned from the memory space. **/ UINT8 EFIAPI CpuMemRead8 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN UINT64 Address ) { return MmioRead8 ((UINTN)Address); } /** 16-bit memory read operations. @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @return A 16-bit value returned from the memory space. **/ UINT16 EFIAPI CpuMemRead16 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN UINT64 Address ) { return MmioRead16 ((UINTN)Address); } /** 32-bit memory read operations. @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @return A 32-bit value returned from the memory space. **/ UINT32 EFIAPI CpuMemRead32 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN UINT64 Address ) { return MmioRead32 ((UINTN)Address); } /** 64-bit memory read operations. @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @return A 64-bit value returned from the memory space. **/ UINT64 EFIAPI CpuMemRead64 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN UINT64 Address ) { return MmioRead64 ((UINTN)Address); } /** 8-bit memory write operations. @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @param[in] Data The data to write. **/ VOID EFIAPI CpuMemWrite8 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN UINT64 Address, IN UINT8 Data ) { MmioWrite8 ((UINTN)Address, Data); } /** 16-bit memory write operations. @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @param[in] Data The data to write. **/ VOID EFIAPI CpuMemWrite16 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN UINT64 Address, IN UINT16 Data ) { MmioWrite16 ((UINTN)Address, Data); } /** 32-bit memory write operations. @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @param[in] Data The data to write. **/ VOID EFIAPI CpuMemWrite32 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN UINT64 Address, IN UINT32 Data ) { MmioWrite32 ((UINTN)Address, Data); } /** 64-bit memory write operations. @param[in] PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. @param[in] This Pointer to local data for the interface. @param[in] Address The physical address of the access. @param[in] Data The data to write. **/ VOID EFIAPI CpuMemWrite64 ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_CPU_IO_PPI *This, IN UINT64 Address, IN UINT64 Data ) { MmioWrite64 ((UINTN)Address, Data); } /** The Entry point of the CPU I/O PEIM This function is the Entry point of the CPU I/O PEIM which installs CpuIoPpi. @param[in] FileHandle Pointer to image file handle. @param[in] PeiServices Pointer to PEI Services Table @retval EFI_SUCCESS CPU I/O PPI successfully installed **/ EFI_STATUS EFIAPI CpuIoInitialize ( IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices ) { EFI_STATUS Status; // // Register so it will be automatically shadowed to memory // Status = PeiServicesRegisterForShadow (FileHandle); // // Make CpuIo pointer in PeiService table point to gCpuIoPpi // (*((EFI_PEI_SERVICES **)PeiServices))->CpuIo = &gCpuIoPpi; if (Status == EFI_ALREADY_STARTED) { // // Shadow completed and running from memory // DEBUG ((EFI_D_INFO, "CpuIO PPI has been loaded into memory. Reinstalled PPI=0x%x\n", &gCpuIoPpi)); } else { Status = PeiServicesInstallPpi (&gPpiList); ASSERT_EFI_ERROR (Status); } return EFI_SUCCESS; }