13cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** @file
23cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  A helper driver to save information to SMRAM after SMRR is enabled.
33cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
43cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  This driver is for ECP platforms.
53cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
6e0d42561a832b0753e6f8575e985c6e885783072Shifei Lu  Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
73cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
83cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
93cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  This program and the accompanying materials are licensed and made available under
103cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
113cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  the terms and conditions of the BSD License that accompanies this distribution.
123cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
133cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  The full text of the license may be found at
143cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
153cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  http://opensource.org/licenses/bsd-license.php.
163cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
173cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
183cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
193cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
203cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
213cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
223cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
233cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
243cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
253cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
263cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/
273cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
283cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei#include <PiSmm.h>
293cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei#include <Library/DebugLib.h>
30e0d42561a832b0753e6f8575e985c6e885783072Shifei Lu#include <Library/UefiDriverEntryPoint.h>
313cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei#include <Library/UefiRuntimeServicesTableLib.h>
323cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei#include <Library/SmmServicesTableLib.h>
333cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei#include <Library/BaseLib.h>
343cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei#include <Library/BaseMemoryLib.h>
353cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei#include <Library/IoLib.h>
363cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei#include <Protocol/SmmSwDispatch.h>
373cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei#include <Protocol/SmmReadyToLock.h>
383cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei#include <Protocol/SmmControl.h>
393cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei#include <Guid/Vlv2DeviceRefCodePkgTokenSpace.h>
403cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
413cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei#define SMM_FROM_SMBASE_DRIVER        0x55
423cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei#define SMM_FROM_CPU_DRIVER_SAVE_INFO 0x81
433cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
443cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei#define EFI_SMRAM_CPU_NVS_HEADER_GUID \
453cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  { \
463cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei    0x429501d9, 0xe447, 0x40f4, 0x86, 0x7b, 0x75, 0xc9, 0x3a, 0x1d, 0xb5, 0x4e \
473cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  }
483cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
493cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiUINT8    mSmiDataRegister;
503cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiBOOLEAN  mLocked = FALSE;
513cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_GUID mSmramCpuNvsHeaderGuid = EFI_SMRAM_CPU_NVS_HEADER_GUID;
523cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
533cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/**
543cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  Dispatch function for a Software SMI handler.
553cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
563cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  @param  DispatchHandle        The handle of this dispatch function.
573cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  @param  DispatchContext       The pointer to the dispatch function's context.
583cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei                                The SwSmiInputValue field is filled in
593cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei                                by the software dispatch driver prior to
603cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei                                invoking this dispatch function.
613cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei                                The dispatch function will only be called
623cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei                                for input values for which it is registered.
633cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
643cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  @return None
653cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
663cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/
673cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiVOID
683cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFIAPI
693cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiSmramSaveInfoHandler (
70e0d42561a832b0753e6f8575e985c6e885783072Shifei Lu  IN  EFI_HANDLE                    DispatchHandle,
71e0d42561a832b0753e6f8575e985c6e885783072Shifei Lu  IN  EFI_SMM_SW_DISPATCH_CONTEXT   *DispatchContext
72e0d42561a832b0753e6f8575e985c6e885783072Shifei Lu  )
733cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{
743cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  ASSERT (DispatchContext != NULL);
753cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  ASSERT (DispatchContext->SwSmiInputValue == SMM_FROM_SMBASE_DRIVER);
763cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
773cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  if (!mLocked && IoRead8 (mSmiDataRegister) == SMM_FROM_CPU_DRIVER_SAVE_INFO) {
783cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      CopyMem (
793cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei        (VOID *)(UINTN)(PcdGetEx64 (&gEfiVLVTokenSpaceGuid, PcdCpuLockBoxDataAddress)),
803cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei        (VOID *)(UINTN)(PcdGetEx64 (&gEfiVLVTokenSpaceGuid, PcdCpuSmramCpuDataAddress)),
813cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei        (UINTN)(PcdGetEx64 (&gEfiVLVTokenSpaceGuid, PcdCpuLockBoxSize))
823cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei        );
833cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  }
843cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei}
853cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
863cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/**
873cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  Smm Ready To Lock event notification handler.
883cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
893cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  It sets a flag indicating that SMRAM has been locked.
903cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
913cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  @param[in] Protocol   Points to the protocol's unique identifier.
923cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  @param[in] Interface  Points to the interface instance.
933cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  @param[in] Handle     The handle on which the interface was installed.
943cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
953cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  @retval EFI_SUCCESS   Notification handler runs successfully.
963cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei **/
973cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_STATUS
983cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFIAPI
993cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiSmmReadyToLockEventNotify (
1003cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  IN CONST EFI_GUID  *Protocol,
1013cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  IN VOID            *Interface,
1023cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  IN EFI_HANDLE      Handle
1033cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  )
1043cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{
1053cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  mLocked = TRUE;
1063cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  return EFI_SUCCESS;
1073cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei}
1083cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
1093cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/**
1103cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  Entry point function of this driver.
1113cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
1123cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  @param[in] ImageHandle  The firmware allocated handle for the EFI image.
1133cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  @param[in] SystemTable  A pointer to the EFI System Table.
1143cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
1153cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  @retval EFI_SUCCESS     The entry point is executed successfully.
1163cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  @retval other           Some error occurs when executing this entry point.
1173cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/
1183cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_STATUS
1193cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFIAPI
1203cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiSmramSaveInfoHandlerSmmMain (
1213cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  IN EFI_HANDLE        ImageHandle,
1223cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  IN EFI_SYSTEM_TABLE  *SystemTable
1233cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  )
1243cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{
1253cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  EFI_STATUS                    Status;
1263cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  EFI_SMM_SW_DISPATCH_PROTOCOL  *SmmSwDispatch;
1273cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  EFI_SMM_SW_DISPATCH_CONTEXT   SmmSwDispatchContext;
1283cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  EFI_HANDLE                    DispatchHandle;
1293cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  EFI_SMM_CONTROL_PROTOCOL      *SmmControl;
1303cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  EFI_SMM_CONTROL_REGISTER      SmmControlRegister;
1313cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  VOID                          *Registration;
1323cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
1333cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  //
1343cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  // Get SMI data register
1353cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  //
1363cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  Status = SystemTable->BootServices->LocateProtocol (
1373cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei                                        &gEfiSmmControlProtocolGuid,
1383cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei                                        NULL,
1393cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei                                        (VOID **)&SmmControl
1403cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei                                        );
1413cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  ASSERT_EFI_ERROR (Status);
1423cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  Status = SmmControl->GetRegisterInfo (SmmControl, &SmmControlRegister);
1433cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  ASSERT_EFI_ERROR (Status);
1443cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  mSmiDataRegister = SmmControlRegister.SmiDataRegister;
1453cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
1463cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  //
1473cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  // Register software SMI handler
1483cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  //
1493cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
1503cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  Status = SystemTable->BootServices->LocateProtocol (
1513cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei                                        &gEfiSmmSwDispatchProtocolGuid,
1523cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei                                        NULL,
1533cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei                                        (VOID **)&SmmSwDispatch
1543cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei                                        );
1553cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  ASSERT_EFI_ERROR (Status);
1563cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
1573cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  SmmSwDispatchContext.SwSmiInputValue = SMM_FROM_SMBASE_DRIVER;
1583cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  Status = SmmSwDispatch->Register (
1593cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei                            SmmSwDispatch,
1603cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei                            &SmramSaveInfoHandler,
1613cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei                            &SmmSwDispatchContext,
1623cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei                            &DispatchHandle
1633cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei                            );
1643cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  ASSERT_EFI_ERROR (Status);
1653cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
1663cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  //
1673cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  // Register SMM Ready To Lock Protocol notification
1683cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  //
1693cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  Status = gSmst->SmmRegisterProtocolNotify (
170                    &gEfiSmmReadyToLockProtocolGuid,
171                    SmmReadyToLockEventNotify,
172                    &Registration
173                    );
174  ASSERT_EFI_ERROR (Status);
175
176  return Status;
177}
178
179