summaryrefslogtreecommitdiff
path: root/Core/EM/Nvme/NvmeSmm
diff options
context:
space:
mode:
Diffstat (limited to 'Core/EM/Nvme/NvmeSmm')
-rw-r--r--Core/EM/Nvme/NvmeSmm/NvmeDef.h253
-rw-r--r--Core/EM/Nvme/NvmeSmm/NvmeSmm.c1127
-rw-r--r--Core/EM/Nvme/NvmeSmm/NvmeSmm.cif13
-rw-r--r--Core/EM/Nvme/NvmeSmm/NvmeSmm.dxs89
-rw-r--r--Core/EM/Nvme/NvmeSmm/NvmeSmm.h222
-rw-r--r--Core/EM/Nvme/NvmeSmm/NvmeSmm.mak95
-rw-r--r--Core/EM/Nvme/NvmeSmm/NvmeSmm.sdl35
7 files changed, 1834 insertions, 0 deletions
diff --git a/Core/EM/Nvme/NvmeSmm/NvmeDef.h b/Core/EM/Nvme/NvmeSmm/NvmeDef.h
new file mode 100644
index 0000000..3bcc083
--- /dev/null
+++ b/Core/EM/Nvme/NvmeSmm/NvmeDef.h
@@ -0,0 +1,253 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/NVMe/NvmeSmm/NvmeDef.h 1 9/04/14 7:54a Anandakrishnanl $
+//
+// $Revision: 1 $
+//
+// $Date: 9/04/14 7:54a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/NVMe/NvmeSmm/NvmeDef.h $
+//
+// 1 9/04/14 7:54a Anandakrishnanl
+// [TAG] EIP180861
+// [Category] Improvement
+// [Description] Legacy Boot support in Aptio 4.x Nvme driver
+// [Files] NvmeSmm.cif
+// NvmeSmm.mak
+// NvmeSmm.dxs
+// NvmeSmm.sdl
+// NvmeSmm.c
+// NvmeSmm.h
+// NvmeDef.h
+//
+//**********************************************************************
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: NvmeDef.h
+//
+// Description: Nvme Smm and Non Smm interface Definitions
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifndef _AMI_NVME_DEF_H_
+#define _AMI_NVME_DEF_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NVME_DATA_EBDA_OFFSET 0x104
+
+#define NVME_API_MASS_DEVICE_REQUEST 0x27
+
+//----------------------------------------------------------------------------
+// NVME Mass Storage Related Data Structures and Equates
+//----------------------------------------------------------------------------
+#define NVME_EMU_NONE 0
+#define NVME_EMU_FLOPPY_ONLY 1
+#define NVME_EMU_HDD_ONLY 2
+#define NVME_EMU_FORCED_FDD 3
+
+// Error returned from API handler
+#define NVME_SUCCESS 0x000
+#define NVME_PARAMETER_ERROR 0x010
+#define NVME_NOT_SUPPORTED 0x020
+#define NVME_INVALID_FUNCTION 0x0F0
+#define NVME_ERROR 0x0FF
+
+#pragma pack(1)
+
+/**
+ This is a URP (NVME Request Packet) structure for the BIOS
+ API call Controller Info
+
+ @param TransferBufferAddress
+ @param NVMEBaseAddress
+ @param PciBus
+ @param PciDevice
+ @param PciFunc
+ @param Port
+ @param DeviceDetected
+ @param DeviceAddress
+ @param NumHeads
+ @param LBANumHeads
+ @param NumCylinders
+ @param LBANumCyls
+ @param NumSectors
+ @param LBANumSectors
+ @param MaxLBA
+ @param BlockSize
+ @param StorageType
+ @param PNM[27]
+ @param NVMEDevice
+ @param NVMEManufactureId[NVME_MANUFACTUREID_LENGTH]
+
+**/
+
+typedef struct {
+ UINT32 TransferBufferAddress;
+ UINT64 NVMEBaseAddress;
+ UINT8 PciBus;
+ UINT8 PciDevice;
+ UINT8 PciFunc;
+ UINT8 Port;
+ BOOLEAN DeviceDetected;
+ UINT8 DeviceAddress;
+ UINT8 NumHeads;
+ UINT8 LBANumHeads;
+ UINT16 NumCylinders;
+ UINT16 LBANumCyls;
+ UINT8 NumSectors;
+ UINT8 LBANumSectors;
+ UINT64 MaxLBA;
+ UINT16 BlockSize;
+ UINT8 StorageType;
+ UINT8 PNM[27];
+ BOOLEAN NVMEDevice;
+ UINT8 NVMEManufactureId[NVME_MANUFACTUREID_LENGTH];
+} CONTROLLER_INFO;
+
+/**
+ This is a URP (NVME Request Packet) structure for the BIOS
+ API call Reset NVME
+
+ @param DeviceAddress
+**/
+
+typedef struct {
+ UINT8 DeviceAddress;
+} RESET_NVME;
+
+
+/**
+ This is a URP (NVME Request Packet) structure for the BIOS
+ API call Read
+
+ @param DeviceAddress
+ @param Port
+ @param LBA
+ @param NumBlks
+ @param BufferAddress
+
+**/
+
+typedef struct {
+ UINT8 DeviceAddress;
+ UINT8 Port;
+ UINT64 LBA; // Starting LBA address
+ UINT16 NumBlks; // Number of blocks to read
+ UINT32 BufferAddress; // Far buffer pointer
+} READ_DATA;
+
+
+/**
+ This is a URP (NVME Request Packet) structure for the BIOS
+ API call Device Geometry
+
+ @param DeviceAddress
+ @param NumHeads
+ @param NumCylinders
+ @param NumSectors
+ @param LBANumHeads
+ @param LBANumCyls
+ @param LBANumSectors
+ @param BlockSize
+ @param MediaType
+ @param MaxLBA
+ @param Int13FunctionNo
+ @param BpbMediaDesc
+
+**/
+typedef struct {
+ UINT8 DeviceAddress;
+ UINT8 NumHeads;
+ UINT16 NumCylinders;
+ UINT8 NumSectors;
+ UINT8 LBANumHeads;
+ UINT16 LBANumCyls;
+ UINT8 LBANumSectors;
+ UINT16 BlockSize;
+ UINT8 MediaType;
+ UINT64 MaxLBA;
+ UINT8 Int13FunctionNo;
+ UINT8 BpbMediaDesc;
+} DEVICE_GEO;
+
+
+/**
+ This is a union data type of all the API related data
+
+ @param Reset
+ @param ControllerInfo
+ @param Read
+ @param DeviceGeo
+**/
+
+typedef union {
+ RESET_NVME Reset;
+ CONTROLLER_INFO ControllerInfo;
+ READ_DATA Read;
+ DEVICE_GEO DeviceGeo;
+} NVME_API_DATA;
+
+
+/**
+ This structure is the URP structure
+
+ @param bFuncNumber
+ @param bSubFunc
+ @param bRetValue
+ @param ApiData
+
+ @note Fields:Name Type Description
+ --------------------------------------------------
+ bFuncNumber UINT8 Function number of the URP
+ bSubFunc UINT8 Sub-func number of the URP
+ bRetValue UINT8 Return value
+ ApiData API_DATA Refer structure definition
+**/
+
+typedef struct {
+ UINT8 bFuncNumber;
+ UINT8 bSubFunc;
+ UINT8 bRetValue;
+ NVME_API_DATA ApiData;
+} NVME_STRUC;
+
+#pragma pack()
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Nvme/NvmeSmm/NvmeSmm.c b/Core/EM/Nvme/NvmeSmm/NvmeSmm.c
new file mode 100644
index 0000000..538a7f0
--- /dev/null
+++ b/Core/EM/Nvme/NvmeSmm/NvmeSmm.c
@@ -0,0 +1,1127 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/NVMe/NvmeSmm/NvmeSmm.c 10 12/08/16 4:21a Karthikar $
+//
+// $Revision: 10 $
+//
+// $Date: 12/08/16 4:21a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/NVMe/NvmeSmm/NvmeSmm.c $
+//
+// 10 12/08/16 4:21a Karthikar
+// [TAG] EIP307568
+// [Category] Bug Fix
+// [Symptom] Legacy Installation and booting fails in
+// (INT)_a_4.6.5.5_NVMe_006
+// [RootCause] Since this NvmeSmm_Support token is not included in
+// Token.h, TransferNvmeDataToSmram() dint get control.
+// [Solution] Added NvmeSmm_Support token in Token.h
+// [Files] NvmeBus.c,NvmeSmm.c,NvmeSmm.sdl
+//
+// 9 11/03/16 5:29a Karthikar
+// [TAG] EIP300640
+// [Category] Improvement
+// [Description] NvmeSmm: Security vulnerability in the NvmeSmm driver
+//
+// 8 2/03/16 2:13a Lavanyap
+// [TAG] EIP254133
+// [Category] New Feature
+// [Description] Modify NVMe driver to avoid repeated FALSE THREAT issue
+// report in Security Advisory.
+// [Files] NvmeSmm.c
+//
+// 7 2/02/16 1:24a Karthikar
+// [TAG] EIP254245
+// [Category] Bug Fix
+// [Symptom] Static code analysis issues found in Aptio4 Nvme module
+// [RootCause] In if condition variable is intialized without proper
+// braces.
+// [Solution] Removed wrong variable initialization
+// from if condition.
+// [Files] NvmeSmm.c
+//
+// 6 5/14/15 2:39a Karthikar
+// [TAG] EIP216763
+// [Category] Improvement
+// [Description] Update the Aptio 4.x Nvme driver to Aptio 5.x Nvme
+// driver Label 05
+// [Files] Nvme.mak,NvmeBus.c, NvmeBus.h, NvmeController.c,
+// NvmePassthru.c,NvmePassthru.h, NvmeSmm.c, NvmExpressPassThru.h,
+// PDiskInfo.h
+//
+// 5 4/20/15 8:52a Anbuprakashp
+// [TAG] EIP214300
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Nvme device with legacy OS can not resume from S4
+// [RootCause] In Aptio 4.x NvmeSmm Driver, Media buffer in
+// EFI_BLOCK_IO_MEDIA holds invalid memory address( i.e. The memory is not
+// allocated in SMRAM ).
+// [Solution] Memory for Media buffer(EFI_BLOCK_IO_MEDIA) is allocated
+// in SMRAM region
+// [Files] NvmeSmm.c
+//
+// 4 4/08/15 10:07a Anbuprakashp
+// [TAG] EIP212320
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] CPU exception in Nvme Driver if
+// PcdCpuSmmCodeAccessCheckEnable is enabled
+// [RootCause] BootService call shouldn't be used inside SMM function.
+// if PcdCpuSmmCodeAccessCheckEnable is enabled, It causes CPU exception.
+// [Solution] Changes made to avoid BootService call inside SMM function
+// [Files] NvmeSmm.c
+// NvmeBus.c
+// AmiNvmeController.h
+//
+// 3 12/10/14 5:14a Lavanyap
+// [TAG] EIP185327
+// [Category] Improvement
+// [Description] Security Enhancement for SMIHandler in Aptio4.x NVMe
+// Driver
+// [Files] NvmeSmm.mak, NvmeSmm.c, NvmeSmm.h
+//
+// 2 9/23/14 2:32a Anandakrishnanl
+// [TAG] EIP180861
+// [Category] Improvement
+// [Description]
+// Add Legacy Boot support in Aptio 4.x Nvme driver - NON PI 1.2 Support
+// [Files] NvmeBus.c
+// NvmeBus.h
+// NvmeSmm.c
+// NvmeSmm.h
+// NvmeSmm.dxs
+// NvmeSmm.sdl
+//
+// 1 9/04/14 7:54a Anandakrishnanl
+// [TAG] EIP180861
+// [Category] Improvement
+// [Description] Legacy Boot support in Aptio 4.x Nvme driver
+// [Files] NvmeSmm.cif
+// NvmeSmm.mak
+// NvmeSmm.dxs
+// NvmeSmm.sdl
+// NvmeSmm.c
+// NvmeSmm.h
+// NvmeDef.h
+//
+//**********************************************************************
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: NvmeSmm.c
+//
+// Description: Nvme SMM driver to handle the Nvme device access
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include "NvmeSmm.h"
+
+EFI_SMM_BASE2_PROTOCOL *gSmmBase2;
+EFI_SMM_SYSTEM_TABLE2 *pSmst2;
+NVME_GLOBAL_DATA *gNvmeData;
+AMI_NVME_CONTROLLER_PROTOCOL *gNvmeController[MAX_NVME_DEVICES] = {0};
+BOOLEAN gFirstAPICall = FALSE;
+
+static EFI_GUID gAmiSmmNvmeCommunicationGuid = AMI_SMM_NVME_COMMUNICATION_GUID;
+
+// ]ApiTable - NVMe API Function Dispatch Table
+
+API_FUNC NvmeMassApiTable[] = {
+ NvmeMassAPIGetDeviceInformation, // Nvme Mass API Sub-Func 00h
+ NvmeMassAPIGetDeviceGeometry, // Nvme Mass API Sub-Func 01h
+ NvmeMassAPIResetDevice, // Nvme Mass API Sub-Func 02h
+ NvmeMassAPIReadDevice, // Nvme Mass API Sub-Func 03h
+ NvmeMassAPIWriteDevice, // Nvme Mass API Sub-Func 04h
+ NvmeMassAPIPass, // Nvme Mass API Sub-Func 05h VerifyDevice
+ NvmeMassAPIPass, // Nvme Mass API Sub-Func 06h FormatDevice
+ NvmeMassAPINotSupported, // Nvme Mass API Sub-Func 07h CommandPassThru
+ NvmeMassAPINotSupported, // Nvme BIOS API function 08h AssignDriveNumber
+ NvmeMassAPINotSupported, // Nvme BIOS API function 09h CheckDevStatus
+ NvmeMassAPINotSupported, // Nvme BIOS API function 0Ah GetDevStatus
+ NvmeMassAPINotSupported // Nvme BIOS API function 0Bh GetDeviceParameters
+};
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: ZeroMemorySmm
+//
+// Description: Clears input Buffer to zero
+//
+// Input:
+// void *Buffer
+// UINTN Size
+//
+// Output:
+// NONE
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+void
+ZeroMemorySmm (
+ void *Buffer,
+ UINTN Size
+ )
+{
+ UINT8 *Ptr;
+ Ptr = Buffer;
+ while (Size--) {
+ *(Ptr++) = 0;
+ }
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: GetDevEntry
+//
+// Description: Get the Index# for the DeviceAddress
+//
+// Input:
+// UINT8 DeviceAddress,
+// ACTIVE_NAMESPACE_DATA **ActiveNameSpace
+//
+// Output:
+// NONE
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+VOID
+GetDevEntry (
+ UINT8 DeviceAddress,
+ ACTIVE_NAMESPACE_DATA **ActiveNameSpace
+)
+{
+
+ UINT8 Count;
+ EFI_LIST_ENTRY *LinkData;
+ AMI_NVME_CONTROLLER_PROTOCOL *NvmeController;
+
+ // Locate a free slot to copy the pointer
+ for (Count = 0; Count < MAX_NVME_DEVICES; Count++ ){
+ if (gNvmeController[Count]) {
+ NvmeController = gNvmeController[Count];
+
+ if(IsListEmpty(&NvmeController->ActiveNameSpaceList)) {
+ continue;
+ }
+
+ for (LinkData = NvmeController->ActiveNameSpaceList.ForwardLink; \
+ LinkData != &NvmeController->ActiveNameSpaceList;
+ LinkData = LinkData->ForwardLink) {
+
+ *ActiveNameSpace = _CR(LinkData ,ACTIVE_NAMESPACE_DATA, Link);
+ if ((*ActiveNameSpace)->Int13DeviceAddress == DeviceAddress) {
+ return;
+ }
+ }
+ }
+ }
+
+ ActiveNameSpace = NULL;
+ return ;
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeMassAPIGetDeviceInformation
+//
+// Description: Return Device information
+//
+// Input:
+// NVME_STRUC *NvmeURP
+//
+// Output:
+// NONE
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID
+NvmeMassAPIGetDeviceInformation (
+ NVME_STRUC *NvmeURP
+)
+{
+
+ NvmeURP->bRetValue = NVME_NOT_SUPPORTED;
+ return;
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeMassAPIGetDeviceGeometry
+//
+// Description: Return Device Geometry
+//
+// Input:
+// NVME_STRUC *NvmeURP
+//
+// Output:
+// NONE
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID
+NvmeMassAPIGetDeviceGeometry (
+ NVME_STRUC *NvmeURP
+)
+{
+ NvmeURP->bRetValue = NVME_NOT_SUPPORTED;
+ return;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeMassAPIResetDevice
+//
+// Description: Reset device
+//
+// Input:
+// NVME_STRUC *NvmeURP
+//
+// Output:
+// NONE
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID
+NvmeMassAPIResetDevice (
+ NVME_STRUC *NvmeURP
+)
+{
+ NvmeURP->bRetValue = NVME_NOT_SUPPORTED;
+ return;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeMassAPIReadDevice
+//
+// Description: Read data from the device
+//
+// Input:
+// NVME_STRUC *NvmeURP
+//
+// Output:
+// NONE
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID
+NvmeMassAPIReadDevice (
+ NVME_STRUC *NvmeURP
+)
+{
+ ACTIVE_NAMESPACE_DATA *ActiveNameSpace = NULL;
+ EFI_STATUS Status;
+ EFI_LBA Lba;
+ UINT16 NumBlks;
+ UINT16 BlksPerTransfer;
+ VOID *Buffer = NULL;
+ VOID *ReadBuffer;
+ UINTN BufferSize;
+ BOOLEAN UnalignedTransfer = FALSE;
+ AMI_NVME_CONTROLLER_PROTOCOL *NvmeController;
+ UINT32 Offset;
+ COMPLETION_QUEUE_ENTRY *pCmdCompletionData;
+
+ GetDevEntry(NvmeURP->ApiData.Read.DeviceAddress, &ActiveNameSpace);
+
+ if(ActiveNameSpace == NULL) {
+ NvmeURP->bRetValue = NVME_PARAMETER_FAILED;
+ return;
+ }
+
+ // Validate if input Buffer address is an non-SMRAM region to avoid SMRAM data
+ // corruption through SMI handlers.
+ // NOTE: As DMA transfer isn't supported inside SMM, Buffer validation is not needed for
+ // NVMe. But below validation code is added to avoid repeated Security False Threat reports.
+
+ Status = AmiValidateMemoryBuffer((VOID*)NvmeURP->ApiData.Read.BufferAddress,
+ NvmeURP->ApiData.Read.NumBlks *
+ ActiveNameSpace->NvmeBlockIO.Media->BlockSize );
+ if (EFI_ERROR(Status)) {
+ NvmeURP->bRetValue = NVME_PARAMETER_FAILED;
+ return;
+ }
+
+ NvmeController = ActiveNameSpace->NvmeController;
+ if (NvmeController->Queue1SubmissionQueueTailPtr == 0xFFFF) {
+ Offset = QUEUE_DOORBELL_OFFSET( NvmeController->NVMQueueNumber, 1, NvmeController->DoorBellStride);
+ NvmeController->Queue1CompletionQueueHeadPtr = CONTROLLER_REG32(NvmeController->NvmeBarOffset, Offset);
+ NvmeController->Queue1SubmissionQueueHeadPtr = NvmeController->Queue1CompletionQueueHeadPtr;
+ NvmeController->Queue1SubmissionQueueTailPtr = NvmeController->Queue1CompletionQueueHeadPtr;
+ // Check if there is a roller over
+ if (NvmeController->Queue1SubmissionQueueTailPtr >= NvmeController->Queue1SubmissionQueueSize) {
+ NvmeController->Queue1SubmissionQueueTailPtr = 0;
+ }
+
+ // Update the phase tag from the Completion queue
+ pCmdCompletionData = (COMPLETION_QUEUE_ENTRY *)NvmeController->Queue1CompletionQueueMappedAddr;
+ NvmeController->Queue1PhaseTag = (UINT8)pCmdCompletionData->PhaseTag;
+ NvmeController->CommandIdentifierQueue1 = 0;
+ NvmeController->CommandIdentifierAdmin = 0;
+ }
+
+
+ Lba=NvmeURP->ApiData.Read.LBA;
+ NumBlks=NvmeURP->ApiData.Read.NumBlks;
+
+ (UINT32)Buffer= NvmeURP->ApiData.Read.BufferAddress;
+
+ BlksPerTransfer = NumBlks;
+ ReadBuffer = Buffer;
+
+ //If Buffer isn't aligned use internal buffer
+ if ((UINTN)NvmeURP->ApiData.Read.BufferAddress & ((1 << ActiveNameSpace->NvmeBlockIO.Media->IoAlign)-1)) {
+ BlksPerTransfer = 1;
+ ReadBuffer = NvmeController->LegacyNvmeBuffer;
+ UnalignedTransfer = TRUE;
+ }
+
+ BufferSize = BlksPerTransfer * ActiveNameSpace->NvmeBlockIO.Media->BlockSize;
+
+ for ( ; NumBlks; NumBlks -= BlksPerTransfer){
+ Status = NvmeReadWriteBlocks (ActiveNameSpace, ActiveNameSpace->NvmeBlockIO.Media->MediaId, Lba, BufferSize, ReadBuffer, NULL, NVME_READ);
+ if (EFI_ERROR(Status)) {
+ break;
+ }
+ if (UnalignedTransfer) {
+ MemCpy (Buffer, ReadBuffer, BufferSize);
+ }
+ (UINTN)Buffer = (UINTN)Buffer + BufferSize;
+ Lba += BlksPerTransfer;
+
+ }
+
+ if (EFI_ERROR(Status)) {
+ NvmeURP->bRetValue = NVME_READ_ERR;
+ } else {
+ NvmeURP->bRetValue = NVME_SUCCESS;
+ }
+
+ return;
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeMassAPIWriteDevice
+//
+// Description: Write data to the device
+//
+// Input:
+// NVME_STRUC *NvmeURP
+//
+// Output:
+// NONE
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID
+NvmeMassAPIWriteDevice (
+ NVME_STRUC *NvmeURP
+)
+{
+ ACTIVE_NAMESPACE_DATA *ActiveNameSpace = NULL;
+ EFI_STATUS Status;
+ EFI_LBA Lba;
+ UINT16 NumBlks;
+ UINT16 BlksPerTransfer;
+ VOID *Buffer = NULL;
+ VOID *ReadBuffer;
+ UINTN BufferSize;
+ BOOLEAN UnalignedTransfer = FALSE;
+ AMI_NVME_CONTROLLER_PROTOCOL *NvmeController;
+ UINT32 Offset;
+ COMPLETION_QUEUE_ENTRY *pCmdCompletionData;
+
+ GetDevEntry(NvmeURP->ApiData.Read.DeviceAddress, &ActiveNameSpace);
+
+ if(ActiveNameSpace == NULL) {
+ NvmeURP->bRetValue = NVME_PARAMETER_FAILED;
+ return;
+ }
+
+ // Validate if input Buffer address is an non-SMRAM region to avoid SMRAM data
+ // corruption through SMI handlers.
+ // NOTE: As DMA transfer isn't supported inside SMM, Buffer validation is not needed for
+ // NVMe. But below validation code is added to avoid repeated Security False Threat reports.
+
+ Status = AmiValidateMemoryBuffer((VOID*)NvmeURP->ApiData.Read.BufferAddress,
+ NvmeURP->ApiData.Read.NumBlks *
+ ActiveNameSpace->NvmeBlockIO.Media->BlockSize );
+ if (EFI_ERROR(Status)) {
+ NvmeURP->bRetValue = NVME_PARAMETER_FAILED;
+ return;
+ }
+
+ NvmeController = ActiveNameSpace->NvmeController;
+ if (NvmeController->Queue1SubmissionQueueTailPtr == 0xFFFF) {
+ Offset = QUEUE_DOORBELL_OFFSET( NvmeController->NVMQueueNumber, 1, NvmeController->DoorBellStride);
+ NvmeController->Queue1CompletionQueueHeadPtr = CONTROLLER_REG32(NvmeController->NvmeBarOffset, Offset);
+ NvmeController->Queue1SubmissionQueueHeadPtr = NvmeController->Queue1CompletionQueueHeadPtr;
+ NvmeController->Queue1SubmissionQueueTailPtr = NvmeController->Queue1CompletionQueueHeadPtr;
+ // Check if there is a roller over
+ if (NvmeController->Queue1SubmissionQueueTailPtr >= NvmeController->Queue1SubmissionQueueSize) {
+ NvmeController->Queue1SubmissionQueueTailPtr = 0;
+ }
+
+ // Update the phase tag from the Completion queue
+ pCmdCompletionData = (COMPLETION_QUEUE_ENTRY *)NvmeController->Queue1CompletionQueueMappedAddr;
+ NvmeController->Queue1PhaseTag = (UINT8)pCmdCompletionData->PhaseTag;
+ NvmeController->CommandIdentifierQueue1 = 0;
+ NvmeController->CommandIdentifierAdmin = 0;
+
+ }
+
+
+ Lba=NvmeURP->ApiData.Read.LBA;
+ NumBlks=NvmeURP->ApiData.Read.NumBlks;
+
+ (UINT32)Buffer= NvmeURP->ApiData.Read.BufferAddress;
+
+ BlksPerTransfer = NumBlks;
+ ReadBuffer = Buffer;
+
+ //If Buffer isn't aligned use internal buffer
+ if ((UINTN)NvmeURP->ApiData.Read.BufferAddress & ((1 << ActiveNameSpace->NvmeBlockIO.Media->IoAlign)-1)) {
+ BlksPerTransfer = 1;
+ ReadBuffer = NvmeController->LegacyNvmeBuffer;
+ UnalignedTransfer = TRUE;
+ }
+
+ BufferSize = BlksPerTransfer * ActiveNameSpace->NvmeBlockIO.Media->BlockSize;
+
+ for ( ; NumBlks; NumBlks -= BlksPerTransfer){
+
+ if (UnalignedTransfer) {
+ MemCpy (ReadBuffer, Buffer, BufferSize);
+ }
+
+ Status = NvmeReadWriteBlocks (ActiveNameSpace, ActiveNameSpace->NvmeBlockIO.Media->MediaId, Lba, BufferSize, ReadBuffer, NULL, NVME_WRITE);
+ if (EFI_ERROR(Status)) {
+ break;
+ }
+
+ (UINTN)Buffer = (UINTN)Buffer + BufferSize;
+ Lba += BlksPerTransfer;
+
+ }
+
+ if (EFI_ERROR(Status)) {
+ NvmeURP->bRetValue = NVME_WRITE_ERR;
+ }
+ else {
+ NvmeURP->bRetValue = NVME_SUCCESS;
+ }
+
+ return;
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeMassAPIPass
+//
+// Description: Dummy handler to return NVME_SUCCESS
+//
+// Input:
+// NVME_STRUC *NvmeURP
+//
+// Output:
+// NONE
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID
+NvmeMassAPIPass(
+ NVME_STRUC *NvmeURP
+)
+{
+
+ NvmeURP->bRetValue = NVME_SUCCESS;
+ return;
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeMassAPINotSupported
+//
+// Description: Dummy handler to return NVME_NOT_SUPPORTED
+//
+// Input:
+// NVME_STRUC *NvmeURP
+//
+// Output:
+// NONE
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID
+NvmeMassAPINotSupported (
+ NVME_STRUC *NvmeURP
+)
+{
+
+ NvmeURP->bRetValue = NVME_NOT_SUPPORTED;
+ return;
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeInitSmmData
+//
+// Description: Initialize NVMe SMM data area
+//
+// Input:
+//
+//
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+#if defined(PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014)
+EFI_STATUS
+EFIAPI
+NvmeInitSmmData (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *Context OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+ )
+#else
+EFI_STATUS
+NvmeInitSmmData (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+)
+#endif
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ ACTIVE_NAMESPACE_DATA *OrgActiveNameSpace;
+ ACTIVE_NAMESPACE_DATA *ActiveNameSpace;
+ AMI_NVME_CONTROLLER_PROTOCOL *NvmeController;
+ AMI_NVME_CONTROLLER_PROTOCOL *OrgNvmeController;
+ UINT8 Count;
+ EFI_LIST_ENTRY *LinkData;
+ UINTN NvmeComBuffer = 0;
+ static EFI_GUID gNvmeSmmGuid = NVME_SMM_GUID;
+ UINTN VariableSize = sizeof(UINTN);
+ EFI_BLOCK_IO_MEDIA *Media = NULL;
+
+ // After the first API call is invoked, don't initialize SMM data area. This is an additional
+ // Security check so that data won't get corrupted.
+ if (gFirstAPICall) {
+ return EFI_SUCCESS;
+ }
+#if defined(PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014)
+
+ // If input is invalid, stop processing this SMI
+ if (CommBuffer == NULL || CommBufferSize == NULL) {
+ return EFI_SUCCESS;
+ }
+ (UINTN)OrgNvmeController = *(UINTN *)CommBuffer;
+#else
+
+ Status = pRS->GetVariable ( L"NvmeSmmBuffer",
+ &gNvmeSmmGuid,
+ NULL,
+ &VariableSize,
+ &NvmeComBuffer );
+
+// TRACE((-1, "NvmeComBuffer in NvmeInitSmmData = %x\n", NvmeComBuffer));
+
+ (UINTN)OrgNvmeController = NvmeComBuffer;
+
+#endif
+
+
+ // Locate a free slot to copy the pointer
+ for (Count = 0; Count < MAX_NVME_DEVICES; Count++ ){
+ if (!gNvmeController[Count]) {
+ break;
+ }
+ }
+
+ if (Count == MAX_NVME_DEVICES) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+#if defined(PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014)
+ Status = pSmst2->SmmAllocatePool (
+#else
+ Status = pSmst->SmmAllocatePool (
+#endif
+ EfiRuntimeServicesData,
+ sizeof (AMI_NVME_CONTROLLER_PROTOCOL),
+ (VOID**)&NvmeController);
+ ASSERT_EFI_ERROR(Status);
+
+ // Copy input NvmeController passed in OrgNvmeController into SMM
+ MemCpy ((VOID *)NvmeController, OrgNvmeController, sizeof (AMI_NVME_CONTROLLER_PROTOCOL));
+
+
+ // Copy IDENTIFY_CONTROLLER_DATA
+#if defined(PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014)
+ Status = pSmst2->SmmAllocatePool (
+#else
+ Status = pSmst->SmmAllocatePool (
+#endif
+ EfiRuntimeServicesData,
+ sizeof (IDENTIFY_CONTROLLER_DATA),
+ (VOID**)&(NvmeController->IdentifyControllerData));
+ ASSERT_EFI_ERROR(Status);
+
+ MemCpy (NvmeController->IdentifyControllerData, OrgNvmeController->IdentifyControllerData, sizeof(IDENTIFY_CONTROLLER_DATA));
+
+ gNvmeController[Count] = NvmeController;
+
+
+ // Initialize some of the pointers to NULL which aren't applicable during runtime
+ NvmeController->PciIO = NULL;
+ NvmeController->NvmeInSmm = TRUE;
+ NvmeController->Queue1SubmissionQueueTailPtr = 0xFFFF;
+
+ InitializeListHead (&NvmeController->ActiveNameSpaceList);
+
+#if defined(PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014)
+ Status = pSmst2->SmmAllocatePool (
+#else
+ Status = pSmst->SmmAllocatePool (
+#endif
+ EfiRuntimeServicesData,
+ sizeof (NVME_COMMAND_WRAPPER),
+ (VOID**)&(NvmeController->NvmeCmdWrapper));
+
+ // Clear memory
+ ZeroMemorySmm (NvmeController->NvmeCmdWrapper, sizeof(NVME_COMMAND_WRAPPER));
+
+ // use original NVMe buffer for this as original address value is used.
+ // Update the NvmeController pointer inside ActiveNameSpace
+ for (LinkData = OrgNvmeController->ActiveNameSpaceList.ForwardLink;
+ LinkData != &OrgNvmeController->ActiveNameSpaceList;
+ LinkData = LinkData->ForwardLink) {
+
+ OrgActiveNameSpace = _CR(LinkData ,ACTIVE_NAMESPACE_DATA, Link);
+
+#if defined(PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014)
+ Status = pSmst2->SmmAllocatePool (
+#else
+ Status = pSmst->SmmAllocatePool (
+#endif
+ EfiRuntimeServicesData,
+ sizeof (ACTIVE_NAMESPACE_DATA),
+ (VOID**)&(ActiveNameSpace));
+ if(EFI_ERROR(Status)) {
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ MemCpy (ActiveNameSpace, OrgActiveNameSpace, sizeof(ACTIVE_NAMESPACE_DATA));
+
+ ActiveNameSpace->NvmeController = NvmeController;
+ ActiveNameSpace->EfiDevicePath = NULL;
+ ActiveNameSpace->UDeviceName = NULL;
+
+#if defined(PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014)
+ Status = pSmst2->SmmAllocatePool (
+#else
+ Status = pSmst->SmmAllocatePool (
+#endif
+ EfiRuntimeServicesData,
+ sizeof (EFI_BLOCK_IO_MEDIA),
+ (VOID**)&(Media) );
+ if(EFI_ERROR(Status)) {
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ MemCpy ( Media, OrgActiveNameSpace->NvmeBlockIO.Media, sizeof(EFI_BLOCK_IO_MEDIA) );
+ ActiveNameSpace->NvmeBlockIO.Media = Media;
+
+ InsertTailList (&NvmeController->ActiveNameSpaceList, &ActiveNameSpace->Link);
+
+ }
+
+ return Status;
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeSWSMIHandler
+//
+// Description: Handle SWSMI generated from NVMe CSM16 module
+//
+// Input:
+//
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+#if defined(PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014)
+EFI_STATUS
+NvmeSWSMIHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+)
+#else
+EFI_STATUS
+NvmeSWSMIHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+)
+#endif
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ NVME_STRUC *NvmeURP=NULL;
+ UINT8 bFuncIndex;
+ UINT8 bNumberOfFunctions;
+ UINT16 EbdaSeg;
+
+ gFirstAPICall = TRUE;
+
+ //
+ // Get the fpURP pointer from EBDA
+ //
+
+ EbdaSeg = *((UINT16*)0x40E);
+ NvmeURP = *(NVME_STRUC**)(UINTN)(((UINT32)EbdaSeg << 4) + NVME_DATA_EBDA_OFFSET);
+ NvmeURP = (NVME_STRUC*)((UINTN)NvmeURP & 0xFFFFFFFF);
+
+ // Validate if URP address is an non-SMRAM region to avoid SMRAM data
+ // corruption through SMI handlers
+ Status = AmiValidateMemoryBuffer((VOID*)NvmeURP, sizeof(NVME_STRUC));
+ if (EFI_ERROR(Status)) {
+ return EFI_SUCCESS;
+ }
+
+ if (NvmeURP->bFuncNumber != NVME_API_MASS_DEVICE_REQUEST) {
+ NvmeURP->bRetValue = NVME_PARAMETER_FAILED;
+ return Status;
+ }
+
+ bFuncIndex = NvmeURP->bSubFunc;
+ bNumberOfFunctions = sizeof NvmeMassApiTable / sizeof (API_FUNC *);
+
+ //
+ // Make sure function number is valid; if function number is not zero
+ // check for valid extended SDIO API function
+ //
+ if (bFuncIndex >= bNumberOfFunctions ) {
+ NvmeURP->bRetValue = NVME_PARAMETER_FAILED;
+ return Status;
+ }
+
+ //
+ // Call the appropriate function
+ //
+
+ NvmeMassApiTable[bFuncIndex](NvmeURP);
+
+ return Status;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: InSmmFunction
+//
+// Description: Nvme InSmmFunction
+//
+// Input:
+// IN EFI_HANDLE ImageHandle,
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+InSmmFunction(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE SwHandle = NULL;
+#if defined(PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014)
+ EFI_SMM_SW_REGISTER_CONTEXT SwContext;
+ EFI_HANDLE DispatchHandle;
+ EFI_SMM_SW_DISPATCH2_PROTOCOL *pSwDispatch = NULL;
+#else
+ EFI_SMM_BASE_PROTOCOL *pSmmBase;
+ EFI_SMM_SW_DISPATCH_PROTOCOL *pSwDispatch = NULL;
+ EFI_SMM_SYSTEM_TABLE *pSmst;
+ EFI_SMM_SW_DISPATCH_CONTEXT NvmeSmmSwContext = { NVME_SWSMI };
+ EFI_SMM_SW_DISPATCH_CONTEXT SwContext;
+#endif
+
+ InitAmiBufferValidationLib(ImageHandle, SystemTable);
+
+#if defined(PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014)
+
+ // PI_1.2 -->>
+
+ Status = pBS->LocateProtocol(&gEfiSmmBase2ProtocolGuid, NULL, &gSmmBase2);
+ if (EFI_ERROR(Status)) {
+ return EFI_SUCCESS;
+ }
+
+ Status = gSmmBase2->GetSmstLocation (gSmmBase2, &pSmst2);
+ if (EFI_ERROR(Status)) {
+ return EFI_SUCCESS;
+ }
+
+ Status = pSmst2->SmmLocateProtocol(&gEfiSmmSwDispatch2ProtocolGuid,
+ NULL,
+ &pSwDispatch);
+ if (EFI_ERROR(Status)) {
+ return EFI_SUCCESS;
+ }
+
+ SwContext.SwSmiInputValue = NVME_SWSMI;
+ Status = pSwDispatch->Register (pSwDispatch,
+ NvmeSWSMIHandler,
+ &SwContext,
+ &SwHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ //Allocate Memory for NVMe global Data.
+ //
+ Status = pSmst2->SmmAllocatePool(EfiRuntimeServicesData,sizeof(NVME_GLOBAL_DATA), &gNvmeData);
+ ASSERT_EFI_ERROR(Status);
+ //
+ // Clear the Buffer
+ //
+ pBS->SetMem((VOID*)gNvmeData, sizeof(NVME_GLOBAL_DATA), 0);
+
+
+ //
+ // Register Nvme handler to transfer data from DXE driver to SMM
+ //
+ Status = pSmst2->SmiHandlerRegister (
+ NvmeInitSmmData,
+ &gAmiSmmNvmeCommunicationGuid,
+ &DispatchHandle
+ );
+
+ ASSERT_EFI_ERROR (Status);
+
+ // PI_1.2 <<--
+#else
+
+ // NON PI 1.2 -->>
+
+ Status = pBS->LocateProtocol(&gEfiSmmSwDispatchProtocolGuid, NULL, &pSwDispatch);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = pBS->LocateProtocol(&gEfiSmmBaseProtocolGuid, NULL, &pSmmBase);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ pSmmBase->GetSmstLocation (pSmmBase, &pSmst);
+
+ Status = pSwDispatch->Register (pSwDispatch,
+ NvmeSWSMIHandler,
+ &NvmeSmmSwContext,
+ &SwHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ //Allocate Memory for NVMe global Data.
+ //
+ Status = pSmst->SmmAllocatePool(EfiRuntimeServicesData,sizeof(NVME_GLOBAL_DATA), &gNvmeData);
+ ASSERT_EFI_ERROR(Status);
+ //
+ // Clear the Buffer
+ //
+ pBS->SetMem((VOID*)gNvmeData, sizeof(NVME_GLOBAL_DATA), 0);
+
+ SwContext.SwSmiInputValue = NVME_INIT_SMM_SWSMI;
+ Status = pSwDispatch->Register (pSwDispatch,
+ NvmeInitSmmData,
+ &SwContext,
+ &SwHandle);
+
+ // NON PI_1.2 <<--
+
+#endif
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeSmmDriverEntryPoint
+//
+// Description: Loads NVMe SMM module into SMM and registers SMI handler
+//
+// Input:
+// IN EFI_HANDLE ImageHandle,
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+NvmeSmmDriverEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+
+
+ InitAmiLib(ImageHandle, SystemTable);
+ return InitSmmHandler (ImageHandle, SystemTable, InSmmFunction, NULL);
+
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Nvme/NvmeSmm/NvmeSmm.cif b/Core/EM/Nvme/NvmeSmm/NvmeSmm.cif
new file mode 100644
index 0000000..56d3f22
--- /dev/null
+++ b/Core/EM/Nvme/NvmeSmm/NvmeSmm.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "NvmeSmm"
+ category = ModulePart
+ LocalRoot = "Core\EM\Nvme\NvmeSmm\"
+ RefName = "NvmeSmm"
+[files]
+"NvmeSmm.mak"
+"NvmeSmm.dxs"
+"NvmeSmm.sdl"
+"NvmeSmm.c"
+"NvmeSmm.h"
+"NvmeDef.h"
+<endComponent>
diff --git a/Core/EM/Nvme/NvmeSmm/NvmeSmm.dxs b/Core/EM/Nvme/NvmeSmm/NvmeSmm.dxs
new file mode 100644
index 0000000..e2e23f9
--- /dev/null
+++ b/Core/EM/Nvme/NvmeSmm/NvmeSmm.dxs
@@ -0,0 +1,89 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/NVMe/NvmeSmm/NvmeSmm.dxs 2 9/23/14 2:33a Anandakrishnanl $
+//
+// $Revision: 2 $
+//
+// $Date: 9/23/14 2:33a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/NVMe/NvmeSmm/NvmeSmm.dxs $
+//
+// 2 9/23/14 2:33a Anandakrishnanl
+// [TAG] EIP180861
+// [Category] Improvement
+// [Description] Add Legacy Boot support in Aptio 4.x Nvme driver - NON
+// PI 1.2 Support
+// [Files] NvmeBus.c
+// NvmeBus.h
+// NvmeSmm.c
+// NvmeSmm.h
+// NvmeSmm.dxs
+// NvmeSmm.sdl
+//
+// 1 9/04/14 7:54a Anandakrishnanl
+// [TAG] EIP180861
+// [Category] Improvement
+// [Description] Legacy Boot support in Aptio 4.x Nvme driver
+// [Files] NvmeSmm.cif
+// NvmeSmm.mak
+// NvmeSmm.dxs
+// NvmeSmm.sdl
+// NvmeSmm.c
+// NvmeSmm.h
+// NvmeDef.h
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: NvmeSmm.dxs
+//
+// Description: This file is the dependency file for the NvmeSmm driver
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#if defined(PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014)
+#include <Protocol\SmmBase2.h>
+#include <Protocol\SmmSwDispatch2.h>
+#else
+#include <Protocol\SmmBase.h>
+#include <Protocol\SmmSwDispatch.h>
+#endif
+
+DEPENDENCY_START
+#if defined(PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014)
+ EFI_SMM_BASE2_PROTOCOL_GUID AND
+ EFI_SMM_SW_DISPATCH2_PROTOCOL_GUID
+#else
+ EFI_SMM_BASE_PROTOCOL_GUID AND
+ EFI_SMM_SW_DISPATCH_PROTOCOL_GUID
+#endif
+DEPENDENCY_END
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Nvme/NvmeSmm/NvmeSmm.h b/Core/EM/Nvme/NvmeSmm/NvmeSmm.h
new file mode 100644
index 0000000..20d13f4
--- /dev/null
+++ b/Core/EM/Nvme/NvmeSmm/NvmeSmm.h
@@ -0,0 +1,222 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/NVMe/NvmeSmm/NvmeSmm.h 3 12/10/14 5:15a Lavanyap $
+//
+// $Revision: 3 $
+//
+// $Date: 12/10/14 5:15a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/NVMe/NvmeSmm/NvmeSmm.h $
+//
+// 3 12/10/14 5:15a Lavanyap
+// [TAG] EIP185327
+// [Category] Improvement
+// [Description] Security Enhancement for SMIHandler in Aptio4.x NVMe
+// Driver
+// [Files] NvmeSmm.mak, NvmeSmm.c, NvmeSmm.h
+//
+// 2 9/23/14 2:34a Anandakrishnanl
+// [TAG] EIP180861
+// [Category] Improvement
+// [Description] Add Legacy Boot support in Aptio 4.x Nvme driver - NON
+// PI 1.2 Support
+// [Files] NvmeBus.c
+// NvmeBus.h
+// NvmeSmm.c
+// NvmeSmm.h
+// NvmeSmm.dxs
+// NvmeSmm.sdl
+//
+// 1 9/04/14 7:54a Anandakrishnanl
+// [TAG] EIP180861
+// [Category] Improvement
+// [Description] Legacy Boot support in Aptio 4.x Nvme driver
+// [Files] NvmeSmm.cif
+// NvmeSmm.mak
+// NvmeSmm.dxs
+// NvmeSmm.sdl
+// NvmeSmm.c
+// NvmeSmm.h
+// NvmeDef.h
+//
+//**********************************************************************
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: NvmeSmm.h
+//
+// Description: Header file for the NvmeSmm
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifndef _AMI_NVME_SMM_DRIVER_H_
+#define _AMI_NVME_SMM_DRIVER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <EFI.h>
+#include <AmiLib.h>
+#include <AmiDxeLib.h>
+#if defined(PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014)
+#include <Protocol\SmmBase2.h>
+#include <Protocol\SmmSwDispatch2.h>
+#else
+#include <Protocol\SmmBase.h>
+#include <Protocol\SmmSwDispatch.h>
+#endif
+#include "NvmeIncludes.h"
+#include "NvmeBus.h"
+#include "NvmeDef.h"
+#include <AmiBufferValidationLib.h>
+
+typedef VOID (*API_FUNC)(NVME_STRUC*);
+
+//-----------------------------------------------
+// ERROR CODE REPORTED TO CALLER
+//-----------------------------------------------
+#define NVME_WRITE_PROTECT_ERR 0x003 // Write protect error
+#define NVME_TIME_OUT_ERR 0x080 // Command timed out error
+#define NVME_DRIVE_NOT_READY_ERR 0x0AA // Drive not ready error
+#define NVME_DATA_CORRECTED_ERR 0x011 // Data corrected error
+#define NVME_PARAMETER_FAILED 0x007 // Bad parameter error
+#define NVME_MARK_NOT_FOUND_ERR 0x002 // Address mark not found error
+#define NVME_NO_MEDIA_ERR 0x031 // No media in drive
+#define NVME_READ_ERR 0x004 // Read error
+#define NVME_WRITE_ERR 0x005 // Write error
+#define NVME_UNCORRECTABLE_ERR 0x010 // Uncorrectable data error
+#define NVME_BAD_SECTOR_ERR 0x00A // Bad sector error
+#define NVME_GENERAL_FAILURE 0x020 // Controller general failure
+
+
+//-----------------------------------------------------------------------;
+// NVME_GLOBAL_DATA
+//-----------------------------------------------------------------------;
+typedef struct{
+ UINT32 TransferBufferAddress;
+ UINT8 NvmeMassEmulationOptionTable[MAX_NVME_DEVICES];
+ ACTIVE_NAMESPACE_DATA NvmeDev[MAX_NVME_DEVICES];
+} NVME_GLOBAL_DATA;
+
+//
+//NVME Setup fields
+//
+
+typedef struct {
+ UINT8 NvmeMode;
+ UINT8 NvmeEmu1;
+ UINT8 NvmeEmu2;
+ UINT8 NvmeEmu3;
+ UINT8 NvmeEmu4;
+ UINT8 NvmeEmu5;
+ UINT8 NvmeEmu6;
+ UINT8 NvmeEmu7;
+ UINT8 NvmeEmu8;
+ UINT8 NvmeMassDevNum;
+} NVME_DEV_CONFIGURATION;
+
+
+EFI_STATUS
+NotInSmmFunction (
+ EFI_HANDLE ImageHandle,
+ EFI_SYSTEM_TABLE *SystemTable
+);
+
+EFI_STATUS
+NvmeInSmmFunction (
+ EFI_HANDLE ImageHandle,
+ EFI_SYSTEM_TABLE *SystemTable
+);
+
+#if defined(PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014)
+EFI_STATUS
+NvmeSWSMIHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+);
+#else
+EFI_STATUS
+NvmeSWSMIHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+);
+#endif
+
+VOID
+ZeroMemorySmm (
+ VOID *Buffer,
+ UINTN Size
+ );
+
+VOID
+NvmeMassAPIGetDeviceInformation (
+ NVME_STRUC *NvmeURP
+);
+
+VOID
+NvmeMassAPIGetDeviceGeometry (
+ NVME_STRUC *NvmeURP
+);
+
+VOID
+NvmeMassAPIResetDevice (
+ NVME_STRUC *NvmeURP
+);
+
+VOID
+NvmeMassAPIReadDevice (
+ NVME_STRUC *NvmeURP
+);
+
+VOID
+NvmeMassAPIWriteDevice (
+ NVME_STRUC *NvmeURP
+);
+
+VOID
+NvmeMassAPINotSupported (
+ NVME_STRUC *NvmeURP
+);
+
+VOID
+NvmeMassAPIPass(
+ NVME_STRUC *NvmeURP
+);
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Nvme/NvmeSmm/NvmeSmm.mak b/Core/EM/Nvme/NvmeSmm/NvmeSmm.mak
new file mode 100644
index 0000000..3c3636b
--- /dev/null
+++ b/Core/EM/Nvme/NvmeSmm/NvmeSmm.mak
@@ -0,0 +1,95 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2014, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/NVMe/NvmeSmm/NvmeSmm.mak 3 7/15/15 5:04a Deepthins $
+#
+# $Revision: 3 $
+#
+# $Date: 7/15/15 5:04a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/NVMe/NvmeSmm/NvmeSmm.mak $
+#
+# 3 7/15/15 5:04a Deepthins
+# [TAG] EIP228506
+# [Description] Legacy Os installation failing for NVME device in AMD
+# platform
+# [Files] NvmeSmm.mak
+#
+# 2 12/10/14 5:16a Lavanyap
+# [TAG] EIP185327
+# [Category] Improvement
+# [Description] Security Enhancement for SMIHandler in Aptio4.x NVMe
+# Driver
+# [Files] NvmeSmm.mak, NvmeSmm.c, NvmeSmm.h
+#
+# 1 9/04/14 7:54a Anandakrishnanl
+# [TAG] EIP180861
+# [Category] Improvement
+# [Description] Legacy Boot support in Aptio 4.x Nvme driver
+# [Files] NvmeSmm.cif
+# NvmeSmm.mak
+# NvmeSmm.dxs
+# NvmeSmm.sdl
+# NvmeSmm.c
+# NvmeSmm.h
+# NvmeDef.h
+#
+#**********************************************************************
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: NvmeSmm.mak
+#
+# Description: Make file for NvmeSmm
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : NvmeSmm
+
+NvmeSmm : $(BUILD_DIR)\NvmeSmm.mak NvmeSmmBin
+
+$(BUILD_DIR)\NvmeSmm.mak : $(NVME_SMM_DIR)\NvmeSmm.cif $(NVME_SMM_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(NVME_SMM_DIR)\NvmeSmm.cif $(CIF2MAK_DEFAULTS)
+
+NVME_SMM_LIB = $(AMIDXELIB) \
+ $(NVMECONTROLLERLIB) \
+ $(BUILD_DIR)\AmiBufferValidationLib.lib
+
+NVME_SMM_INCLUDES=\
+ /I$(NVME_DIR)\
+
+NvmeSmmBin : $(NVME_SMM_LIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\NvmeSmm.mak all\
+ GUID=E5E2C9D9-5BF5-497E-8860-94F81A09ADE0\
+ ENTRY_POINT=NvmeSmmDriverEntryPoint\
+ "MY_INCLUDES=$(NVME_SMM_INCLUDES)"\
+ TYPE=SMM_DRIVER\
+ COMPRESS=1
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2014, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/Nvme/NvmeSmm/NvmeSmm.sdl b/Core/EM/Nvme/NvmeSmm/NvmeSmm.sdl
new file mode 100644
index 0000000..e9ab0e7
--- /dev/null
+++ b/Core/EM/Nvme/NvmeSmm/NvmeSmm.sdl
@@ -0,0 +1,35 @@
+TOKEN
+ Name = "NvmeSmm_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable NvmeSmm support in Project"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+ Token = "CSM_SUPPORT" "=" "1"
+ Token = "NVMEINT13_SUPPORT" "=" "1"
+End
+
+PATH
+ Name = "NVME_SMM_DIR"
+End
+
+TOKEN
+ Name = "NVME_INIT_SMM_SWSMI"
+ Value = "0x45"
+ Help = "Data to be written to SW SMI port to Init NVME Smm Data."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+MODULE
+ Help = "Includes NvmeSmm.mak to Project"
+ File = "NvmeSmm.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\NvmeSmm.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+