4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Produces the SMM CPU I/O Protocol.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCopyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncThis program and the accompanying materials
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncare licensed and made available under the terms and conditions of the BSD License
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncwhich accompanies this distribution. The full text of the license may be found at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// Handle for the SMM CPU I/O Protocol
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// SMM CPU I/O Protocol instance
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// Lookup table for increment values based on transfer widths
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Check parameters to a SMM CPU I/O Protocol service request.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] MmioOperation TRUE for an MMIO operation, FALSE for I/O Port operation.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Width Signifies the width of the I/O operations.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Address The base address of the I/O operations. The caller is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync responsible for aligning the Address if required.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Count The number of I/O operations to perform.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Buffer For read operations, the destination buffer to store
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the results. For write operations, the source buffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync from which to write data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The data was read from or written to the device.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_UNSUPPORTED The Address is not valid for this system.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check to see if Buffer is NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check to see if Width is in the valid range
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check to see if Width is in the valid range for I/O Port operations
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check to see if any address associated with this transfer exceeds the maximum
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // allowed address. The maximum address implied by the parameters passed in is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Address + Size * Count. If the following condition is met, then the transfer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // is not supported.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Address + Size * Count > (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS) + 1
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Since MAX_ADDRESS can be the maximum integer value supported by the CPU and Count
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // can also be the maximum integer value supported by the CPU, this range
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // check must be adjusted to avoid all overflow conditions.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The following form of the range check is equivalent but assumes that
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // MAX_ADDRESS and MAX_IO_PORT_ADDRESS are of the form (2^n - 1).
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Limit = (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Address > LShiftU64 (MaxCount - Count + 1, Width)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check to see if Address is aligned
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Address & (UINT64)(mStride[Width] - 1)) != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Reads memory-mapped registers.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The I/O operations are carried out exactly as requested. The caller is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync responsible for any alignment and I/O width issues that the bus, device,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync platform, or type of I/O might require.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] This The EFI_SMM_CPU_IO2_PROTOCOL instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Width Signifies the width of the I/O operations.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Address The base address of the I/O operations. The caller is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync responsible for aligning the Address if required.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Count The number of I/O operations to perform.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] Buffer For read operations, the destination buffer to store
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the results. For write operations, the source buffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync from which to write data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The data was read from or written to the device.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_UNSUPPORTED The Address is not valid for this system.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync lack of resources
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Select loop based on the width of the transfer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Uint8Buffer = Buffer; Count > 0; Address += Stride, Uint8Buffer += Stride, Count--) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Writes memory-mapped registers.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The I/O operations are carried out exactly as requested. The caller is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync responsible for any alignment and I/O width issues that the bus, device,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync platform, or type of I/O might require.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] This The EFI_SMM_CPU_IO2_PROTOCOL instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Width Signifies the width of the I/O operations.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Address The base address of the I/O operations. The caller is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync responsible for aligning the Address if required.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Count The number of I/O operations to perform.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Buffer For read operations, the destination buffer to store
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the results. For write operations, the source buffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync from which to write data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The data was read from or written to the device.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_UNSUPPORTED The Address is not valid for this system.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync lack of resources
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Select loop based on the width of the transfer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Uint8Buffer = Buffer; Count > 0; Address += Stride, Uint8Buffer += Stride, Count--) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Reads I/O registers.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The I/O operations are carried out exactly as requested. The caller is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync responsible for any alignment and I/O width issues that the bus, device,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync platform, or type of I/O might require.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] This The EFI_SMM_CPU_IO2_PROTOCOL instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Width Signifies the width of the I/O operations.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Address The base address of the I/O operations. The caller is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync responsible for aligning the Address if required.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Count The number of I/O operations to perform.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] Buffer For read operations, the destination buffer to store
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the results. For write operations, the source buffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync from which to write data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The data was read from or written to the device.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_UNSUPPORTED The Address is not valid for this system.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync lack of resources
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Select loop based on the width of the transfer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Uint8Buffer = Buffer; Count > 0; Address += Stride, Uint8Buffer += Stride, Count--) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *((UINT16 *)Uint8Buffer) = IoRead16 ((UINTN)Address);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *((UINT32 *)Uint8Buffer) = IoRead32 ((UINTN)Address);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Write I/O registers.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The I/O operations are carried out exactly as requested. The caller is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync responsible for any alignment and I/O width issues that the bus, device,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync platform, or type of I/O might require.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] This The EFI_SMM_CPU_IO2_PROTOCOL instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Width Signifies the width of the I/O operations.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Address The base address of the I/O operations. The caller is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync responsible for aligning the Address if required.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Count The number of I/O operations to perform.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Buffer For read operations, the destination buffer to store
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the results. For write operations, the source buffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync from which to write data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The data was read from or written to the device.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_UNSUPPORTED The Address is not valid for this system.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync lack of resources
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Make sure the parameters are valid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Select loop based on the width of the transfer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Uint8Buffer = (UINT8 *)Buffer; Count > 0; Address += Stride, Uint8Buffer += Stride, Count--) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IoWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IoWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The module Entry Point SmmCpuIoProtocol driver
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] ImageHandle The firmware allocated handle for the EFI image.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] SystemTable A pointer to the EFI System Table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The entry point is executed successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Other Some error occurs when executing this entry point.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Copy the SMM CPU I/O Protocol instance into the System Management System Table
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&gSmst->SmmIo, &mSmmCpuIo2, sizeof (mSmmCpuIo2));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Install the SMM CPU I/O Protocol into the SMM protocol database