diff options
author | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
---|---|---|
committer | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
commit | b7c51c9cf4864df6aabb99a1ae843becd577237c (patch) | |
tree | eebe9b0d0ca03062955223097e57da84dd618b9a /Core/EM/Nvme/NvmeSmm | |
download | zprj-master.tar.xz |
Diffstat (limited to 'Core/EM/Nvme/NvmeSmm')
-rw-r--r-- | Core/EM/Nvme/NvmeSmm/NvmeDef.h | 253 | ||||
-rw-r--r-- | Core/EM/Nvme/NvmeSmm/NvmeSmm.c | 1127 | ||||
-rw-r--r-- | Core/EM/Nvme/NvmeSmm/NvmeSmm.cif | 13 | ||||
-rw-r--r-- | Core/EM/Nvme/NvmeSmm/NvmeSmm.dxs | 89 | ||||
-rw-r--r-- | Core/EM/Nvme/NvmeSmm/NvmeSmm.h | 222 | ||||
-rw-r--r-- | Core/EM/Nvme/NvmeSmm/NvmeSmm.mak | 95 | ||||
-rw-r--r-- | Core/EM/Nvme/NvmeSmm/NvmeSmm.sdl | 35 |
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 + |