diff options
Diffstat (limited to 'ReferenceCode/Haswell/SampleCode/Library/SmmIo')
6 files changed, 430 insertions, 0 deletions
diff --git a/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIo.c b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIo.c new file mode 100644 index 0000000..9f1e19d --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIo.c @@ -0,0 +1,169 @@ +/** @file + SMM I/O access utility implementation file, for Ia32 + +@copyright + Copyright (c) 1999 - 2013 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement +**/ + +/// +/// Include files +/// +#include "SmmIoLib.h" + +/** + Do a one byte IO read + + @param[in] Address - IO address to read + + @retval Data read +**/ +UINT8 +SmmIoRead8 ( + IN UINT16 Address + ) +{ + UINT8 Buffer; + + ASSERT (mSmst); + + mSmst->SmmIo.Io.Read ( + &mSmst->SmmIo, + SMM_IO_UINT8, + Address, + 1, + &Buffer + ); + return Buffer; +} + +/** + Do a one byte IO write + + @param[in] Address - IO address to write + @param[in] Data - Data to write +**/ +VOID +SmmIoWrite8 ( + IN UINT16 Address, + IN UINT8 Data + ) +{ + ASSERT (mSmst); + + mSmst->SmmIo.Io.Write ( + &mSmst->SmmIo, + SMM_IO_UINT8, + Address, + 1, + &Data + ); +} + +/** + Do a two byte IO read + + @param[in] Address - IO address to read + + @retval Data read +**/ +UINT16 +SmmIoRead16 ( + IN UINT16 Address + ) +{ + UINT16 Buffer; + + ASSERT (mSmst); + + mSmst->SmmIo.Io.Read ( + &mSmst->SmmIo, + SMM_IO_UINT16, + Address, + 1, + &Buffer + ); + return Buffer; +} + +/** + Do a two byte IO write + + @param[in] Address - IO address to write + @param[in] Data - Data to write +**/ +VOID +SmmIoWrite16 ( + IN UINT16 Address, + IN UINT16 Data + ) +{ + ASSERT (mSmst); + + mSmst->SmmIo.Io.Write ( + &mSmst->SmmIo, + SMM_IO_UINT16, + Address, + 1, + &Data + ); +} + +/** + Do a four byte IO read + + @param[in] Address - IO address to read + + @retval Data read +**/ +UINT32 +SmmIoRead32 ( + IN UINT16 Address + ) +{ + UINT32 Buffer; + + ASSERT (mSmst); + + mSmst->SmmIo.Io.Read ( + &mSmst->SmmIo, + SMM_IO_UINT32, + Address, + 1, + &Buffer + ); + return Buffer; +} + +/** + Do a four byte IO write + + @param[in] Address - IO address to write + @param[in] Data - Data to write +**/ +VOID +SmmIoWrite32 ( + IN UINT16 Address, + IN UINT32 Data + ) +{ + ASSERT (mSmst); + + mSmst->SmmIo.Io.Write ( + &mSmst->SmmIo, + SMM_IO_UINT32, + Address, + 1, + &Data + ); +} diff --git a/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.cif b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.cif new file mode 100644 index 0000000..ec8cae7 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.cif @@ -0,0 +1,12 @@ +<component> + name = "SmmIoLib" + category = ModulePart + LocalRoot = "ReferenceCode\Haswell\SampleCode\Library\SmmIo" + RefName = "SmmIoLib" +[files] +"SmmIoLib.sdl" +"SmmIoLib.mak" +"SmmIoLib.inf" +"SmmIo.c" +"SmmPciIo.c" +<endComponent> diff --git a/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.inf b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.inf new file mode 100644 index 0000000..43045eb --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.inf @@ -0,0 +1,48 @@ +## @file +# Component description file. +# +#@copyright +# Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved +# This software and associated documentation (if any) is furnished +# under a license and may only be used or copied in accordance +# with the terms of the license. Except as permitted by such +# license, no part of this software or documentation may be +# reproduced, stored in a retrieval system, or transmitted in any +# form or by any means without the express written consent of +# Intel Corporation. +# +# This file contains a 'Sample Driver' and is licensed as such +# under the terms of your license agreement with Intel or your +# vendor. This file may be modified by the user, subject to +# the additional terms of the license agreement +# + + +[defines] +BASE_NAME = SmmIoLib +COMPONENT_TYPE = LIBRARY + +[sources.common] + SmmIo.c + SmmPciIo.c + +[includes.common] + $(EDK_SOURCE)/Foundation/Framework + $(EDK_SOURCE)/Foundation/Efi + $(EFI_SOURCE)/Framework + . + $(EDK_SOURCE)/Foundation/Include + $(EDK_SOURCE)/Foundation/Efi/Include + $(EDK_SOURCE)/Foundation/Framework/Include + $(EDK_SOURCE)/Foundation/Include/IndustryStandard + $(EDK_SOURCE)/Foundation/Library/Dxe/Include + $(EFI_SOURCE) + $(EDK_SOURCE)/Foundation/Core/Dxe + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include + $(EDK_SOURCE)/Foundation + $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)/SampleCode/Include + +[libraries.common] + EdkFrameworkProtocolLib + +[nmake.common] diff --git a/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.mak b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.mak new file mode 100644 index 0000000..12b9d5e --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.mak @@ -0,0 +1,15 @@ +# MAK file for the ModulePart:CpuPlatformLib + +$(SmmIoLib_LIB) : SmmIoLib + +SmmIoLib : $(BUILD_DIR)\SmmIoLib.mak SmmIoLibBin + +$(BUILD_DIR)\SmmIoLib.mak : $(SmmIoLib_DIR)\$(@B).cif $(SmmIoLib_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(SmmIoLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +SmmIoLibBin : + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + BUILD_DIR=$(BUILD_DIR) \ + /f $(BUILD_DIR)\SmmIoLib.mak all\ + "MY_INCLUDES=$(EDK_INCLUDES) $(EdkIIGlueLib_INCLUDES) $(PROJECT_CPU_INCLUDES)" \ + TYPE=LIBRARY "PARAMETERS=LIBRARY_NAME=$$(SmmIoLib_LIB)"
\ No newline at end of file diff --git a/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.sdl b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.sdl new file mode 100644 index 0000000..537a750 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmIoLib.sdl @@ -0,0 +1,25 @@ +TOKEN + Name = SmmIoLib_SUPPORT + Value = 1 + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable SmmIoLib support in Project" +End + +TOKEN + Name = "SmmIoLib_LIB" + Value = "$$(LIB_BUILD_DIR)\SmmIoLib.lib" + TokenType = Expression + TargetMAK = Yes +End + +MODULE + Help = "Includes SmmIoLib.mak to Project" + File = "SmmIoLib.mak" +End + +PATH + Name = "SmmIoLib_DIR" +End
\ No newline at end of file diff --git a/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmPciIo.c b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmPciIo.c new file mode 100644 index 0000000..f6fd18f --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/SmmIo/SmmPciIo.c @@ -0,0 +1,161 @@ +/** @file + SMM PCI config space I/O access utility implementation file, for Ia32 + +@copyright + Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement +**/ +#include "SmmIoLib.h" + +STATIC +EFI_STATUS +SmmSingleSegmentPciAccess ( + IN EFI_SMM_CPU_IO_INTERFACE *CpuIo, + IN BOOLEAN IsWrite, + IN SMM_PCI_IO_WIDTH Width, + IN SMM_PCI_IO_ADDRESS *Address, + IN OUT VOID *Buffer + ); + +/** + Read value from the specified PCI config space register + + @param[in] Width - The width (8, 16 or 32 bits) of accessed pci config space register + @param[in] Address - The address of the accessed pci register (bus, dev, func, offset) + @param[in] Buffer - The returned value + + @retval EFI_SUCCESS - All operations successfully + @retval EFI_INVALID_PARAMETER - Width is not valid or dosn't match register address + @retval Other error code - If any error occured when calling libiary functions +**/ +EFI_STATUS +SmmPciCfgRead ( + IN SMM_PCI_IO_WIDTH Width, + IN SMM_PCI_IO_ADDRESS *Address, + IN OUT VOID *Buffer + ) +{ + EFI_SMM_CPU_IO_INTERFACE *SmmCpuIo; + + ASSERT (mSmst); + + SmmCpuIo = &(mSmst->SmmIo); + + return SmmSingleSegmentPciAccess (SmmCpuIo, FALSE, Width, Address, Buffer); +} + +/** + Write value into the specified PCI config space register + + @param[in] Width - The width (8, 16 or 32 bits) of accessed pci config space register + @param[in] Address - The address of the accessed pci register (bus, dev, func, offset) + @param[in] Buffer - The returned value + + @retval EFI_SUCCESS - All operations successfully + @retval EFI_INVALID_PARAMETER - Width is not valid or dosn't match register address + @retval Other error code - If any error occured when calling libiary functions +**/ +EFI_STATUS +SmmPciCfgWrite ( + IN SMM_PCI_IO_WIDTH Width, + IN SMM_PCI_IO_ADDRESS *Address, + IN OUT VOID *Buffer + ) +{ + EFI_SMM_CPU_IO_INTERFACE *SmmCpuIo; + + ASSERT (mSmst); + + SmmCpuIo = &(mSmst->SmmIo); + + return SmmSingleSegmentPciAccess (SmmCpuIo, TRUE, Width, Address, Buffer); +} + +/** + Access a PCI config space address, including read and write + + @param[in] CpuIo - The cpu I/O accessing interface provided by EFI runtime sys table + @param[in] IsWrite - Indicates whether this operation is a write access or read + @param[in] Width - The width (8, 16 or 32 bits) of accessed pci config space register + @param[in] Address - The address of the accessed pci register (bus, dev, func, offset) + @param[in] Buffer - The returned value when this is a reading operation or the data + to be written when this is a writing one + + @retval EFI_SUCCESS - All operations successfully + @retval EFI_INVALID_PARAMETER - Width is not valid or dosn't match register address + @retval Other error code - If any error occured when calling libiary functions +**/ +STATIC +EFI_STATUS +SmmSingleSegmentPciAccess ( + IN EFI_SMM_CPU_IO_INTERFACE *CpuIo, + IN BOOLEAN IsWrite, + IN SMM_PCI_IO_WIDTH Width, + IN SMM_PCI_IO_ADDRESS *Address, + IN OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + PCI_CONFIG_ACCESS_CF8 PciCf8Data; + UINT64 PciDataReg; + + /// + /// PCI Config access are all 32-bit alligned, but by accessing the + /// CONFIG_DATA_REGISTER (0xcfc) with different widths more cycle types + /// are possible on PCI. + /// + /// To read a byte of PCI config space you load 0xcf8 and + /// read 0xcfc, 0xcfd, 0xcfe, 0xcff + /// + /// The validation of passed in arguments "Address" will be checked in the + /// CPU IO functions, so we don't check them here + /// + if (Width >= SmmPciWidthMaximum) { + return EFI_INVALID_PARAMETER; + } + + PciCf8Data.Reg = Address->Register & 0xfc; + PciCf8Data.Func = Address->Function; + PciCf8Data.Dev = Address->Device; + PciCf8Data.Bus = Address->Bus; + PciCf8Data.Reserved = 0; + PciCf8Data.Enable = 1; + + Status = CpuIo->Io.Write (CpuIo, SmmPciWidthUint32, 0xcf8, 1, &PciCf8Data); + if (EFI_ERROR (Status)) { + return Status; + } + + PciDataReg = 0xcfc + (Address->Register & 0x03); + + if (IsWrite) { + /// + /// This is a Pci write operation, write data into (0xcfc + offset) + /// + Status = CpuIo->Io.Write (CpuIo, Width, PciDataReg, 1, Buffer); + if (EFI_ERROR (Status)) { + return Status; + } + } else { + /// + /// This is a Pci Read operation, read returned data from (0xcfc + offset) + /// + Status = CpuIo->Io.Read (CpuIo, Width, PciDataReg, 1, Buffer); + if (EFI_ERROR (Status)) { + return Status; + } + } + + return EFI_SUCCESS; +} |