From 9f01a361767bfec4222daf72a8836666bedffdff Mon Sep 17 00:00:00 2001 From: Guo Mang Date: Fri, 23 Dec 2016 10:51:21 +0800 Subject: BroxtonSiPkg: Add SmmAccess Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang --- .../BroxtonSiPkg/Cpu/SmmAccess/Dxe/SmmAccess.inf | 47 ++++ .../Cpu/SmmAccess/Dxe/SmmAccessDriver.c | 276 +++++++++++++++++++ .../Cpu/SmmAccess/Dxe/SmmAccessDriver.h | 171 ++++++++++++ .../BroxtonSiPkg/Cpu/SmmAccess/Pei/SmmAccess.inf | 45 ++++ .../Cpu/SmmAccess/Pei/SmmAccessDriver.c | 292 +++++++++++++++++++++ .../Cpu/SmmAccess/Pei/SmmAccessDriver.h | 167 ++++++++++++ 6 files changed, 998 insertions(+) create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SmmAccess/Dxe/SmmAccess.inf create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SmmAccess/Dxe/SmmAccessDriver.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SmmAccess/Dxe/SmmAccessDriver.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SmmAccess/Pei/SmmAccess.inf create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SmmAccess/Pei/SmmAccessDriver.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SmmAccess/Pei/SmmAccessDriver.h (limited to 'Silicon') diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SmmAccess/Dxe/SmmAccess.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SmmAccess/Dxe/SmmAccess.inf new file mode 100644 index 0000000000..b24d9b704a --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SmmAccess/Dxe/SmmAccess.inf @@ -0,0 +1,47 @@ +## @file +# SmmAccess module. +# +# Copyright (c) 1999 - 2016, 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. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SmmAccess + FILE_GUID = 326E9CC6-9839-4885-B2ED-275903B668E1 + VERSION_STRING = 1.0 + MODULE_TYPE = DXE_DRIVER + ENTRY_POINT = SmmAccessDriverEntryPoint + +[Sources] + SmmAccessDriver.h + SmmAccessDriver.c + +[Packages] + MdePkg/MdePkg.dec + BroxtonSiPkg/BroxtonSiPkg.dec + +[LibraryClasses] + BaseMemoryLib + HobLib + DebugLib + MemoryAllocationLib + UefiBootServicesTableLib + UefiDriverEntryPoint + +[Guids] + gEfiSmmPeiSmramMemoryReserveGuid ## UNDEFINED + +[Protocols] + gEfiSmmAccess2ProtocolGuid ## PRODUCES + +[Depex] + gEfiPciRootBridgeIoProtocolGuid diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SmmAccess/Dxe/SmmAccessDriver.c b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SmmAccess/Dxe/SmmAccessDriver.c new file mode 100644 index 0000000000..0167024364 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SmmAccess/Dxe/SmmAccessDriver.c @@ -0,0 +1,276 @@ +/** @file + This is the driver that publishes the SMM Access Protocol + instance for System Agent. + + Copyright (c) 1999 - 2016, 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 "SmmAccessDriver.h" +#include +#include +#include +#include +#include +#include +#include + + +static SMM_ACCESS_PRIVATE_DATA mSmmAccess; + +/** + This is the standard EFI driver point that detects + whether there is an GMCH815 chipset in the system + and if so, installs an SMM Access Protocol + + @param[in] ImageHandle Handle for the image of this driver + @param[in] SystemTable Pointer to the EFI System Table + + @retval EFI_SUCCESS Protocol successfully started and installed + @retval EFI_UNSUPPORTED Protocol can't be started + +**/ +EFI_STATUS +EFIAPI +SmmAccessDriverEntryPoint( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + UINTN Index; + EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *DescriptorBlock; + VOID *GuidHob; + + // + // Initialize Global variables + // + ZeroMem (&mSmmAccess, sizeof (mSmmAccess)); + + mSmmAccess.Signature = SMM_ACCESS_PRIVATE_DATA_SIGNATURE; + mSmmAccess.Handle = NULL; + + GuidHob = GetFirstGuidHob (&gEfiSmmPeiSmramMemoryReserveGuid); + if (!GuidHob) { + DEBUG ((EFI_D_ERROR, "SmramMemoryReserve HOB not found\n")); + return(EFI_NOT_FOUND); + } + + DescriptorBlock = (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *) ((UINT8 *) GuidHob + sizeof (EFI_HOB_GUID_TYPE)); + // + // use the hob to publish SMRAM capabilities + // + for (Index = 0; Index < DescriptorBlock->NumberOfSmmReservedRegions; Index++) { + mSmmAccess.SmramDesc[Index].PhysicalStart = + DescriptorBlock->Descriptor[Index].PhysicalStart; + mSmmAccess.SmramDesc[Index].CpuStart = + DescriptorBlock->Descriptor[Index].CpuStart; + mSmmAccess.SmramDesc[Index].PhysicalSize = + DescriptorBlock->Descriptor[Index].PhysicalSize; + mSmmAccess.SmramDesc[Index].RegionState = + DescriptorBlock->Descriptor[Index].RegionState; + } + + mSmmAccess.NumberRegions = Index; + mSmmAccess.SmmAccess.Open = Open; + mSmmAccess.SmmAccess.Close = Close; + mSmmAccess.SmmAccess.Lock = Lock; + mSmmAccess.SmmAccess.GetCapabilities = GetCapabilities; + mSmmAccess.SmmAccess.LockState = FALSE; + mSmmAccess.SmmAccess.OpenState = FALSE; + + // + // Install our protocol interfaces on the device's handle + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &mSmmAccess.Handle, + &gEfiSmmAccess2ProtocolGuid, + &mSmmAccess.SmmAccess, + NULL + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "InstallMultipleProtocolInterfaces returned %r\n", Status)); + return EFI_UNSUPPORTED; + } + + return EFI_SUCCESS; +} + + +/** + This routine accepts a request to "open" a region of SMRAM. The + region could be legacy ABSEG, HSEG, or TSEG near top of physical memory. + The use of "open" means that the memory is visible from all boot-service + and SMM agents. + + @param[in] This Pointer to the SMM Access Interface + + @retval EFI_SUCCESS The region was successfully opened + @retval EFI_DEVICE_ERROR The region could not be opened because locked by chipset + @retval EFI_INVALID_PARAMETER The descriptor index was out of bounds. + +**/ +EFI_STATUS +EFIAPI +Open ( + IN EFI_SMM_ACCESS2_PROTOCOL *This + ) +{ + SMM_ACCESS_PRIVATE_DATA *SmmAccess; + UINTN Index; + + SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS(This); + + for (Index = 0; Index < SmmAccess->NumberRegions; Index ++) { + if (SmmAccess->SmramDesc[Index].RegionState & EFI_SMRAM_LOCKED) { + DEBUG ((EFI_D_WARN, "Cannot open a locked SMRAM region\n")); + continue; + } + + Mmio64AndThenOr (MCH_BASE_ADDRESS, 0x6840, 0, 0xFF); + + Mmio64AndThenOr (MCH_BASE_ADDRESS, 0x6848, 0, 0xFF); + + SmmAccess->SmramDesc[Index].RegionState &= ~(EFI_SMRAM_CLOSED |EFI_ALLOCATED); + SmmAccess->SmramDesc[Index].RegionState |= EFI_SMRAM_OPEN; + } + SmmAccess->SmmAccess.OpenState = TRUE; + + return EFI_SUCCESS; +} + + +/** + This routine accepts a request to "close" a region of SMRAM. The + region could be legacy AB or TSEG near top of physical memory. + The use of "close" means that the memory is only visible from SMM agents, + not from BS or RT code. + + @param[in] This Pointer to the SMM Access Interface + + @retval EFI_SUCCESS The region was successfully closed + @retval EFI_DEVICE_ERROR The region could not be closed because locked by chipset + @retval EFI_INVALID_PARAMETER The descriptor index was out of bounds + +**/ +EFI_STATUS +EFIAPI +Close ( + IN EFI_SMM_ACCESS2_PROTOCOL *This + ) +{ + SMM_ACCESS_PRIVATE_DATA *SmmAccess; + UINTN Index; + + SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS(This); + + for (Index = 0; Index < SmmAccess->NumberRegions; Index ++) { + if (SmmAccess->SmramDesc[Index].RegionState & EFI_SMRAM_LOCKED) { + DEBUG ((EFI_D_WARN, "Cannot close a locked SMRAM region\n")); + continue; + } + if (SmmAccess->SmramDesc[Index].RegionState & EFI_SMRAM_CLOSED) { + continue; + } + + SmmAccess->SmramDesc[Index].RegionState &= ~EFI_SMRAM_OPEN; + SmmAccess->SmramDesc[Index].RegionState |= (EFI_SMRAM_CLOSED |EFI_ALLOCATED); + } + SmmAccess->SmmAccess.OpenState = FALSE; + + return EFI_SUCCESS; +} + + +/** + This routine accepts a request to "lock" SMRAM. The + region could be legacy AB or TSEG near top of physical memory. + The use of "lock" means that the memory can no longer be opened + to BS state. + + @param[in] This Pointer to the SMM Access Interface + + @retval EFI_SUCCESS The region was successfully locked. + @retval EFI_DEVICE_ERROR The region could not be locked because at least one range is still open. + @retval EFI_INVALID_PARAMETER The descriptor index was out of bounds. + +**/ +EFI_STATUS +EFIAPI +Lock ( + IN EFI_SMM_ACCESS2_PROTOCOL *This + ) +{ + SMM_ACCESS_PRIVATE_DATA *SmmAccess; + UINTN Index; + + SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS(This); + + for (Index = 0; Index < SmmAccess->NumberRegions; Index ++) { + if (SmmAccess->SmmAccess.OpenState) { + DEBUG ((EFI_D_WARN, "Cannot lock SMRAM when SMRAM regions are still open\n")); + return EFI_DEVICE_ERROR; + } + + Mmio64AndThenOr (MCH_BASE_ADDRESS, 0x6838, 0, 0x00); + + SmmAccess->SmramDesc[Index].RegionState |= EFI_SMRAM_LOCKED; + } + SmmAccess->SmmAccess.LockState = TRUE; + + return EFI_SUCCESS; +} + +/** + This routine services a user request to discover the SMRAM + capabilities of this platform. This will report the possible + ranges that are possible for SMRAM access, based upon the + memory controller capabilities. + + @param[in] This Pointer to the SMRAM Access Interface. + @param[in, out] SmramMapSize Pointer to the variable containing size of the buffer to contain the description information + @param[in, out] SmramMap Buffer containing the data describing the Smram region descriptors + + @retval EFI_BUFFER_TOO_SMALL The user did not provide a sufficient buffer. + @retval EFI_SUCCESS The user provided a sufficiently-sized buffer. + +**/ +EFI_STATUS +EFIAPI +GetCapabilities ( + IN CONST EFI_SMM_ACCESS2_PROTOCOL *This, + IN OUT UINTN *SmramMapSize, + IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap + ) +{ + EFI_STATUS Status; + SMM_ACCESS_PRIVATE_DATA *SmmAccess; + UINTN NecessaryBufferSize; + + SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS(This); + + NecessaryBufferSize = SmmAccess->NumberRegions * sizeof (EFI_SMRAM_DESCRIPTOR); + + if (*SmramMapSize < NecessaryBufferSize) { + if (*SmramMapSize != 0) { + DEBUG((EFI_D_WARN, "SMRAM Map Buffer too small\n")); + } + Status = EFI_BUFFER_TOO_SMALL; + } else { + CopyMem (SmramMap, SmmAccess->SmramDesc, NecessaryBufferSize); + DEBUG ((EFI_D_INFO, "SMRAM Map Buffer installed complete\n")); + Status = EFI_SUCCESS; + } + *SmramMapSize = NecessaryBufferSize; + + return Status; +} + diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SmmAccess/Dxe/SmmAccessDriver.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SmmAccess/Dxe/SmmAccessDriver.h new file mode 100644 index 0000000000..4ee4d56e8f --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SmmAccess/Dxe/SmmAccessDriver.h @@ -0,0 +1,171 @@ +/** @file + Header file for SMM Access Driver. + + Copyright (c) 1999 - 2016, 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. + +**/ + +#ifndef _SMM_ACCESS_DRIVER_H_ +#define _SMM_ACCESS_DRIVER_H_ + +#include +#include +#include +#include + +#define SMM_ACCESS_PRIVATE_DATA_SIGNATURE SIGNATURE_32('4','5','s','a') + +// +// Chipset specific constants +// + +#define MAX_SMRAM_RANGES 2 + +// PCI "address" of chipset +#define PCI_BUS 0 +#define PCI_DEV 0 +#define PCI_FNC 0 + +// Chipset identifying registers +#define CHIPSET_VID 0x8086 +#define CHIPSET_DID 0xA000 + +// +// Chipset register(s) +// + +// SMM configuration register +typedef UINT8 SMRAM; // System Management RAM Control +#define SMRAM_OFFSET HUNIT_HSMMCTL + +// +// Private data +// +typedef struct { + UINTN Signature; + EFI_HANDLE Handle; + EFI_SMM_ACCESS2_PROTOCOL SmmAccess; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; + // + // Local Data for SMM Access interface goes here + // + UINTN NumberRegions; + EFI_SMRAM_DESCRIPTOR SmramDesc[MAX_SMRAM_RANGES]; +} SMM_ACCESS_PRIVATE_DATA; + +#define SMM_ACCESS_PRIVATE_DATA_FROM_THIS(a) \ + CR(a, SMM_ACCESS_PRIVATE_DATA, SmmAccess, SMM_ACCESS_PRIVATE_DATA_SIGNATURE) + +// +// Prototypes +// Driver model protocol interface +// + +/** + This is the standard EFI driver point that detects + whether there is an GMCH815 chipset in the system + and if so, installs an SMM Access Protocol + + @param[in] ImageHandle Handle for the image of this driver + @param[in] SystemTable Pointer to the EFI System Table + + @retval EFI_SUCCESS Protocol successfully started and installed + @retval EFI_UNSUPPORTED Protocol can't be started + +**/ +EFI_STATUS +EFIAPI +SmmAccessDriverEntryPoint( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + This routine accepts a request to "open" a region of SMRAM. The + region could be legacy ABSEG, HSEG, or TSEG near top of physical memory. + The use of "open" means that the memory is visible from all boot-service + and SMM agents. + + @param[in] This Pointer to the SMM Access Interface + + @retval EFI_SUCCESS The region was successfully opened + @retval EFI_DEVICE_ERROR The region could not be opened because locked by chipset + @retval EFI_INVALID_PARAMETER The descriptor index was out of bounds. + +**/ +EFI_STATUS +EFIAPI +Open ( + IN EFI_SMM_ACCESS2_PROTOCOL *This + ); + +/** + This routine accepts a request to "close" a region of SMRAM. The + region could be legacy AB or TSEG near top of physical memory. + The use of "close" means that the memory is only visible from SMM agents, + not from BS or RT code. + + @param[in] This Pointer to the SMM Access Interface + + @retval EFI_SUCCESS The region was successfully closed + @retval EFI_DEVICE_ERROR The region could not be closed because locked by chipset + @retval EFI_INVALID_PARAMETER The descriptor index was out of bounds + +**/ +EFI_STATUS +EFIAPI +Close ( + IN EFI_SMM_ACCESS2_PROTOCOL *This + ); + +/** + This routine accepts a request to "lock" SMRAM. The + region could be legacy AB or TSEG near top of physical memory. + The use of "lock" means that the memory can no longer be opened + to BS state. + + @param[in] This Pointer to the SMM Access Interface + + @retval EFI_SUCCESS The region was successfully locked. + @retval EFI_DEVICE_ERROR The region could not be locked because at least one range is still open. + @retval EFI_INVALID_PARAMETER The descriptor index was out of bounds. + +**/ +EFI_STATUS +EFIAPI +Lock ( + IN EFI_SMM_ACCESS2_PROTOCOL *This + ); + +/** + This routine services a user request to discover the SMRAM + capabilities of this platform. This will report the possible + ranges that are possible for SMRAM access, based upon the + memory controller capabilities. + + @param[in] This Pointer to the SMRAM Access Interface. + @param[in, out] SmramMapSize Pointer to the variable containing size of the buffer to contain the description information + @param[in, out] SmramMap Buffer containing the data describing the Smram region descriptors + + @retval EFI_BUFFER_TOO_SMALL The user did not provide a sufficient buffer. + @retval EFI_SUCCESS The user provided a sufficiently-sized buffer. + +**/ +EFI_STATUS +EFIAPI +GetCapabilities ( + IN CONST EFI_SMM_ACCESS2_PROTOCOL *This, + IN OUT UINTN *SmramMapSize, + IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap + ); + +#endif + diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SmmAccess/Pei/SmmAccess.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SmmAccess/Pei/SmmAccess.inf new file mode 100644 index 0000000000..26d61f843d --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SmmAccess/Pei/SmmAccess.inf @@ -0,0 +1,45 @@ +## @file +# SmmAccess module. +# +# Copyright (c) 1999 - 2016, 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. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PeiSmmAccess + FILE_GUID = B4E0CDFC-30CD-4b29-A445-B0AA95A532E4 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + ENTRY_POINT = SmmAccessDriverEntryPoint + +[Sources] + SmmAccessDriver.h + SmmAccessDriver.c + +[Packages] + MdePkg/MdePkg.dec + BroxtonSiPkg/BroxtonSiPkg.dec + +[LibraryClasses] + PeimEntryPoint + DebugLib + HobLib + BaseMemoryLib + +[Guids] + gEfiSmmPeiSmramMemoryReserveGuid ## UNDEFINED + +[Ppis] + gPeiSmmAccessPpiGuid ## PRODUCES + +[Depex] + gEfiPeiMemoryDiscoveredPpiGuid diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SmmAccess/Pei/SmmAccessDriver.c b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SmmAccess/Pei/SmmAccessDriver.c new file mode 100644 index 0000000000..6341f8eb78 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SmmAccess/Pei/SmmAccessDriver.c @@ -0,0 +1,292 @@ +/** @file + This is the driver that publishes the SMM Access Protocol + instance for System Agent. + + Copyright (c) 1999 - 2016, 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 "SmmAccessDriver.h" + + +/** + This is the constructor for the SMM Access Ppi + + @param[in] FileHandle FileHandle. + @param[in] PeiServices General purpose services available to every PEIM. + + @retval EFI_SUCCESS Protocol successfully started and installed + @retval EFI_UNSUPPORTED Protocol can't be started + +**/ +EFI_STATUS +EFIAPI +SmmAccessDriverEntryPoint ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + UINTN Index; + EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *DescriptorBlock; + SMM_ACCESS_PRIVATE_DATA *SmmAccessPrivate; + EFI_PEI_PPI_DESCRIPTOR *PpiList; + EFI_PEI_HOB_POINTERS HobList; + + // + // Initialize private data + // + Status = (**PeiServices).AllocatePool ( + PeiServices, + sizeof (*SmmAccessPrivate), + (VOID **) &SmmAccessPrivate + ); + ASSERT_EFI_ERROR (Status); + + Status = (**PeiServices).AllocatePool ( + PeiServices, + sizeof (*PpiList), + (VOID **) &PpiList + ); + ASSERT_EFI_ERROR (Status); + + // + // Build SMM related information + // + SmmAccessPrivate->Signature = SMM_ACCESS_PRIVATE_DATA_SIGNATURE; + + // + // Get Hob list + // + HobList.Raw = GetFirstGuidHob (&gEfiSmmPeiSmramMemoryReserveGuid); + ASSERT(HobList.Raw != NULL); + DescriptorBlock = GET_GUID_HOB_DATA (HobList.Raw); + if (DescriptorBlock == NULL) { + ASSERT (FALSE); + return EFI_NOT_FOUND; + } + + // + // Use the hob to publish SMRAM capabilities + // + ASSERT (DescriptorBlock->NumberOfSmmReservedRegions <= MAX_SMRAM_RANGES); + for (Index = 0; Index < DescriptorBlock->NumberOfSmmReservedRegions; Index++) { + SmmAccessPrivate->SmramDesc[Index].PhysicalStart = DescriptorBlock->Descriptor[Index].PhysicalStart; + SmmAccessPrivate->SmramDesc[Index].CpuStart = DescriptorBlock->Descriptor[Index].CpuStart; + SmmAccessPrivate->SmramDesc[Index].PhysicalSize = DescriptorBlock->Descriptor[Index].PhysicalSize; + SmmAccessPrivate->SmramDesc[Index].RegionState = DescriptorBlock->Descriptor[Index].RegionState; + } + + SmmAccessPrivate->NumberRegions = Index; + SmmAccessPrivate->SmmAccess.Open = Open; + SmmAccessPrivate->SmmAccess.Close = Close; + SmmAccessPrivate->SmmAccess.Lock = Lock; + SmmAccessPrivate->SmmAccess.GetCapabilities = GetCapabilities; + SmmAccessPrivate->SmmAccess.LockState = FALSE; + SmmAccessPrivate->SmmAccess.OpenState = FALSE; + + PpiList->Flags = (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST); + PpiList->Guid = &gPeiSmmAccessPpiGuid; + PpiList->Ppi = &SmmAccessPrivate->SmmAccess; + + Status = (**PeiServices).InstallPpi (PeiServices, PpiList); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} + + +/** + This routine accepts a request to "open" a region of SMRAM. The + region could be legacy ABSEG, HSEG, or TSEG near top of physical memory. + The use of "open" means that the memory is visible from all PEIM + and SMM agents. + + @param[in] PeiServices General purpose services available to every PEIM + @param[in] This Pointer to the SMM Access Interface + @param[in] DescriptorIndex Region of SMRAM to Open + + @retval EFI_SUCCESS The region was successfully opened. + @retval EFI_DEVICE_ERROR The region could not be opened because locked by chipset. + @retval EFI_INVALID_PARAMETER The descriptor index was out of bounds. + +**/ +EFI_STATUS +EFIAPI +Open ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_SMM_ACCESS_PPI *This, + IN UINTN DescriptorIndex + ) +{ + SMM_ACCESS_PRIVATE_DATA *SmmAccess; + + SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This); + + if (DescriptorIndex >= SmmAccess->NumberRegions) { + DEBUG (( EFI_D_ERROR, "SMRAM region out of range\n")); + return EFI_INVALID_PARAMETER; + } else if (SmmAccess->SmramDesc[DescriptorIndex].RegionState & EFI_SMRAM_LOCKED) { + DEBUG ((EFI_D_ERROR, "Cannot open a locked SMRAM region\n")); + return EFI_DEVICE_ERROR; + } + + + Mmio64AndThenOr (MCH_BASE_ADDRESS, 0x6840, 0, 0xFF); + Mmio64AndThenOr (MCH_BASE_ADDRESS, 0x6848, 0, 0xFF); + + // + // END CHIPSET SPECIFIC CODE + // + SmmAccess->SmramDesc[DescriptorIndex].RegionState &= ~(EFI_SMRAM_CLOSED | EFI_ALLOCATED); + SmmAccess->SmramDesc[DescriptorIndex].RegionState |= EFI_SMRAM_OPEN; + SmmAccess->SmmAccess.OpenState = TRUE; + + return EFI_SUCCESS; +} + + +/** + This routine accepts a request to "close" a region of SMRAM. This is valid for + compatible SMRAM region. + + @param[in] PeiServices General purpose services available to every PEIM + @param[in] This Pointer to the SMM Access Interface + @param[in] DescriptorIndex Region of SMRAM to Close + + @retval EFI_SUCCESS The region was successfully closed. + @retval EFI_DEVICE_ERROR The region could not be closed because locked by chipset. + @retval EFI_INVALID_PARAMETER The descriptor index was out of bounds. + +**/ +EFI_STATUS +EFIAPI +Close ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_SMM_ACCESS_PPI *This, + IN UINTN DescriptorIndex + ) +{ + SMM_ACCESS_PRIVATE_DATA *SmmAccess; + + SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This); + + if (DescriptorIndex >= SmmAccess->NumberRegions) { + DEBUG ((EFI_D_ERROR, "SMRAM region out of range\n")); + return EFI_INVALID_PARAMETER; + } else if (SmmAccess->SmramDesc[DescriptorIndex].RegionState & EFI_SMRAM_LOCKED) { + DEBUG ((EFI_D_ERROR, "Cannot close a locked SMRAM region\n")); + return EFI_DEVICE_ERROR; + } + if (SmmAccess->SmramDesc[DescriptorIndex].RegionState & EFI_SMRAM_CLOSED) { + return EFI_DEVICE_ERROR; + } + + SmmAccess->SmramDesc[DescriptorIndex].RegionState &= ~EFI_SMRAM_OPEN; + SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (EFI_SMRAM_CLOSED | EFI_ALLOCATED); + + SmmAccess->SmmAccess.OpenState = FALSE; + + return EFI_SUCCESS; +} + + +/** + This routine accepts a request to "lock" SMRAM. The + region could be legacy AB or TSEG near top of physical memory. + The use of "lock" means that the memory can no longer be opened + to PEIM. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] This Pointer to the SMM Access Interface. + @param[in] DescriptorIndex Region of SMRAM to Lock. + + @retval EFI_SUCCESS The region was successfully locked. + @retval EFI_DEVICE_ERROR The region could not be locked because at least one range is still open. + @retval EFI_INVALID_PARAMETER The descriptor index was out of bounds. + +**/ +EFI_STATUS +EFIAPI +Lock ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_SMM_ACCESS_PPI *This, + IN UINTN DescriptorIndex + ) +{ + SMM_ACCESS_PRIVATE_DATA *SmmAccess; + + SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This); + + if (DescriptorIndex >= SmmAccess->NumberRegions) { + DEBUG ((EFI_D_ERROR, "SMRAM region out of range\n")); + return EFI_INVALID_PARAMETER; + } else if (SmmAccess->SmmAccess.OpenState) { + DEBUG ((EFI_D_ERROR, "Cannot lock SMRAM when SMRAM regions are still open\n")); + return EFI_DEVICE_ERROR; + } + + Mmio64AndThenOr (MCH_BASE_ADDRESS, 0x6838, 0, 0x00); + + SmmAccess->SmramDesc[DescriptorIndex].RegionState |= EFI_SMRAM_LOCKED; + SmmAccess->SmmAccess.LockState = TRUE; + + return EFI_SUCCESS; +} + + +/** + This routine services a user request to discover the SMRAM + capabilities of this platform. This will report the possible + ranges that are possible for SMRAM access, based upon the + memory controller capabilities. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] This Pointer to the SMRAM Access Interface. + @param[in, out] SmramMapSize Pointer to the variable containing size of the + buffer to contain the description information. + @param[in, out] SmramMap Buffer containing the data describing the Smram + region descriptors. + + @retval EFI_BUFFER_TOO_SMALL The user did not provide a sufficient buffer. + @retval EFI_SUCCESS The user provided a sufficiently-sized buffer. + +**/ +EFI_STATUS +EFIAPI +GetCapabilities ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_SMM_ACCESS_PPI *This, + IN OUT UINTN *SmramMapSize, + IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap + ) +{ + EFI_STATUS Status; + SMM_ACCESS_PRIVATE_DATA *SmmAccess; + UINTN BufferSize; + + SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This); + BufferSize = SmmAccess->NumberRegions * sizeof (EFI_SMRAM_DESCRIPTOR); + + if (*SmramMapSize < BufferSize) { + if (*SmramMapSize != 0) { + DEBUG((EFI_D_ERROR, "SMRAM Map Buffer too small\n")); + } + Status = EFI_BUFFER_TOO_SMALL; + } else { + CopyMem (SmramMap, SmmAccess->SmramDesc, *SmramMapSize); + Status = EFI_SUCCESS; + } + *SmramMapSize = BufferSize; + + return Status; +} + diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SmmAccess/Pei/SmmAccessDriver.h b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SmmAccess/Pei/SmmAccessDriver.h new file mode 100644 index 0000000000..9ad1bdec18 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/Cpu/SmmAccess/Pei/SmmAccessDriver.h @@ -0,0 +1,167 @@ +/** @file + Header file for SMM Access Driver. + + Copyright (c) 1999 - 2016, 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. + +**/ + +#ifndef _PEI_SMM_ACCESS_DRIVER_H +#define _PEI_SMM_ACCESS_DRIVER_H + +#include "PiPei.h" +#include "Library/HobLib.h" +#include "Guid/SmramMemoryReserve.h" +#include "Ppi/SmmAccess.h" +#include "Library/DebugLib.h" +#include "Library/BaseMemoryLib.h" +#include "SaAccess.h" + +// +// Chipset specific constants +// +#define MAX_SMRAM_RANGES 2 + +// +// Chipset register(s) +// +typedef UINT8 SMRAM; // System Management RAM Control + +// +// Private data structure +// +#define SMM_ACCESS_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('i', 's', 'm', 'a') + +typedef struct { + UINTN Signature; + EFI_HANDLE Handle; + PEI_SMM_ACCESS_PPI SmmAccess; + // + // Local Data for SMM Access interface goes here + // + UINTN NumberRegions; + EFI_SMRAM_DESCRIPTOR SmramDesc[MAX_SMRAM_RANGES]; +} SMM_ACCESS_PRIVATE_DATA; + +#define SMM_ACCESS_PRIVATE_DATA_FROM_THIS(a) \ + CR (a, SMM_ACCESS_PRIVATE_DATA, SmmAccess, SMM_ACCESS_PRIVATE_DATA_SIGNATURE) + +/** + This is the constructor for the SMM Access Ppi + + @param[in] FileHandle FileHandle. + @param[in] PeiServices General purpose services available to every PEIM. + + @retval EFI_SUCCESS Protocol successfully started and installed + @retval EFI_UNSUPPORTED Protocol can't be started + +**/ +EFI_STATUS +EFIAPI +SmmAccessDriverEntryPoint( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ); + +/** + This routine accepts a request to "open" a region of SMRAM. The + region could be legacy ABSEG, HSEG, or TSEG near top of physical memory. + The use of "open" means that the memory is visible from all PEIM + and SMM agents. + + @param[in] PeiServices General purpose services available to every PEIM + @param[in] This Pointer to the SMM Access Interface + @param[in] DescriptorIndex Region of SMRAM to Open + + @retval EFI_SUCCESS The region was successfully opened. + @retval EFI_DEVICE_ERROR The region could not be opened because locked by chipset. + @retval EFI_INVALID_PARAMETER The descriptor index was out of bounds. + +**/ +EFI_STATUS +EFIAPI +Open ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_SMM_ACCESS_PPI *This, + IN UINTN DescriptorIndex + ); + +/** + This routine accepts a request to "close" a region of SMRAM. This is valid for + compatible SMRAM region. + + @param[in] PeiServices General purpose services available to every PEIM + @param[in] This Pointer to the SMM Access Interface + @param[in] DescriptorIndex Region of SMRAM to Close + + @retval EFI_SUCCESS The region was successfully closed. + @retval EFI_DEVICE_ERROR The region could not be closed because locked by chipset. + @retval EFI_INVALID_PARAMETER The descriptor index was out of bounds. + +**/ +EFI_STATUS +EFIAPI +Close ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_SMM_ACCESS_PPI *This, + IN UINTN DescriptorIndex + ); + +/** + This routine accepts a request to "lock" SMRAM. The + region could be legacy AB or TSEG near top of physical memory. + The use of "lock" means that the memory can no longer be opened + to PEIM. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] This Pointer to the SMM Access Interface. + @param[in] DescriptorIndex Region of SMRAM to Lock. + + @retval EFI_SUCCESS The region was successfully locked. + @retval EFI_DEVICE_ERROR The region could not be locked because at least one range is still open. + @retval EFI_INVALID_PARAMETER The descriptor index was out of bounds. + +**/ +EFI_STATUS +EFIAPI +Lock ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_SMM_ACCESS_PPI *This, + IN UINTN DescriptorIndex + ); + +/** + This routine services a user request to discover the SMRAM + capabilities of this platform. This will report the possible + ranges that are possible for SMRAM access, based upon the + memory controller capabilities. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] This Pointer to the SMRAM Access Interface. + @param[in, out] SmramMapSize Pointer to the variable containing size of the + buffer to contain the description information. + @param[in, out] SmramMap Buffer containing the data describing the Smram + region descriptors. + + @retval EFI_BUFFER_TOO_SMALL The user did not provide a sufficient buffer. + @retval EFI_SUCCESS The user provided a sufficiently-sized buffer. + +**/ +EFI_STATUS +EFIAPI +GetCapabilities ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_SMM_ACCESS_PPI *This, + IN OUT UINTN *SmramMapSize, + IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap + ); + +#endif + -- cgit v1.2.3