summaryrefslogtreecommitdiff
path: root/BraswellPlatformPkg
diff options
context:
space:
mode:
authorGuo Mang <mang.guo@intel.com>2016-06-02 10:17:58 +0800
committerHao Wu <hao.a.wu@intel.com>2016-06-07 09:56:32 +0800
commitf2bcdcd5540522a47aa23186f824d07a3bed9884 (patch)
tree6827bb3a8ec1d52bd66a5b802b4fe6d0e975945f /BraswellPlatformPkg
parent2c9875ddeeb3dc8364c78334b00df4051fe416c7 (diff)
downloadedk2-platforms-f2bcdcd5540522a47aa23186f824d07a3bed9884.tar.xz
BraswellPlatformPkg: Add SmmIoLib
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang <mang.guo@intel.com>
Diffstat (limited to 'BraswellPlatformPkg')
-rw-r--r--BraswellPlatformPkg/Library/SmmIo/SmmIo.c355
-rw-r--r--BraswellPlatformPkg/Library/SmmIo/SmmIoLib.inf35
-rw-r--r--BraswellPlatformPkg/Library/SmmIo/SmmPciIo.c162
3 files changed, 552 insertions, 0 deletions
diff --git a/BraswellPlatformPkg/Library/SmmIo/SmmIo.c b/BraswellPlatformPkg/Library/SmmIo/SmmIo.c
new file mode 100644
index 0000000000..3b0d4fc45d
--- /dev/null
+++ b/BraswellPlatformPkg/Library/SmmIo/SmmIo.c
@@ -0,0 +1,355 @@
+/** @file
+ SMM I/O access utility implementation file, for Ia32
+
+ Copyright (c) 1999 - 2015, Intel Corporation. All rights reserved.<BR>
+
+ 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 files
+//
+#include "Library/SmmIoLib.h"
+
+/**
+ Do a one byte IO read
+
+ @param[in] Address IO address to read
+
+ @return 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
+
+ @return 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
+ );
+}
+
+/**
+ Do a one byte Memory write
+
+ @param[in] Dest Memory address to write
+ @param[in] Data Data to write
+
+**/
+VOID
+SmmMemWrite8 (
+ IN UINT64 Dest,
+ IN UINT8 Data
+ )
+{
+ mSmst->SmmIo.Mem.Write (
+ &mSmst->SmmIo,
+ SMM_IO_UINT8,
+ Dest,
+ 1,
+ &Data
+ );
+
+ return ;
+}
+
+/**
+ Do a one byte Memory read
+
+ @param[in] Dest Memory address to read
+
+ @Return Data read
+
+**/
+UINT8
+SmmMemRead8 (
+ IN UINT64 Dest
+ )
+{
+ UINT8 Data;
+ mSmst->SmmIo.Mem.Read (
+ &mSmst->SmmIo,
+ SMM_IO_UINT8,
+ Dest,
+ 1,
+ &Data
+ );
+
+ return Data;
+}
+
+/**
+ Do a two bytes Memory write
+
+ @param[in] Dest Memory address to write
+ @param[in] Data Data to write
+
+**/
+VOID
+SmmMemWrite16 (
+ IN UINT64 Dest,
+ IN UINT16 Data
+ )
+{
+ mSmst->SmmIo.Mem.Write (
+ &mSmst->SmmIo,
+ SMM_IO_UINT16,
+ Dest,
+ 1,
+ &Data
+ );
+
+ return ;
+}
+
+/**
+ Do a two bytes Memory read
+
+ @param[in] Dest Memory address to read
+
+ @return Data read
+
+**/
+UINT16
+SmmMemRead16 (
+ IN UINT64 Dest
+ )
+{
+ UINT16 Data;
+ mSmst->SmmIo.Mem.Read (
+ &mSmst->SmmIo,
+ SMM_IO_UINT16,
+ Dest,
+ 1,
+ &Data
+ );
+
+ return Data;
+}
+
+/**
+ Do a four bytes Memory write
+
+ @param[in] Dest Memory address to write
+ @param[in] Data Data to write
+
+**/
+VOID
+SmmMemWrite32 (
+ IN UINT64 Dest,
+ IN UINT32 Data
+ )
+{
+ mSmst->SmmIo.Mem.Write (
+ &mSmst->SmmIo,
+ SMM_IO_UINT32,
+ Dest,
+ 1,
+ &Data
+ );
+
+ return ;
+}
+
+/**
+ Do a four bytes Memory read
+
+ @param[in] Dest Memory address to read
+
+ @return Data read
+
+**/
+UINT32
+SmmMemRead32 (
+ IN UINT64 Dest
+ )
+{
+ UINT32 Data;
+ mSmst->SmmIo.Mem.Read (
+ &mSmst->SmmIo,
+ SMM_IO_UINT32,
+ Dest,
+ 1,
+ &Data
+ );
+
+ return Data;
+}
+
+/**
+ Do a four bytes Memory read, then AND with Data, then write back to the same address
+
+ @param[in] Dest Memory address to write
+ @param[in] Data Data to do AND
+
+**/
+VOID
+SmmMemAnd32 (
+ IN UINT64 Dest,
+ IN UINT32 Data
+ )
+{
+ UINT32 Data_And;
+ mSmst->SmmIo.Mem.Read (
+ &mSmst->SmmIo,
+ SMM_IO_UINT32,
+ Dest,
+ 1,
+ &Data_And
+ );
+ Data_And&=Data;
+ mSmst->SmmIo.Mem.Write (
+ &mSmst->SmmIo,
+ SMM_IO_UINT32,
+ Dest,
+ 1,
+ &Data_And
+ );
+
+ return ;
+}
diff --git a/BraswellPlatformPkg/Library/SmmIo/SmmIoLib.inf b/BraswellPlatformPkg/Library/SmmIo/SmmIoLib.inf
new file mode 100644
index 0000000000..17b5aa5d49
--- /dev/null
+++ b/BraswellPlatformPkg/Library/SmmIo/SmmIoLib.inf
@@ -0,0 +1,35 @@
+## @file
+# Component description file for SMM IO Library.
+#
+# Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
+#
+# 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.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SmmIoLib
+ FILE_GUID = A6A16CCB-91B0-42f4-B4F3-D16D7A8662E6
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = SmmIoLib
+
+[Sources]
+ SmmIo.c
+ SmmPciIo.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ BraswellPlatformPkg/BraswellPlatformPkg.dec
+
+[LibraryClasses]
+ PciLib
+ IoLib
+ BaseLib
diff --git a/BraswellPlatformPkg/Library/SmmIo/SmmPciIo.c b/BraswellPlatformPkg/Library/SmmIo/SmmPciIo.c
new file mode 100644
index 0000000000..5af687e3b1
--- /dev/null
+++ b/BraswellPlatformPkg/Library/SmmIo/SmmPciIo.c
@@ -0,0 +1,162 @@
+/** @file
+ SMM PCI config space I/O access utility implementation file, for Ia32
+
+ Copyright (c) 1999 - 2015, Intel Corporation. All rights reserved.<BR>
+
+ 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 "Library/SmmIoLib.h"
+
+STATIC
+EFI_STATUS
+SmmSingleSegmentPciAccess (
+ IN EFI_SMM_CPU_IO2_PROTOCOL *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, out] 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_IO2_PROTOCOL *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, out] 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_IO2_PROTOCOL *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, out] 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_IO2_PROTOCOL *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.Bits.Reg = Address->Register & 0xfc;
+ PciCf8Data.Bits.Func = Address->Function;
+ PciCf8Data.Bits.Dev = Address->Device;
+ PciCf8Data.Bits.Bus = Address->Bus;
+ PciCf8Data.Bits.Reserved = 0;
+ PciCf8Data.Bits.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;
+}