summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuo Mang <mang.guo@intel.com>2016-06-02 13:46:47 +0800
committerHao Wu <hao.a.wu@intel.com>2016-06-07 09:55:32 +0800
commite468aeccbf0401410445639ed516f3b72f8209bb (patch)
tree3ebdb907da9d26ecd722b56737cfd5bce3fd3347
parent6a6948731aca21511b20fb3a558167fdcafc9d58 (diff)
downloadedk2-platforms-e468aeccbf0401410445639ed516f3b72f8209bb.tar.xz
ChvRefCodePkg: Add SmmAccess module.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang <mang.guo@intel.com>
-rw-r--r--ChvRefCodePkg/CherryViewSoc/NorthCluster/SmmAccess/Dxe/SmmAccess.inf54
-rw-r--r--ChvRefCodePkg/CherryViewSoc/NorthCluster/SmmAccess/Dxe/SmmAccessDriver.c284
-rw-r--r--ChvRefCodePkg/CherryViewSoc/NorthCluster/SmmAccess/Dxe/SmmAccessDriver.h113
-rw-r--r--ChvRefCodePkg/CherryViewSoc/NorthCluster/SmmAccess/Pei/SmmAccess.inf53
-rw-r--r--ChvRefCodePkg/CherryViewSoc/NorthCluster/SmmAccess/Pei/SmmAccessDriver.c292
-rw-r--r--ChvRefCodePkg/CherryViewSoc/NorthCluster/SmmAccess/Pei/SmmAccessDriver.h101
6 files changed, 897 insertions, 0 deletions
diff --git a/ChvRefCodePkg/CherryViewSoc/NorthCluster/SmmAccess/Dxe/SmmAccess.inf b/ChvRefCodePkg/CherryViewSoc/NorthCluster/SmmAccess/Dxe/SmmAccess.inf
new file mode 100644
index 0000000000..323f86b204
--- /dev/null
+++ b/ChvRefCodePkg/CherryViewSoc/NorthCluster/SmmAccess/Dxe/SmmAccess.inf
@@ -0,0 +1,54 @@
+## @file
+# SMM Access Dxe Module
+#
+# This module provides a SMM access protocol instance for open/close/lock
+# SMRAM operaton.
+#
+# 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.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SmmAccess
+ FILE_GUID = F778112F-59E7-4B11-A9DC-09CAF5757754
+ VERSION_STRING = 1.0
+ MODULE_TYPE = DXE_DRIVER
+ ENTRY_POINT = SmmAccessDriverEntryPoint
+
+[Sources]
+ SmmAccessDriver.h
+ SmmAccessDriver.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ChvRefCodePkg/ChvRefCodePkg.dec
+ IntelFrameworkPkg/IntelFrameworkPkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ HobLib
+ DebugLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+
+[Guids]
+ ## CONSUMES ## HOB
+ gEfiSmmPeiSmramMemoryReserveGuid
+
+[Protocols]
+ ## PRODUCES
+ gEfiSmmAccess2ProtocolGuid
+
+[Depex]
+ gEfiPciRootBridgeIoProtocolGuid
+
diff --git a/ChvRefCodePkg/CherryViewSoc/NorthCluster/SmmAccess/Dxe/SmmAccessDriver.c b/ChvRefCodePkg/CherryViewSoc/NorthCluster/SmmAccess/Dxe/SmmAccessDriver.c
new file mode 100644
index 0000000000..a0d8c24727
--- /dev/null
+++ b/ChvRefCodePkg/CherryViewSoc/NorthCluster/SmmAccess/Dxe/SmmAccessDriver.c
@@ -0,0 +1,284 @@
+/** @file
+ This is the driver that publishes the SMM Access Protocol
+ instance for the Cherryview.
+
+ 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 "SmmAccessDriver.h"
+#include <Library/BaseMemoryLib.h>
+#include <Library/HobLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Guid/SmramMemoryReserve.h>
+
+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.
+ @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_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;
+ }
+
+ //
+ // Allow access to all CPU HOST
+ //
+ MsgBus32Write (0x03, 0x2C, 0xFF);
+
+ //
+ // Allow access to all CPU HOST
+ //
+ MsgBus32Write (0x03, 0x2D, 0xFF);
+
+ SmmAccess->SmramDesc[Index].RegionState &= (~(UINT64)(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.
+ @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_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 &= (~(UINT64)EFI_SMRAM_OPEN);
+ SmmAccess->SmramDesc[Index].RegionState |= (UINT64)(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.
+ @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_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;
+ }
+
+ SmmAccess->SmramDesc[Index].RegionState |= EFI_SMRAM_LOCKED;
+ }
+
+ MsgBus32Write (0x03, 0x2B, 0x00|0x04|0x100);
+ 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] SmramMapSize Pointer to the variable containing size of the
+ buffer to contain the description information.
+ @param[in] 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) {
+ DEBUG ((EFI_D_WARN, "SMRAM Map Buffer too small\n"));
+ Status = EFI_BUFFER_TOO_SMALL;
+ } else {
+ CopyMem(SmramMap, SmmAccess->SmramDesc, NecessaryBufferSize);
+ DEBUG ((EFI_D_WARN, "SMRAM Map Buffer installed complet\n"));
+ Status = EFI_SUCCESS;
+ }
+
+ *SmramMapSize = NecessaryBufferSize;
+
+ return Status;
+}
diff --git a/ChvRefCodePkg/CherryViewSoc/NorthCluster/SmmAccess/Dxe/SmmAccessDriver.h b/ChvRefCodePkg/CherryViewSoc/NorthCluster/SmmAccess/Dxe/SmmAccessDriver.h
new file mode 100644
index 0000000000..4db2ea108e
--- /dev/null
+++ b/ChvRefCodePkg/CherryViewSoc/NorthCluster/SmmAccess/Dxe/SmmAccessDriver.h
@@ -0,0 +1,113 @@
+/** @file
+ Header file for SMM Access Driver.
+
+ 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.
+
+**/
+
+#ifndef _SMM_ACCESS_DRIVER_H_
+#define _SMM_ACCESS_DRIVER_H_
+
+#include <Cherryview.h>
+#include <ChvAccess.h>
+#include <Protocol/SmmAccess2.h>
+#include <Protocol/PciRootBridgeIo.h>
+
+#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
+//
+/**
+ @todo add description
+
+**/
+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
+//
+
+EFI_STATUS
+EFIAPI
+SmmAccessDriverEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+EFI_STATUS
+EFIAPI
+Open (
+ IN EFI_SMM_ACCESS2_PROTOCOL *This
+ );
+
+EFI_STATUS
+EFIAPI
+Close (
+ IN EFI_SMM_ACCESS2_PROTOCOL *This
+ );
+
+EFI_STATUS
+EFIAPI
+Lock (
+ IN EFI_SMM_ACCESS2_PROTOCOL *This
+ );
+
+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/ChvRefCodePkg/CherryViewSoc/NorthCluster/SmmAccess/Pei/SmmAccess.inf b/ChvRefCodePkg/CherryViewSoc/NorthCluster/SmmAccess/Pei/SmmAccess.inf
new file mode 100644
index 0000000000..47aca05cf0
--- /dev/null
+++ b/ChvRefCodePkg/CherryViewSoc/NorthCluster/SmmAccess/Pei/SmmAccess.inf
@@ -0,0 +1,53 @@
+## @file
+# SMM Access Peim Module
+#
+# Provides the ability to control access to the System Management RAM regions in
+# PEI.
+#
+# 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.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PeiSmmAccess
+ FILE_GUID = ABDE7B50-510C-40A4-925A-6C443F1EFCF7
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ ENTRY_POINT = SmmAccessDriverEntryPoint
+
+[Sources]
+ SmmAccessDriver.h
+ SmmAccessDriver.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ ChvRefCodePkg/ChvRefCodePkg.dec
+ IntelFrameworkPkg/IntelFrameworkPkg.dec
+
+[LibraryClasses]
+ PeimEntryPoint
+ DebugLib
+ HobLib
+ BaseMemoryLib
+
+[Guids]
+ ## CONSUMES ## HOB
+ gEfiSmmPeiSmramMemoryReserveGuid
+
+[Ppis]
+ ## PRODUCES
+ gPeiSmmAccessPpiGuid
+
+[Depex]
+ gEfiPeiMemoryDiscoveredPpiGuid
+
diff --git a/ChvRefCodePkg/CherryViewSoc/NorthCluster/SmmAccess/Pei/SmmAccessDriver.c b/ChvRefCodePkg/CherryViewSoc/NorthCluster/SmmAccess/Pei/SmmAccessDriver.c
new file mode 100644
index 0000000000..9684fcdbff
--- /dev/null
+++ b/ChvRefCodePkg/CherryViewSoc/NorthCluster/SmmAccess/Pei/SmmAccessDriver.c
@@ -0,0 +1,292 @@
+/** @file
+ Header file for SMM Access Driver.
+
+ 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 "SmmAccessDriver.h"
+
+/**
+ This is the constructor for the SMM Access Ppi
+
+ @param[in] FfsHeader - FfsHeader.
+ @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(DescriptorBlock != NULL);
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // 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;
+ }
+
+ //
+ // Allow access to all CPU HOST
+ //
+ MsgBus32Write (0x03, 0x2C, 0xFF);
+
+ //
+ // Allow access to all CPU HOST
+ //
+ MsgBus32Write (0x03, 0x2D, 0xFF);
+
+ //
+ // END CHIPSET SPECIFIC CODE
+ //
+
+ SmmAccess->SmramDesc[DescriptorIndex].RegionState &= (~(UINT64)(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 &= (~(UINT64)EFI_SMRAM_OPEN);
+ SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (UINT64)(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;
+ }
+
+ MsgBus32Write (0x03, 0x2B, 0x00|0x04|0x100);
+
+ 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) {
+ 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/ChvRefCodePkg/CherryViewSoc/NorthCluster/SmmAccess/Pei/SmmAccessDriver.h b/ChvRefCodePkg/CherryViewSoc/NorthCluster/SmmAccess/Pei/SmmAccessDriver.h
new file mode 100644
index 0000000000..af2267373e
--- /dev/null
+++ b/ChvRefCodePkg/CherryViewSoc/NorthCluster/SmmAccess/Pei/SmmAccessDriver.h
@@ -0,0 +1,101 @@
+/** @file
+ Header file for SMM Access Driver.
+
+ 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.
+
+**/
+
+#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 "ChvAccess.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)
+
+//
+// Prototypes
+// Driver model protocol interface
+//
+
+EFI_STATUS
+EFIAPI
+SmmAccessDriverEntryPoint(
+ IN EFI_PEI_FILE_HANDLE FfsHeader,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ );
+
+EFI_STATUS
+EFIAPI
+Open (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SMM_ACCESS_PPI *This,
+ IN UINTN DescriptorIndex
+ );
+
+EFI_STATUS
+EFIAPI
+Close (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SMM_ACCESS_PPI *This,
+ IN UINTN DescriptorIndex
+ );
+
+EFI_STATUS
+EFIAPI
+Lock (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SMM_ACCESS_PPI *This,
+ IN UINTN DescriptorIndex
+ );
+
+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