From 26aab7effb41957820b1696f27bf9aff632473f0 Mon Sep 17 00:00:00 2001 From: Guo Mang Date: Wed, 3 Aug 2016 09:53:32 +0800 Subject: BraswellPlatformPkg: Move Flash to Common/Flash Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang Reviewed-by: David Wei --- .../Common/Flash/FvbRuntimeDxe/FvbInfo.c | 369 ++++++ .../Common/Flash/FvbRuntimeDxe/FvbRuntimeDxe.inf | 91 ++ .../Common/Flash/FvbRuntimeDxe/FvbService.c | 1226 ++++++++++++++++++++ .../Common/Flash/FvbRuntimeDxe/FvbService.h | 187 +++ .../Common/Flash/FvbRuntimeDxe/FvbServiceDxe.c | 197 ++++ .../Common/Flash/FvbRuntimeDxe/FvbServiceSmm.c | 263 +++++ .../Common/Flash/FvbRuntimeDxe/FvbSmm.inf | 93 ++ .../Common/Flash/FvbRuntimeDxe/FvbSmmCommon.h | 75 ++ .../Common/Flash/FvbRuntimeDxe/FvbSmmDxe.c | 933 +++++++++++++++ .../Common/Flash/FvbRuntimeDxe/FvbSmmDxe.h | 231 ++++ .../Common/Flash/FvbRuntimeDxe/FvbSmmDxe.inf | 57 + .../Common/Flash/SpiDeviceDxe/SpiDevice.c | 659 +++++++++++ .../Common/Flash/SpiDeviceDxe/SpiDevice.h | 211 ++++ .../Common/Flash/SpiDeviceDxe/SpiDeviceDxe.c | 152 +++ .../Common/Flash/SpiDeviceDxe/SpiDeviceDxe.inf | 64 + .../Common/Flash/SpiDeviceDxe/SpiDeviceSmm.c | 222 ++++ .../Common/Flash/SpiDeviceDxe/SpiDeviceSmm.inf | 62 + .../Common/Flash/SpiDeviceDxe/SpiDeviceSmmComm.h | 73 ++ .../Common/Flash/SpiDeviceDxe/SpiDeviceSmmDxe.c | 437 +++++++ .../Common/Flash/SpiDeviceDxe/SpiDeviceSmmDxe.inf | 51 + .../Common/Flash/SpiFlashParts/MX25/MX25.c | 208 ++++ .../Common/Flash/SpiFlashParts/MX25/MX25.inf | 41 + .../Common/Flash/SpiFlashParts/W25/W25.c | 192 +++ .../Common/Flash/SpiFlashParts/W25/W25.inf | 41 + BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbInfo.c | 369 ------ .../Flash/FvbRuntimeDxe/FvbRuntimeDxe.inf | 91 -- .../Flash/FvbRuntimeDxe/FvbService.c | 1226 -------------------- .../Flash/FvbRuntimeDxe/FvbService.h | 187 --- .../Flash/FvbRuntimeDxe/FvbServiceDxe.c | 197 ---- .../Flash/FvbRuntimeDxe/FvbServiceSmm.c | 263 ----- BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbSmm.inf | 93 -- .../Flash/FvbRuntimeDxe/FvbSmmCommon.h | 75 -- .../Flash/FvbRuntimeDxe/FvbSmmDxe.c | 933 --------------- .../Flash/FvbRuntimeDxe/FvbSmmDxe.h | 231 ---- .../Flash/FvbRuntimeDxe/FvbSmmDxe.inf | 57 - BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDevice.c | 659 ----------- BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDevice.h | 211 ---- .../Flash/SpiDeviceDxe/SpiDeviceDxe.c | 152 --- .../Flash/SpiDeviceDxe/SpiDeviceDxe.inf | 64 - .../Flash/SpiDeviceDxe/SpiDeviceSmm.c | 222 ---- .../Flash/SpiDeviceDxe/SpiDeviceSmm.inf | 62 - .../Flash/SpiDeviceDxe/SpiDeviceSmmComm.h | 73 -- .../Flash/SpiDeviceDxe/SpiDeviceSmmDxe.c | 437 ------- .../Flash/SpiDeviceDxe/SpiDeviceSmmDxe.inf | 51 - .../Flash/SpiFlashParts/MX25/MX25.c | 208 ---- .../Flash/SpiFlashParts/MX25/MX25.inf | 41 - BraswellPlatformPkg/Flash/SpiFlashParts/W25/W25.c | 192 --- .../Flash/SpiFlashParts/W25/W25.inf | 41 - 48 files changed, 6135 insertions(+), 6135 deletions(-) create mode 100644 BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbInfo.c create mode 100644 BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbRuntimeDxe.inf create mode 100644 BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbService.c create mode 100644 BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbService.h create mode 100644 BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbServiceDxe.c create mode 100644 BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbServiceSmm.c create mode 100644 BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbSmm.inf create mode 100644 BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbSmmCommon.h create mode 100644 BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbSmmDxe.c create mode 100644 BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbSmmDxe.h create mode 100644 BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbSmmDxe.inf create mode 100644 BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDevice.c create mode 100644 BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDevice.h create mode 100644 BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDeviceDxe.c create mode 100644 BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDeviceDxe.inf create mode 100644 BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDeviceSmm.c create mode 100644 BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDeviceSmm.inf create mode 100644 BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDeviceSmmComm.h create mode 100644 BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDeviceSmmDxe.c create mode 100644 BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDeviceSmmDxe.inf create mode 100644 BraswellPlatformPkg/Common/Flash/SpiFlashParts/MX25/MX25.c create mode 100644 BraswellPlatformPkg/Common/Flash/SpiFlashParts/MX25/MX25.inf create mode 100644 BraswellPlatformPkg/Common/Flash/SpiFlashParts/W25/W25.c create mode 100644 BraswellPlatformPkg/Common/Flash/SpiFlashParts/W25/W25.inf delete mode 100644 BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbInfo.c delete mode 100644 BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbRuntimeDxe.inf delete mode 100644 BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbService.c delete mode 100644 BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbService.h delete mode 100644 BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbServiceDxe.c delete mode 100644 BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbServiceSmm.c delete mode 100644 BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbSmm.inf delete mode 100644 BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbSmmCommon.h delete mode 100644 BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbSmmDxe.c delete mode 100644 BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbSmmDxe.h delete mode 100644 BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbSmmDxe.inf delete mode 100644 BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDevice.c delete mode 100644 BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDevice.h delete mode 100644 BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDeviceDxe.c delete mode 100644 BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDeviceDxe.inf delete mode 100644 BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDeviceSmm.c delete mode 100644 BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDeviceSmm.inf delete mode 100644 BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDeviceSmmComm.h delete mode 100644 BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDeviceSmmDxe.c delete mode 100644 BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDeviceSmmDxe.inf delete mode 100644 BraswellPlatformPkg/Flash/SpiFlashParts/MX25/MX25.c delete mode 100644 BraswellPlatformPkg/Flash/SpiFlashParts/MX25/MX25.inf delete mode 100644 BraswellPlatformPkg/Flash/SpiFlashParts/W25/W25.c delete mode 100644 BraswellPlatformPkg/Flash/SpiFlashParts/W25/W25.inf diff --git a/BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbInfo.c b/BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbInfo.c new file mode 100644 index 0000000000..15aae661e9 --- /dev/null +++ b/BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbInfo.c @@ -0,0 +1,369 @@ +/** @file + Defines data structure that is the volume header found. + These data is intent to decouple FVB driver with FV header. + + Copyright (c) 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include "FvbService.h" + +#define FVB_MEDIA_BLOCK_SIZE PcdGet32(PcdFlashMinEraseSize) + +typedef struct { + EFI_PHYSICAL_ADDRESS BaseAddress; + EFI_FIRMWARE_VOLUME_HEADER FvbInfo; + // + //EFI_FV_BLOCK_MAP_ENTRY ExtraBlockMap[n];//n=0 + // + EFI_FV_BLOCK_MAP_ENTRY End[1]; +} EFI_FVB2_MEDIA_INFO; + +// +// This data structure contains a template of all correct FV headers, which is used to restore +// Fv header if it's corrupted. +// +EFI_FVB2_MEDIA_INFO mPlatformFvbMediaInfo[] = { + // + // Main BIOS FVB + // + { + 0, + { + {0,}, //ZeroVector[16] + EFI_FIRMWARE_FILE_SYSTEM2_GUID, + 0, + EFI_FVH_SIGNATURE, + 0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2 + sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY), + 0, //CheckSum, check the FD for the value. + 0, //ExtHeaderOffset + {0,}, //Reserved[1] + 2, //Revision + { + { + 0, + 0, + } + } + }, + { + { + 0, + 0 + } + } + }, + // + // Systen NvStorage FVB + // + { + 0, + { + {0,}, //ZeroVector[16] + EFI_SYSTEM_NV_DATA_FV_GUID, + 0, + EFI_FVH_SIGNATURE, + 0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2 + sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY), + 0, //CheckSum which will be calucated dynamically. + 0, //ExtHeaderOffset + {0,}, //Reserved[1] + 2, //Revision + { + { + 0, + 0, + } + } + }, + { + { + 0, + 0 + } + } + }, + // + // Recovery BIOS FVB + // + { + 0, + { + {0,}, //ZeroVector[16] + EFI_FIRMWARE_FILE_SYSTEM2_GUID, + 0, + EFI_FVH_SIGNATURE, + 0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2 + sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY), + 0, //CheckSum which will be calucated dynamically. + 0, //ExtHeaderOffset + {0,}, //Reserved[1] + 2, //Revision + { + { + 0, + 0, + } + } + }, + { + { + 0, + 0 + } + } + }, + // + // Recovery 2 BIOS FVB + // + { + 0, + { + {0,}, //ZeroVector[16] + EFI_FIRMWARE_FILE_SYSTEM2_GUID, + 0, + EFI_FVH_SIGNATURE, + 0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2 + sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY), + 0, //CheckSum which will be calucated dynamically. + 0, //ExtHeaderOffset + {0,}, //Reserved[1] + 2, //Revision + { + { + 0, + 0, + } + } + }, + { + { + 0, + 0 + } + } + }, + // + // Payload FVB + // + { + 0, + { + {0,}, //ZeroVector[16] + EFI_FIRMWARE_FILE_SYSTEM2_GUID, + 0, + EFI_FVH_SIGNATURE, + 0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2 + sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY), + 0, //CheckSum which will be calucated dynamically. + 0x60, //ExtHeaderOffset + {0,}, //Reserved[1] + 2, //Revision + { + { + 0, + 0, + } + } + }, + { + { + 0, + 0 + } + } + } +}; + +// +// FTW working space and FTW spare space don't have FV header. +// We need create one for them and use it for FVB protocol. +// +EFI_FVB2_MEDIA_INFO mPlatformFtwFvbInfo[] = { + // + // System variable FTW working FVB + // + { + 0, + { + {0,}, //ZeroVector[16] + EFI_SYSTEM_NV_DATA_FV_GUID, + 0, + EFI_FVH_SIGNATURE, + 0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2 + sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY), + 0, //CheckSum which will be calucated dynamically. + 0, //ExtHeaderOffset + {0,}, //Reserved[1] + 2, //Revision + { + { + 0, + 0, + } + } + }, + { + { + 0, + 0 + } + } + }, + // + // Systen NV variable FTW spare FVB + // + { + 0, + { + {0,}, //ZeroVector[16] + EFI_SYSTEM_NV_DATA_FV_GUID, + 0, + EFI_FVH_SIGNATURE, + 0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2 + sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY), + 0, //CheckSum which will be calucated dynamically. + 0, //ExtHeaderOffset + {0,}, //Reserved[1] + 2, //Revision + { + { + 0, + 0, + } + } + }, + { + { + 0, + 0 + } + } + } +}; + +EFI_STATUS +GetFtwFvbInfo ( + IN EFI_PHYSICAL_ADDRESS FvBaseAddress, + OUT EFI_FIRMWARE_VOLUME_HEADER **FvbInfo + ) +{ + UINTN Index; + EFI_FIRMWARE_VOLUME_HEADER *FvHeader; + + // + // Init Fvb data + // + mPlatformFtwFvbInfo[0].BaseAddress = PcdGet32 (PcdFlashNvStorageFtwWorkingBase); + mPlatformFtwFvbInfo[0].FvbInfo.FvLength = PcdGet32 (PcdFlashNvStorageFtwWorkingSize); + mPlatformFtwFvbInfo[0].FvbInfo.BlockMap[0].NumBlocks = PcdGet32 (PcdFlashNvStorageFtwWorkingSize) / FVB_MEDIA_BLOCK_SIZE; + mPlatformFtwFvbInfo[0].FvbInfo.BlockMap[0].Length = FVB_MEDIA_BLOCK_SIZE; + ASSERT ((PcdGet32 (PcdFlashNvStorageFtwWorkingSize) % FVB_MEDIA_BLOCK_SIZE) == 0); + + mPlatformFtwFvbInfo[1].BaseAddress = PcdGet32 (PcdFlashNvStorageFtwSpareBase); + mPlatformFtwFvbInfo[1].FvbInfo.FvLength = PcdGet32 (PcdFlashNvStorageFtwSpareSize); + mPlatformFtwFvbInfo[1].FvbInfo.BlockMap[0].NumBlocks = PcdGet32 (PcdFlashNvStorageFtwSpareSize) / FVB_MEDIA_BLOCK_SIZE; + mPlatformFtwFvbInfo[1].FvbInfo.BlockMap[0].Length = FVB_MEDIA_BLOCK_SIZE; + ASSERT ((PcdGet32 (PcdFlashNvStorageFtwSpareSize) % FVB_MEDIA_BLOCK_SIZE) == 0); + + for (Index=0; Index < sizeof (mPlatformFtwFvbInfo)/sizeof (mPlatformFtwFvbInfo[0]); Index += 1) { + if (mPlatformFtwFvbInfo[Index].BaseAddress == FvBaseAddress) { + FvHeader = &mPlatformFtwFvbInfo[Index].FvbInfo; + // + // Update the checksum value of FV header. + // + FvHeader->Checksum = CalculateCheckSum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16)); + + *FvbInfo = FvHeader; + + DEBUG ((EFI_D_INFO, "\nFTW BaseAddr: 0x%lx \n", FvBaseAddress)); + DEBUG ((EFI_D_INFO, "FvLength: 0x%lx \n", (*FvbInfo)->FvLength)); + DEBUG ((EFI_D_INFO, "HeaderLength: 0x%x \n", (*FvbInfo)->HeaderLength)); + DEBUG ((EFI_D_INFO, "FvBlockMap[0].NumBlocks: 0x%x \n", (*FvbInfo)->BlockMap[0].NumBlocks)); + DEBUG ((EFI_D_INFO, "FvBlockMap[0].BlockLength: 0x%x \n", (*FvbInfo)->BlockMap[0].Length)); + DEBUG ((EFI_D_INFO, "FvBlockMap[1].NumBlocks: 0x%x \n", (*FvbInfo)->BlockMap[1].NumBlocks)); + DEBUG ((EFI_D_INFO, "FvBlockMap[1].BlockLength: 0x%x \n\n", (*FvbInfo)->BlockMap[1].Length)); + + return EFI_SUCCESS; + } + } + + return EFI_NOT_FOUND; +} + +EFI_STATUS +GetFvbInfo ( + IN EFI_PHYSICAL_ADDRESS FvBaseAddress, + OUT EFI_FIRMWARE_VOLUME_HEADER **FvbInfo + ) +{ + UINTN Index; + EFI_FIRMWARE_VOLUME_HEADER *FvHeader; + + // + // Init Fvb data + // + mPlatformFvbMediaInfo[0].BaseAddress = PcdGet32 (PcdFlashFvMainBase); + mPlatformFvbMediaInfo[0].FvbInfo.FvLength = PcdGet32 (PcdFlashFvMainSize); + mPlatformFvbMediaInfo[0].FvbInfo.BlockMap[0].NumBlocks = PcdGet32 (PcdFlashFvMainSize) / FVB_MEDIA_BLOCK_SIZE; + mPlatformFvbMediaInfo[0].FvbInfo.BlockMap[0].Length = FVB_MEDIA_BLOCK_SIZE; + ASSERT ((PcdGet32 (PcdFlashFvMainSize) % FVB_MEDIA_BLOCK_SIZE) == 0); + + mPlatformFvbMediaInfo[1].BaseAddress = PcdGet32 (PcdFlashNvStorageVariableBase); + mPlatformFvbMediaInfo[1].FvbInfo.FvLength = PcdGet32 (PcdFlashNvStorageVariableSize); + mPlatformFvbMediaInfo[1].FvbInfo.BlockMap[0].NumBlocks = PcdGet32 (PcdFlashNvStorageVariableSize) / FVB_MEDIA_BLOCK_SIZE; + mPlatformFvbMediaInfo[1].FvbInfo.BlockMap[0].Length = FVB_MEDIA_BLOCK_SIZE; + ASSERT ((PcdGet32 (PcdFlashNvStorageVariableSize) % FVB_MEDIA_BLOCK_SIZE) == 0); + + mPlatformFvbMediaInfo[2].BaseAddress = PcdGet32 (PcdFlashFvRecoveryBase); + mPlatformFvbMediaInfo[2].FvbInfo.FvLength = PcdGet32 (PcdFlashFvRecoverySize); + mPlatformFvbMediaInfo[2].FvbInfo.BlockMap[0].NumBlocks = PcdGet32 (PcdFlashFvRecoverySize) / FVB_MEDIA_BLOCK_SIZE; + mPlatformFvbMediaInfo[2].FvbInfo.BlockMap[0].Length = FVB_MEDIA_BLOCK_SIZE; + ASSERT ((PcdGet32 (PcdFlashFvRecoverySize) % FVB_MEDIA_BLOCK_SIZE) == 0); + + mPlatformFvbMediaInfo[3].BaseAddress = PcdGet32 (PcdFlashFvRecovery2Base); + mPlatformFvbMediaInfo[3].FvbInfo.FvLength = PcdGet32 (PcdFlashFvRecovery2Size); + mPlatformFvbMediaInfo[3].FvbInfo.BlockMap[0].NumBlocks = PcdGet32 (PcdFlashFvRecovery2Size) / FVB_MEDIA_BLOCK_SIZE; + mPlatformFvbMediaInfo[3].FvbInfo.BlockMap[0].Length = FVB_MEDIA_BLOCK_SIZE; + ASSERT ((PcdGet32 (PcdFlashFvRecovery2Size) % FVB_MEDIA_BLOCK_SIZE) == 0); + + mPlatformFvbMediaInfo[4].BaseAddress = PcdGet32 (PcdFlashPayloadBase); + mPlatformFvbMediaInfo[4].FvbInfo.FvLength = PcdGet32 (PcdFlashPayloadSize); + mPlatformFvbMediaInfo[4].FvbInfo.BlockMap[0].NumBlocks = PcdGet32 (PcdFlashPayloadSize) / FVB_MEDIA_BLOCK_SIZE; + mPlatformFvbMediaInfo[4].FvbInfo.BlockMap[0].Length = FVB_MEDIA_BLOCK_SIZE; + ASSERT ((PcdGet32 (PcdFlashPayloadSize) % FVB_MEDIA_BLOCK_SIZE) == 0); + + for (Index=0; Index < sizeof (mPlatformFvbMediaInfo)/sizeof (mPlatformFvbMediaInfo[0]); Index += 1) { + if (mPlatformFvbMediaInfo[Index].BaseAddress == FvBaseAddress) { + FvHeader = &mPlatformFvbMediaInfo[Index].FvbInfo; + // + // Update the checksum value of FV header. + // + FvHeader->Checksum = CalculateCheckSum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16)); + + *FvbInfo = FvHeader; + + DEBUG ((EFI_D_INFO, "\nBaseAddr: 0x%lx \n", FvBaseAddress)); + DEBUG ((EFI_D_INFO, "FvLength: 0x%lx \n", (*FvbInfo)->FvLength)); + DEBUG ((EFI_D_INFO, "HeaderLength: 0x%x \n", (*FvbInfo)->HeaderLength)); + DEBUG ((EFI_D_INFO, "FvBlockMap[0].NumBlocks: 0x%x \n", (*FvbInfo)->BlockMap[0].NumBlocks)); + DEBUG ((EFI_D_INFO, "FvBlockMap[0].BlockLength: 0x%x \n", (*FvbInfo)->BlockMap[0].Length)); + DEBUG ((EFI_D_INFO, "FvBlockMap[1].NumBlocks: 0x%x \n", (*FvbInfo)->BlockMap[1].NumBlocks)); + DEBUG ((EFI_D_INFO, "FvBlockMap[1].BlockLength: 0x%x \n\n", (*FvbInfo)->BlockMap[1].Length)); + + return EFI_SUCCESS; + } + } + + return EFI_NOT_FOUND; +} diff --git a/BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbRuntimeDxe.inf b/BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbRuntimeDxe.inf new file mode 100644 index 0000000000..347ed88159 --- /dev/null +++ b/BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbRuntimeDxe.inf @@ -0,0 +1,91 @@ +## @file +# Firmware Volume Block access module +# +# Provides the ability to perform read, write and erase operations on a Firmware +# Volume. Read and write operations are possible at the byte level but the +# erase operation can only be done at the block level. +# +# Copyright (c) 2015, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010018 + BASE_NAME = FvbRuntimeDxe + FILE_GUID = 7CB9C516-E7AA-4582-86A2-371EA9B3AFA3 + MODULE_TYPE = DXE_RUNTIME_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = DxeFvbInitialize + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# +# + +[Sources] + FvbInfo.c + FvbService.h + FvbService.c + FvbServiceDxe.c + +[Packages] + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + BraswellPlatformPkg/BraswellPlatformPkg.dec + +[LibraryClasses] + PcdLib + MemoryAllocationLib + CacheMaintenanceLib + IoLib + BaseMemoryLib + DebugLib + BaseLib + UefiLib + UefiRuntimeLib + UefiBootServicesTableLib + UefiDriverEntryPoint + HobLib + +[Guids] + gEfiFirmwareFileSystem2Guid ## SOMETIMES_CONSUMES ## GUID + gEfiSystemNvDataFvGuid ## SOMETIMES_CONSUMES ## GUID + gEfiEventVirtualAddressChangeGuid ## CONSUMES ## Event + +[Protocols] + gEfiDevicePathProtocolGuid ## SOMETIMES_PRODUCES + gEfiFirmwareVolumeBlockProtocolGuid ## PRODUCES + gSpiDeviceProtocolGuid ## CONSUMES + +[Pcd] + gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES + gPlatformModuleTokenSpaceGuid.PcdFlashFvMainBase ## CONSUMES + gPlatformModuleTokenSpaceGuid.PcdFlashFvMainSize ## CONSUMES + gPlatformModuleTokenSpaceGuid.PcdFlashFvRecoveryBase ## CONSUMES + gPlatformModuleTokenSpaceGuid.PcdFlashFvRecoverySize ## CONSUMES + gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Base ## CONSUMES + gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Size ## CONSUMES + gPlatformModuleTokenSpaceGuid.PcdFlashPayloadBase ## CONSUMES + gPlatformModuleTokenSpaceGuid.PcdFlashPayloadSize ## CONSUMES + + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize ## CONSUMES + gPlatformModuleTokenSpaceGuid.PcdFlashMinEraseSize ## CONSUMES + +[Depex] + gSpiDeviceProtocolGuid + diff --git a/BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbService.c b/BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbService.c new file mode 100644 index 0000000000..1e5f151620 --- /dev/null +++ b/BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbService.c @@ -0,0 +1,1226 @@ +/** @file + Firmware Volume Block Driver for Braswell Platform. + + Copyright (c) 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "FvbService.h" + +// +// Global variable for this FVB driver which contains +// the private data of all firmware volume block instances +// +FWB_GLOBAL mFvbModuleGlobal; + +FV_MEMMAP_DEVICE_PATH mFvMemmapDevicePathTemplate = { + { + { + HARDWARE_DEVICE_PATH, + HW_MEMMAP_DP, + { + (UINT8)(sizeof (MEMMAP_DEVICE_PATH)), + (UINT8)(sizeof (MEMMAP_DEVICE_PATH) >> 8) + } + }, + EfiMemoryMappedIO, + (EFI_PHYSICAL_ADDRESS) 0, + (EFI_PHYSICAL_ADDRESS) 0, + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + END_DEVICE_PATH_LENGTH, + 0 + } + } +}; + +FV_PIWG_DEVICE_PATH mFvPIWGDevicePathTemplate = { + { + { + MEDIA_DEVICE_PATH, + MEDIA_PIWG_FW_VOL_DP, + { + (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH)), + (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH) >> 8) + } + }, + { 0 } + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + END_DEVICE_PATH_LENGTH, + 0 + } + } +}; + +// +// Template structure used when installing FVB protocol +// +EFI_FW_VOL_BLOCK_DEVICE mFvbDeviceTemplate = { + FVB_DEVICE_SIGNATURE, + NULL, + 0, // Instance + { + FvbProtocolGetAttributes, + FvbProtocolSetAttributes, + FvbProtocolGetPhysicalAddress, + FvbProtocolGetBlockSize, + FvbProtocolRead, + FvbProtocolWrite, + FvbProtocolEraseBlocks, + NULL + } // FwVolBlockInstance +}; + +SPI_DEVICE_PROTOCOL *mSpiDeviceProtocol; + +/** + Get the pointer to EFI_FW_VOL_INSTANCE from the buffer pointed + by mFvbModuleGlobal.FvInstance based on a index. + Each EFI_FW_VOL_INSTANCE is with variable length as + we have a block map at the end of the EFI_FIRMWARE_VOLUME_HEADER. + + @param[in] Instance The index of the EFI_FW_VOL_INSTANCE. + + @return A pointer to EFI_FW_VOL_INSTANCE. + +**/ +EFI_FW_VOL_INSTANCE * +GetFvbInstance ( + IN UINTN Instance + ) +{ + EFI_FW_VOL_INSTANCE *FwhRecord; + + if ( Instance >= mFvbModuleGlobal.NumFv ) { + ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); + return NULL; + } + + // + // Find the right instance of the FVB private data + // + FwhRecord = mFvbModuleGlobal.FvInstance; + while ( Instance > 0 ) { + FwhRecord = (EFI_FW_VOL_INSTANCE *) ((UINTN)((UINT8 *)FwhRecord) + + FwhRecord->VolumeHeader.HeaderLength + + (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))); + Instance --; + } + + return FwhRecord; +} + +/** + Get the EFI_FVB_ATTRIBUTES_2 of a FV. + + @param[in] The index of the EFI_FW_VOL_INSTANCE. + + @return EFI_FVB_ATTRIBUTES_2 of the FV identified by Instance. + +**/ +STATIC +EFI_FVB_ATTRIBUTES_2 +FvbGetVolumeAttributes ( + IN UINTN Instance + ) +{ + return GetFvbInstance (Instance)->VolumeHeader.Attributes; +} + +/** + Retrieves the starting address of an LBA in an FV. It also + return a few other attribut of the FV. + + @param[in] Instance The index of the EFI_FW_VOL_INSTANCE. + @param[in] Lba The logical block address + @param[out] FlashLinearAddress Provides the linear address into the flash device. + @param[out] LbaAddress On output, contains the physical starting address + of the Lba + @param[out] LbaLength On output, contains the length of the block + @param[out] NumOfBlocks A pointer to a caller allocated UINTN in which the + number of consecutive blocks starting with Lba is + returned. All blocks in this range have a size of + BlockSize + + @retval EFI_SUCCESS Successfully returns + @retval EFI_INVALID_PARAMETER Instance not found + +**/ +STATIC +EFI_STATUS +FvbGetLbaAddress ( + IN UINTN Instance, + IN EFI_LBA Lba, + OUT UINTN *FlashLinearAddress, + OUT UINTN *LbaAddress, + OUT UINTN *LbaLength, + OUT UINTN *NumOfBlocks + ) +{ + UINT32 NumBlocks; + UINT32 BlockLength; + UINTN Offset; + EFI_LBA StartLba; + EFI_LBA NextLba; + EFI_FW_VOL_INSTANCE *FwhInstance; + EFI_FV_BLOCK_MAP_ENTRY *BlockMap; + + // + // Find the right instance of the FVB private data + // + FwhInstance = GetFvbInstance (Instance); + + StartLba = 0; + Offset = 0; + BlockMap = &(FwhInstance->VolumeHeader.BlockMap[0]); + + // + // Parse the blockmap of the FV to find which map entry the Lba belongs to + // + while (TRUE) { + NumBlocks = BlockMap->NumBlocks; + BlockLength = BlockMap->Length; + + if (NumBlocks == 0 || BlockLength == 0) { + return EFI_INVALID_PARAMETER; + } + + NextLba = StartLba + NumBlocks; + + // + // The map entry found + // + if (Lba >= StartLba && Lba < NextLba) { + Offset = Offset + (UINTN)MultU64x32((Lba - StartLba), BlockLength); + if (FlashLinearAddress) { + *FlashLinearAddress = FwhInstance->FvFlashLinearAddress + Offset; + } + + if (LbaAddress) { + *LbaAddress = FwhInstance->FvBase + Offset; + } + + if (LbaLength) { + *LbaLength = BlockLength; + } + + if (NumOfBlocks) { + *NumOfBlocks = (UINTN)(NextLba - Lba); + } + return EFI_SUCCESS; + } + + StartLba = NextLba; + Offset = Offset + NumBlocks * BlockLength; + BlockMap++; + } +} + +/** + Reads specified number of bytes into a buffer from the specified block + + @param[in] Instance The FV instance to be read from + @param[in] Lba The logical block address to be read from + @param[in] BlockOffset Offset into the block at which to begin reading + @param[in] NumBytes Pointer that on input contains the total size of + the buffer. On output, it contains the total number + of bytes read + @param[in] Buffer Pointer to a caller allocated buffer that will be + used to hold the data read + + @retval EFI_SUCCESS The firmware volume was read successfully and + contents are in Buffer + @retval EFI_BAD_BUFFER_SIZE Read attempted across a LBA boundary. On output, + NumBytes contains the total number of bytes returned + in Buffer + @retval EFI_ACCESS_DENIED The firmware volume is in the ReadDisabled state + @retval EFI_DEVICE_ERROR The block device is not functioning correctly and + could not be read + @retval EFI_INVALID_PARAMETER Instance not found, or NumBytes, Buffer are NULL + +**/ +STATIC +EFI_STATUS +FvbReadBlock ( + IN UINTN Instance, + IN EFI_LBA Lba, + IN UINTN BlockOffset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ) +{ + EFI_FVB_ATTRIBUTES_2 Attributes; + UINTN LbaLength; + EFI_STATUS Status; + EFI_STATUS Status1; + UINTN FlashAddress; + + // + // Validate input parameters. + // + if ((NumBytes == NULL) || (Buffer == NULL)) { + return (EFI_INVALID_PARAMETER); + } + if (*NumBytes == 0) { + return (EFI_INVALID_PARAMETER); + } + + // + // Get information for the specific LBA. + // + Status = FvbGetLbaAddress (Instance, Lba, &FlashAddress, NULL, &LbaLength, NULL); + if (EFI_ERROR (Status)) { + return EFI_INVALID_PARAMETER; + } + + // + // Check if operation can happen in the current state. + // + Attributes = FvbGetVolumeAttributes (Instance); + if ((Attributes & EFI_FVB2_READ_STATUS) == 0) { + return EFI_ACCESS_DENIED; + } + + // + // Check to make sure that block information is valid for the current FV and + // correct it if needed. + // + if (BlockOffset > LbaLength) { + return EFI_INVALID_PARAMETER; + } + if (LbaLength < (*NumBytes + BlockOffset)) { + *NumBytes = (UINT32) (LbaLength - BlockOffset); + Status = EFI_BAD_BUFFER_SIZE; + } + + // + // Perform read. + // + Status1 = mSpiDeviceProtocol->SpiRead (FlashAddress + BlockOffset, NumBytes, Buffer); + if (Status1 == EFI_DEVICE_ERROR) { + return Status1; + } + + return Status; +} + +/** + Writes specified number of bytes from the input buffer to the block + + @param[in] Instance The FV instance to be written to + @param[in] Lba The starting logical block index to write to + @param[in] BlockOffset Offset into the block at which to begin writing + @param[in] NumBytes Pointer that on input contains the total size of + the buffer. On output, it contains the total number + of bytes actually written + @param[in] Buffer Pointer to a caller allocated buffer that contains + the source for the write + @retval EFI_SUCCESS The firmware volume was written successfully + @retval EFI_BAD_BUFFER_SIZE Write attempted across a LBA boundary. On output, + NumBytes contains the total number of bytes + actually written + @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state + @retval EFI_DEVICE_ERROR The block device is not functioning correctly and + could not be written + @retval EFI_INVALID_PARAMETER Instance not found, or NumBytes, Buffer are NULL + +**/ +EFI_STATUS +FvbWriteBlock ( + IN UINTN Instance, + IN EFI_LBA Lba, + IN UINTN BlockOffset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ) +{ + EFI_FVB_ATTRIBUTES_2 Attributes; + UINTN LbaAddress; + UINTN LbaLength; + EFI_FW_VOL_INSTANCE *FwhInstance; + EFI_STATUS Status; + EFI_STATUS Status1; + UINTN FlashAddress; + + // + // Validate input parameters. + // + if ((NumBytes == NULL) || (Buffer == NULL)) { + return (EFI_INVALID_PARAMETER); + } + if (*NumBytes == 0) { + return (EFI_INVALID_PARAMETER); + } + + // + // Get the information for the FV specified. + // + FwhInstance = GetFvbInstance (Instance); + Status = FvbGetLbaAddress (Instance, Lba, &FlashAddress, &LbaAddress, &LbaLength, NULL); + if (EFI_ERROR (Status)) { + return EFI_INVALID_PARAMETER; + } + + // + // Check if the FV is write enabled + // + Attributes = FvbGetVolumeAttributes (Instance); + if ((Attributes & EFI_FVB2_WRITE_STATUS) == 0) { + return EFI_ACCESS_DENIED; + } + + // + // Perform boundary checks and adjust NumBytes if needed. + // + if (BlockOffset > LbaLength) { + return EFI_INVALID_PARAMETER; + } + if ( LbaLength < ( *NumBytes + BlockOffset ) ) { + *NumBytes = (UINT32) (LbaLength - BlockOffset); + Status = EFI_BAD_BUFFER_SIZE; + } + + // + // Perform the write and flush the cache. + // + mSpiDeviceProtocol->SpiLock (FlashAddress, LbaLength, FALSE); + Status1 = mSpiDeviceProtocol->SpiWrite (FlashAddress + BlockOffset, NumBytes, Buffer); + mSpiDeviceProtocol->SpiLock (FlashAddress, LbaLength, TRUE); + WriteBackInvalidateDataCacheRange ((VOID *) (LbaAddress + BlockOffset), *NumBytes); + + // + // Determine the error to return based on PI spec. + // + if (Status1 == EFI_DEVICE_ERROR) { + return Status1; + } + + return Status; +} + +/** + Erases and initializes a firmware volume block + + @param[in] Instance The FV instance to be erased + @param[in] Lba The logical block index to be erased + + @retval EFI_SUCCESS The erase request was successfully completed + @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state + @retval EFI_DEVICE_ERROR The block device is not functioning correctly and + could not be written. Firmware device may have been + partially erased + @retval EFI_INVALID_PARAMETER Instance not found + +**/ +EFI_STATUS +FvbEraseBlock ( + IN UINTN Instance, + IN EFI_LBA Lba + ) +{ + EFI_FVB_ATTRIBUTES_2 Attributes; + UINTN LbaAddress; + EFI_FW_VOL_INSTANCE *FwhInstance; + UINTN LbaLength; + EFI_STATUS Status; + EFI_STATUS Status1; + UINTN FlashAddress; + + // + // Find the right instance of the FVB private data + // + FwhInstance = GetFvbInstance (Instance); + + // + // Check if the FV is write enabled + // + Attributes = FvbGetVolumeAttributes (Instance); + if ((Attributes & EFI_FVB2_WRITE_STATUS) == 0) { + return EFI_ACCESS_DENIED; + } + + // + // Get the starting address of the block for erase. + // + Status = FvbGetLbaAddress (Instance, Lba, &FlashAddress, &LbaAddress, &LbaLength, NULL); + if (EFI_ERROR (Status)) { + return EFI_INVALID_PARAMETER; + } + + // + // Perform erase. + // + mSpiDeviceProtocol->SpiLock (FlashAddress, LbaLength, FALSE); + Status1 = mSpiDeviceProtocol->SpiErase (FlashAddress, LbaLength); + mSpiDeviceProtocol->SpiLock (FlashAddress, LbaLength, TRUE); + WriteBackInvalidateDataCacheRange ((VOID *) LbaAddress, LbaLength); + + // + // Check to see if the erase was successful. If not return a device error to + // meet PI required return values. + // + if (Status1 == EFI_DEVICE_ERROR) { + return Status1; + } + + return EFI_SUCCESS; +} + +/** + Modifies the current settings of the firmware volume according to the + input parameter, and returns the new setting of the volume + + @param[in] Instance The FV instance whose attributes is going to be + modified + @param[in] Attributes On input, it is a pointer to EFI_FVB_ATTRIBUTES_2 + containing the desired firmware volume settings. + On successful return, it contains the new settings + of the firmware volume + + @retval EFI_SUCCESS Successfully returns + @retval EFI_ACCESS_DENIED The volume setting is locked and cannot be modified + @retval EFI_INVALID_PARAMETER Instance not found, or The attributes requested are + in conflict with the capabilities as declared in the + firmware volume header + +**/ +STATIC +EFI_STATUS +FvbSetVolumeAttributes ( + IN UINTN Instance, + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ) +{ + EFI_FW_VOL_INSTANCE *FwhInstance; + EFI_FVB_ATTRIBUTES_2 OldAttributes; + EFI_FVB_ATTRIBUTES_2 *AttribPtr; + EFI_FVB_ATTRIBUTES_2 UnchangedAttributes; + UINT32 Capabilities; + UINT32 OldStatus, NewStatus; + + // + // Find the right instance of the FVB private data + // + FwhInstance = GetFvbInstance (Instance); + + AttribPtr = (EFI_FVB_ATTRIBUTES_2 *) &(FwhInstance->VolumeHeader.Attributes); + OldAttributes = *AttribPtr; + Capabilities = OldAttributes & EFI_FVB2_CAPABILITIES; + OldStatus = OldAttributes & EFI_FVB2_STATUS; + NewStatus = *Attributes & EFI_FVB2_STATUS; + + UnchangedAttributes = EFI_FVB2_READ_DISABLED_CAP | \ + EFI_FVB2_READ_ENABLED_CAP | \ + EFI_FVB2_WRITE_DISABLED_CAP | \ + EFI_FVB2_WRITE_ENABLED_CAP | \ + EFI_FVB2_LOCK_CAP | \ + EFI_FVB2_STICKY_WRITE | \ + EFI_FVB2_MEMORY_MAPPED | \ + EFI_FVB2_ERASE_POLARITY | \ + EFI_FVB2_READ_LOCK_CAP | \ + EFI_FVB2_WRITE_LOCK_CAP | \ + EFI_FVB2_ALIGNMENT; + + // + // Some attributes of FV is read only can *not* be set + // + if ((OldAttributes & UnchangedAttributes) ^ (*Attributes & UnchangedAttributes)) { + return EFI_INVALID_PARAMETER; + } + + // + // If firmware volume is locked, no status bit can be updated + // + if ( OldAttributes & EFI_FVB2_LOCK_STATUS ) { + if ( OldStatus ^ NewStatus ) { + return EFI_ACCESS_DENIED; + } + } + + // + // Test read disable + // + if ((Capabilities & EFI_FVB2_READ_DISABLED_CAP) == 0) { + if ((NewStatus & EFI_FVB2_READ_STATUS) == 0) { + return EFI_INVALID_PARAMETER; + } + } + + // + // Test read enable + // + if ((Capabilities & EFI_FVB2_READ_ENABLED_CAP) == 0) { + if (NewStatus & EFI_FVB2_READ_STATUS) { + return EFI_INVALID_PARAMETER; + } + } + + // + // Test write disable + // + if ((Capabilities & EFI_FVB2_WRITE_DISABLED_CAP) == 0) { + if ((NewStatus & EFI_FVB2_WRITE_STATUS) == 0) { + return EFI_INVALID_PARAMETER; + } + } + + // + // Test write enable + // + if ((Capabilities & EFI_FVB2_WRITE_ENABLED_CAP) == 0) { + if (NewStatus & EFI_FVB2_WRITE_STATUS) { + return EFI_INVALID_PARAMETER; + } + } + + // + // Test lock + // + if ((Capabilities & EFI_FVB2_LOCK_CAP) == 0) { + if (NewStatus & EFI_FVB2_LOCK_STATUS) { + return EFI_INVALID_PARAMETER; + } + } + + *AttribPtr = (*AttribPtr) & (0xFFFFFFFF & (~EFI_FVB2_STATUS)); + *AttribPtr = (*AttribPtr) | NewStatus; + *Attributes = *AttribPtr; + + return EFI_SUCCESS; +} + +// +// FVB protocol APIs +// + +/** + Retrieves the physical address of the device. + + @param[in] This A pointer to EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL. + @param[out] Address Output buffer containing the address. + + retval EFI_SUCCESS The function always return successfully. + +**/ +EFI_STATUS +EFIAPI +FvbProtocolGetPhysicalAddress ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + OUT EFI_PHYSICAL_ADDRESS *Address + ) +{ + EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; + + FvbDevice = FVB_DEVICE_FROM_THIS (This); + *Address = GetFvbInstance (FvbDevice->Instance)->FvBase; + + return EFI_SUCCESS; +} + +/** + Retrieve the size of a logical block + + @param[in] This Calling context + @param[in] Lba Indicates which block to return the size for. + @param[out] BlockSize A pointer to a caller allocated UINTN in which + the size of the block is returned + @param[out] NumOfBlocks A pointer to a caller allocated UINTN in which the + number of consecutive blocks starting with Lba is + returned. All blocks in this range have a size of + BlockSize + + @retval EFI_SUCCESS The function always return successfully. + +**/ +EFI_STATUS +EFIAPI +FvbProtocolGetBlockSize ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN EFI_LBA Lba, + OUT UINTN *BlockSize, + OUT UINTN *NumOfBlocks + ) +{ + EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; + + FvbDevice = FVB_DEVICE_FROM_THIS (This); + return FvbGetLbaAddress ( + FvbDevice->Instance, + Lba, + NULL, + NULL, + BlockSize, + NumOfBlocks + ); +} + +/** + Retrieves Volume attributes. No polarity translations are done. + + @param[in] This Calling context + @param[out] Attributes Output buffer which contains attributes + + @retval EFI_SUCCESS The function always return successfully. + +**/ +EFI_STATUS +EFIAPI +FvbProtocolGetAttributes ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ) +{ + EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; + + FvbDevice = FVB_DEVICE_FROM_THIS (This); + *Attributes = FvbGetVolumeAttributes (FvbDevice->Instance); + + return EFI_SUCCESS; +} + +/** + Sets Volume attributes. No polarity translations are done. + + @param[in] This Calling context + @param[out] Attributes Output buffer which contains attributes + + @retval EFI_SUCCESS The function always return successfully. + +**/ +EFI_STATUS +EFIAPI +FvbProtocolSetAttributes ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ) +{ + EFI_STATUS Status; + EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; + + FvbDevice = FVB_DEVICE_FROM_THIS (This); + Status = FvbSetVolumeAttributes (FvbDevice->Instance, Attributes); + + return Status; +} + +/** + The EraseBlock() function erases one or more blocks as denoted by the + variable argument list. The entire parameter list of blocks must be verified + prior to erasing any blocks. If a block is requested that does not exist + within the associated firmware volume (it has a larger index than the last + block of the firmware volume), the EraseBlock() function must return + EFI_INVALID_PARAMETER without modifying the contents of the firmware volume. + + @param[in] This Calling context + @param[in] ... Starting LBA followed by Number of Lba to erase. + a -1 to terminate the list. + + @retval EFI_SUCCESS The erase request was successfully completed + @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state + @retval EFI_DEVICE_ERROR The block device is not functioning correctly and + could not be written. Firmware device may have been + partially erased + +**/ +EFI_STATUS +EFIAPI +FvbProtocolEraseBlocks ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + ... + ) +{ + EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; + EFI_FW_VOL_INSTANCE *FwhInstance; + UINTN NumOfBlocks; + VA_LIST args; + EFI_LBA StartingLba; + UINTN NumOfLba; + EFI_STATUS Status; + EFI_FVB_ATTRIBUTES_2 Attributes; + + // + // Initialize data. + // + FvbDevice = FVB_DEVICE_FROM_THIS (This); + FwhInstance = GetFvbInstance (FvbDevice->Instance); + NumOfBlocks = FwhInstance->NumOfBlocks; + + // + // Check if this FV can be written to. + // + Attributes = FvbGetVolumeAttributes (FvbDevice->Instance); + if ((Attributes & EFI_FVB2_WRITE_STATUS) == 0) { + return EFI_ACCESS_DENIED; + } + + // + // Validate LBA information passed in by caller. + // + VA_START (args, This); + do { + // + // Check for last entry in variable argument list. + // + StartingLba = VA_ARG (args, EFI_LBA); + if (StartingLba == EFI_LBA_LIST_TERMINATOR) { + break; + } + + // + // Get parameter from stack. + // + NumOfLba = VA_ARG (args, UINT32); + + // + // Check input parameters + // + if (NumOfLba == 0) { + VA_END (args); + return EFI_INVALID_PARAMETER; + } + if ((StartingLba + NumOfLba) > NumOfBlocks) { + VA_END (args); + return EFI_INVALID_PARAMETER; + } + } while (1); + VA_END (args); + + // + // Perform erase operation on all selected LBA. + // + VA_START (args, This); + do { + // + // Check for last entry in variable argument list. + // + StartingLba = VA_ARG (args, EFI_LBA); + if (StartingLba == EFI_LBA_LIST_TERMINATOR) { + break; + } + + // + // Get parameter from stack. + // + NumOfLba = VA_ARG (args, UINT32); + + // + // Perform the erase operation for the specific LBA. + // + while (NumOfLba > 0) { + Status = FvbEraseBlock (FvbDevice->Instance, StartingLba); + if (EFI_ERROR (Status)) { + VA_END (args); + return Status; + } + StartingLba ++; + NumOfLba --; + } + } while (1); + VA_END (args); + + return EFI_SUCCESS; +} + +/** + Writes data beginning at Lba:Offset from FV. The write terminates either + when *NumBytes of data have been written, or when a block boundary is + reached. *NumBytes is updated to reflect the actual number of bytes + written. The write opertion does not include erase. This routine will + attempt to write only the specified bytes. If the writes do not stick, + it will return an error. + + @param[in] This Calling context + @param[in] Lba Block in which to begin write + @param[in] Offset Offset in the block at which to begin write + @param[in, out] NumBytes On input, indicates the requested write size. On + output, indicates the actual number of bytes written + @param[in] Buffer Buffer containing source data for the write. + + @retval EFI_SUCCESS The firmware volume was written successfully + @retval EFI_BAD_BUFFER_SIZE Write attempted across a LBA boundary. On output, + NumBytes contains the total number of bytes + actually written + @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state + @retval EFI_DEVICE_ERROR The block device is not functioning correctly and + could not be written + @retval EFI_INVALID_PARAMETER NumBytes or Buffer are NULL + +**/ +EFI_STATUS +EFIAPI +FvbProtocolWrite ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ) +{ + EFI_STATUS Status; + EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; + + FvbDevice = FVB_DEVICE_FROM_THIS (This); + Status = FvbWriteBlock (FvbDevice->Instance, Lba, Offset, NumBytes, Buffer); + + return Status; +} + +/** + Reads data beginning at Lba:Offset from FV. The Read terminates either + when *NumBytes of data have been read, or when a block boundary is + reached. *NumBytes is updated to reflect the actual number of bytes + written. The write opertion does not include erase. This routine will + attempt to write only the specified bytes. If the writes do not stick, + it will return an error. + + @param[in] This Calling context + @param[in] Lba Block in which to begin write + @param[in] Offset Offset in the block at which to begin write + @param[in, out] NumBytes On input, indicates the requested write size. On + output, indicates the actual number of bytes written + @param[in] Buffer Buffer containing source data for the write. + +Returns: + @retval EFI_SUCCESS The firmware volume was read successfully and + contents are in Buffer + @retval EFI_BAD_BUFFER_SIZE Read attempted across a LBA boundary. On output, + NumBytes contains the total number of bytes returned + in Buffer + @retval EFI_ACCESS_DENIED The firmware volume is in the ReadDisabled state + @retval EFI_DEVICE_ERROR The block device is not functioning correctly and + could not be read + @retval EFI_INVALID_PARAMETER NumBytes or Buffer are NULL + +**/ +EFI_STATUS +EFIAPI +FvbProtocolRead ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + OUT UINT8 *Buffer + ) +{ + + EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; + EFI_STATUS Status; + + FvbDevice = FVB_DEVICE_FROM_THIS (This); + Status = FvbReadBlock (FvbDevice->Instance, Lba, Offset, NumBytes, Buffer); + + return Status; +} + +/** + Check the integrity of firmware volume header + + @param[in] FwVolHeader A pointer to a firmware volume header + + @retval TRUE The firmware volume is consistent + @retval FALSE The firmware volume has corrupted. + +**/ +STATIC +BOOLEAN +IsFvHeaderValid ( + IN EFI_PHYSICAL_ADDRESS FvBase, + IN CONST EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader + ) +{ + UINT16 Checksum; + + if (FvBase == PcdGet32(PcdFlashNvStorageVariableBase)) { + if (CompareMem (&FwVolHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid, sizeof(EFI_GUID)) != 0 ) { + return FALSE; + } + } else { + if (CompareMem (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystem2Guid, sizeof(EFI_GUID)) != 0 ) { + return FALSE; + } + } + if ((FwVolHeader->Revision != EFI_FVH_REVISION) || + (FwVolHeader->Signature != EFI_FVH_SIGNATURE) || + (FwVolHeader->FvLength == ((UINTN) -1)) || + ((FwVolHeader->HeaderLength & 0x01 ) !=0)) { + return FALSE; + } + + Checksum = CalculateCheckSum16 ((UINT16 *) FwVolHeader, FwVolHeader->HeaderLength); + if (Checksum != 0) { + DEBUG (( DEBUG_ERROR, + "ERROR - Invalid Firmware Volume Header Checksum, change 0x%04x to 0x%04x\r\n", + FwVolHeader->Checksum, + (UINT16)( Checksum + FwVolHeader->Checksum ))); + return FALSE; + } + + return TRUE; +} + +/** + The driver entry point for Firmware Volume Block Driver. + + The function does the necessary initialization work + Firmware Volume Block Driver. + + @param[in] ImageHandle The firmware allocated handle for the UEFI image. + @param[in] SystemTable A pointer to the EFI system table. + + @retval EFI_SUCCESS This funtion always return EFI_SUCCESS. + It will ASSERT on errors. + +**/ +EFI_STATUS +FvbInitialize ( + ) +{ + EFI_FW_VOL_INSTANCE *FwhInstance; + EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; + EFI_FIRMWARE_VOLUME_HEADER *FvHeader; + EFI_FV_BLOCK_MAP_ENTRY *PtrBlockMapEntry; + EFI_PHYSICAL_ADDRESS BaseAddress; + EFI_STATUS Status; + UINTN BufferSize; + UINTN TmpHeaderLength; + UINTN Idx; + UINT32 MaxLbaSize; + BOOLEAN FvHeaderValid; + UINTN FvFlashLinearAddress; + EFI_BOOT_MODE BootMode; + UINT32 Index; + UINT32 PlatformFvBaseAddress[5]; + UINT32 PlatformFvBaseAddressCount; + UINT32 PlatformFvLockList[4]; + UINT32 PlatformFvLockListCount; + + // + // This platform driver knows there are 3 FVs on + // FD, which are FvRecovery, FvMain and FvNvStorage. + // + BootMode = GetBootModeHob (); + if (BootMode == BOOT_IN_RECOVERY_MODE) { + // + // On recovery boot, don't report any firmware FV images except payload, because their data can't be trusted. + // + PlatformFvBaseAddressCount = 2; + PlatformFvBaseAddress[0] = PcdGet32 (PcdFlashNvStorageVariableBase); + PlatformFvBaseAddress[1] = PcdGet32 (PcdFlashPayloadBase); + } else { + PlatformFvBaseAddressCount = 5; + PlatformFvBaseAddress[0] = PcdGet32 (PcdFlashFvMainBase); + PlatformFvBaseAddress[1] = PcdGet32 (PcdFlashNvStorageVariableBase); + PlatformFvBaseAddress[2] = PcdGet32 (PcdFlashFvRecoveryBase); + PlatformFvBaseAddress[3] = PcdGet32 (PcdFlashFvRecovery2Base); + PlatformFvBaseAddress[4] = PcdGet32 (PcdFlashPayloadBase); + } + + // + // List of FVs that should be write protected on normal boots. + // + PlatformFvLockListCount = 4; + PlatformFvLockList[0] = PcdGet32 (PcdFlashFvMainBase); + PlatformFvLockList[1] = PcdGet32 (PcdFlashFvRecoveryBase); + PlatformFvLockList[2] = PcdGet32 (PcdFlashFvRecovery2Base); + PlatformFvLockList[3] = PcdGet32 (PcdFlashPayloadBase); + + // + // Calculate the total size for all firmware volume block instances and + // allocate a buffer to store them in. + // + BufferSize = 0; + for (Idx = 0; Idx < PlatformFvBaseAddressCount; Idx++) { + FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PlatformFvBaseAddress[Idx]; + if (FvHeader == NULL) { + continue; + } + BufferSize += (FvHeader->HeaderLength + + sizeof (EFI_FW_VOL_INSTANCE) - + sizeof (EFI_FIRMWARE_VOLUME_HEADER) + ); + } + mFvbModuleGlobal.FvInstance = (EFI_FW_VOL_INSTANCE *) AllocateRuntimeZeroPool (BufferSize); + ASSERT (NULL != mFvbModuleGlobal.FvInstance); + + // + // Perform other variable initialization. + // + MaxLbaSize = 0; + FwhInstance = mFvbModuleGlobal.FvInstance; + mFvbModuleGlobal.NumFv = 0; + + for (Idx = 0; Idx < PlatformFvBaseAddressCount; Idx++) { + + if ((BootMode == BOOT_ASSUMING_NO_CONFIGURATION_CHANGES) && PlatformFvBaseAddress[Idx]!= PcdGet32 (PcdFlashNvStorageVariableBase) && PlatformFvBaseAddress[Idx]!= PcdGet32 (PcdFlashPayloadBase)) { + continue; + } + // + // Get base address information. + // + BaseAddress = PlatformFvBaseAddress[Idx]; + FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) BaseAddress; + if (FwVolHeader == NULL) { + continue; + } + // + // Find the flash linear address of the current FV. + // + FvFlashLinearAddress = (UINTN) FLASH_LINEAR_ADDRESS(BaseAddress); + + if (!IsFvHeaderValid (BaseAddress, FwVolHeader)) { + FvHeaderValid = FALSE; + + // + // If not valid, get FvbInfo from the information carried in + // FVB driver. + // + DEBUG ((EFI_D_ERROR, "Fvb: FV header @ 0x%lx invalid\n", BaseAddress)); + Status = GetFvbInfo (BaseAddress, &FwVolHeader); + ASSERT_EFI_ERROR(Status); + + // + // Write back a healthy FV header. + // + DEBUG ((EFI_D_INFO, "FwBlockService.c: Writing back healthy FV header\n")); + mSpiDeviceProtocol->SpiLock (FvFlashLinearAddress, FwVolHeader->BlockMap->Length, FALSE); + + Status = mSpiDeviceProtocol->SpiErase (FvFlashLinearAddress, FwVolHeader->BlockMap->Length); + + TmpHeaderLength = (UINTN) FwVolHeader->HeaderLength; + Status = mSpiDeviceProtocol->SpiWrite ( + FvFlashLinearAddress, + &TmpHeaderLength, + (UINT8 *) FwVolHeader + ); + + mSpiDeviceProtocol->SpiLock (FvFlashLinearAddress, FwVolHeader->BlockMap->Length, TRUE); + + WriteBackInvalidateDataCacheRange ( + (VOID *) (UINTN) BaseAddress, + FwVolHeader->BlockMap->Length + ); + + } + + // + // Copy FV header into local storage and assign base address. + // + CopyMem (&(FwhInstance->VolumeHeader), FwVolHeader, FwVolHeader->HeaderLength); + FwVolHeader = &(FwhInstance->VolumeHeader); + FwhInstance->FvBase = (UINTN)BaseAddress; + FwhInstance->FvFlashLinearAddress = FvFlashLinearAddress; + + // + // In some cases the Recovery and Main FVs should be considered locked from + // write access by this protocol. Only in the case of flash updates and + // configuration mode should they be left unlocked. + // + if (BootMode != BOOT_IN_RECOVERY_MODE && + BootMode != BOOT_ON_FLASH_UPDATE) { + for (Index = 0; Index < PlatformFvLockListCount; Index++) { + if (FwhInstance->FvBase == PlatformFvLockList[Index]) { + // + // For all FVs in the lock list we need to clear the write status bit + // and lock write status updates. This will make sure this protocol + // will not attempt to write to the FV. + // + FwhInstance->VolumeHeader.Attributes &= (UINT64) ~EFI_FVB2_WRITE_STATUS; + FwhInstance->VolumeHeader.Attributes |= (EFI_FVB2_LOCK_STATUS | EFI_FVB2_WRITE_LOCK_STATUS); + } + } + } + + // + // Process the block map for each FV + // + FwhInstance->NumOfBlocks = 0; + for (PtrBlockMapEntry = FwVolHeader->BlockMap; + PtrBlockMapEntry->NumBlocks != 0; + PtrBlockMapEntry++) { + // + // Get the maximum size of a block. + // + if (MaxLbaSize < PtrBlockMapEntry->Length) { + MaxLbaSize = PtrBlockMapEntry->Length; + } + FwhInstance->NumOfBlocks += PtrBlockMapEntry->NumBlocks; + } + + // + // Add a FVB Protocol Instance + // + mFvbModuleGlobal.NumFv++; + InstallFvbProtocol (FwhInstance, mFvbModuleGlobal.NumFv - 1); + + // + // Move on to the next FwhInstance + // + FwhInstance = (EFI_FW_VOL_INSTANCE *) ((UINTN)((UINT8 *)FwhInstance) + + FwVolHeader->HeaderLength + + (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))); + } + + if ((PcdGet32 (PcdFlashNvStorageFtwWorkingBase) == 0) || (PcdGet32 (PcdFlashNvStorageFtwSpareBase) == 0)) { + return EFI_SUCCESS; + } + + // + // Install FVB protocols for FTW spare space and FTW working space. + // These is no FV header for these 2 spaces. + // + mFvbModuleGlobal.FvInstance = (EFI_FW_VOL_INSTANCE *) ReallocateRuntimePool ( + BufferSize, + BufferSize + (sizeof (EFI_FW_VOL_INSTANCE) + sizeof (EFI_FV_BLOCK_MAP_ENTRY)) * 2, + mFvbModuleGlobal.FvInstance + ); + ASSERT (NULL != mFvbModuleGlobal.FvInstance); + PlatformFvBaseAddress[0] = PcdGet32 (PcdFlashNvStorageFtwWorkingBase); + PlatformFvBaseAddress[1] = PcdGet32 (PcdFlashNvStorageFtwSpareBase); + + for (Idx = 0; Idx < 2; Idx++) { + BaseAddress = PlatformFvBaseAddress[Idx]; + Status = GetFtwFvbInfo (BaseAddress, &FwVolHeader); + ASSERT_EFI_ERROR(Status); + + // + // Copy FV header into local storage and assign base address. + // + mFvbModuleGlobal.NumFv++; + FwhInstance = GetFvbInstance (mFvbModuleGlobal.NumFv - 1); + CopyMem (&(FwhInstance->VolumeHeader), FwVolHeader, FwVolHeader->HeaderLength); + FwVolHeader = &(FwhInstance->VolumeHeader); + + // + // Process the block map for each FV + // + FwhInstance->NumOfBlocks = 0; + for (PtrBlockMapEntry = FwVolHeader->BlockMap; + PtrBlockMapEntry->NumBlocks != 0; + PtrBlockMapEntry++) { + FwhInstance->NumOfBlocks += PtrBlockMapEntry->NumBlocks; + } + + FwhInstance->FvBase = (UINTN)BaseAddress; + FwhInstance->FvFlashLinearAddress = (UINTN) FLASH_LINEAR_ADDRESS(BaseAddress); + + InstallFvbProtocol (FwhInstance, mFvbModuleGlobal.NumFv - 1); + } + + return EFI_SUCCESS; +} + diff --git a/BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbService.h b/BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbService.h new file mode 100644 index 0000000000..ed9e579307 --- /dev/null +++ b/BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbService.h @@ -0,0 +1,187 @@ +/** @file + The header file for Firmware volume block driver. + + Copyright (c) 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _FW_BLOCK_SERVICE_H +#define _FW_BLOCK_SERVICE_H + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +// Define two helper macro to extract the Capability field or Status field in FVB +// bit fields +// +#define EFI_FVB2_CAPABILITIES (EFI_FVB2_READ_DISABLED_CAP | \ + EFI_FVB2_READ_ENABLED_CAP | \ + EFI_FVB2_WRITE_DISABLED_CAP | \ + EFI_FVB2_WRITE_ENABLED_CAP | \ + EFI_FVB2_LOCK_CAP \ + ) + +#define EFI_FVB2_STATUS (EFI_FVB2_READ_STATUS | EFI_FVB2_WRITE_STATUS | EFI_FVB2_LOCK_STATUS) + +typedef struct { + UINTN FvBase; + UINTN NumOfBlocks; + UINTN FvFlashLinearAddress; + // + // Note!!!: VolumeHeader must be the last element + // of the structure. + // + EFI_FIRMWARE_VOLUME_HEADER VolumeHeader; +} EFI_FW_VOL_INSTANCE; + +typedef struct { + EFI_FW_VOL_INSTANCE *FvInstance; + UINT32 NumFv; +} FWB_GLOBAL; + +// +// Fvb Protocol instance data +// +#define FVB_DEVICE_FROM_THIS(a) CR(a, EFI_FW_VOL_BLOCK_DEVICE, FwVolBlockInstance, FVB_DEVICE_SIGNATURE) +#define FVB_EXTEND_DEVICE_FROM_THIS(a) CR(a, EFI_FW_VOL_BLOCK_DEVICE, FvbExtension, FVB_DEVICE_SIGNATURE) +#define FVB_DEVICE_SIGNATURE SIGNATURE_32('F','V','B','C') + +typedef struct { + MEDIA_FW_VOL_DEVICE_PATH FvDevPath; + EFI_DEVICE_PATH_PROTOCOL EndDevPath; +} FV_PIWG_DEVICE_PATH; + +typedef struct { + MEMMAP_DEVICE_PATH MemMapDevPath; + EFI_DEVICE_PATH_PROTOCOL EndDevPath; +} FV_MEMMAP_DEVICE_PATH; + +typedef struct { + UINT32 Signature; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + UINTN Instance; + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL FwVolBlockInstance; +} EFI_FW_VOL_BLOCK_DEVICE; + +EFI_STATUS +GetFvbInfo ( + IN EFI_PHYSICAL_ADDRESS FvBaseAddress, + OUT EFI_FIRMWARE_VOLUME_HEADER **FvbInfo + ); + +EFI_STATUS +GetFtwFvbInfo ( + IN EFI_PHYSICAL_ADDRESS FvBaseAddress, + OUT EFI_FIRMWARE_VOLUME_HEADER **FvbInfo + ); + +VOID +InstallFvbProtocol ( + IN EFI_FW_VOL_INSTANCE *FwhInstance, + IN UINTN InstanceNum + ); + +EFI_STATUS +FvbInitialize ( + ); + +EFI_FW_VOL_INSTANCE * +GetFvbInstance ( + IN UINTN Instance + ); + +// +// Protocol APIs +// +EFI_STATUS +EFIAPI +FvbProtocolGetAttributes ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ); + +EFI_STATUS +EFIAPI +FvbProtocolSetAttributes ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ); + +EFI_STATUS +EFIAPI +FvbProtocolGetPhysicalAddress ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + OUT EFI_PHYSICAL_ADDRESS *Address + ); + +EFI_STATUS +EFIAPI +FvbProtocolGetBlockSize ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN EFI_LBA Lba, + OUT UINTN *BlockSize, + OUT UINTN *NumOfBlocks + ); + +EFI_STATUS +EFIAPI +FvbProtocolRead ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + OUT UINT8 *Buffer + ); + +EFI_STATUS +EFIAPI +FvbProtocolWrite ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ); + +EFI_STATUS +EFIAPI +FvbProtocolEraseBlocks ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + ... + ); + +extern FWB_GLOBAL mFvbModuleGlobal; +extern EFI_FW_VOL_BLOCK_DEVICE mFvbDeviceTemplate; +extern FV_PIWG_DEVICE_PATH mFvPIWGDevicePathTemplate; +extern FV_MEMMAP_DEVICE_PATH mFvMemmapDevicePathTemplate; +extern SPI_DEVICE_PROTOCOL *mSpiDeviceProtocol; + +#endif + diff --git a/BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbServiceDxe.c b/BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbServiceDxe.c new file mode 100644 index 0000000000..26effe7181 --- /dev/null +++ b/BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbServiceDxe.c @@ -0,0 +1,197 @@ +/** @file + Firmware Volume Block Driver for Tunnel Mountain Platform. + + Copyright (c) 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include "FvbService.h" + +/** + Call back function on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event. + + Fixup internal data so that the driver is callable in EFI runtime + in virtual mode. Convert the mFvbModuleGlobal date items to there + virtual address. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context The context of the Notification context. Not used in + this call back function. + +**/ +VOID +EFIAPI +FvbVirtualddressChangeEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_FW_VOL_INSTANCE *FwhInstance; + UINTN Index; + + // + // Convert the base address of all the instances + // + for (Index = 0; Index < mFvbModuleGlobal.NumFv; Index++) { + FwhInstance = GetFvbInstance (Index); + EfiConvertPointer (0, (VOID **) &FwhInstance->FvBase); + } + + EfiConvertPointer (0, (VOID **) &mFvbModuleGlobal.FvInstance); + + EfiConvertPointer (0, (VOID **)&mSpiDeviceProtocol); +} + +/** + The function installs EFI_FIRMWARE_VOLUME_BLOCK protocol + for each FV in the system. + + @param[in] FwhInstance The pointer to a FW volume instance structure, + which contains the information about one FV. + @param[in] InstanceNum The instance number which can be used as a ID + to locate this FwhInstance in other functions. + + @retval VOID + +**/ +VOID +InstallFvbProtocol ( + IN EFI_FW_VOL_INSTANCE *FwhInstance, + IN UINTN InstanceNum + ) +{ + EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; + EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; + EFI_STATUS Status; + EFI_HANDLE FwbHandle; + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *OldFwbInterface; + + FvbDevice = (EFI_FW_VOL_BLOCK_DEVICE *) AllocateRuntimeCopyPool ( + sizeof (EFI_FW_VOL_BLOCK_DEVICE), + &mFvbDeviceTemplate + ); + ASSERT (FvbDevice != NULL); + + FvbDevice->Instance = InstanceNum; + FwVolHeader = &FwhInstance->VolumeHeader; + + // + // Set up the devicepath + // + DEBUG ((EFI_D_INFO, "FwBlockService.c: Setting up DevicePath for 0x%lx:\n", FwhInstance->FvBase)); + if (FwVolHeader->ExtHeaderOffset == 0) { + // + // FV does not contains extension header, then produce MEMMAP_DEVICE_PATH + // + FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateRuntimeCopyPool (sizeof (FV_MEMMAP_DEVICE_PATH), &mFvMemmapDevicePathTemplate); + ((FV_MEMMAP_DEVICE_PATH *) FvbDevice->DevicePath)->MemMapDevPath.StartingAddress = FwhInstance->FvBase; + ((FV_MEMMAP_DEVICE_PATH *) FvbDevice->DevicePath)->MemMapDevPath.EndingAddress = FwhInstance->FvBase + FwVolHeader->FvLength - 1; + } else { + FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateRuntimeCopyPool (sizeof (FV_PIWG_DEVICE_PATH), &mFvPIWGDevicePathTemplate); + CopyGuid ( + &((FV_PIWG_DEVICE_PATH *)FvbDevice->DevicePath)->FvDevPath.FvName, + (GUID *)(UINTN)(FwhInstance->FvBase + FwVolHeader->ExtHeaderOffset) + ); + } + + // + // Find a handle with a matching device path that has supports FW Block protocol + // + Status = gBS->LocateDevicePath (&gEfiFirmwareVolumeBlockProtocolGuid, &FvbDevice->DevicePath, &FwbHandle); + if (EFI_ERROR (Status) ) { + // + // LocateDevicePath fails so install a new interface and device path + // + DEBUG ((EFI_D_INFO, "FwBlockService.c: LocateDevicePath failed, install new interface 0x%lx:\n", FwhInstance->FvBase)); + FwbHandle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces ( + &FwbHandle, + &gEfiFirmwareVolumeBlockProtocolGuid, + &FvbDevice->FwVolBlockInstance, + &gEfiDevicePathProtocolGuid, + FvbDevice->DevicePath, + NULL + ); + ASSERT_EFI_ERROR (Status); + DEBUG ((EFI_D_INFO, "FwBlockService.c: IMPI FirmwareVolBlockProt, DevPath 0x%lx: %r\n", FwhInstance->FvBase, Status)); + + } else if (IsDevicePathEnd (FvbDevice->DevicePath)) { + // + // Device allready exists, so reinstall the FVB protocol + // + DEBUG ((EFI_D_INFO, "FwBlockService.c: LocateDevicePath succeeded, reinstall interface 0x%lx:\n", FwhInstance->FvBase)); + Status = gBS->HandleProtocol ( + FwbHandle, + &gEfiFirmwareVolumeBlockProtocolGuid, + (VOID **) &OldFwbInterface + ); + ASSERT_EFI_ERROR (Status); + + Status = gBS->ReinstallProtocolInterface ( + FwbHandle, + &gEfiFirmwareVolumeBlockProtocolGuid, + OldFwbInterface, + &FvbDevice->FwVolBlockInstance + ); + ASSERT_EFI_ERROR (Status); + + } else { + // + // There was a FVB protocol on an End Device Path node + // + ASSERT (FALSE); + } + +} + +EFI_STATUS +EFIAPI +DxeFvbInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_EVENT Event; + + // + // Register for a callback when virtual addressing is updated. + // + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + FvbVirtualddressChangeEvent, + NULL, + &gEfiEventVirtualAddressChangeGuid, + &Event + ); + ASSERT_EFI_ERROR (Status); + + // + // Locate required protocol for access to flash. + // + Status = gBS->LocateProtocol ( + &gSpiDeviceProtocolGuid, + NULL, + (VOID **) &mSpiDeviceProtocol + ); + ASSERT_EFI_ERROR(Status); + + // + // Initialize the rest of the module. + // + Status = FvbInitialize (); + + return Status; +} diff --git a/BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbServiceSmm.c b/BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbServiceSmm.c new file mode 100644 index 0000000000..ffe101e08e --- /dev/null +++ b/BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbServiceSmm.c @@ -0,0 +1,263 @@ +/** @file + SMM Firmware Volume Block Driver for the Tunnel Creek Platform. + + Copyright (c) 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include "FvbSmmCommon.h" +#include "FvbService.h" + +/** + Communication service SMI Handler entry. + + This SMI handler provides communication services with the SMM FVB runtime driver. + + @param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister(). + @param[in] RegisterContext Points to an optional handler context which was specified when the + handler was registered. + @param[in, out] CommBuffer A pointer to a collection of data in memory that will + be conveyed from a non-SMM environment into an SMM environment. + @param[in, out] CommBufferSize The size of the CommBuffer. + + @retval EFI_SUCCESS The interrupt was handled successfully. + @retval EFI_UNSUPPORTED The request was not supported by the handler. + +**/ +EFI_STATUS +EFIAPI +FvbSmmHandler ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *RegisterContext, + IN OUT VOID *CommBuffer, + IN OUT UINTN *CommBufferSize + ) +{ + EFI_STATUS Status; + SMM_FVB_COMMUNICATE_FUNCTION_HEADER *SmmFvbFunctionHeader; + SMM_FVB_ATTRIBUTES_HEADER *SmmFvbAttributesHeader; + SMM_FVB_PHYSICAL_ADDRESS_HEADER *SmmFvbPhysicalAddressHeader; + SMM_FVB_BLOCK_SIZE_HEADER *SmmFvbBlockSizeHeader; + SMM_FVB_READ_WRITE_HEADER *SmmFvbReadWriteHeader; + SMM_FVB_BLOCKS_HEADER *SmmFvbBlocksHeader; + + ASSERT (CommBuffer != NULL); + + // + // Determine the function that is being requested and execute it. + // + SmmFvbFunctionHeader = (SMM_FVB_COMMUNICATE_FUNCTION_HEADER *) CommBuffer; + switch (SmmFvbFunctionHeader->Function) { + case EFI_FUNCTION_GET_ATTRIBUTES: + SmmFvbAttributesHeader = (SMM_FVB_ATTRIBUTES_HEADER *) SmmFvbFunctionHeader->Data; + Status = FvbProtocolGetAttributes ( + SmmFvbAttributesHeader->SmmFvb, + &SmmFvbAttributesHeader->Attributes + ); + break; + case EFI_FUNCTION_SET_ATTRIBUTES: + SmmFvbAttributesHeader = (SMM_FVB_ATTRIBUTES_HEADER *) SmmFvbFunctionHeader->Data; + Status = FvbProtocolSetAttributes ( + SmmFvbAttributesHeader->SmmFvb, + &SmmFvbAttributesHeader->Attributes + ); + break; + case EFI_FUNCTION_GET_PHYSICAL_ADDRESS: + SmmFvbPhysicalAddressHeader = (SMM_FVB_PHYSICAL_ADDRESS_HEADER *) SmmFvbFunctionHeader->Data; + Status = FvbProtocolGetPhysicalAddress ( + SmmFvbPhysicalAddressHeader->SmmFvb, + &SmmFvbPhysicalAddressHeader->Address + ); + break; + case EFI_FUNCTION_GET_BLOCK_SIZE: + SmmFvbBlockSizeHeader = (SMM_FVB_BLOCK_SIZE_HEADER *) SmmFvbFunctionHeader->Data; + Status = FvbProtocolGetBlockSize ( + SmmFvbBlockSizeHeader->SmmFvb, + SmmFvbBlockSizeHeader->Lba, + &SmmFvbBlockSizeHeader->BlockSize, + &SmmFvbBlockSizeHeader->NumOfBlocks + ); + break; + case EFI_FUNCTION_READ: + SmmFvbReadWriteHeader = (SMM_FVB_READ_WRITE_HEADER *) SmmFvbFunctionHeader->Data; + Status = FvbProtocolRead ( + SmmFvbReadWriteHeader->SmmFvb, + SmmFvbReadWriteHeader->Lba, + SmmFvbReadWriteHeader->Offset, + &SmmFvbReadWriteHeader->NumBytes, + (UINT8 *) (SmmFvbReadWriteHeader + 1) + ); + break; + case EFI_FUNCTION_WRITE: + SmmFvbReadWriteHeader = (SMM_FVB_READ_WRITE_HEADER *) SmmFvbFunctionHeader->Data; + Status = FvbProtocolWrite ( + SmmFvbReadWriteHeader->SmmFvb, + SmmFvbReadWriteHeader->Lba, + SmmFvbReadWriteHeader->Offset, + &SmmFvbReadWriteHeader->NumBytes, + (UINT8 *) (SmmFvbReadWriteHeader + 1) + ); + break; + case EFI_FUNCTION_ERASE_BLOCKS: + SmmFvbBlocksHeader = (SMM_FVB_BLOCKS_HEADER *) SmmFvbFunctionHeader->Data; + Status = FvbProtocolEraseBlocks ( + SmmFvbBlocksHeader->SmmFvb, + SmmFvbBlocksHeader->StartLba, + SmmFvbBlocksHeader->NumOfLba, + EFI_LBA_LIST_TERMINATOR, + 0 + ); + break; + default: + ASSERT (FALSE); + Status = EFI_UNSUPPORTED; + } + + // + // Set the return value. + // + SmmFvbFunctionHeader->ReturnStatus = Status; + + return EFI_SUCCESS; +} + +/** + The function installs EFI_SMM_FIRMWARE_VOLUME_BLOCK protocol + for each FV in the system. + + @param[in] FwhInstance The pointer to a FW volume instance structure, + which contains the information about one FV. + @param[in] InstanceNum The instance number which can be used as a ID + to locate this FwhInstance in other functions. + + @retval VOID + +**/ +VOID +InstallFvbProtocol ( + IN EFI_FW_VOL_INSTANCE *FwhInstance, + IN UINTN InstanceNum + ) +{ + EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; + EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; + EFI_STATUS Status; + EFI_HANDLE FvbHandle; + + FvbDevice = (EFI_FW_VOL_BLOCK_DEVICE *) AllocateRuntimeCopyPool ( + sizeof (EFI_FW_VOL_BLOCK_DEVICE), + &mFvbDeviceTemplate + ); + ASSERT (FvbDevice != NULL); + + FvbDevice->Instance = InstanceNum; + FwVolHeader = &FwhInstance->VolumeHeader; + + // + // Set up the devicepath + // + if (FwVolHeader->ExtHeaderOffset == 0) { + // + // FV does not contains extension header, then produce MEMMAP_DEVICE_PATH + // + FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateRuntimeCopyPool (sizeof (FV_MEMMAP_DEVICE_PATH), &mFvMemmapDevicePathTemplate); + ((FV_MEMMAP_DEVICE_PATH *) FvbDevice->DevicePath)->MemMapDevPath.StartingAddress = FwhInstance->FvBase; + ((FV_MEMMAP_DEVICE_PATH *) FvbDevice->DevicePath)->MemMapDevPath.EndingAddress = FwhInstance->FvBase + FwVolHeader->FvLength - 1; + } else { + FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateRuntimeCopyPool (sizeof (FV_PIWG_DEVICE_PATH), &mFvPIWGDevicePathTemplate); + CopyGuid ( + &((FV_PIWG_DEVICE_PATH *)FvbDevice->DevicePath)->FvDevPath.FvName, + (GUID *)(UINTN)(FwhInstance->FvBase + FwVolHeader->ExtHeaderOffset) + ); + } + + // + // Install the SMM Firmware Volume Block Protocol and Device Path Protocol + // + FvbHandle = NULL; + Status = gSmst->SmmInstallProtocolInterface ( + &FvbHandle, + &gEfiSmmFirmwareVolumeBlockProtocolGuid, + EFI_NATIVE_INTERFACE, + &FvbDevice->FwVolBlockInstance + ); + ASSERT_EFI_ERROR (Status); + + Status = gSmst->SmmInstallProtocolInterface ( + &FvbHandle, + &gEfiDevicePathProtocolGuid, + EFI_NATIVE_INTERFACE, + FvbDevice->DevicePath + ); + ASSERT_EFI_ERROR (Status); + + // + // Notify the Fvb wrapper driver SMM fvb is ready + // + FvbHandle = NULL; + Status = gBS->InstallProtocolInterface ( + &FvbHandle, + &gEfiSmmFirmwareVolumeBlockProtocolGuid, + EFI_NATIVE_INTERFACE, + &FvbDevice->FwVolBlockInstance + ); +} + +/** + The driver entry point for SMM Firmware Volume Block Driver. + + The function does the necessary initialization work + Firmware Volume Block Driver. + + @param[in] ImageHandle The firmware allocated handle for the UEFI image. + @param[in] SystemTable A pointer to the EFI system table. + + @retval EFI_SUCCESS This funtion always return EFI_SUCCESS. + It will ASSERT on errors. + +**/ +EFI_STATUS +EFIAPI +FvbSmmInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_HANDLE FvbHandle; + + // + // Locate required protocol for access to flash. + // + Status = gSmst->SmmLocateProtocol ( + &gSmmSpiDeviceProtocolGuid, + NULL, + (VOID **) &mSpiDeviceProtocol + ); + ASSERT_EFI_ERROR(Status); + + // + // Initialize the rest of the module. + // + FvbInitialize (); + + // + // Register SMM variable SMI handler + // + Status = gSmst->SmiHandlerRegister (FvbSmmHandler, &gEfiSmmFirmwareVolumeBlockProtocolGuid, &FvbHandle); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} + diff --git a/BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbSmm.inf b/BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbSmm.inf new file mode 100644 index 0000000000..a295cb512c --- /dev/null +++ b/BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbSmm.inf @@ -0,0 +1,93 @@ +## @file +# Firmware volume block service SMM driver. +# +# Provides the ability to perform read, write and erase operations on a Firmware +# Volume based on SMM. Read and write operations are possible at the byte level +# but the erase operation can only be done at the block level. +# +# Copyright (c) 2015, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010018 + BASE_NAME = FvbSmm + FILE_GUID = 564188F4-B6DD-48D0-A33A-F62507FA4FBF + MODULE_TYPE = DXE_SMM_DRIVER + VERSION_STRING = 1.0 + PI_SPECIFICATION_VERSION = 0x0001000A + ENTRY_POINT = FvbSmmInitialize + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# +# VIRTUAL_ADDRESS_MAP_CALLBACK = FvbVirtualddressChangeEvent +# + +[Sources] + FvbInfo.c + FvbService.h + FvbService.c + FvbServiceSmm.c + FvbSmmCommon.h + +[Packages] + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + BraswellPlatformPkg/BraswellPlatformPkg.dec + +[LibraryClasses] + PcdLib + MemoryAllocationLib + CacheMaintenanceLib + IoLib + BaseMemoryLib + DebugLib + BaseLib + UefiLib + UefiBootServicesTableLib + UefiDriverEntryPoint + SmmServicesTableLib + HobLib + +[Guids] + gEfiFirmwareFileSystem2Guid ## CONSUMES ## GUID + gEfiSystemNvDataFvGuid ## CONSUMES ## GUID + +[Protocols] + gEfiDevicePathProtocolGuid ## PRODUCES + gEfiSmmFirmwareVolumeBlockProtocolGuid ## PRODUCES # GUID value is also used to register an SMI Handler + gSmmSpiDeviceProtocolGuid ## CONSUMES + +[Pcd] + gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES + gPlatformModuleTokenSpaceGuid.PcdFlashFvMainBase ## CONSUMES + gPlatformModuleTokenSpaceGuid.PcdFlashFvMainSize ## CONSUMES + gPlatformModuleTokenSpaceGuid.PcdFlashFvRecoveryBase ## CONSUMES + gPlatformModuleTokenSpaceGuid.PcdFlashFvRecoverySize ## CONSUMES + gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Base ## CONSUMES + gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Size ## CONSUMES + gPlatformModuleTokenSpaceGuid.PcdFlashPayloadBase ## CONSUMES + gPlatformModuleTokenSpaceGuid.PcdFlashPayloadSize ## CONSUMES + + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize ## CONSUMES + gPlatformModuleTokenSpaceGuid.PcdFlashMinEraseSize ## CONSUMES + +[Depex] + gSmmSpiDeviceProtocolGuid + diff --git a/BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbSmmCommon.h b/BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbSmmCommon.h new file mode 100644 index 0000000000..a3c6f97829 --- /dev/null +++ b/BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbSmmCommon.h @@ -0,0 +1,75 @@ +/** @file + The common header file for SMM FVB module and SMM FVB runtime Module. + + Copyright (c) 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _SMM_FVB_COMMON_H_ +#define _SMM_FVB_COMMON_H_ + +#include + +#define EFI_FUNCTION_GET_ATTRIBUTES 1 +#define EFI_FUNCTION_SET_ATTRIBUTES 2 +#define EFI_FUNCTION_GET_PHYSICAL_ADDRESS 3 +#define EFI_FUNCTION_GET_BLOCK_SIZE 4 +#define EFI_FUNCTION_READ 5 +#define EFI_FUNCTION_WRITE 6 +#define EFI_FUNCTION_ERASE_BLOCKS 7 + +typedef struct { + UINTN Function; + EFI_STATUS ReturnStatus; + UINT8 Data[1]; +} SMM_FVB_COMMUNICATE_FUNCTION_HEADER; + +/// +/// Size of SMM communicate header, without including the payload. +/// +#define SMM_COMMUNICATE_HEADER_SIZE (OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)) + +/// +/// Size of SMM FVB communicate function header, without including the payload. +/// +#define SMM_FVB_COMMUNICATE_HEADER_SIZE (OFFSET_OF (SMM_FVB_COMMUNICATE_FUNCTION_HEADER, Data)) + +typedef struct { + EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; + EFI_FVB_ATTRIBUTES_2 Attributes; +} SMM_FVB_ATTRIBUTES_HEADER; + +typedef struct { + EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; + EFI_PHYSICAL_ADDRESS Address; +} SMM_FVB_PHYSICAL_ADDRESS_HEADER; + +typedef struct { + EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; + EFI_LBA Lba; + UINTN BlockSize; + UINTN NumOfBlocks; +} SMM_FVB_BLOCK_SIZE_HEADER; + +typedef struct { + EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; + EFI_LBA Lba; + UINTN Offset; + UINTN NumBytes; +} SMM_FVB_READ_WRITE_HEADER; + +typedef struct { + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; + EFI_LBA StartLba; + UINTN NumOfLba; +} SMM_FVB_BLOCKS_HEADER; + +#endif diff --git a/BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbSmmDxe.c b/BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbSmmDxe.c new file mode 100644 index 0000000000..c82be4ba40 --- /dev/null +++ b/BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbSmmDxe.c @@ -0,0 +1,933 @@ +/** @file + Implement the Firmware Volume Block (FVB) services based on SMM FVB + module and install FVB protocol. + + Copyright (c) 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "FvbSmmDxe.h" + +EFI_HANDLE mHandle = NULL; +EFI_SMM_COMMUNICATION_PROTOCOL *mSmmCommunication = NULL; + +// +// Template structure used when installing FVB protocol +// +EFI_FVB_DEVICE mFvbDeviceTemplate = { + FVB_DEVICE_SIGNATURE, + NULL, + { + FvbGetAttributes, + FvbSetAttributes, + FvbGetPhysicalAddress, + FvbGetBlockSize, + FvbRead, + FvbWrite, + FvbEraseBlocks, + NULL + }, + NULL +}; + +FV_MEMMAP_DEVICE_PATH mFvMemmapDevicePathTemplate = { + { + { + HARDWARE_DEVICE_PATH, + HW_MEMMAP_DP, + { + (UINT8)(sizeof (MEMMAP_DEVICE_PATH)), + (UINT8)(sizeof (MEMMAP_DEVICE_PATH) >> 8) + } + }, + EfiMemoryMappedIO, + (EFI_PHYSICAL_ADDRESS) 0, + (EFI_PHYSICAL_ADDRESS) 0, + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + END_DEVICE_PATH_LENGTH, + 0 + } + } +}; + +FV_PIWG_DEVICE_PATH mFvPIWGDevicePathTemplate = { + { + { + MEDIA_DEVICE_PATH, + MEDIA_PIWG_FW_VOL_DP, + { + (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH)), + (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH) >> 8) + } + }, + { 0 } + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + END_DEVICE_PATH_LENGTH, + 0 + } + } +}; + +/** + Initialize the communicate buffer using DataSize and Function. + + The communicate size is: SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + + DataSize. + + @param[out] CommunicateBuffer The communicate buffer. Caller should free it after use. + @param[out] DataPtr Points to the data in the communicate buffer. Caller should not free it. + @param[in] DataSize The payload size. + @param[in] Function The function number used to initialize the communicate header. + + @retval EFI_INVALID_PARAMETER The data size is too big. + @retval EFI_SUCCESS Find the specified variable. + +**/ +EFI_STATUS +InitCommunicateBuffer ( + OUT VOID **CommunicateBuffer, + OUT VOID **DataPtr, + IN UINTN DataSize, + IN UINTN Function + ) +{ + EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; + SMM_FVB_COMMUNICATE_FUNCTION_HEADER *SmmFvbFunctionHeader; + + // + // The whole buffer size: SMM_COMMUNICATE_HEADER_SIZE + SMM_FVB_COMMUNICATE_HEADER_SIZE + DataSize. + // + SmmCommunicateHeader = AllocatePool (DataSize + SMM_COMMUNICATE_HEADER_SIZE + SMM_FVB_COMMUNICATE_HEADER_SIZE); + ASSERT (SmmCommunicateHeader != NULL); + + // + // Prepare data buffer. + // + CopyGuid (&SmmCommunicateHeader->HeaderGuid, &gEfiSmmFirmwareVolumeBlockProtocolGuid); + SmmCommunicateHeader->MessageLength = DataSize + SMM_FVB_COMMUNICATE_HEADER_SIZE; + + SmmFvbFunctionHeader = (SMM_FVB_COMMUNICATE_FUNCTION_HEADER *) SmmCommunicateHeader->Data; + SmmFvbFunctionHeader->Function = Function; + + *CommunicateBuffer = SmmCommunicateHeader; + *DataPtr = SmmFvbFunctionHeader->Data; + + return EFI_SUCCESS; +} + +/** + Send the data in communicate buffer to SMM. + + @param[out] SmmCommunicateHeader The communicate buffer. + @param[in] DataSize The payload size. + +**/ +EFI_STATUS +SendCommunicateBuffer ( + IN EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader, + IN UINTN DataSize + ) +{ + EFI_STATUS Status; + UINTN CommSize; + SMM_FVB_COMMUNICATE_FUNCTION_HEADER *SmmFvbFunctionHeader; + + CommSize = DataSize + SMM_COMMUNICATE_HEADER_SIZE + SMM_FVB_COMMUNICATE_HEADER_SIZE; + Status = mSmmCommunication->Communicate (mSmmCommunication, SmmCommunicateHeader, &CommSize); + ASSERT_EFI_ERROR (Status); + + SmmFvbFunctionHeader = (SMM_FVB_COMMUNICATE_FUNCTION_HEADER *) SmmCommunicateHeader->Data; + + return SmmFvbFunctionHeader->ReturnStatus; +} + +/** + This function retrieves the attributes and current settings of the block. + + @param[in] This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. + + @param[out] Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the attributes + and current settings are returned. Type EFI_FVB_ATTRIBUTES_2 + is defined in EFI_FIRMWARE_VOLUME_HEADER. + + @retval EFI_SUCCESS The firmware volume attributes were returned. + @retval EFI_INVALID_PARAMETER Attributes is NULL +**/ +EFI_STATUS +EFIAPI +FvbGetAttributes ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ) +{ + EFI_STATUS Status; + UINTN PayloadSize; + EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; + SMM_FVB_ATTRIBUTES_HEADER *SmmFvbAttributesHeader; + EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; + EFI_FVB_DEVICE *FvbDevice; + + if (Attributes == NULL) { + return EFI_INVALID_PARAMETER; + } + + FvbDevice = FVB_DEVICE_FROM_THIS (This); + SmmFvb = FvbDevice->SmmFvbInstance; + + // + // Initialize the communicate buffer. + // + PayloadSize = sizeof (SMM_FVB_ATTRIBUTES_HEADER); + Status = InitCommunicateBuffer ((VOID **)&SmmCommunicateHeader, (VOID **)&SmmFvbAttributesHeader, PayloadSize, EFI_FUNCTION_GET_ATTRIBUTES); + if (EFI_ERROR (Status)) { + return Status; + } + + SmmFvbAttributesHeader->SmmFvb = SmmFvb; + SmmFvbAttributesHeader->Attributes = 0; + + // + // Send data to SMM. + // + Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize); + + // + // Get data from SMM + // + *Attributes = SmmFvbAttributesHeader->Attributes; + FreePool (SmmCommunicateHeader); + + return Status; +} + +/** + Sets Volume attributes. No polarity translations are done. + + @param[in] This Calling context + @param[out] Attributes Output buffer which contains attributes + + @retval EFI_SUCCESS Set the Attributes successfully. + @retval EFI_INVALID_PARAMETER Attributes is NULL + +**/ +EFI_STATUS +EFIAPI +FvbSetAttributes ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ) +{ + EFI_STATUS Status; + UINTN PayloadSize; + EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; + SMM_FVB_ATTRIBUTES_HEADER *SmmFvbAttributesHeader; + EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; + EFI_FVB_DEVICE *FvbDevice; + + if (Attributes == NULL) { + return EFI_INVALID_PARAMETER; + } + + FvbDevice = FVB_DEVICE_FROM_THIS (This); + SmmFvb = FvbDevice->SmmFvbInstance; + + // + // Initialize the communicate buffer. + // + PayloadSize = sizeof (SMM_FVB_ATTRIBUTES_HEADER); + Status = InitCommunicateBuffer ((VOID **)&SmmCommunicateHeader, (VOID **)&SmmFvbAttributesHeader, PayloadSize, EFI_FUNCTION_SET_ATTRIBUTES); + if (EFI_ERROR (Status)) { + return Status; + } + + SmmFvbAttributesHeader->SmmFvb = SmmFvb; + SmmFvbAttributesHeader->Attributes = *Attributes; + + // + // Send data to SMM. + // + Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize); + + // + // Get data from SMM + // + *Attributes = SmmFvbAttributesHeader->Attributes; + FreePool (SmmCommunicateHeader); + + return Status; +} + +/** + Retrieves the physical address of the FVB instance. + + @param[in] SmmFvb A pointer to EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL. + @param[out] Address Output buffer containing the address. + + @retval EFI_SUCCESS Get the address successfully. + @retval Others Failed to get address. + +**/ +EFI_STATUS +GetPhysicalAddress ( + IN EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb, + OUT EFI_PHYSICAL_ADDRESS *Address + ) +{ + EFI_STATUS Status; + UINTN PayloadSize; + EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; + SMM_FVB_PHYSICAL_ADDRESS_HEADER *SmmFvbPhysicalAddressHeader; + + // + // Initialize the communicate buffer. + // + PayloadSize = sizeof (SMM_FVB_PHYSICAL_ADDRESS_HEADER); + Status = InitCommunicateBuffer ((VOID **)&SmmCommunicateHeader, (VOID **)&SmmFvbPhysicalAddressHeader, PayloadSize, EFI_FUNCTION_GET_PHYSICAL_ADDRESS); + if (EFI_ERROR (Status)) { + return Status; + } + + SmmFvbPhysicalAddressHeader->SmmFvb = SmmFvb; + SmmFvbPhysicalAddressHeader->Address = 0; + + // + // Send data to SMM. + // + Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize); + + // + // Get data from SMM + // + *Address = SmmFvbPhysicalAddressHeader->Address; + FreePool (SmmCommunicateHeader); + + return Status; +} + +/** + Retrieves the physical address of the FVB instance. + + @param[in] This A pointer to EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL. + @param[out] Address Output buffer containing the address. + + @retval EFI_SUCCESS Get the address successfully. + @retval Others Failed to get the address. + +**/ +EFI_STATUS +EFIAPI +FvbGetPhysicalAddress ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + OUT EFI_PHYSICAL_ADDRESS *Address + ) +{ + EFI_STATUS Status; + EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; + EFI_FVB_DEVICE *FvbDevice; + + if (Address == NULL) { + return EFI_INVALID_PARAMETER; + } + + FvbDevice = FVB_DEVICE_FROM_THIS (This); + SmmFvb = FvbDevice->SmmFvbInstance; + + Status = GetPhysicalAddress (SmmFvb, Address); + + return Status; +} + +/** + Retrieve the size of a logical block + + @param[in] SmmFvb A pointer to EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL. + @param[in] Lba Indicates which block to return the size for. + @param[out] BlockSize A pointer to a caller allocated UINTN in which + the size of the block is returned + @param[out] NumOfBlocks A pointer to a caller allocated UINTN in which the + number of consecutive blocks starting with Lba is + returned. All blocks in this range have a size of + BlockSize + + @retval EFI_SUCCESS Get BlockSize and NumOfBlocks successfully. + @retval EFI_INVALID_PARAMETER BlockSize or NumOfBlocks are NULL. +**/ +EFI_STATUS +GetBlockSize ( + IN EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb, + IN EFI_LBA Lba, + OUT UINTN *BlockSize, + OUT UINTN *NumOfBlocks + ) +{ + EFI_STATUS Status; + UINTN PayloadSize; + EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; + SMM_FVB_BLOCK_SIZE_HEADER *SmmFvbBlockSizeHeader; + + if ((BlockSize == NULL) || (NumOfBlocks == NULL)) { + return EFI_INVALID_PARAMETER; + } + + // + // Initialize the communicate buffer. + // + PayloadSize = sizeof (SMM_FVB_BLOCK_SIZE_HEADER); + Status = InitCommunicateBuffer ((VOID **)&SmmCommunicateHeader, (VOID **)&SmmFvbBlockSizeHeader, PayloadSize, EFI_FUNCTION_GET_BLOCK_SIZE); + if (EFI_ERROR (Status)) { + return Status; + } + + SmmFvbBlockSizeHeader->SmmFvb = SmmFvb; + SmmFvbBlockSizeHeader->Lba = Lba; + + // + // Send data to SMM. + // + Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize); + + // + // Get data from SMM + // + *BlockSize = SmmFvbBlockSizeHeader->BlockSize; + *NumOfBlocks = SmmFvbBlockSizeHeader->NumOfBlocks; + FreePool (SmmCommunicateHeader); + + return Status; +} + +/** + Retrieve the size of a logical block + + @param[in] This Calling context + @param[in] Lba Indicates which block to return the size for. + @param[out] BlockSize A pointer to a caller allocated UINTN in which + the size of the block is returned + @param[out] NumOfBlocks A pointer to a caller allocated UINTN in which the + number of consecutive blocks starting with Lba is + returned. All blocks in this range have a size of + BlockSize + + @retval EFI_SUCCESS Get BlockSize and NumOfBlocks successfully. + @retval EFI_INVALID_PARAMETER BlockSize or NumOfBlocks are NULL. +**/ +EFI_STATUS +EFIAPI +FvbGetBlockSize ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN EFI_LBA Lba, + OUT UINTN *BlockSize, + OUT UINTN *NumOfBlocks + ) +{ + EFI_STATUS Status; + EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; + EFI_FVB_DEVICE *FvbDevice; + + FvbDevice = FVB_DEVICE_FROM_THIS (This); + SmmFvb = FvbDevice->SmmFvbInstance; + + Status = GetBlockSize (SmmFvb, Lba, BlockSize, NumOfBlocks); + return Status; +} + +/** + Reads data beginning at Lba:Offset from FV. The Read terminates either + when *NumBytes of data have been read, or when a block boundary is + reached. *NumBytes is updated to reflect the actual number of bytes + written. The write opertion does not include erase. This routine will + attempt to write only the specified bytes. If the writes do not stick, + it will return an error. + + @param[in] This Calling context + @param[in] Lba Block in which to begin write + @param[in] Offset Offset in the block at which to begin write + @param[in, out] NumBytes On input, indicates the requested write size. On + output, indicates the actual number of bytes written + @param[in] Buffer Buffer containing source data for the write. + +Returns: + @retval EFI_SUCCESS The firmware volume was read successfully and + contents are in Buffer + @retval EFI_BAD_BUFFER_SIZE Read attempted across a LBA boundary. On output, + NumBytes contains the total number of bytes returned + in Buffer + @retval EFI_ACCESS_DENIED The firmware volume is in the ReadDisabled state + @retval EFI_DEVICE_ERROR The block device is not functioning correctly and + could not be read + @retval EFI_INVALID_PARAMETER NumBytes or Buffer are NULL + +**/ +EFI_STATUS +EFIAPI +FvbRead ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + OUT UINT8 *Buffer + ) +{ + EFI_STATUS Status; + UINTN PayloadSize; + EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; + SMM_FVB_READ_WRITE_HEADER *SmmFvbReadWriteHeader; + EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; + EFI_FVB_DEVICE *FvbDevice; + + if ((NumBytes == NULL) || (Buffer == NULL)) { + return EFI_INVALID_PARAMETER; + } + + FvbDevice = FVB_DEVICE_FROM_THIS (This); + SmmFvb = FvbDevice->SmmFvbInstance; + + // + // Initialize the communicate buffer. + // + PayloadSize = sizeof (SMM_FVB_READ_WRITE_HEADER) + *NumBytes; + Status = InitCommunicateBuffer ((VOID **)&SmmCommunicateHeader, (VOID **)&SmmFvbReadWriteHeader, PayloadSize, EFI_FUNCTION_READ); + if (EFI_ERROR (Status)) { + return Status; + } + + SmmFvbReadWriteHeader->SmmFvb = SmmFvb; + SmmFvbReadWriteHeader->Lba = Lba; + SmmFvbReadWriteHeader->Offset = Offset; + SmmFvbReadWriteHeader->NumBytes = *NumBytes; + + // + // Send data to SMM. + // + Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize); + + // + // Get data from SMM + // + *NumBytes = SmmFvbReadWriteHeader->NumBytes; + if (!EFI_ERROR (Status)) { + CopyMem (Buffer, (UINT8 *)(SmmFvbReadWriteHeader + 1), *NumBytes); + } + FreePool (SmmCommunicateHeader); + + return Status; +} + +/** + Writes data beginning at Lba:Offset from FV. The write terminates either + when *NumBytes of data have been written, or when a block boundary is + reached. *NumBytes is updated to reflect the actual number of bytes + written. The write opertion does not include erase. This routine will + attempt to write only the specified bytes. If the writes do not stick, + it will return an error. + + @param[in] This Calling context + @param[in] Lba Block in which to begin write + @param[in] Offset Offset in the block at which to begin write + @param[in, out] NumBytes On input, indicates the requested write size. On + output, indicates the actual number of bytes written + @param[in] Buffer Buffer containing source data for the write. + + @retval EFI_SUCCESS The firmware volume was written successfully + @retval EFI_BAD_BUFFER_SIZE Write attempted across a LBA boundary. On output, + NumBytes contains the total number of bytes + actually written + @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state + @retval EFI_DEVICE_ERROR The block device is not functioning correctly and + could not be written + @retval EFI_INVALID_PARAMETER NumBytes or Buffer are NULL + +**/ +EFI_STATUS +EFIAPI +FvbWrite ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ) +{ + EFI_STATUS Status; + UINTN PayloadSize; + EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; + SMM_FVB_READ_WRITE_HEADER *SmmFvbReadWriteHeader; + EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; + EFI_FVB_DEVICE *FvbDevice; + + if ((NumBytes == NULL) || (Buffer == NULL)) { + return EFI_INVALID_PARAMETER; + } + + FvbDevice = FVB_DEVICE_FROM_THIS (This); + SmmFvb = FvbDevice->SmmFvbInstance; + + // + // Initialize the communicate buffer. + // + PayloadSize = sizeof (SMM_FVB_READ_WRITE_HEADER) + *NumBytes; + Status = InitCommunicateBuffer ((VOID **)&SmmCommunicateHeader, (VOID **)&SmmFvbReadWriteHeader, PayloadSize, EFI_FUNCTION_WRITE); + if (EFI_ERROR (Status)) { + return Status; + } + + SmmFvbReadWriteHeader->SmmFvb = SmmFvb; + SmmFvbReadWriteHeader->Lba = Lba; + SmmFvbReadWriteHeader->Offset = Offset; + SmmFvbReadWriteHeader->NumBytes = *NumBytes; + CopyMem ((UINT8 *)(SmmFvbReadWriteHeader + 1), Buffer, *NumBytes); + + // + // Send data to SMM. + // + Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize); + + // + // Get data from SMM + // + *NumBytes = SmmFvbReadWriteHeader->NumBytes; + FreePool (SmmCommunicateHeader); + + return Status; +} + +/** + The EraseBlock() function erases NumOfLba blocks started from StartingLba. + + @param[in] This Calling context + @param[in] StartingLba Starting LBA followed to erase. + @param[in] NumOfLba Number of block to erase. + + @retval EFI_SUCCESS The erase request was successfully completed + @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state + @retval EFI_DEVICE_ERROR The block device is not functioning correctly and + could not be written. Firmware device may have been + partially erased + +**/ +EFI_STATUS +EraseBlock ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN EFI_LBA StartingLba, + IN UINTN NumOfLba + ) +{ + EFI_STATUS Status; + UINTN PayloadSize; + EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; + SMM_FVB_BLOCKS_HEADER *SmmFvbBlocksHeader; + EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; + EFI_FVB_DEVICE *FvbDevice; + + FvbDevice = FVB_DEVICE_FROM_THIS (This); + SmmFvb = FvbDevice->SmmFvbInstance; + + // + // Initialize the communicate buffer. + // + PayloadSize = sizeof (SMM_FVB_BLOCKS_HEADER); + Status = InitCommunicateBuffer ((VOID **)&SmmCommunicateHeader, (VOID **)&SmmFvbBlocksHeader, PayloadSize, EFI_FUNCTION_ERASE_BLOCKS); + if (EFI_ERROR (Status)) { + return Status; + } + + SmmFvbBlocksHeader->SmmFvb = SmmFvb; + SmmFvbBlocksHeader->StartLba = StartingLba; + SmmFvbBlocksHeader->NumOfLba = NumOfLba; + + // + // Send data to SMM. + // + Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize); + + // + // Get data from SMM + // + FreePool (SmmCommunicateHeader); + + return Status; +} + +/** + The EraseBlocks() function erases one or more blocks as denoted by the + variable argument list. The entire parameter list of blocks must be verified + prior to erasing any blocks. If a block is requested that does not exist + within the associated firmware volume (it has a larger index than the last + block of the firmware volume), the EraseBlock() function must return + EFI_INVALID_PARAMETER without modifying the contents of the firmware volume. + + @param[in] This Calling context + @param[in] ... Starting LBA followed by Number of Lba to erase. + a -1 to terminate the list. + + @retval EFI_SUCCESS The erase request was successfully completed + @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state + @retval EFI_DEVICE_ERROR The block device is not functioning correctly and + could not be written. Firmware device may have been + partially erased + +**/ +EFI_STATUS +EFIAPI +FvbEraseBlocks ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + ... + ) +{ + EFI_STATUS Status; + VA_LIST Marker; + EFI_LBA StartingLba; + UINTN NumOfLba; + EFI_FVB_DEVICE *FvbDevice; + + FvbDevice = FVB_DEVICE_FROM_THIS (This); + Status = EFI_SUCCESS; + + // + // Check the parameter + // + VA_START (Marker, This); + do { + StartingLba = VA_ARG (Marker, EFI_LBA); + if (StartingLba == EFI_LBA_LIST_TERMINATOR) { + break; + } + + NumOfLba = VA_ARG (Marker, UINT32); + if (NumOfLba == 0) { + VA_END (Marker); + return EFI_INVALID_PARAMETER; + } + + if ((StartingLba + NumOfLba) > FvbDevice->NumOfBlocks) { + VA_END (Marker); + return EFI_INVALID_PARAMETER; + } + } while (1); + VA_END (Marker); + + // + // Erase the blocks + // + VA_START (Marker, This); + do { + StartingLba = VA_ARG (Marker, EFI_LBA); + if (StartingLba == EFI_LBA_LIST_TERMINATOR ) { + break; + } + NumOfLba = VA_ARG (Marker, UINT32); + Status = EraseBlock (This, StartingLba, NumOfLba); + if (EFI_ERROR (Status)) { + break; + } + } while (1); + VA_END (Marker); + + return Status; +} + +/** + Install the FVB protocol which based on SMM FVB protocol. + + @param[in] SmmFvb The SMM FVB protocol. + +**/ +VOID +InstallFvb ( + IN EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb + ) +{ + EFI_STATUS Status; + EFI_HANDLE FvbHandle; + EFI_FVB_DEVICE *FvbDevice; + EFI_FIRMWARE_VOLUME_HEADER *VolumeHeader; + EFI_PHYSICAL_ADDRESS Address; + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *OldFvbInterface; + UINTN BlockSize; + UINTN NumOfBlocks; + + FvbDevice = AllocateRuntimeCopyPool (sizeof (EFI_FVB_DEVICE), &mFvbDeviceTemplate); + ASSERT (FvbDevice != NULL); + FvbDevice->SmmFvbInstance = SmmFvb; + + Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &mSmmCommunication); + ASSERT_EFI_ERROR (Status); + + Status = GetBlockSize (SmmFvb, 0, &BlockSize, &NumOfBlocks); + ASSERT_EFI_ERROR (Status); + FvbDevice->NumOfBlocks = NumOfBlocks; + + Status = GetPhysicalAddress (SmmFvb, &Address); + ASSERT_EFI_ERROR (Status); + + VolumeHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN)Address; + + // + // Set up the devicepath + // + if (VolumeHeader->ExtHeaderOffset == 0) { + // + // FV does not contains extension header, then produce MEMMAP_DEVICE_PATH + // + FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateRuntimeCopyPool (sizeof (FV_MEMMAP_DEVICE_PATH), &mFvMemmapDevicePathTemplate); + ((FV_MEMMAP_DEVICE_PATH *) FvbDevice->DevicePath)->MemMapDevPath.StartingAddress = (UINTN)Address; + ((FV_MEMMAP_DEVICE_PATH *) FvbDevice->DevicePath)->MemMapDevPath.EndingAddress = (UINTN)Address + VolumeHeader->FvLength - 1; + } else { + FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateRuntimeCopyPool (sizeof (FV_PIWG_DEVICE_PATH), &mFvPIWGDevicePathTemplate); + CopyGuid ( + &((FV_PIWG_DEVICE_PATH *)FvbDevice->DevicePath)->FvDevPath.FvName, + (GUID *)(UINTN)((UINTN)Address + VolumeHeader->ExtHeaderOffset) + ); + } + + // + // Find a handle with a matching device path that has supports FW Block protocol + // + Status = gBS->LocateDevicePath (&gEfiFirmwareVolumeBlockProtocolGuid, &FvbDevice->DevicePath, &FvbHandle); + if (EFI_ERROR (Status) ) { + // + // LocateDevicePath fails so install a new interface and device path + // + FvbHandle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces ( + &FvbHandle, + &gEfiFirmwareVolumeBlockProtocolGuid, + &FvbDevice->FvbInstance, + &gEfiDevicePathProtocolGuid, + FvbDevice->DevicePath, + NULL + ); + ASSERT_EFI_ERROR (Status); + } else if (IsDevicePathEnd (FvbDevice->DevicePath)) { + // + // Device allready exists, so reinstall the FVB protocol + // + Status = gBS->HandleProtocol ( + FvbHandle, + &gEfiFirmwareVolumeBlockProtocolGuid, + (VOID **) &OldFvbInterface + ); + ASSERT_EFI_ERROR (Status); + + Status = gBS->ReinstallProtocolInterface ( + FvbHandle, + &gEfiFirmwareVolumeBlockProtocolGuid, + OldFvbInterface, + &FvbDevice->FvbInstance + ); + ASSERT_EFI_ERROR (Status); + } else { + // + // There was a FVB protocol on an End Device Path node + // + ASSERT (FALSE); + } +} + +/** + SMM Firmware Volume Block Protocol notification event handler. + + Discover NV Variable Store and install Variable Write Arch Protocol. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context Pointer to the notification function's context. +**/ +VOID +EFIAPI +SmmFvbReady ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + UINTN HandleCount; + UINTN Index; + EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; + + // + // Locate all handles of Smm Fvb protocol. + // + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiSmmFirmwareVolumeBlockProtocolGuid, + NULL, + &HandleCount, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + return ; + } + + // + // Install FVB protocol. + // + for (Index = 0; Index < HandleCount; Index++) { + SmmFvb = NULL; + Status = gBS->HandleProtocol ( + HandleBuffer[Index], + &gEfiSmmFirmwareVolumeBlockProtocolGuid, + (VOID **) &SmmFvb + ); + if (EFI_ERROR (Status)) { + break; + } + + InstallFvb (SmmFvb); + } + + FreePool (HandleBuffer); +} + +/** + The driver entry point for Firmware Volume Block Driver. + + The function does the necessary initialization work + Firmware Volume Block Driver. + + @param[in] ImageHandle The firmware allocated handle for the UEFI image. + @param[in] SystemTable A pointer to the EFI system table. + + @retval EFI_SUCCESS This funtion always return EFI_SUCCESS. + It will ASSERT on errors. + +**/ +EFI_STATUS +EFIAPI +FvbSmmDxeInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + VOID *SmmFvbRegistration; + + // + // Smm FVB driver is ready + // + EfiCreateProtocolNotifyEvent ( + &gEfiSmmFirmwareVolumeBlockProtocolGuid, + TPL_CALLBACK, + SmmFvbReady, + NULL, + &SmmFvbRegistration + ); + + return EFI_SUCCESS; +} + diff --git a/BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbSmmDxe.h b/BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbSmmDxe.h new file mode 100644 index 0000000000..cee43bae72 --- /dev/null +++ b/BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbSmmDxe.h @@ -0,0 +1,231 @@ +/** @file + The internal header file includes the common header files, defines + internal structure and functions used by FVB module. + + Copyright (c) 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _SMM_FVB_DXE_H_ +#define _SMM_FVB_DXE_H_ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "FvbSmmCommon.h" + +#define FVB_DEVICE_SIGNATURE SIGNATURE_32 ('F', 'V', 'B', 'S') +#define FVB_DEVICE_FROM_THIS(a) CR (a, EFI_FVB_DEVICE, FvbInstance, FVB_DEVICE_SIGNATURE) + +typedef struct { + MEDIA_FW_VOL_DEVICE_PATH FvDevPath; + EFI_DEVICE_PATH_PROTOCOL EndDevPath; +} FV_PIWG_DEVICE_PATH; + +typedef struct { + MEMMAP_DEVICE_PATH MemMapDevPath; + EFI_DEVICE_PATH_PROTOCOL EndDevPath; +} FV_MEMMAP_DEVICE_PATH; + +typedef struct { + UINTN Signature; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL FvbInstance; + EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvbInstance; + UINTN NumOfBlocks; +} EFI_FVB_DEVICE; + +/** + This function retrieves the attributes and current settings of the block. + + @param[in] This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. + + @param[out] Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the attributes + and current settings are returned. Type EFI_FVB_ATTRIBUTES_2 + is defined in EFI_FIRMWARE_VOLUME_HEADER. + + @retval EFI_SUCCESS The firmware volume attributes were returned. + +**/ +EFI_STATUS +EFIAPI +FvbGetAttributes ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ); + + /** + Sets Volume attributes. No polarity translations are done. + + @param[in] This Calling context + @param[out] Attributes Output buffer which contains attributes + + @retval EFI_SUCCESS The function always return successfully. + +**/ +EFI_STATUS +EFIAPI +FvbSetAttributes ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ); + +/** + Retrieves the physical address of the device. + + @param[in] This A pointer to EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL. + @param[out] Address Output buffer containing the address. + + @retval EFI_SUCCESS The function always return successfully. + +**/ +EFI_STATUS +EFIAPI +FvbGetPhysicalAddress ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + OUT EFI_PHYSICAL_ADDRESS *Address + ); + +/** + Retrieve the size of a logical block + + @param[in] This Calling context + @param[in] Lba Indicates which block to return the size for. + @param[out] BlockSize A pointer to a caller allocated UINTN in which + the size of the block is returned + @param[out] NumOfBlocks A pointer to a caller allocated UINTN in which the + number of consecutive blocks starting with Lba is + returned. All blocks in this range have a size of + BlockSize + + @retval EFI_SUCCESS The function always return successfully. + +**/ +EFI_STATUS +EFIAPI +FvbGetBlockSize ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN EFI_LBA Lba, + OUT UINTN *BlockSize, + OUT UINTN *NumOfBlocks + ); + +/** + Reads data beginning at Lba:Offset from FV. The Read terminates either + when *NumBytes of data have been read, or when a block boundary is + reached. *NumBytes is updated to reflect the actual number of bytes + written. The write opertion does not include erase. This routine will + attempt to write only the specified bytes. If the writes do not stick, + it will return an error. + + @param[in] This Calling context + @param[in] Lba Block in which to begin write + @param[in] Offset Offset in the block at which to begin write + @param[in, out] NumBytes On input, indicates the requested write size. On + output, indicates the actual number of bytes written + @param[in] Buffer Buffer containing source data for the write. + +Returns: + @retval EFI_SUCCESS The firmware volume was read successfully and + contents are in Buffer + @retval EFI_BAD_BUFFER_SIZE Read attempted across a LBA boundary. On output, + NumBytes contains the total number of bytes returned + in Buffer + @retval EFI_ACCESS_DENIED The firmware volume is in the ReadDisabled state + @retval EFI_DEVICE_ERROR The block device is not functioning correctly and + could not be read + @retval EFI_INVALID_PARAMETER NumBytes or Buffer are NULL + +**/ +EFI_STATUS +EFIAPI +FvbRead ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + OUT UINT8 *Buffer + ); + +/** + Writes data beginning at Lba:Offset from FV. The write terminates either + when *NumBytes of data have been written, or when a block boundary is + reached. *NumBytes is updated to reflect the actual number of bytes + written. The write opertion does not include erase. This routine will + attempt to write only the specified bytes. If the writes do not stick, + it will return an error. + + @param[in] This Calling context + @param[in] Lba Block in which to begin write + @param[in] Offset Offset in the block at which to begin write + @param[in, out] NumBytes On input, indicates the requested write size. On + output, indicates the actual number of bytes written + @param[in] Buffer Buffer containing source data for the write. + + @retval EFI_SUCCESS The firmware volume was written successfully + @retval EFI_BAD_BUFFER_SIZE Write attempted across a LBA boundary. On output, + NumBytes contains the total number of bytes + actually written + @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state + @retval EFI_DEVICE_ERROR The block device is not functioning correctly and + could not be written + @retval EFI_INVALID_PARAMETER NumBytes or Buffer are NULL + +**/ +EFI_STATUS +EFIAPI +FvbWrite ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ); + +/** + The EraseBlock() function erases one or more blocks as denoted by the + variable argument list. The entire parameter list of blocks must be verified + prior to erasing any blocks. If a block is requested that does not exist + within the associated firmware volume (it has a larger index than the last + block of the firmware volume), the EraseBlock() function must return + EFI_INVALID_PARAMETER without modifying the contents of the firmware volume. + + @param[in] This Calling context + @param[in] ... Starting LBA followed by Number of Lba to erase. + a -1 to terminate the list. + + @retval EFI_SUCCESS The erase request was successfully completed + @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state + @retval EFI_DEVICE_ERROR The block device is not functioning correctly and + could not be written. Firmware device may have been + partially erased + +**/ +EFI_STATUS +EFIAPI +FvbEraseBlocks ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + ... + ); + +#endif diff --git a/BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbSmmDxe.inf b/BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbSmmDxe.inf new file mode 100644 index 0000000000..d1ae766266 --- /dev/null +++ b/BraswellPlatformPkg/Common/Flash/FvbRuntimeDxe/FvbSmmDxe.inf @@ -0,0 +1,57 @@ +## @file +# SMM based Firmware Volume Block Dxe Driver +# +# This driver provides the Firmware Volume Block (FVB) services based on SMM +# FVB module and install FVB protocol. +# +# Copyright (c) 2015, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010018 + BASE_NAME = FvbSmmDxe + FILE_GUID = BEB88806-1143-4156-A2AF-4CA781EA313B + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = FvbSmmDxeInitialize +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + FvbSmmDxe.c + FvbSmmDxe.h + FvbSmmCommon.h + +[Packages] + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + BraswellPlatformPkg/BraswellPlatformPkg.dec + +[LibraryClasses] + BaseLib + UefiBootServicesTableLib + DebugLib + DxeServicesTableLib + UefiDriverEntryPoint + PcdLib + +[Protocols] + gEfiFirmwareVolumeBlockProtocolGuid ## PRODUCES + gEfiSmmCommunicationProtocolGuid ## CONSUMES + gEfiSmmFirmwareVolumeBlockProtocolGuid ## CONSUMES # GUID value is also used with SMM Communication Protocol to invoke an SMI Handler + +[Depex] + gEfiSmmCommunicationProtocolGuid + diff --git a/BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDevice.c b/BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDevice.c new file mode 100644 index 0000000000..d4eaced0d4 --- /dev/null +++ b/BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDevice.c @@ -0,0 +1,659 @@ +/** @file + SPI Device driver for Braswell Platform. + + Copyright (c) 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include "SpiDevice.h" + +EFI_SPI_PROTOCOL *mSpiProtocol; + +UINTN mNvStorageBase = 0; + +EFI_STATUS +EFIAPI +SpiRead ( + IN UINTN SpiOffset, + IN OUT UINTN *Size, + OUT UINT8 *Buffer + ) +{ + EFI_STATUS Status; + VOID *BiosMmioAddress; + UINTN RegionOffset; + UINTN Length; + UINTN RemainingBytes; + + // + // Validate parameters. + // + if (Size == NULL || Buffer == NULL) { + return EFI_INVALID_PARAMETER; + } + if (SpiOffset + *Size > PcdGet32 (PcdFlashAreaSize)) { + return EFI_INVALID_PARAMETER; + } + + // + // Check to see if the read is taking place in a memory mapped part of the flash. + // Some flash regions may not be mapped for runtime access by the OS and must + // be accessed through the controller and not MMIO. + // + if (ReadUsingMmio (SpiOffset)) { + // + // Convert BIOS region offset into an actual memory address. + // + BiosMmioAddress = (VOID*) (SpiOffset + PcdGet32 (PcdFlashAreaBaseAddress)); + + // + // Do memory copy instead of using SPI controller. + // + CopyMem ((VOID*) Buffer, BiosMmioAddress, *Size); + } else if ((SpiOffset >= VN_STORAGE_REGION_FLASH_OFFSET) && (SpiOffset < (VN_STORAGE_REGION_FLASH_OFFSET + PcdGet32 (PcdFlashAreaSize)))) { + // + // Convert the offset into a memory address into the NV Storage region. At + // runtime this is the only region of the flash that is mapped for runtime + // access. Prior to runtime the preceding case will cover MMIO flash access. + // + BiosMmioAddress = (VOID*) ((SpiOffset - VN_STORAGE_REGION_FLASH_OFFSET) + mNvStorageBase); + + // + // Do memory copy instead of using SPI controller. + // + CopyMem ((VOID*) Buffer, BiosMmioAddress, *Size); + } else { + Status = EFI_SUCCESS; + RemainingBytes = *Size; + RegionOffset = SpiOffset; + while (RemainingBytes > 0) { + if (RemainingBytes > SIZE_4KB) { + Length = SIZE_4KB; + } else { + Length = RemainingBytes; + } + Status = mSpiProtocol->Execute ( + mSpiProtocol, + SPI_READ, + 0, + TRUE, + TRUE, + FALSE, + (UINT32) RegionOffset, + (UINT32) Length, + Buffer, + EnumSpiRegionAll + ); + if (EFI_ERROR (Status)) { + DEBUG((EFI_D_ERROR, "Failed to read SPI region.\n")); + break; + } + RemainingBytes -= Length; + RegionOffset += Length; + Buffer += Length; + } + } + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +SpiWrite ( + IN UINTN SpiOffset, + IN OUT UINTN *Size, + IN UINT8 *Buffer + ) +{ + EFI_STATUS Status; + UINTN RegionOffset; + UINTN Length; + UINTN RemainingBytes; + + // + // Validate the input parameters + // + if (Size == NULL || Buffer == NULL) { + return EFI_INVALID_PARAMETER; + } + if (SpiOffset + *Size > PcdGet32 (PcdFlashAreaSize)) { + return EFI_INVALID_PARAMETER; + } + + Status = EFI_SUCCESS; + RemainingBytes = *Size; + RegionOffset = SpiOffset; + + while (RemainingBytes > 0) { + if (RemainingBytes > SIZE_4KB) { + Length = SIZE_4KB; + } else { + Length = RemainingBytes; + } + Status = mSpiProtocol->Execute ( + mSpiProtocol, + SPI_PROG, + SPI_WREN, + TRUE, + TRUE, + TRUE, + (UINT32) RegionOffset, + (UINT32) Length, + Buffer, + EnumSpiRegionAll + ); + if (EFI_ERROR (Status)) { + DEBUG((EFI_D_ERROR, "Failed to write SPI region.\n")); + break; + } + RemainingBytes -= Length; + RegionOffset += Length; + Buffer += Length; + } + + return Status; +} + +EFI_STATUS +EFIAPI +SpiErase ( + IN UINTN SpiOffset, + IN OUT UINTN Size + ) +{ + EFI_STATUS Status; + UINTN RegionOffset; + UINTN BytesRemaining; + + // + // Validate the input parameters + // + Status = EFI_INVALID_PARAMETER; + if (SpiOffset + Size > PcdGet32 (PcdFlashAreaSize)) { + return EFI_INVALID_PARAMETER; + } + + // + // Force the minimal alignment of 4k. + // + BytesRemaining = Size; + RegionOffset = SpiOffset; + if (RegionOffset & (SIZE_4KB - 1)) { + DEBUG((EFI_D_INFO, "Forcing SPI Device Erase alignment to a 4k base.\n")); + BytesRemaining += (RegionOffset & (SIZE_4KB - 1)); + RegionOffset = RegionOffset & (SIZE_4KB - 1); + } + + // + // Perform as many erase operations as needed to erase requested region. + // + while (BytesRemaining > 0) { + Status = mSpiProtocol->Execute ( + mSpiProtocol, + SPI_SERASE, + SPI_WREN, + FALSE, + TRUE, + FALSE, + (UINT32) RegionOffset, + 0, + NULL, + EnumSpiRegionAll + ); + if (EFI_ERROR (Status)) { + DEBUG((EFI_D_ERROR, "Failed to erase SPI region.\n")); + break; + } + + // + // Update the number of bytes left to erase. + // + BytesRemaining -= SIZE_4KB; + RegionOffset += SIZE_4KB; + } + + return Status; +} + +EFI_STATUS +EFIAPI +SpiLock ( + IN UINTN SpiOffset, + IN OUT UINTN Size, + IN BOOLEAN Lock + ) +{ + // + // Block/Sector locking is not supported in this implementation. Use SpiSetRange + // and SpiLockRanges to protect areas of the flash. + // + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +SpiSetRange ( + IN UINTN SpiOffset, + IN UINTN Size, + IN BOOLEAN ReadLock, + IN BOOLEAN WriteLock + ) +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +SpiLockRanges ( + ) +{ + // + // Call lock on the SPI interface. This will lock down further configuration + // changes in the SPI controller. + // + return mSpiProtocol->Lock (mSpiProtocol); +} + +/** + Get the JEDED ID from the SPI flash part. + + @param[in] Context Pointer to a context data structure + needed by the SPI controller driver + @param[in] Description Description of the flash device + @param[in] BufferLength Length of the JedecId buffer + @param[out] JedecId Pointer to a buffer to fill with + the JEDEC ID value + + @retval EFI_SUCCESS The JEDEC ID value is in the buffer + @retval EFI_INVALID_PARAMETER JedecId is NULL + @retval EFI_INVALID_PARAMETER Description is NULL + @retval EFI_INVALID_PARAMETER Too few opcode entries + @retval EFI_INVALID_PARAMETER JEDEC ID response buffer too small + @retval EFI_UNSUPPORTED JEDEC ID opcode not found + +**/ +EFI_STATUS +EFIAPI +JedecIdRead ( + IN VOID *Context, + IN CONST FLASH_PART_DESCRIPTION *Description, + IN UINTN BufferLength, + OUT UINT8 *JedecId + ) +{ + // + // Validate parameters. + // + if ((JedecId == NULL) + || (Description == NULL) + || (BufferLength < Description->JededIdResponseLengthInBytes)) { + return EFI_INVALID_PARAMETER; + } + + return mSpiProtocol->ReadId (mSpiProtocol, 0, JedecId); +} + +/** + Determine the flash size and description + + @param[in] PerformJedecIdOperation Callback routine to initiate + the JEDEC ID operation using + the SPI controller to identify + the flash part. + @param[in] Context Pointer to a context structure to pass + to PerformJedecIdOperation + @param[out] FlashDescription Pointer to a buffer to receive a + pointer to a FLASH_PART_DESCRIPTION + data structure containing the flash + part information. + + @return This routine returns the size of the flash part if it is + supported. Zero is returned if the flash part is not + supported. + +**/ +UINT64 +EFIAPI +FindFlashSupport ( + IN PERFORM_JEDEC_ID_OPERATION PerformJedecIdOperation, + IN VOID *Context, + OUT CONST FLASH_PART_DESCRIPTION **FlashDescription + ) +{ + UINTN BufferLength; + CONST FLASH_PART_DESCRIPTION *Description; + UINT64 FlashSize; + EFI_HANDLE *HandleArray; + UINTN HandleCount; + UINTN HandleIndex; + UINT8 *JedecId; + UINT32 MaxPriority; + UINT32 Priority; + SPI_FLASH_PART_PROTOCOL *Protocol; + SPI_FLASH_PART_PROTOCOL **SpiFlashPartProtocol; + EFI_STATUS Status; + + // + // Assume failure + // + FlashSize = 0; + HandleArray = NULL; + JedecId = NULL; + SpiFlashPartProtocol = NULL; + + // + // Locate handles containing SPI_FLASH_PART_PROTOCOLS + // + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gSpiFlashPartProtocolGuid, + NULL, + &HandleCount, + &HandleArray + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "ERROR - Failed to locate SPI_FLASH_PART_PROTOCOL, Status: %r\r\n", Status)); + } else { + // + // Allocate and fill in the protocol array + // + DEBUG ((DEBUG_INFO, "%d SPI flash part descriptions found\r\n", HandleCount)); + SpiFlashPartProtocol = AllocatePool (HandleCount * sizeof (*SpiFlashPartProtocol)); + if (SpiFlashPartProtocol == NULL) { + DEBUG ((DEBUG_ERROR, "ERROR - Failed to allocate SpiFlashDataProtocol buffer\r\n")); + } else { + for (HandleIndex = 0; HandleCount > HandleIndex; HandleIndex++) { + Status = gBS->OpenProtocol ( + HandleArray [HandleIndex], + &gSpiFlashPartProtocolGuid, + (VOID **) &SpiFlashPartProtocol [HandleIndex], + NULL, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "ERROR - Failed to open SPI_FLASH_DATA_PROTOCOL, Status: %r\r\n", Status)); + break; + } + } + if (!EFI_ERROR (Status)) { + // + // Allocate the JEDEC ID buffer + // + BufferLength = 0; + for (HandleIndex = 0; HandleCount > HandleIndex; HandleIndex++) { + // + // Get the JEDEC ID opcode description + // + Protocol = SpiFlashPartProtocol [HandleIndex]; + Description = Protocol->GetFlashDescription ( + Protocol, + NULL, + NULL + ); + if (BufferLength < Description->JededIdResponseLengthInBytes) { + BufferLength = Description->JededIdResponseLengthInBytes; + } + } + JedecId = AllocatePool (BufferLength); + if (JedecId == NULL) { + DEBUG ((DEBUG_ERROR, "ERROR - Failed to allocate JedecId buffer\r\n")); + } else { + // + // Start with the first flash type description; + // + MaxPriority = 0xffffffff; + do { + // + // Determine the highest priority protocol + // + Priority = 0; + for (HandleIndex = 0; HandleCount > HandleIndex; HandleIndex++) { + Protocol = SpiFlashPartProtocol [HandleIndex]; + if ((MaxPriority >= Protocol->Priority) + && (Priority < Protocol->Priority)) + Priority = Protocol->Priority; + } + if (Priority == 0) { + // + // The flash is not supported + // + break; + } + + // + // Walk the handles containing the SPI flash part protocol + // + HandleIndex = 0; + do { + // + // Verify the description type matches and the opcode table + // supports the minimum number of entries required for the code + // + Protocol = SpiFlashPartProtocol [HandleIndex]; + if (Priority == Protocol->Priority) { + // + // Get the JEDEC ID opcode description + // + Description = Protocol->GetFlashDescription ( + Protocol, + NULL, + NULL + ); + if ((Description == NULL) + || (SPI_FLASH_PART_OPCODE_JEDEC_ID == Description->OpcodeTableEntries)) { + DEBUG ((DEBUG_ERROR, "ERROR - JEDEC ID opcode not available\r\n")); + } else { + // + // Display the flash part + // + DEBUG ((DEBUG_INFO, "Priority: 0x%08x, SPI Flash Part: %s\r\n", Priority, Description->PartNumber )); + + // + // Attempt to read the JEDEC ID + // + Status = PerformJedecIdOperation ( + Context, + Description, + Description->JededIdResponseLengthInBytes, + JedecId + ); + if (!EFI_ERROR (Status)) { + // + // Display the JEDEC ID + // + DEBUG_CODE_BEGIN (); + { + UINTN Index; + + DEBUG ((DEBUG_INFO, "JEDEC ID:")); + for (Index = 0; Description->JededIdResponseLengthInBytes > Index; Index++) { + DEBUG ((DEBUG_INFO, " 0x%02x", JedecId [Index])); + } + DEBUG ((DEBUG_INFO, "\r\n")); + } + DEBUG_CODE_END (); + + // + // Verify support and determine flash size + // + Description = Protocol->GetFlashDescription ( + Protocol, + JedecId, + &FlashSize + ); + if (Description != NULL) { + // + // The flash device is supported + // Return the table for this flash device + // + DEBUG ((DEBUG_INFO, "SPI flash device found: %s\r\n", Description->PartNumber)); + *FlashDescription = Description; + goto PartFound; + } + } + } + } + + // + // Set next handle + // + HandleIndex += 1; + } while (HandleCount > HandleIndex); + + // + // Set the next priority + // + MaxPriority = Priority - 1; + } while (Priority != 0); + + // + // No flash device found + // + DEBUG ((DEBUG_ERROR, "Matching SPI flash description not found\r\n")); + } + } + } + } + +PartFound: + // + // Free the buffers + // + if (JedecId != NULL) { + FreePool (JedecId); + } + if (SpiFlashPartProtocol != NULL) { + FreePool (SpiFlashPartProtocol); + } + if (HandleArray != NULL) { + FreePool (HandleArray); + } + + // + // Return the flash size + // Zero (0) indicates flash not found or not supported + // + return FlashSize; +} + +/** + Load opcode into the SPI controller for specific flash device + + @param[in] FlashDescription Description of the flash device + + @retval EFI_SUCCESS The opcode was successfully loaded + @retval EFI_UNSUPPORTED The opcode was not found + +**/ +EFI_STATUS +SpiFlashInit ( + IN CONST FLASH_PART_DESCRIPTION *FlashDescription + ) +{ + EFI_STATUS Status; + SPI_INIT_DATA SpiInitTable; + UINTN Index; + UINT8 CmdCfgIndex; + CONST UINT8 OpcodeMap [] = { + SPI_READ_ID, // SPI_FLASH_PART_OPCODE_JEDEC_ID + SPI_RDSR, // SPI_FLASH_PART_OPCODE_READ_STATUS + SPI_WRSR, // SPI_FLASH_PART_OPCODE_WRITE_STATUS + SPI_READ, // SPI_FLASH_PART_OPCODE_READ_BYTES + SPI_PROG, // SPI_FLASH_PART_OPCODE_WRITE_256_BYTE_PAGE + SPI_SERASE, // SPI_FLASH_PART_OPCODE_ERASE_4K_BYTE_BLOCK + SPI_BERASE, // SPI_FLASH_PART_OPCODE_ERASE_64K_BYTE_BLOCK + SPI_WRDI_SFDP // SPI_FLASH_PART_OPCODE_WRITE_DISABLE + }; + + Status = EFI_SUCCESS; + + ZeroMem (&SpiInitTable, sizeof (SPI_INIT_DATA)); + + SpiInitTable.PrefixOpcode[SPI_WREN] = FlashDescription->WriteEnable; + SpiInitTable.PrefixOpcode[SPI_EWSR] = FlashDescription->WriteStatusEnable; + + SpiInitTable.BiosStartOffset = (UINTN)BIOS_REGION_FLASH_OFFSET; + SpiInitTable.BiosSize = (UINTN)PcdGet32 (PcdBiosImageSize); + SpiInitTable.SpecialOpcodeEntry = NULL; + + ASSERT (FlashDescription->OpcodeTableEntries <= SPI_NUM_OPCODE); + + for (Index = 0;Index < FlashDescription->OpcodeTableEntries;Index++) { + CmdCfgIndex = OpcodeMap[Index]; + switch (FlashDescription->OpcodeTable[Index].MaxFrequency) { + case 20000000: + SpiInitTable.SpiCmdConfig[CmdCfgIndex].Frequency = EnumSpiCycle20MHz; + break; + + case 33000000: + SpiInitTable.SpiCmdConfig[CmdCfgIndex].Frequency = EnumSpiCycle33MHz; + break; + + case 50000000: + SpiInitTable.SpiCmdConfig[CmdCfgIndex].Frequency = EnumSpiCycle50MHz; + break; + + case 66000000: + SpiInitTable.SpiCmdConfig[CmdCfgIndex].Frequency = EnumSpiCycle66MHz; + break; + + default: + SpiInitTable.SpiCmdConfig[CmdCfgIndex].Frequency = EnumSpiCycle33MHz; + break; + } + + switch (FlashDescription->OpcodeTable[Index].OpcodeIndex) { + case SPI_FLASH_PART_OPCODE_JEDEC_ID: + SpiInitTable.SpiCmdConfig[CmdCfgIndex].Operation = EnumSpiOperationJedecId; + break; + + case SPI_FLASH_PART_OPCODE_READ_STATUS: + SpiInitTable.SpiCmdConfig[CmdCfgIndex].Operation = EnumSpiOperationReadStatus; + break; + + case SPI_FLASH_PART_OPCODE_WRITE_STATUS: + SpiInitTable.SpiCmdConfig[CmdCfgIndex].Operation = EnumSpiOperationWriteStatus; + break; + + case SPI_FLASH_PART_OPCODE_READ_BYTES: + SpiInitTable.SpiCmdConfig[CmdCfgIndex].Operation = EnumSpiOperationReadData; + break; + + case SPI_FLASH_PART_OPCODE_WRITE_256_BYTE_PAGE: + SpiInitTable.SpiCmdConfig[CmdCfgIndex].Operation = EnumSpiOperationProgramData_1_Byte; + break; + + case SPI_FLASH_PART_OPCODE_ERASE_4K_BYTE_BLOCK: + SpiInitTable.SpiCmdConfig[CmdCfgIndex].Operation = EnumSpiOperationErase_4K_Byte; + break; + + case SPI_FLASH_PART_OPCODE_ERASE_64K_BYTE_BLOCK: + SpiInitTable.SpiCmdConfig[CmdCfgIndex].Operation = EnumSpiOperationErase_64K_Byte; + break; + + case SPI_FLASH_PART_OPCODE_WRITE_DISABLE_DISCOVERY: + SpiInitTable.SpiCmdConfig[CmdCfgIndex].Operation = EnumSpiOperationWriteDisable; + break; + + default: + DEBUG ((DEBUG_ERROR, "Unrecognized opcode index\r\n")); + ASSERT(FALSE); + break; + } + } + + Status = mSpiProtocol->Init (mSpiProtocol, &SpiInitTable); + + return Status; +} diff --git a/BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDevice.h b/BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDevice.h new file mode 100644 index 0000000000..cb8229629d --- /dev/null +++ b/BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDevice.h @@ -0,0 +1,211 @@ +/** @file + SPI Device driver for Braswell Platform. + + Copyright (c) 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _SPI_DEVICE_H_ +#define _SPI_DEVICE_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +// +// Defines the offset in the SPI device where the BIOS region starts. +// +#define BIOS_REGION_FLASH_OFFSET (PcdGet32 (PcdBiosImageBase) - PcdGet32 (PcdFlashAreaBaseAddress)) +#define VN_STORAGE_REGION_FLASH_OFFSET (PcdGet32 (PcdFlashNvStorageVariableBase) - PcdGet32 (PcdFlashAreaBaseAddress)) + +extern EFI_SPI_PROTOCOL *mSpiProtocol; +extern UINTN mNvStorageBase; + +// +// Prefix Opcode Index on the host SPI controller +// +typedef enum { + SPI_WREN, // Prefix Opcode 0: Write Enable + SPI_EWSR, // Prefix Opcode 1: Enable Write Status Register +} PREFIX_OPCODE_INDEX; + +// +// Opcode Menu Index on the host SPI controller +// +typedef enum { + SPI_READ_ID, // Opcode 0: READ ID, Read cycle with address + SPI_READ, // Opcode 1: READ, Read cycle with address + SPI_RDSR, // Opcode 2: Read Status Register, No address + SPI_WRDI_SFDP, // Opcode 3: Write Disable or Discovery Parameters, No address + SPI_SERASE, // Opcode 4: Sector Erase (4KB), Write cycle with address + SPI_BERASE, // Opcode 5: Block Erase (32KB), Write cycle with address + SPI_PROG, // Opcode 6: Byte Program, Write cycle with address + SPI_WRSR, // Opcode 7: Write Status Register, No address +} SPI_OPCODE_INDEX; + +EFI_STATUS +EFIAPI +InitSpiDevice ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +EFI_STATUS +EFIAPI +SpiRead ( + IN UINTN SpiOffset, + IN OUT UINTN *Size, + OUT UINT8 *Buffer + ); + +EFI_STATUS +EFIAPI +SpiWrite ( + IN UINTN SpiOffset, + IN OUT UINTN *Size, + IN UINT8 *Buffer + ); + +EFI_STATUS +EFIAPI +SpiErase ( + IN UINTN SpiOffset, + IN OUT UINTN Size + ); + +EFI_STATUS +EFIAPI +SpiLock ( + IN UINTN SpiOffset, + IN OUT UINTN Size, + IN BOOLEAN Lock + ); + +EFI_STATUS +EFIAPI +SpiSetRange ( + IN UINTN SpiOffset, + IN UINTN Size, + IN BOOLEAN ReadLock, + IN BOOLEAN WriteLock + ); + +EFI_STATUS +EFIAPI +SpiLockRanges ( + ); + +BOOLEAN +ReadUsingMmio ( + IN UINTN SpiOffset + ); + +/** + Get the JEDED ID from the SPI flash part. + + @param[in] Context Pointer to a context data structure + needed by the SPI controller driver + @param[in] Description Description of the flash device + @param[in] BufferLength Length of the JedecId buffer + @param[out] JedecId Pointer to a buffer to fill with + the JEDEC ID value + + @retval EFI_SUCCESS The JEDEC ID value is in the buffer + @retval EFI_INVALID_PARAMETER JedecId is NULL + @retval EFI_INVALID_PARAMETER Description is NULL + @retval EFI_INVALID_PARAMETER Too few opcode entries + @retval EFI_INVALID_PARAMETER JEDEC ID response buffer too small + @retval EFI_UNSUPPORTED JEDEC ID opcode not found + +**/ +EFI_STATUS +EFIAPI +JedecIdRead ( + IN VOID *Context, + IN CONST FLASH_PART_DESCRIPTION *Description, + IN UINTN BufferLength, + OUT UINT8 *JedecId + ); + +/** + Get the JEDED ID from the SPI flash part. + + @param[in] Context Pointer to a context data structure + needed by the SPI controller driver + @param[in] Description Description of the flash device + @param[in] BufferLength Length of the JedecId buffer + @param[out] JedecId Pointer to a buffer to fill with + the JEDEC ID value + + @retval EFI_SUCCESS The JEDEC ID value is in the buffer + @retval EFI_INVALID_PARAMETER JedecId is NULL + @retval EFI_INVALID_PARAMETER Description is NULL + @retval EFI_INVALID_PARAMETER Too few opcode entries + @retval EFI_INVALID_PARAMETER JEDEC ID response buffer too small + +**/ +typedef +EFI_STATUS +(EFIAPI *PERFORM_JEDEC_ID_OPERATION) ( + IN VOID *Context, + IN CONST FLASH_PART_DESCRIPTION *Description, + IN UINTN BufferLength, + OUT UINT8 *JedecId + ); + +/** + Determine the flash size and description + + @param[in] PerformJedecIdOperation Callback routine to initiate + the JEDEC ID operation using + the SPI controller to identify + the flash part. + @param[in] Context Pointer to a context structure to pass + to PerformJedecIdOperation + @param[out] FlashDescription Pointer to a buffer to receive a + pointer to a FLASH_PART_DESCRIPTION + data structure containing the flash + part information. + + @return This routine returns the size of the flash part if it is + supported. Zero is returned if the flash part is not + supported. + +**/ +UINT64 +EFIAPI +FindFlashSupport ( + IN PERFORM_JEDEC_ID_OPERATION PerformJedecIdOperation, + IN VOID *Context, + OUT CONST FLASH_PART_DESCRIPTION **FlashDescription + ); + + +/** + Load opcode into the SPI controller for specific flash device + + @param[in] FlashDescription Description of the flash device + + @retval EFI_SUCCESS The opcode was successfully loaded + @retval EFI_UNSUPPORTED The opcode was not found + +**/ +EFI_STATUS +SpiFlashInit ( + IN CONST FLASH_PART_DESCRIPTION *FlashDescription + ); + +#endif diff --git a/BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDeviceDxe.c b/BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDeviceDxe.c new file mode 100644 index 0000000000..907b8e9517 --- /dev/null +++ b/BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDeviceDxe.c @@ -0,0 +1,152 @@ +/** @file + This driver for SPI Device initialization + + Copyright (c) 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include "SpiDevice.h" + +SPI_DEVICE_PROTOCOL mSpiDevProtocol = { + SpiRead, + SpiWrite, + SpiErase, + SpiLock, + SpiSetRange, + SpiLockRanges +}; + +VOID +EFIAPI +SpiDeviceVirtualAddressChangeEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + // + // Update protocol pointer to the SPI Controller interface. + // + EfiConvertPointer (0x00, (VOID**) &(mSpiProtocol)); + + // + // Update the NV Storage location for runtime access. + // + EfiConvertPointer (0x00, (VOID**) &(mNvStorageBase)); + + // + // Take care of pointers in protocol. + // + EfiConvertPointer (0x00, (VOID**) &(mSpiDevProtocol.SpiRead)); + EfiConvertPointer (0x00, (VOID**) &(mSpiDevProtocol.SpiWrite)); + EfiConvertPointer (0x00, (VOID**) &(mSpiDevProtocol.SpiErase)); + EfiConvertPointer (0x00, (VOID**) &(mSpiDevProtocol.SpiLock)); +} + +EFI_STATUS +EFIAPI +InitSpiDevice ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_EVENT Event; + CONST FLASH_PART_DESCRIPTION *FlashDescription; + UINT64 FlashSize; + EFI_HANDLE Handle; + EFI_STATUS Status; + + mNvStorageBase = PcdGet32 (PcdFlashNvStorageVariableBase); + + // + // Locate the SPI controller protocol and save it for later. + // + DEBUG((EFI_D_INFO, "Locating SPI Controller Protocol.\n")); + Status = gBS->LocateProtocol ( + &gEfiSpiProtocolGuid, + NULL, + (VOID **) &mSpiProtocol + ); + ASSERT_EFI_ERROR(Status); + + // + // Loop through all the flash devices that are supported and see if one will + // initialize the SPI Controller interface. + // + FlashSize = FindFlashSupport ( + &JedecIdRead, + NULL, + &FlashDescription + ); + if (FlashSize == 0) { + DEBUG((EFI_D_ERROR, "No SPI flash part description found!\r\n")); + } else { + // + // Attempt to configure the SPI controller for this device. + // + DEBUG((EFI_D_INFO, "SPI flash size: %d MBytes\n", DivU64x32(FlashSize, 1024 * 1024 ))); + DEBUG((EFI_D_INFO, "Configuring SPI Controller.\n")); + + Status = SpiFlashInit (FlashDescription); + if (!EFI_ERROR (Status)) { + // + // Publish the SPI Device protocol. + // + DEBUG((EFI_D_INFO, "Installing SPI Device Protocol.\n")); + Handle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gSpiDeviceProtocolGuid, + &mSpiDevProtocol, + NULL + ); + if (EFI_ERROR (Status)) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Make sure we can handle virtual address changes. + // + Event = NULL; + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + SpiDeviceVirtualAddressChangeEvent, + NULL, + &gEfiEventVirtualAddressChangeGuid, + &Event + ); + + return EFI_SUCCESS; + } + } + + // + // Unable to find a supported SPI device + // + DEBUG((EFI_D_ERROR, "Unable to configure SPI Controller for SPI device present.\n")); + + return EFI_UNSUPPORTED; +} + +BOOLEAN +ReadUsingMmio ( + IN UINTN SpiOffset + ) +{ + return (BOOLEAN) ((SpiOffset >= BIOS_REGION_FLASH_OFFSET) && (SpiOffset < (BIOS_REGION_FLASH_OFFSET + PcdGet32 (PcdBiosImageSize))) && (!EfiAtRuntime ())); +} diff --git a/BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDeviceDxe.inf b/BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDeviceDxe.inf new file mode 100644 index 0000000000..9db458076c --- /dev/null +++ b/BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDeviceDxe.inf @@ -0,0 +1,64 @@ +## @file +# SPI Flash Device Driver +# +# Adds platform support to configure the SPI controller with the correct values +# to be used when using software sequencing. +# +# Copyright (c) 2015, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010018 + BASE_NAME = SpiDeviceDxe + FILE_GUID = DA28E378-C84B-4969-BD4D-90AA883C091A + MODULE_TYPE = DXE_RUNTIME_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = InitSpiDevice + +[Sources] + SpiDeviceDxe.c + SpiDevice.c + SpiDevice.h + +[Packages] + ChvRefCodePkg/ChvRefCodePkg.dec + BraswellPlatformPkg/BraswellPlatformPkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + DebugLib + DxeServicesTableLib + UefiBootServicesTableLib + UefiDriverEntryPoint + UefiRuntimeLib + MemoryAllocationLib + +[Protocols] + gEfiSpiProtocolGuid ## CONSUMES + gSpiDeviceProtocolGuid ## PRODUCES + gSpiFlashPartProtocolGuid ## CONSUMES + gEfiSmmCommunicationProtocolGuid ## UNDEFINED + +[Guids] + gEfiEventVirtualAddressChangeGuid ## SOMETIMES_CONSUMES ## NOTIFY + +[Pcd] + gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES + gPlatformModuleTokenSpaceGuid.PcdFlashAreaSize ## CONSUMES + gPlatformModuleTokenSpaceGuid.PcdBiosImageBase ## CONSUMES + gPlatformModuleTokenSpaceGuid.PcdBiosImageSize ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase ## CONSUMES + +[Depex] + gEfiSpiProtocolGuid + diff --git a/BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDeviceSmm.c b/BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDeviceSmm.c new file mode 100644 index 0000000000..7d02aff9d0 --- /dev/null +++ b/BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDeviceSmm.c @@ -0,0 +1,222 @@ +/** @file + SMM driver for SPI Device initialization. + + Copyright (c) 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include "SpiDevice.h" +#include "SpiDeviceSmmComm.h" + +SPI_DEVICE_PROTOCOL mSpiDevProtocol = { + SpiRead, + SpiWrite, + SpiErase, + SpiLock, + SpiSetRange, + SpiLockRanges +}; + +EFI_STATUS +EFIAPI +SpiDeviceSmmHandler ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *RegisterContext, + IN OUT VOID *CommBuffer, + IN OUT UINTN *CommBufferSize + ) +{ + EFI_STATUS Status; + SMM_SPI_DEV_COMMUNICATE_FUNCTION_HEADER *SpiDevCommHeader; + SMM_SPI_DEV_READ_WRITE_ERASE_HEADER *SpiDevDataOpHeader; + SMM_SPI_DEV_LOCK_HEADER *SpiDevLockHeader; + SMM_SPI_DEV_SET_RANGE_HEADER *SpiDevSetRangeHeader; + + ASSERT (CommBuffer != NULL); + + SpiDevCommHeader = (SMM_SPI_DEV_COMMUNICATE_FUNCTION_HEADER*) CommBuffer; + switch (SpiDevCommHeader->Function) { + case SPI_DEV_FUNCTION_READ: + SpiDevDataOpHeader = (SMM_SPI_DEV_READ_WRITE_ERASE_HEADER*) SpiDevCommHeader->Data; + Status = SpiRead ( + SpiDevDataOpHeader->Offset, + &SpiDevDataOpHeader->Size, + (UINT8*) (SpiDevDataOpHeader + 1) + ); + break; + case SPI_DEV_FUNCTION_WRITE: + SpiDevDataOpHeader = (SMM_SPI_DEV_READ_WRITE_ERASE_HEADER*) SpiDevCommHeader->Data; + Status = SpiWrite ( + SpiDevDataOpHeader->Offset, + &SpiDevDataOpHeader->Size, + (UINT8*) (SpiDevDataOpHeader + 1) + ); + break; + case SPI_DEV_FUNCTION_ERASE: + SpiDevDataOpHeader = (SMM_SPI_DEV_READ_WRITE_ERASE_HEADER*) SpiDevCommHeader->Data; + Status = SpiErase ( + SpiDevDataOpHeader->Offset, + SpiDevDataOpHeader->Size + ); + break; + case SPI_DEV_FUNCTION_LOCK: + SpiDevLockHeader = (SMM_SPI_DEV_LOCK_HEADER*) SpiDevCommHeader->Data; + Status = SpiLock ( + SpiDevLockHeader->Offset, + SpiDevLockHeader->Size, + SpiDevLockHeader->Lock + ); + break; + case SPI_DEV_FUNCTION_SET_RANGE: + SpiDevSetRangeHeader = (SMM_SPI_DEV_SET_RANGE_HEADER*) SpiDevCommHeader->Data; + Status = SpiSetRange ( + SpiDevSetRangeHeader->Offset, + SpiDevSetRangeHeader->Size, + SpiDevSetRangeHeader->ReadLock, + SpiDevSetRangeHeader->WriteLock + ); + break; + case SPI_DEV_FUNCTION_LOCK_RANGES: + Status = SpiLockRanges (); + break; + default: + ASSERT (FALSE); + Status = EFI_UNSUPPORTED; + break; + } + + // + // Set the return value. + // + SpiDevCommHeader->ReturnStatus = Status; + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +InitSpiDevice ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + CONST FLASH_PART_DESCRIPTION *FlashDescription; + UINT64 FlashSize; + EFI_HANDLE Handle; + EFI_STATUS Status; + + //-------------------------------------------------- + // + // Note only this routine is able to make calls + // into the DXE environment since it is called + // synchronously from that environment and DXE + // is still executing in physical mode. + // + //-------------------------------------------------- + + mNvStorageBase = PcdGet32 (PcdFlashNvStorageVariableBase); + + // + // Locate the SPI controller protocol and save it for later. + // + DEBUG((EFI_D_INFO, "Locating SPI Controller Protocol.\n")); + Status = gSmst->SmmLocateProtocol ( + &gEfiSmmSpi2ProtocolGuid, + NULL, + (VOID **) &mSpiProtocol + ); + ASSERT_EFI_ERROR(Status); + + + // + // Loop through all the flash devices that are supported and see if one will + // initialize the SPI Controller interface. + // + FlashSize = FindFlashSupport ( + &JedecIdRead, + NULL, + &FlashDescription + ); + if (FlashSize == 0) { + DEBUG((EFI_D_ERROR, "No SPI flash part description found!\r\n")); + } else { + // + // Attempt to configure the SPI controller for this device. + // + DEBUG((EFI_D_INFO, "SPI flash size: %d MBytes\n", DivU64x32(FlashSize, 1024 * 1024 ))); + DEBUG((EFI_D_INFO, "Configuring SPI Controller.\n")); + Status = SpiFlashInit (FlashDescription); + if (!EFI_ERROR (Status)) { + // + // Publish the SMM SPI Device protocol for FVB service + // + DEBUG((EFI_D_INFO, "Installing SPI Device Protocol.\n")); + Handle = NULL; + Status = gSmst->SmmInstallProtocolInterface ( + &Handle, + &gSmmSpiDeviceProtocolGuid, + EFI_NATIVE_INTERFACE, + &mSpiDevProtocol + ); + if (EFI_ERROR (Status)) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Install protocol to inform other DXE drivers the SMM service is available. + // + Handle = NULL; + Status = gBS->InstallProtocolInterface ( + &Handle, + &gSmmSpiDeviceProtocolGuid, + EFI_NATIVE_INTERFACE, + &mSpiDevProtocol + ); + if (EFI_ERROR (Status)) { + DEBUG((EFI_D_ERROR, "Unable to install SMM SPI device protocol, Status: %r\n", Status)); + return Status; + } + + // + // Install communication handler. + // + Handle = NULL; + Status = gSmst->SmiHandlerRegister (SpiDeviceSmmHandler, &gSmmSpiDeviceProtocolGuid, &Handle); + if (EFI_ERROR (Status)) { + DEBUG((EFI_D_ERROR, "Unable to register SMM SPI handler, Status: %r\n", Status)); + return Status; + } + + DEBUG((EFI_D_INFO, "SPI flash controller configured successfully\n", Status)); + return EFI_SUCCESS; + } + } + + // + // Unable to find a supported SPI device + // + DEBUG((EFI_D_ERROR, "Unable to configure SPI Controller for SPI device present.\n")); + + return EFI_UNSUPPORTED; +} + +BOOLEAN +ReadUsingMmio ( + IN UINTN SpiOffset + ) +{ + return (BOOLEAN) ((SpiOffset >= BIOS_REGION_FLASH_OFFSET) && (SpiOffset < (BIOS_REGION_FLASH_OFFSET + PcdGet32 (PcdBiosImageSize)))); +} diff --git a/BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDeviceSmm.inf b/BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDeviceSmm.inf new file mode 100644 index 0000000000..d698f25159 --- /dev/null +++ b/BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDeviceSmm.inf @@ -0,0 +1,62 @@ +## @file +# SPI Device SMM Driver +# +# Adds platform support to configure the SPI controller with the correct values +# to be used when using software sequencing. This driver initializes EMST* F25L016A +# SPI flash device and installs gSmmSpiDeviceProtocolGuid protocol. +# +# Copyright (c) 2015, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010018 + BASE_NAME = SpiDeviceSmm + FILE_GUID = 163774A8-917F-40E5-AB54-B4BFA11D41F9 + MODULE_TYPE = DXE_SMM_DRIVER + VERSION_STRING = 1.0 + PI_SPECIFICATION_VERSION = 0x0001000A + ENTRY_POINT = InitSpiDevice + +[Sources] + SpiDeviceSmm.c + SpiDevice.c + SpiDevice.h + +[Packages] + ChvRefCodePkg/ChvRefCodePkg.dec + BraswellPlatformPkg/BraswellPlatformPkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + UefiBootServicesTableLib + UefiDriverEntryPoint + DebugLib + SmmServicesTableLib + BaseLib + MemoryAllocationLib + +[Protocols] + gEfiSmmSpi2ProtocolGuid ## CONSUMES + gSmmSpiDeviceProtocolGuid ## PRODUCES + gSpiFlashPartProtocolGuid ## CONSUMES + +[Pcd] + gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES + gPlatformModuleTokenSpaceGuid.PcdFlashAreaSize ## CONSUMES + gPlatformModuleTokenSpaceGuid.PcdBiosImageBase ## CONSUMES + gPlatformModuleTokenSpaceGuid.PcdBiosImageSize ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase ## CONSUMES + +[Depex] + gEfiSmmSpi2ProtocolGuid + diff --git a/BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDeviceSmmComm.h b/BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDeviceSmmComm.h new file mode 100644 index 0000000000..ee2d0a42a4 --- /dev/null +++ b/BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDeviceSmmComm.h @@ -0,0 +1,73 @@ +/** @file + SMM Communication formats for the SPI Device protocols. + + Copyright (c) 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _SPI_DEVICE_SMM_COMM_H_ +#define _SPI_DEVICE_SMM_COMM_H_ + +#include + +// +// Define communication constants +// +#define SPI_DEV_FUNCTION_READ 1 +#define SPI_DEV_FUNCTION_WRITE 2 +#define SPI_DEV_FUNCTION_ERASE 3 +#define SPI_DEV_FUNCTION_LOCK 4 +#define SPI_DEV_FUNCTION_SET_RANGE 5 +#define SPI_DEV_FUNCTION_LOCK_RANGES 6 + +// +// Generic SPI Device communication structure header. +// +typedef struct { + UINTN Function; + EFI_STATUS ReturnStatus; + UINT8 Data[1]; +} SMM_SPI_DEV_COMMUNICATE_FUNCTION_HEADER; + +// +// Macros used to determine size of the headers without data size. +// +#define SMM_COMMUNICATE_HEADER_SIZE (OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)) +#define SMM_SPI_DEV_COMMUNICATE_FUNCTION_HEADER_SIZE (OFFSET_OF (SMM_SPI_DEV_COMMUNICATE_FUNCTION_HEADER, Data)) + +// +// SPI Read, Write and Erase Data. Erase will not have any extra data. +// +typedef struct { + UINTN Offset; + UINTN Size; +} SMM_SPI_DEV_READ_WRITE_ERASE_HEADER; + +// +// SPI Lock +// +typedef struct { + UINTN Offset; + UINTN Size; + BOOLEAN Lock; +} SMM_SPI_DEV_LOCK_HEADER; + +// +// SPI Set Range +// +typedef struct { + UINTN Offset; + UINTN Size; + BOOLEAN ReadLock; + BOOLEAN WriteLock; +} SMM_SPI_DEV_SET_RANGE_HEADER; + +#endif diff --git a/BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDeviceSmmDxe.c b/BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDeviceSmmDxe.c new file mode 100644 index 0000000000..392c549a95 --- /dev/null +++ b/BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDeviceSmmDxe.c @@ -0,0 +1,437 @@ +/** @file + Provides an interface to the SMM SPI Device driver. + + gSpiDeviceProtocolGuid (DXE: SpiDeviceSmmDxe) + | + | via gEfiSmmCommunicationProtocolGuid + V + gSmmSpiDeviceProtocolGuid (SMM: SpiDeviceSmm) + | + | + V + gEfiSmmSpi2ProtocolGuid (SMM: SpiSmm) + + Copyright (c) 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include +#include "SpiDevice.h" +#include "SpiDeviceSmmComm.h" + +EFI_SMM_COMMUNICATION_PROTOCOL *mSmmComm = NULL; + +SPI_DEVICE_PROTOCOL mSpiDevProtocol = { + SpiRead, + SpiWrite, + SpiErase, + SpiLock, + SpiSetRange, + SpiLockRanges +}; + +VOID +EFIAPI +SmmSpiDeviceReady ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +EFI_STATUS +CreateCommBuffer ( + OUT VOID **CommBuffer, + OUT VOID **DataArea, + IN UINTN DataSize, + IN UINTN Function + ) +{ + EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; + SMM_SPI_DEV_COMMUNICATE_FUNCTION_HEADER *SmmSpiDevFunctionHeader; + + // + // Allocate communication buffer. + // + SmmCommunicateHeader = AllocatePool (DataSize + SMM_COMMUNICATE_HEADER_SIZE + SMM_SPI_DEV_COMMUNICATE_FUNCTION_HEADER_SIZE); + if (SmmCommunicateHeader == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Fill in new structure will data from caller. + // + CopyGuid (&SmmCommunicateHeader->HeaderGuid, &gSmmSpiDeviceProtocolGuid); + SmmCommunicateHeader->MessageLength = DataSize + SMM_SPI_DEV_COMMUNICATE_FUNCTION_HEADER_SIZE; + SmmSpiDevFunctionHeader = (SMM_SPI_DEV_COMMUNICATE_FUNCTION_HEADER*) SmmCommunicateHeader->Data; + SmmSpiDevFunctionHeader->Function = Function; + + // + // Assign return values. + // + *CommBuffer = SmmCommunicateHeader; + if (DataArea != NULL) { + *DataArea = SmmSpiDevFunctionHeader->Data; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +SendCommBuffer ( + IN OUT EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader, + IN UINTN DataSize + ) +{ + EFI_STATUS Status; + UINTN CommSize; + SMM_SPI_DEV_COMMUNICATE_FUNCTION_HEADER *SmmSpiDevFunctionHeader; + + // + // Compute actual size of communication data. + // + CommSize = DataSize + SMM_COMMUNICATE_HEADER_SIZE + SMM_SPI_DEV_COMMUNICATE_FUNCTION_HEADER_SIZE; + + // + // Send the message to be processed in SMM. + // + Status = mSmmComm->Communicate (mSmmComm, SmmCommunicateHeader, &CommSize); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Get the return value from the SMM function. + // + SmmSpiDevFunctionHeader = (SMM_SPI_DEV_COMMUNICATE_FUNCTION_HEADER*) SmmCommunicateHeader->Data; + + return SmmSpiDevFunctionHeader->ReturnStatus; +} + +EFI_STATUS +EFIAPI +SpiRead ( + IN UINTN SpiOffset, + IN OUT UINTN *Size, + OUT UINT8 *Buffer + ) +{ + EFI_STATUS Status; + UINTN DataSize; + EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; + SMM_SPI_DEV_READ_WRITE_ERASE_HEADER *SpiDevReadHeader; + + // + // Validate input parameters. + // + if (Size == NULL || Buffer == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Determine the actual data size required for the transaction. + // + DataSize = *Size + sizeof(SMM_SPI_DEV_READ_WRITE_ERASE_HEADER); + + // + // Create the communication buffer. + // + Status = CreateCommBuffer ((VOID**) &SmmCommunicateHeader, (VOID**) &SpiDevReadHeader, DataSize, SPI_DEV_FUNCTION_READ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Fill in communication buffer parameters. + // + SpiDevReadHeader->Offset = SpiOffset; + SpiDevReadHeader->Size = *Size; + + // + // Communicate request to SMM driver and fill in return values. + // + Status = SendCommBuffer (SmmCommunicateHeader, DataSize); + *Size = SpiDevReadHeader->Size; + if (!EFI_ERROR (Status)) { + CopyMem (Buffer, (UINT8*)(SpiDevReadHeader + 1), *Size); + } + + return Status; +} + +EFI_STATUS +EFIAPI +SpiWrite ( + IN UINTN SpiOffset, + IN OUT UINTN *Size, + IN UINT8 *Buffer + ) +{ + EFI_STATUS Status; + UINTN DataSize; + EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; + SMM_SPI_DEV_READ_WRITE_ERASE_HEADER *SpiDevWriteHeader; + + // + // Validate input parameters. + // + if (Size == NULL || Buffer == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Determine the actual data size required for the transaction. + // + DataSize = *Size + sizeof(SMM_SPI_DEV_READ_WRITE_ERASE_HEADER); + + // + // Create the communication buffer. + // + Status = CreateCommBuffer ((VOID**) &SmmCommunicateHeader, (VOID**) &SpiDevWriteHeader, DataSize, SPI_DEV_FUNCTION_WRITE); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Fill in communication buffer parameters. + // + SpiDevWriteHeader->Offset = SpiOffset; + SpiDevWriteHeader->Size = *Size; + CopyMem ((UINT8*)(SpiDevWriteHeader + 1), Buffer, *Size); + + // + // Communicate request to SMM driver and fill in return values. + // + Status = SendCommBuffer (SmmCommunicateHeader, DataSize); + *Size = SpiDevWriteHeader->Size; + + return Status; +} + +EFI_STATUS +EFIAPI +SpiErase ( + IN UINTN SpiOffset, + IN OUT UINTN Size + ) +{ + EFI_STATUS Status; + UINTN DataSize; + EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; + SMM_SPI_DEV_READ_WRITE_ERASE_HEADER *SpiDevEraseHeader; + + // + // Determine the actual data size required for the transaction. + // + DataSize = sizeof(SMM_SPI_DEV_READ_WRITE_ERASE_HEADER); + + // + // Create the communication buffer. + // + Status = CreateCommBuffer ((VOID**) &SmmCommunicateHeader, (VOID**) &SpiDevEraseHeader, DataSize, SPI_DEV_FUNCTION_ERASE); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Fill in communication buffer parameters. + // + SpiDevEraseHeader->Offset = SpiOffset; + SpiDevEraseHeader->Size = Size; + + // + // Communicate request to SMM driver and fill in return values. + // + Status = SendCommBuffer (SmmCommunicateHeader, DataSize); + + return Status; +} + +EFI_STATUS +EFIAPI +SpiLock ( + IN UINTN SpiOffset, + IN OUT UINTN Size, + IN BOOLEAN Lock + ) +{ + EFI_STATUS Status; + UINTN DataSize; + EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; + SMM_SPI_DEV_LOCK_HEADER *SmmSpiDevLockHeader; + + // + // Compute data size required for the transaction. + // + DataSize = sizeof(SMM_SPI_DEV_LOCK_HEADER); + + // + // Create the communication buffer. + // + Status = CreateCommBuffer ((VOID**) &SmmCommunicateHeader, (VOID**) &SmmSpiDevLockHeader, DataSize, SPI_DEV_FUNCTION_LOCK); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Fill in communication buffer parameters. + // + SmmSpiDevLockHeader->Offset = SpiOffset; + SmmSpiDevLockHeader->Size = Size; + SmmSpiDevLockHeader->Lock = Lock; + + // + // Communicate request to SMM driver and fill in return values. + // + Status = SendCommBuffer (SmmCommunicateHeader, DataSize); + + return Status; +} + +EFI_STATUS +EFIAPI +SpiSetRange ( + IN UINTN SpiOffset, + IN UINTN Size, + IN BOOLEAN ReadLock, + IN BOOLEAN WriteLock + ) +{ + EFI_STATUS Status; + UINTN DataSize; + EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; + SMM_SPI_DEV_SET_RANGE_HEADER *SmmSpiDevSetRangeHeader; + + // + // Compute data size required for the transaction. + // + DataSize = sizeof(SMM_SPI_DEV_SET_RANGE_HEADER); + + // + // Create the communication buffer. + // + Status = CreateCommBuffer ((VOID**) &SmmCommunicateHeader, (VOID**) &SmmSpiDevSetRangeHeader, DataSize, SPI_DEV_FUNCTION_SET_RANGE); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Fill in communication buffer parameters. + // + SmmSpiDevSetRangeHeader->Offset = SpiOffset; + SmmSpiDevSetRangeHeader->Size = Size; + SmmSpiDevSetRangeHeader->ReadLock = ReadLock; + SmmSpiDevSetRangeHeader->WriteLock = WriteLock; + + // + // Communicate request to SMM driver and fill in return values. + // + Status = SendCommBuffer (SmmCommunicateHeader, DataSize); + + return Status; +} + +EFI_STATUS +EFIAPI +SpiLockRanges ( + ) +{ + EFI_STATUS Status; + EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; + + // + // Create the communication buffer. + // + Status = CreateCommBuffer ((VOID**) &SmmCommunicateHeader, NULL, 0, SPI_DEV_FUNCTION_LOCK_RANGES); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Communicate request to SMM driver and fill in return values. + // + Status = SendCommBuffer (SmmCommunicateHeader, 0); + + return Status; +} + +EFI_STATUS +EFIAPI +InitSpiDevice ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + VOID *SmmSpiDeviceReg; + + // + // Register for a callback when the SMM version of the SPI Device protocol + // is installed. + // + EfiCreateProtocolNotifyEvent ( + &gSmmSpiDeviceProtocolGuid, + TPL_CALLBACK, + SmmSpiDeviceReady, + NULL, + &SmmSpiDeviceReg + ); + + return EFI_SUCCESS; +} + +VOID +EFIAPI +SmmSpiDeviceReady ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_HANDLE Handle; + SPI_DEVICE_PROTOCOL *SmmSpiDevice; + EFI_STATUS Status; + + // + // Locate the protocol first just to make sure it was actually installed. + // + Status = gBS->LocateProtocol ( + &gSmmSpiDeviceProtocolGuid, + NULL, + (VOID **) &SmmSpiDevice + ); + if (EFI_ERROR (Status)) { + return; + } + + // + // SMM Service installed so get communication link to SMM + // + Status = gBS->LocateProtocol ( + &gEfiSmmCommunicationProtocolGuid, + NULL, + (VOID **) &mSmmComm + ); + ASSERT_EFI_ERROR (Status); + + // + // Install DXE protocol so it can be used by drivers. + // + Handle = NULL; + Status = gBS->InstallProtocolInterface ( + &Handle, + &gSpiDeviceProtocolGuid, + EFI_NATIVE_INTERFACE, + &mSpiDevProtocol + ); + ASSERT_EFI_ERROR (Status); +} diff --git a/BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDeviceSmmDxe.inf b/BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDeviceSmmDxe.inf new file mode 100644 index 0000000000..d7effc6668 --- /dev/null +++ b/BraswellPlatformPkg/Common/Flash/SpiDeviceDxe/SpiDeviceSmmDxe.inf @@ -0,0 +1,51 @@ +## @file +# SMM Based SPI Device Dxe Driver +# +# Adds platform support to configure the SPI controller with the correct values +# to be used when using software sequencing. This driver installs gSpiDeviceProtocolGuid +# protocol based on SMM based SPI device driver. +# +# Copyright (c) 2015, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010018 + BASE_NAME = SpiDeviceSmmDxe + FILE_GUID = D7AC2008-CFBE-44A4-AD92-573F1AB9DF45 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = InitSpiDevice + +[Sources] + SpiDeviceSmmDxe.c + SpiDevice.h + +[Packages] + ChvRefCodePkg/ChvRefCodePkg.dec + BraswellPlatformPkg/BraswellPlatformPkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + DebugLib + DxeServicesTableLib + UefiBootServicesTableLib + UefiDriverEntryPoint + +[Protocols] + gSpiDeviceProtocolGuid ## PRODUCES + gSmmSpiDeviceProtocolGuid ## CONSUMES + gEfiSmmCommunicationProtocolGuid ## CONSUMES + +[Depex] + gEfiSmmCommunicationProtocolGuid + diff --git a/BraswellPlatformPkg/Common/Flash/SpiFlashParts/MX25/MX25.c b/BraswellPlatformPkg/Common/Flash/SpiFlashParts/MX25/MX25.c new file mode 100644 index 0000000000..424dcc3186 --- /dev/null +++ b/BraswellPlatformPkg/Common/Flash/SpiFlashParts/MX25/MX25.c @@ -0,0 +1,208 @@ +/** @file + MACRONIX MX25*** family SPI flash support + + Copyright (c) 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include + +// +// Initialization data that can be used to identify SPI flash part +// DeviceId0 Device ID0 of the SPI device +// DeviceId1 Device ID1 of the SPI device +// +typedef struct _SPI_CHIP_ID { + UINT8 DeviceId0; + UINT8 DeviceId1; +} SPI_CHIP_ID; + +// +// Serial Flash VendorId and DeviceId +// +#define SF_VENDOR_ID_MACRONIX 0xC2 +#define SF_DEVICE_ID0_MX25LXX 0x20 +#define SF_DEVICE_ID0_MX25UXX 0x25 +#define SF_DEVICE_ID1_MX25L16 0x15 +#define SF_DEVICE_ID1_MX25L32 0x16 +#define SF_DEVICE_ID1_MX25L64 0x17 +#define SF_DEVICE_ID1_MX25L128 0x18 +#define SF_DEVICE_ID1_MX25U32 0x36 +#define SF_DEVICE_ID1_MX25U64 0x37 + +// +// Generic SPI flash part description +// +CONST FLASH_PART_DESCRIPTION mFlashDescription = { + L"MACRONIX MX25*** family", // Part number + 1, // Number of status bytes + 0x06, // Write enable + 0x50, // Write status enable + 3, // Length of JEDEC ID response + 8, // Number of opcodes in the table + + // Opcode table + { + {33000000, 3, FALSE, 0x9f, 0, SPI_FLASH_PART_OPCODE_JEDEC_ID}, + {50000000, 1, FALSE, 0x05, 0, SPI_FLASH_PART_OPCODE_READ_STATUS}, + {50000000, 1, TRUE, 0x01, 0, SPI_FLASH_PART_OPCODE_WRITE_STATUS}, + {33000000, 0xffffffff, FALSE, 0x03, 3, SPI_FLASH_PART_OPCODE_READ_BYTES}, + {50000000, 1, TRUE, 0x02, 3, SPI_FLASH_PART_OPCODE_WRITE_256_BYTE_PAGE}, + {50000000, 0, TRUE, 0x20, 3, SPI_FLASH_PART_OPCODE_ERASE_4K_BYTE_BLOCK}, + {50000000, 0, TRUE, 0xd8, 3, SPI_FLASH_PART_OPCODE_ERASE_64K_BYTE_BLOCK}, + {50000000, 0, TRUE, 0x5a, 0, SPI_FLASH_PART_OPCODE_WRITE_DISABLE_DISCOVERY} + } +}; + +SPI_CHIP_ID mSpiChipIdTable[] = { + { + SF_DEVICE_ID0_MX25LXX, // DeviceId 0 + SF_DEVICE_ID1_MX25L16 // DeviceId 1 + }, + { + SF_DEVICE_ID0_MX25LXX, // DeviceId 0 + SF_DEVICE_ID1_MX25L32 // DeviceId 1 + }, + { + SF_DEVICE_ID0_MX25LXX, // DeviceId 0 + SF_DEVICE_ID1_MX25L64 // DeviceId 1 + }, + { + SF_DEVICE_ID0_MX25LXX, // DeviceId 0 + SF_DEVICE_ID1_MX25L128 // DeviceId 1 + }, + { + SF_DEVICE_ID0_MX25UXX, // DeviceId 0 + SF_DEVICE_ID1_MX25U32 // DeviceId 1 + }, + { + SF_DEVICE_ID0_MX25UXX, // DeviceId 0 + SF_DEVICE_ID1_MX25U64 // DeviceId 1 + } +}; + +/** + Get the flash part size and opcode table. + + Validate support for this flash part and determine + the flash part size and opcode description table + from the JEDEC ID information provided. + + @param[in] This Pointer to a SPI_FLASH_DATA_PROTOCOL + data structure. + @param[in] JedecId Pointer to a three byte buffer containing + the JEDEC ID returned by the flash part. + If the input value is NULL then a + table containing the description for the + JEDEC ID opcode is returned by this + routine. + @param[out] FlashSize Pointer to receive the size of the flash + part in bytes. Zero (0) is returned when + JedecId is NULL. + @returns When JedecId is not NULL, this routine returns a pointer + to a FLASH_PART_DESCRIPTION data structure which supports + this flash part. The returned value is NULL if the flash + part is not supported. + When JedecId is NULL, this routine returns a pointer to + a FLASH_PART_DESCRIPTION structure which supports the + JEDEC ID command. This opcode description may be used + to determine the manufacture and product data for the + SPI flash part. + +**/ +CONST FLASH_PART_DESCRIPTION * +EFIAPI +GetFlashDescription ( + IN SPI_FLASH_PART_PROTOCOL *This, + IN UINT8 *JedecId OPTIONAL, + OUT UINT64 *FlashSize OPTIONAL + ) +{ + CONST FLASH_PART_DESCRIPTION *FlashDescription; + UINT8 Shift; + UINT64 Size; + UINTN Index; + + // + // Determine if the SPI flash device is supported + // + Size = 0; + FlashDescription = &mFlashDescription; + if (JedecId != NULL) { + FlashDescription = NULL; + if (JedecId [0] != SF_VENDOR_ID_MACRONIX) + return NULL; + + for (Index = 0;Index < (sizeof (mSpiChipIdTable) / sizeof (SPI_CHIP_ID));Index++) { + if ((JedecId [1] == mSpiChipIdTable[Index].DeviceId0) + && (JedecId [2] == mSpiChipIdTable[Index].DeviceId1)) + break; + } + + if (Index >= (sizeof (mSpiChipIdTable) / sizeof (SPI_CHIP_ID))) + return NULL; + + Shift = JedecId[2]; + + if (JedecId [1] == SF_DEVICE_ID0_MX25UXX) + Shift-= 0x20; + + if (Shift < 64) { + Size = LShiftU64 (1, Shift); + FlashDescription = &mFlashDescription; + } + } + + // + // Return the flash size + // + if (FlashSize != NULL) { + *FlashSize = Size; + } + + return FlashDescription; +} + +SPI_FLASH_PART_PROTOCOL mSpiFlashPartProtocol = { + 0xC0000000, /// SPI flash part family priority + GetFlashDescription +}; + +/** + Indicate that all the SPI devices are available + + @retval EFI_SUCCESS SPI flash part protocol installed successfully + +**/ +EFI_STATUS +EFIAPI +SpiFlashPart ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + // + // Install the SPI flash part protocol + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &gImageHandle, + &gSpiFlashPartProtocolGuid, + &mSpiFlashPartProtocol, + NULL + ); + + return Status; +} diff --git a/BraswellPlatformPkg/Common/Flash/SpiFlashParts/MX25/MX25.inf b/BraswellPlatformPkg/Common/Flash/SpiFlashParts/MX25/MX25.inf new file mode 100644 index 0000000000..aae1c00e9e --- /dev/null +++ b/BraswellPlatformPkg/Common/Flash/SpiFlashParts/MX25/MX25.inf @@ -0,0 +1,41 @@ +## @file +# MACRONIX* MX25*** family SPI flash support +# +# Copyright (c) 2015, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010018 + BASE_NAME = MX25XXX + FILE_GUID = FB7900FB-BC92-4a34-BFB6-8CC0E63B52FC + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = SpiFlashPart + +[Sources] + MX25.c + +[Packages] + MdePkg/MdePkg.dec + BraswellPlatformPkg/BraswellPlatformPkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + BaseLib + UefiBootServicesTableLib + +[Protocols] + gSpiFlashPartProtocolGuid ## PRODUCES + +[Depex] + TRUE + diff --git a/BraswellPlatformPkg/Common/Flash/SpiFlashParts/W25/W25.c b/BraswellPlatformPkg/Common/Flash/SpiFlashParts/W25/W25.c new file mode 100644 index 0000000000..b23351d23d --- /dev/null +++ b/BraswellPlatformPkg/Common/Flash/SpiFlashParts/W25/W25.c @@ -0,0 +1,192 @@ +/** @file + WINBOND W25*** family SPI flash support + + Copyright (c) 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include + + +// +// Initialization data that can be used to identify SPI flash part +// DeviceId0 Device ID0 of the SPI device +// DeviceId1 Device ID1 of the SPI device +// +typedef struct _SPI_CHIP_ID { + UINT8 DeviceId0; + UINT8 DeviceId1; +} SPI_CHIP_ID; + +// +// Flash VendorId and DeviceId +// + +#define SF_VENDOR_ID_WINBOND 0xEF +#define SF_DEVICE_ID0_W25XXX 0x30 +#define SF_DEVICE_ID1_W25X32 0x16 +#define SF_DEVICE_ID1_W25X64 0x17 +#define SF_DEVICE_ID0_W25QXX 0x60 +#define SF_DEVICE_ID0_W25QXX2 0x40 +#define SF_DEVICE_ID1_W25Q16 0x15 +#define SF_DEVICE_ID1_W25Q32 0x16 +#define SF_DEVICE_ID1_W25Q64 0x17 +#define SF_DEVICE_ID1_W25Q128 0x18 + +// +// Generic SPI flash part description +// +CONST FLASH_PART_DESCRIPTION mFlashDescription = { + L"WINBOND W25Q*** family", // Part number + 1, // Number of status bytes + 0x06, // Write enable + 0x50, // Write status enable + 3, // Length of JEDEC ID response + 8, // Number of opcodes in the table + + // Opcode table + { + {33000000, 3, FALSE, 0x9f, 0, SPI_FLASH_PART_OPCODE_JEDEC_ID}, + {50000000, 1, FALSE, 0x05, 0, SPI_FLASH_PART_OPCODE_READ_STATUS}, + {50000000, 1, TRUE, 0x01, 0, SPI_FLASH_PART_OPCODE_WRITE_STATUS}, + {33000000, 0xffffffff, FALSE, 0x03, 3, SPI_FLASH_PART_OPCODE_READ_BYTES}, + {50000000, 1, TRUE, 0x02, 3, SPI_FLASH_PART_OPCODE_WRITE_256_BYTE_PAGE}, + {50000000, 0, TRUE, 0x20, 3, SPI_FLASH_PART_OPCODE_ERASE_4K_BYTE_BLOCK}, + {50000000, 0, TRUE, 0xd8, 3, SPI_FLASH_PART_OPCODE_ERASE_64K_BYTE_BLOCK}, + {50000000, 0, TRUE, 0x5a, 0, SPI_FLASH_PART_OPCODE_WRITE_DISABLE_DISCOVERY} + } +}; + +SPI_CHIP_ID mSpiChipIdTable[] = { + { + SF_DEVICE_ID0_W25QXX, // DeviceId 0 + SF_DEVICE_ID1_W25Q64 // DeviceId 1 + }, + { + SF_DEVICE_ID0_W25QXX2, // DeviceId 0 + SF_DEVICE_ID1_W25Q64 // DeviceId 1 + } +}; + +/** + Get the flash part size and opcode table. + + Validate support for this flash part and determine + the flash part size and opcode description table + from the JEDEC ID information provided. + + @param[in] This Pointer to a SPI_FLASH_DATA_PROTOCOL + data structure. + @param[in] JedecId Pointer to a three byte buffer containing + the JEDEC ID returned by the flash part. + If the input value is NULL then a + table containing the description for the + JEDEC ID opcode is returned by this + routine. + @param[out] FlashSize Pointer to receive the size of the flash + part in bytes. Zero (0) is returned when + JedecId is NULL. + @returns When JedecId is not NULL, this routine returns a pointer + to a FLASH_PART_DESCRIPTION data structure which supports + this flash part. The returned value is NULL if the flash + part is not supported. + When JedecId is NULL, this routine returns a pointer to + a FLASH_PART_DESCRIPTION structure which supports the + JEDEC ID command. This opcode description may be used + to determine the manufacture and product data for the + SPI flash part. + +**/ +CONST FLASH_PART_DESCRIPTION * +EFIAPI +GetFlashDescription ( + IN SPI_FLASH_PART_PROTOCOL *This, + IN UINT8 *JedecId OPTIONAL, + OUT UINT64 *FlashSize OPTIONAL + ) +{ + CONST FLASH_PART_DESCRIPTION *FlashDescription; + UINT8 Shift; + UINT64 Size; + UINTN Index; + + // + // Determine if the SPI flash device is supported + // + Size = 0; + FlashDescription = &mFlashDescription; + if (JedecId != NULL) { + FlashDescription = NULL; + if (JedecId [0] != SF_VENDOR_ID_WINBOND) + return NULL; + + for (Index = 0;Index < (sizeof (mSpiChipIdTable) / sizeof (SPI_CHIP_ID));Index++) { + if ((JedecId [1] == mSpiChipIdTable[Index].DeviceId0) + && (JedecId [2] == mSpiChipIdTable[Index].DeviceId1)) + break; + } + + if (Index >= (sizeof (mSpiChipIdTable) / sizeof (SPI_CHIP_ID))) + return NULL; + + Shift = JedecId[2]; + if (Shift < 64) { + Size = LShiftU64 (1, Shift); + FlashDescription = &mFlashDescription; + } + } + + // + // Return the flash size + // + if (FlashSize != NULL) { + *FlashSize = Size; + } + + return FlashDescription; +} + +SPI_FLASH_PART_PROTOCOL mSpiFlashPartProtocol = { + 0xC0000000, /// SPI flash part family priority + GetFlashDescription +}; + +/** + Indicate that all the SPI devices are available + + @retval EFI_SUCCESS SPI flash part protocol installed successfully + +**/ +EFI_STATUS +EFIAPI +SpiFlashPart ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + // + // Install the SPI flash part protocol + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &gImageHandle, + &gSpiFlashPartProtocolGuid, + &mSpiFlashPartProtocol, + NULL + ); + + return Status; +} diff --git a/BraswellPlatformPkg/Common/Flash/SpiFlashParts/W25/W25.inf b/BraswellPlatformPkg/Common/Flash/SpiFlashParts/W25/W25.inf new file mode 100644 index 0000000000..d48ca15a09 --- /dev/null +++ b/BraswellPlatformPkg/Common/Flash/SpiFlashParts/W25/W25.inf @@ -0,0 +1,41 @@ +## @file +# WINBOND W25*** family SPI flash support +# +# Copyright (c) 2015, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010018 + BASE_NAME = W25XXX + FILE_GUID = 1EAFA124-4F73-45B3-B749-8E7F80741CE4 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = SpiFlashPart + +[Sources] + W25.c + +[Packages] + MdePkg/MdePkg.dec + BraswellPlatformPkg/BraswellPlatformPkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + BaseLib + UefiBootServicesTableLib + +[Protocols] + gSpiFlashPartProtocolGuid ## PRODUCES + +[Depex] + TRUE + diff --git a/BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbInfo.c b/BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbInfo.c deleted file mode 100644 index 15aae661e9..0000000000 --- a/BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbInfo.c +++ /dev/null @@ -1,369 +0,0 @@ -/** @file - Defines data structure that is the volume header found. - These data is intent to decouple FVB driver with FV header. - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include -#include "FvbService.h" - -#define FVB_MEDIA_BLOCK_SIZE PcdGet32(PcdFlashMinEraseSize) - -typedef struct { - EFI_PHYSICAL_ADDRESS BaseAddress; - EFI_FIRMWARE_VOLUME_HEADER FvbInfo; - // - //EFI_FV_BLOCK_MAP_ENTRY ExtraBlockMap[n];//n=0 - // - EFI_FV_BLOCK_MAP_ENTRY End[1]; -} EFI_FVB2_MEDIA_INFO; - -// -// This data structure contains a template of all correct FV headers, which is used to restore -// Fv header if it's corrupted. -// -EFI_FVB2_MEDIA_INFO mPlatformFvbMediaInfo[] = { - // - // Main BIOS FVB - // - { - 0, - { - {0,}, //ZeroVector[16] - EFI_FIRMWARE_FILE_SYSTEM2_GUID, - 0, - EFI_FVH_SIGNATURE, - 0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2 - sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY), - 0, //CheckSum, check the FD for the value. - 0, //ExtHeaderOffset - {0,}, //Reserved[1] - 2, //Revision - { - { - 0, - 0, - } - } - }, - { - { - 0, - 0 - } - } - }, - // - // Systen NvStorage FVB - // - { - 0, - { - {0,}, //ZeroVector[16] - EFI_SYSTEM_NV_DATA_FV_GUID, - 0, - EFI_FVH_SIGNATURE, - 0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2 - sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY), - 0, //CheckSum which will be calucated dynamically. - 0, //ExtHeaderOffset - {0,}, //Reserved[1] - 2, //Revision - { - { - 0, - 0, - } - } - }, - { - { - 0, - 0 - } - } - }, - // - // Recovery BIOS FVB - // - { - 0, - { - {0,}, //ZeroVector[16] - EFI_FIRMWARE_FILE_SYSTEM2_GUID, - 0, - EFI_FVH_SIGNATURE, - 0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2 - sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY), - 0, //CheckSum which will be calucated dynamically. - 0, //ExtHeaderOffset - {0,}, //Reserved[1] - 2, //Revision - { - { - 0, - 0, - } - } - }, - { - { - 0, - 0 - } - } - }, - // - // Recovery 2 BIOS FVB - // - { - 0, - { - {0,}, //ZeroVector[16] - EFI_FIRMWARE_FILE_SYSTEM2_GUID, - 0, - EFI_FVH_SIGNATURE, - 0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2 - sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY), - 0, //CheckSum which will be calucated dynamically. - 0, //ExtHeaderOffset - {0,}, //Reserved[1] - 2, //Revision - { - { - 0, - 0, - } - } - }, - { - { - 0, - 0 - } - } - }, - // - // Payload FVB - // - { - 0, - { - {0,}, //ZeroVector[16] - EFI_FIRMWARE_FILE_SYSTEM2_GUID, - 0, - EFI_FVH_SIGNATURE, - 0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2 - sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY), - 0, //CheckSum which will be calucated dynamically. - 0x60, //ExtHeaderOffset - {0,}, //Reserved[1] - 2, //Revision - { - { - 0, - 0, - } - } - }, - { - { - 0, - 0 - } - } - } -}; - -// -// FTW working space and FTW spare space don't have FV header. -// We need create one for them and use it for FVB protocol. -// -EFI_FVB2_MEDIA_INFO mPlatformFtwFvbInfo[] = { - // - // System variable FTW working FVB - // - { - 0, - { - {0,}, //ZeroVector[16] - EFI_SYSTEM_NV_DATA_FV_GUID, - 0, - EFI_FVH_SIGNATURE, - 0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2 - sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY), - 0, //CheckSum which will be calucated dynamically. - 0, //ExtHeaderOffset - {0,}, //Reserved[1] - 2, //Revision - { - { - 0, - 0, - } - } - }, - { - { - 0, - 0 - } - } - }, - // - // Systen NV variable FTW spare FVB - // - { - 0, - { - {0,}, //ZeroVector[16] - EFI_SYSTEM_NV_DATA_FV_GUID, - 0, - EFI_FVH_SIGNATURE, - 0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2 - sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY), - 0, //CheckSum which will be calucated dynamically. - 0, //ExtHeaderOffset - {0,}, //Reserved[1] - 2, //Revision - { - { - 0, - 0, - } - } - }, - { - { - 0, - 0 - } - } - } -}; - -EFI_STATUS -GetFtwFvbInfo ( - IN EFI_PHYSICAL_ADDRESS FvBaseAddress, - OUT EFI_FIRMWARE_VOLUME_HEADER **FvbInfo - ) -{ - UINTN Index; - EFI_FIRMWARE_VOLUME_HEADER *FvHeader; - - // - // Init Fvb data - // - mPlatformFtwFvbInfo[0].BaseAddress = PcdGet32 (PcdFlashNvStorageFtwWorkingBase); - mPlatformFtwFvbInfo[0].FvbInfo.FvLength = PcdGet32 (PcdFlashNvStorageFtwWorkingSize); - mPlatformFtwFvbInfo[0].FvbInfo.BlockMap[0].NumBlocks = PcdGet32 (PcdFlashNvStorageFtwWorkingSize) / FVB_MEDIA_BLOCK_SIZE; - mPlatformFtwFvbInfo[0].FvbInfo.BlockMap[0].Length = FVB_MEDIA_BLOCK_SIZE; - ASSERT ((PcdGet32 (PcdFlashNvStorageFtwWorkingSize) % FVB_MEDIA_BLOCK_SIZE) == 0); - - mPlatformFtwFvbInfo[1].BaseAddress = PcdGet32 (PcdFlashNvStorageFtwSpareBase); - mPlatformFtwFvbInfo[1].FvbInfo.FvLength = PcdGet32 (PcdFlashNvStorageFtwSpareSize); - mPlatformFtwFvbInfo[1].FvbInfo.BlockMap[0].NumBlocks = PcdGet32 (PcdFlashNvStorageFtwSpareSize) / FVB_MEDIA_BLOCK_SIZE; - mPlatformFtwFvbInfo[1].FvbInfo.BlockMap[0].Length = FVB_MEDIA_BLOCK_SIZE; - ASSERT ((PcdGet32 (PcdFlashNvStorageFtwSpareSize) % FVB_MEDIA_BLOCK_SIZE) == 0); - - for (Index=0; Index < sizeof (mPlatformFtwFvbInfo)/sizeof (mPlatformFtwFvbInfo[0]); Index += 1) { - if (mPlatformFtwFvbInfo[Index].BaseAddress == FvBaseAddress) { - FvHeader = &mPlatformFtwFvbInfo[Index].FvbInfo; - // - // Update the checksum value of FV header. - // - FvHeader->Checksum = CalculateCheckSum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16)); - - *FvbInfo = FvHeader; - - DEBUG ((EFI_D_INFO, "\nFTW BaseAddr: 0x%lx \n", FvBaseAddress)); - DEBUG ((EFI_D_INFO, "FvLength: 0x%lx \n", (*FvbInfo)->FvLength)); - DEBUG ((EFI_D_INFO, "HeaderLength: 0x%x \n", (*FvbInfo)->HeaderLength)); - DEBUG ((EFI_D_INFO, "FvBlockMap[0].NumBlocks: 0x%x \n", (*FvbInfo)->BlockMap[0].NumBlocks)); - DEBUG ((EFI_D_INFO, "FvBlockMap[0].BlockLength: 0x%x \n", (*FvbInfo)->BlockMap[0].Length)); - DEBUG ((EFI_D_INFO, "FvBlockMap[1].NumBlocks: 0x%x \n", (*FvbInfo)->BlockMap[1].NumBlocks)); - DEBUG ((EFI_D_INFO, "FvBlockMap[1].BlockLength: 0x%x \n\n", (*FvbInfo)->BlockMap[1].Length)); - - return EFI_SUCCESS; - } - } - - return EFI_NOT_FOUND; -} - -EFI_STATUS -GetFvbInfo ( - IN EFI_PHYSICAL_ADDRESS FvBaseAddress, - OUT EFI_FIRMWARE_VOLUME_HEADER **FvbInfo - ) -{ - UINTN Index; - EFI_FIRMWARE_VOLUME_HEADER *FvHeader; - - // - // Init Fvb data - // - mPlatformFvbMediaInfo[0].BaseAddress = PcdGet32 (PcdFlashFvMainBase); - mPlatformFvbMediaInfo[0].FvbInfo.FvLength = PcdGet32 (PcdFlashFvMainSize); - mPlatformFvbMediaInfo[0].FvbInfo.BlockMap[0].NumBlocks = PcdGet32 (PcdFlashFvMainSize) / FVB_MEDIA_BLOCK_SIZE; - mPlatformFvbMediaInfo[0].FvbInfo.BlockMap[0].Length = FVB_MEDIA_BLOCK_SIZE; - ASSERT ((PcdGet32 (PcdFlashFvMainSize) % FVB_MEDIA_BLOCK_SIZE) == 0); - - mPlatformFvbMediaInfo[1].BaseAddress = PcdGet32 (PcdFlashNvStorageVariableBase); - mPlatformFvbMediaInfo[1].FvbInfo.FvLength = PcdGet32 (PcdFlashNvStorageVariableSize); - mPlatformFvbMediaInfo[1].FvbInfo.BlockMap[0].NumBlocks = PcdGet32 (PcdFlashNvStorageVariableSize) / FVB_MEDIA_BLOCK_SIZE; - mPlatformFvbMediaInfo[1].FvbInfo.BlockMap[0].Length = FVB_MEDIA_BLOCK_SIZE; - ASSERT ((PcdGet32 (PcdFlashNvStorageVariableSize) % FVB_MEDIA_BLOCK_SIZE) == 0); - - mPlatformFvbMediaInfo[2].BaseAddress = PcdGet32 (PcdFlashFvRecoveryBase); - mPlatformFvbMediaInfo[2].FvbInfo.FvLength = PcdGet32 (PcdFlashFvRecoverySize); - mPlatformFvbMediaInfo[2].FvbInfo.BlockMap[0].NumBlocks = PcdGet32 (PcdFlashFvRecoverySize) / FVB_MEDIA_BLOCK_SIZE; - mPlatformFvbMediaInfo[2].FvbInfo.BlockMap[0].Length = FVB_MEDIA_BLOCK_SIZE; - ASSERT ((PcdGet32 (PcdFlashFvRecoverySize) % FVB_MEDIA_BLOCK_SIZE) == 0); - - mPlatformFvbMediaInfo[3].BaseAddress = PcdGet32 (PcdFlashFvRecovery2Base); - mPlatformFvbMediaInfo[3].FvbInfo.FvLength = PcdGet32 (PcdFlashFvRecovery2Size); - mPlatformFvbMediaInfo[3].FvbInfo.BlockMap[0].NumBlocks = PcdGet32 (PcdFlashFvRecovery2Size) / FVB_MEDIA_BLOCK_SIZE; - mPlatformFvbMediaInfo[3].FvbInfo.BlockMap[0].Length = FVB_MEDIA_BLOCK_SIZE; - ASSERT ((PcdGet32 (PcdFlashFvRecovery2Size) % FVB_MEDIA_BLOCK_SIZE) == 0); - - mPlatformFvbMediaInfo[4].BaseAddress = PcdGet32 (PcdFlashPayloadBase); - mPlatformFvbMediaInfo[4].FvbInfo.FvLength = PcdGet32 (PcdFlashPayloadSize); - mPlatformFvbMediaInfo[4].FvbInfo.BlockMap[0].NumBlocks = PcdGet32 (PcdFlashPayloadSize) / FVB_MEDIA_BLOCK_SIZE; - mPlatformFvbMediaInfo[4].FvbInfo.BlockMap[0].Length = FVB_MEDIA_BLOCK_SIZE; - ASSERT ((PcdGet32 (PcdFlashPayloadSize) % FVB_MEDIA_BLOCK_SIZE) == 0); - - for (Index=0; Index < sizeof (mPlatformFvbMediaInfo)/sizeof (mPlatformFvbMediaInfo[0]); Index += 1) { - if (mPlatformFvbMediaInfo[Index].BaseAddress == FvBaseAddress) { - FvHeader = &mPlatformFvbMediaInfo[Index].FvbInfo; - // - // Update the checksum value of FV header. - // - FvHeader->Checksum = CalculateCheckSum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16)); - - *FvbInfo = FvHeader; - - DEBUG ((EFI_D_INFO, "\nBaseAddr: 0x%lx \n", FvBaseAddress)); - DEBUG ((EFI_D_INFO, "FvLength: 0x%lx \n", (*FvbInfo)->FvLength)); - DEBUG ((EFI_D_INFO, "HeaderLength: 0x%x \n", (*FvbInfo)->HeaderLength)); - DEBUG ((EFI_D_INFO, "FvBlockMap[0].NumBlocks: 0x%x \n", (*FvbInfo)->BlockMap[0].NumBlocks)); - DEBUG ((EFI_D_INFO, "FvBlockMap[0].BlockLength: 0x%x \n", (*FvbInfo)->BlockMap[0].Length)); - DEBUG ((EFI_D_INFO, "FvBlockMap[1].NumBlocks: 0x%x \n", (*FvbInfo)->BlockMap[1].NumBlocks)); - DEBUG ((EFI_D_INFO, "FvBlockMap[1].BlockLength: 0x%x \n\n", (*FvbInfo)->BlockMap[1].Length)); - - return EFI_SUCCESS; - } - } - - return EFI_NOT_FOUND; -} diff --git a/BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbRuntimeDxe.inf b/BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbRuntimeDxe.inf deleted file mode 100644 index 347ed88159..0000000000 --- a/BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbRuntimeDxe.inf +++ /dev/null @@ -1,91 +0,0 @@ -## @file -# Firmware Volume Block access module -# -# Provides the ability to perform read, write and erase operations on a Firmware -# Volume. Read and write operations are possible at the byte level but the -# erase operation can only be done at the block level. -# -# Copyright (c) 2015, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php. -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010018 - BASE_NAME = FvbRuntimeDxe - FILE_GUID = 7CB9C516-E7AA-4582-86A2-371EA9B3AFA3 - MODULE_TYPE = DXE_RUNTIME_DRIVER - VERSION_STRING = 1.0 - ENTRY_POINT = DxeFvbInitialize - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 -# -# - -[Sources] - FvbInfo.c - FvbService.h - FvbService.c - FvbServiceDxe.c - -[Packages] - MdeModulePkg/MdeModulePkg.dec - MdePkg/MdePkg.dec - BraswellPlatformPkg/BraswellPlatformPkg.dec - -[LibraryClasses] - PcdLib - MemoryAllocationLib - CacheMaintenanceLib - IoLib - BaseMemoryLib - DebugLib - BaseLib - UefiLib - UefiRuntimeLib - UefiBootServicesTableLib - UefiDriverEntryPoint - HobLib - -[Guids] - gEfiFirmwareFileSystem2Guid ## SOMETIMES_CONSUMES ## GUID - gEfiSystemNvDataFvGuid ## SOMETIMES_CONSUMES ## GUID - gEfiEventVirtualAddressChangeGuid ## CONSUMES ## Event - -[Protocols] - gEfiDevicePathProtocolGuid ## SOMETIMES_PRODUCES - gEfiFirmwareVolumeBlockProtocolGuid ## PRODUCES - gSpiDeviceProtocolGuid ## CONSUMES - -[Pcd] - gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES - gPlatformModuleTokenSpaceGuid.PcdFlashFvMainBase ## CONSUMES - gPlatformModuleTokenSpaceGuid.PcdFlashFvMainSize ## CONSUMES - gPlatformModuleTokenSpaceGuid.PcdFlashFvRecoveryBase ## CONSUMES - gPlatformModuleTokenSpaceGuid.PcdFlashFvRecoverySize ## CONSUMES - gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Base ## CONSUMES - gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Size ## CONSUMES - gPlatformModuleTokenSpaceGuid.PcdFlashPayloadBase ## CONSUMES - gPlatformModuleTokenSpaceGuid.PcdFlashPayloadSize ## CONSUMES - - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize ## CONSUMES - gPlatformModuleTokenSpaceGuid.PcdFlashMinEraseSize ## CONSUMES - -[Depex] - gSpiDeviceProtocolGuid - diff --git a/BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbService.c b/BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbService.c deleted file mode 100644 index 1e5f151620..0000000000 --- a/BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbService.c +++ /dev/null @@ -1,1226 +0,0 @@ -/** @file - Firmware Volume Block Driver for Braswell Platform. - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "FvbService.h" - -// -// Global variable for this FVB driver which contains -// the private data of all firmware volume block instances -// -FWB_GLOBAL mFvbModuleGlobal; - -FV_MEMMAP_DEVICE_PATH mFvMemmapDevicePathTemplate = { - { - { - HARDWARE_DEVICE_PATH, - HW_MEMMAP_DP, - { - (UINT8)(sizeof (MEMMAP_DEVICE_PATH)), - (UINT8)(sizeof (MEMMAP_DEVICE_PATH) >> 8) - } - }, - EfiMemoryMappedIO, - (EFI_PHYSICAL_ADDRESS) 0, - (EFI_PHYSICAL_ADDRESS) 0, - }, - { - END_DEVICE_PATH_TYPE, - END_ENTIRE_DEVICE_PATH_SUBTYPE, - { - END_DEVICE_PATH_LENGTH, - 0 - } - } -}; - -FV_PIWG_DEVICE_PATH mFvPIWGDevicePathTemplate = { - { - { - MEDIA_DEVICE_PATH, - MEDIA_PIWG_FW_VOL_DP, - { - (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH)), - (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH) >> 8) - } - }, - { 0 } - }, - { - END_DEVICE_PATH_TYPE, - END_ENTIRE_DEVICE_PATH_SUBTYPE, - { - END_DEVICE_PATH_LENGTH, - 0 - } - } -}; - -// -// Template structure used when installing FVB protocol -// -EFI_FW_VOL_BLOCK_DEVICE mFvbDeviceTemplate = { - FVB_DEVICE_SIGNATURE, - NULL, - 0, // Instance - { - FvbProtocolGetAttributes, - FvbProtocolSetAttributes, - FvbProtocolGetPhysicalAddress, - FvbProtocolGetBlockSize, - FvbProtocolRead, - FvbProtocolWrite, - FvbProtocolEraseBlocks, - NULL - } // FwVolBlockInstance -}; - -SPI_DEVICE_PROTOCOL *mSpiDeviceProtocol; - -/** - Get the pointer to EFI_FW_VOL_INSTANCE from the buffer pointed - by mFvbModuleGlobal.FvInstance based on a index. - Each EFI_FW_VOL_INSTANCE is with variable length as - we have a block map at the end of the EFI_FIRMWARE_VOLUME_HEADER. - - @param[in] Instance The index of the EFI_FW_VOL_INSTANCE. - - @return A pointer to EFI_FW_VOL_INSTANCE. - -**/ -EFI_FW_VOL_INSTANCE * -GetFvbInstance ( - IN UINTN Instance - ) -{ - EFI_FW_VOL_INSTANCE *FwhRecord; - - if ( Instance >= mFvbModuleGlobal.NumFv ) { - ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); - return NULL; - } - - // - // Find the right instance of the FVB private data - // - FwhRecord = mFvbModuleGlobal.FvInstance; - while ( Instance > 0 ) { - FwhRecord = (EFI_FW_VOL_INSTANCE *) ((UINTN)((UINT8 *)FwhRecord) + - FwhRecord->VolumeHeader.HeaderLength + - (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))); - Instance --; - } - - return FwhRecord; -} - -/** - Get the EFI_FVB_ATTRIBUTES_2 of a FV. - - @param[in] The index of the EFI_FW_VOL_INSTANCE. - - @return EFI_FVB_ATTRIBUTES_2 of the FV identified by Instance. - -**/ -STATIC -EFI_FVB_ATTRIBUTES_2 -FvbGetVolumeAttributes ( - IN UINTN Instance - ) -{ - return GetFvbInstance (Instance)->VolumeHeader.Attributes; -} - -/** - Retrieves the starting address of an LBA in an FV. It also - return a few other attribut of the FV. - - @param[in] Instance The index of the EFI_FW_VOL_INSTANCE. - @param[in] Lba The logical block address - @param[out] FlashLinearAddress Provides the linear address into the flash device. - @param[out] LbaAddress On output, contains the physical starting address - of the Lba - @param[out] LbaLength On output, contains the length of the block - @param[out] NumOfBlocks A pointer to a caller allocated UINTN in which the - number of consecutive blocks starting with Lba is - returned. All blocks in this range have a size of - BlockSize - - @retval EFI_SUCCESS Successfully returns - @retval EFI_INVALID_PARAMETER Instance not found - -**/ -STATIC -EFI_STATUS -FvbGetLbaAddress ( - IN UINTN Instance, - IN EFI_LBA Lba, - OUT UINTN *FlashLinearAddress, - OUT UINTN *LbaAddress, - OUT UINTN *LbaLength, - OUT UINTN *NumOfBlocks - ) -{ - UINT32 NumBlocks; - UINT32 BlockLength; - UINTN Offset; - EFI_LBA StartLba; - EFI_LBA NextLba; - EFI_FW_VOL_INSTANCE *FwhInstance; - EFI_FV_BLOCK_MAP_ENTRY *BlockMap; - - // - // Find the right instance of the FVB private data - // - FwhInstance = GetFvbInstance (Instance); - - StartLba = 0; - Offset = 0; - BlockMap = &(FwhInstance->VolumeHeader.BlockMap[0]); - - // - // Parse the blockmap of the FV to find which map entry the Lba belongs to - // - while (TRUE) { - NumBlocks = BlockMap->NumBlocks; - BlockLength = BlockMap->Length; - - if (NumBlocks == 0 || BlockLength == 0) { - return EFI_INVALID_PARAMETER; - } - - NextLba = StartLba + NumBlocks; - - // - // The map entry found - // - if (Lba >= StartLba && Lba < NextLba) { - Offset = Offset + (UINTN)MultU64x32((Lba - StartLba), BlockLength); - if (FlashLinearAddress) { - *FlashLinearAddress = FwhInstance->FvFlashLinearAddress + Offset; - } - - if (LbaAddress) { - *LbaAddress = FwhInstance->FvBase + Offset; - } - - if (LbaLength) { - *LbaLength = BlockLength; - } - - if (NumOfBlocks) { - *NumOfBlocks = (UINTN)(NextLba - Lba); - } - return EFI_SUCCESS; - } - - StartLba = NextLba; - Offset = Offset + NumBlocks * BlockLength; - BlockMap++; - } -} - -/** - Reads specified number of bytes into a buffer from the specified block - - @param[in] Instance The FV instance to be read from - @param[in] Lba The logical block address to be read from - @param[in] BlockOffset Offset into the block at which to begin reading - @param[in] NumBytes Pointer that on input contains the total size of - the buffer. On output, it contains the total number - of bytes read - @param[in] Buffer Pointer to a caller allocated buffer that will be - used to hold the data read - - @retval EFI_SUCCESS The firmware volume was read successfully and - contents are in Buffer - @retval EFI_BAD_BUFFER_SIZE Read attempted across a LBA boundary. On output, - NumBytes contains the total number of bytes returned - in Buffer - @retval EFI_ACCESS_DENIED The firmware volume is in the ReadDisabled state - @retval EFI_DEVICE_ERROR The block device is not functioning correctly and - could not be read - @retval EFI_INVALID_PARAMETER Instance not found, or NumBytes, Buffer are NULL - -**/ -STATIC -EFI_STATUS -FvbReadBlock ( - IN UINTN Instance, - IN EFI_LBA Lba, - IN UINTN BlockOffset, - IN OUT UINTN *NumBytes, - IN UINT8 *Buffer - ) -{ - EFI_FVB_ATTRIBUTES_2 Attributes; - UINTN LbaLength; - EFI_STATUS Status; - EFI_STATUS Status1; - UINTN FlashAddress; - - // - // Validate input parameters. - // - if ((NumBytes == NULL) || (Buffer == NULL)) { - return (EFI_INVALID_PARAMETER); - } - if (*NumBytes == 0) { - return (EFI_INVALID_PARAMETER); - } - - // - // Get information for the specific LBA. - // - Status = FvbGetLbaAddress (Instance, Lba, &FlashAddress, NULL, &LbaLength, NULL); - if (EFI_ERROR (Status)) { - return EFI_INVALID_PARAMETER; - } - - // - // Check if operation can happen in the current state. - // - Attributes = FvbGetVolumeAttributes (Instance); - if ((Attributes & EFI_FVB2_READ_STATUS) == 0) { - return EFI_ACCESS_DENIED; - } - - // - // Check to make sure that block information is valid for the current FV and - // correct it if needed. - // - if (BlockOffset > LbaLength) { - return EFI_INVALID_PARAMETER; - } - if (LbaLength < (*NumBytes + BlockOffset)) { - *NumBytes = (UINT32) (LbaLength - BlockOffset); - Status = EFI_BAD_BUFFER_SIZE; - } - - // - // Perform read. - // - Status1 = mSpiDeviceProtocol->SpiRead (FlashAddress + BlockOffset, NumBytes, Buffer); - if (Status1 == EFI_DEVICE_ERROR) { - return Status1; - } - - return Status; -} - -/** - Writes specified number of bytes from the input buffer to the block - - @param[in] Instance The FV instance to be written to - @param[in] Lba The starting logical block index to write to - @param[in] BlockOffset Offset into the block at which to begin writing - @param[in] NumBytes Pointer that on input contains the total size of - the buffer. On output, it contains the total number - of bytes actually written - @param[in] Buffer Pointer to a caller allocated buffer that contains - the source for the write - @retval EFI_SUCCESS The firmware volume was written successfully - @retval EFI_BAD_BUFFER_SIZE Write attempted across a LBA boundary. On output, - NumBytes contains the total number of bytes - actually written - @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state - @retval EFI_DEVICE_ERROR The block device is not functioning correctly and - could not be written - @retval EFI_INVALID_PARAMETER Instance not found, or NumBytes, Buffer are NULL - -**/ -EFI_STATUS -FvbWriteBlock ( - IN UINTN Instance, - IN EFI_LBA Lba, - IN UINTN BlockOffset, - IN OUT UINTN *NumBytes, - IN UINT8 *Buffer - ) -{ - EFI_FVB_ATTRIBUTES_2 Attributes; - UINTN LbaAddress; - UINTN LbaLength; - EFI_FW_VOL_INSTANCE *FwhInstance; - EFI_STATUS Status; - EFI_STATUS Status1; - UINTN FlashAddress; - - // - // Validate input parameters. - // - if ((NumBytes == NULL) || (Buffer == NULL)) { - return (EFI_INVALID_PARAMETER); - } - if (*NumBytes == 0) { - return (EFI_INVALID_PARAMETER); - } - - // - // Get the information for the FV specified. - // - FwhInstance = GetFvbInstance (Instance); - Status = FvbGetLbaAddress (Instance, Lba, &FlashAddress, &LbaAddress, &LbaLength, NULL); - if (EFI_ERROR (Status)) { - return EFI_INVALID_PARAMETER; - } - - // - // Check if the FV is write enabled - // - Attributes = FvbGetVolumeAttributes (Instance); - if ((Attributes & EFI_FVB2_WRITE_STATUS) == 0) { - return EFI_ACCESS_DENIED; - } - - // - // Perform boundary checks and adjust NumBytes if needed. - // - if (BlockOffset > LbaLength) { - return EFI_INVALID_PARAMETER; - } - if ( LbaLength < ( *NumBytes + BlockOffset ) ) { - *NumBytes = (UINT32) (LbaLength - BlockOffset); - Status = EFI_BAD_BUFFER_SIZE; - } - - // - // Perform the write and flush the cache. - // - mSpiDeviceProtocol->SpiLock (FlashAddress, LbaLength, FALSE); - Status1 = mSpiDeviceProtocol->SpiWrite (FlashAddress + BlockOffset, NumBytes, Buffer); - mSpiDeviceProtocol->SpiLock (FlashAddress, LbaLength, TRUE); - WriteBackInvalidateDataCacheRange ((VOID *) (LbaAddress + BlockOffset), *NumBytes); - - // - // Determine the error to return based on PI spec. - // - if (Status1 == EFI_DEVICE_ERROR) { - return Status1; - } - - return Status; -} - -/** - Erases and initializes a firmware volume block - - @param[in] Instance The FV instance to be erased - @param[in] Lba The logical block index to be erased - - @retval EFI_SUCCESS The erase request was successfully completed - @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state - @retval EFI_DEVICE_ERROR The block device is not functioning correctly and - could not be written. Firmware device may have been - partially erased - @retval EFI_INVALID_PARAMETER Instance not found - -**/ -EFI_STATUS -FvbEraseBlock ( - IN UINTN Instance, - IN EFI_LBA Lba - ) -{ - EFI_FVB_ATTRIBUTES_2 Attributes; - UINTN LbaAddress; - EFI_FW_VOL_INSTANCE *FwhInstance; - UINTN LbaLength; - EFI_STATUS Status; - EFI_STATUS Status1; - UINTN FlashAddress; - - // - // Find the right instance of the FVB private data - // - FwhInstance = GetFvbInstance (Instance); - - // - // Check if the FV is write enabled - // - Attributes = FvbGetVolumeAttributes (Instance); - if ((Attributes & EFI_FVB2_WRITE_STATUS) == 0) { - return EFI_ACCESS_DENIED; - } - - // - // Get the starting address of the block for erase. - // - Status = FvbGetLbaAddress (Instance, Lba, &FlashAddress, &LbaAddress, &LbaLength, NULL); - if (EFI_ERROR (Status)) { - return EFI_INVALID_PARAMETER; - } - - // - // Perform erase. - // - mSpiDeviceProtocol->SpiLock (FlashAddress, LbaLength, FALSE); - Status1 = mSpiDeviceProtocol->SpiErase (FlashAddress, LbaLength); - mSpiDeviceProtocol->SpiLock (FlashAddress, LbaLength, TRUE); - WriteBackInvalidateDataCacheRange ((VOID *) LbaAddress, LbaLength); - - // - // Check to see if the erase was successful. If not return a device error to - // meet PI required return values. - // - if (Status1 == EFI_DEVICE_ERROR) { - return Status1; - } - - return EFI_SUCCESS; -} - -/** - Modifies the current settings of the firmware volume according to the - input parameter, and returns the new setting of the volume - - @param[in] Instance The FV instance whose attributes is going to be - modified - @param[in] Attributes On input, it is a pointer to EFI_FVB_ATTRIBUTES_2 - containing the desired firmware volume settings. - On successful return, it contains the new settings - of the firmware volume - - @retval EFI_SUCCESS Successfully returns - @retval EFI_ACCESS_DENIED The volume setting is locked and cannot be modified - @retval EFI_INVALID_PARAMETER Instance not found, or The attributes requested are - in conflict with the capabilities as declared in the - firmware volume header - -**/ -STATIC -EFI_STATUS -FvbSetVolumeAttributes ( - IN UINTN Instance, - IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes - ) -{ - EFI_FW_VOL_INSTANCE *FwhInstance; - EFI_FVB_ATTRIBUTES_2 OldAttributes; - EFI_FVB_ATTRIBUTES_2 *AttribPtr; - EFI_FVB_ATTRIBUTES_2 UnchangedAttributes; - UINT32 Capabilities; - UINT32 OldStatus, NewStatus; - - // - // Find the right instance of the FVB private data - // - FwhInstance = GetFvbInstance (Instance); - - AttribPtr = (EFI_FVB_ATTRIBUTES_2 *) &(FwhInstance->VolumeHeader.Attributes); - OldAttributes = *AttribPtr; - Capabilities = OldAttributes & EFI_FVB2_CAPABILITIES; - OldStatus = OldAttributes & EFI_FVB2_STATUS; - NewStatus = *Attributes & EFI_FVB2_STATUS; - - UnchangedAttributes = EFI_FVB2_READ_DISABLED_CAP | \ - EFI_FVB2_READ_ENABLED_CAP | \ - EFI_FVB2_WRITE_DISABLED_CAP | \ - EFI_FVB2_WRITE_ENABLED_CAP | \ - EFI_FVB2_LOCK_CAP | \ - EFI_FVB2_STICKY_WRITE | \ - EFI_FVB2_MEMORY_MAPPED | \ - EFI_FVB2_ERASE_POLARITY | \ - EFI_FVB2_READ_LOCK_CAP | \ - EFI_FVB2_WRITE_LOCK_CAP | \ - EFI_FVB2_ALIGNMENT; - - // - // Some attributes of FV is read only can *not* be set - // - if ((OldAttributes & UnchangedAttributes) ^ (*Attributes & UnchangedAttributes)) { - return EFI_INVALID_PARAMETER; - } - - // - // If firmware volume is locked, no status bit can be updated - // - if ( OldAttributes & EFI_FVB2_LOCK_STATUS ) { - if ( OldStatus ^ NewStatus ) { - return EFI_ACCESS_DENIED; - } - } - - // - // Test read disable - // - if ((Capabilities & EFI_FVB2_READ_DISABLED_CAP) == 0) { - if ((NewStatus & EFI_FVB2_READ_STATUS) == 0) { - return EFI_INVALID_PARAMETER; - } - } - - // - // Test read enable - // - if ((Capabilities & EFI_FVB2_READ_ENABLED_CAP) == 0) { - if (NewStatus & EFI_FVB2_READ_STATUS) { - return EFI_INVALID_PARAMETER; - } - } - - // - // Test write disable - // - if ((Capabilities & EFI_FVB2_WRITE_DISABLED_CAP) == 0) { - if ((NewStatus & EFI_FVB2_WRITE_STATUS) == 0) { - return EFI_INVALID_PARAMETER; - } - } - - // - // Test write enable - // - if ((Capabilities & EFI_FVB2_WRITE_ENABLED_CAP) == 0) { - if (NewStatus & EFI_FVB2_WRITE_STATUS) { - return EFI_INVALID_PARAMETER; - } - } - - // - // Test lock - // - if ((Capabilities & EFI_FVB2_LOCK_CAP) == 0) { - if (NewStatus & EFI_FVB2_LOCK_STATUS) { - return EFI_INVALID_PARAMETER; - } - } - - *AttribPtr = (*AttribPtr) & (0xFFFFFFFF & (~EFI_FVB2_STATUS)); - *AttribPtr = (*AttribPtr) | NewStatus; - *Attributes = *AttribPtr; - - return EFI_SUCCESS; -} - -// -// FVB protocol APIs -// - -/** - Retrieves the physical address of the device. - - @param[in] This A pointer to EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL. - @param[out] Address Output buffer containing the address. - - retval EFI_SUCCESS The function always return successfully. - -**/ -EFI_STATUS -EFIAPI -FvbProtocolGetPhysicalAddress ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - OUT EFI_PHYSICAL_ADDRESS *Address - ) -{ - EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; - - FvbDevice = FVB_DEVICE_FROM_THIS (This); - *Address = GetFvbInstance (FvbDevice->Instance)->FvBase; - - return EFI_SUCCESS; -} - -/** - Retrieve the size of a logical block - - @param[in] This Calling context - @param[in] Lba Indicates which block to return the size for. - @param[out] BlockSize A pointer to a caller allocated UINTN in which - the size of the block is returned - @param[out] NumOfBlocks A pointer to a caller allocated UINTN in which the - number of consecutive blocks starting with Lba is - returned. All blocks in this range have a size of - BlockSize - - @retval EFI_SUCCESS The function always return successfully. - -**/ -EFI_STATUS -EFIAPI -FvbProtocolGetBlockSize ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - IN EFI_LBA Lba, - OUT UINTN *BlockSize, - OUT UINTN *NumOfBlocks - ) -{ - EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; - - FvbDevice = FVB_DEVICE_FROM_THIS (This); - return FvbGetLbaAddress ( - FvbDevice->Instance, - Lba, - NULL, - NULL, - BlockSize, - NumOfBlocks - ); -} - -/** - Retrieves Volume attributes. No polarity translations are done. - - @param[in] This Calling context - @param[out] Attributes Output buffer which contains attributes - - @retval EFI_SUCCESS The function always return successfully. - -**/ -EFI_STATUS -EFIAPI -FvbProtocolGetAttributes ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - OUT EFI_FVB_ATTRIBUTES_2 *Attributes - ) -{ - EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; - - FvbDevice = FVB_DEVICE_FROM_THIS (This); - *Attributes = FvbGetVolumeAttributes (FvbDevice->Instance); - - return EFI_SUCCESS; -} - -/** - Sets Volume attributes. No polarity translations are done. - - @param[in] This Calling context - @param[out] Attributes Output buffer which contains attributes - - @retval EFI_SUCCESS The function always return successfully. - -**/ -EFI_STATUS -EFIAPI -FvbProtocolSetAttributes ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes - ) -{ - EFI_STATUS Status; - EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; - - FvbDevice = FVB_DEVICE_FROM_THIS (This); - Status = FvbSetVolumeAttributes (FvbDevice->Instance, Attributes); - - return Status; -} - -/** - The EraseBlock() function erases one or more blocks as denoted by the - variable argument list. The entire parameter list of blocks must be verified - prior to erasing any blocks. If a block is requested that does not exist - within the associated firmware volume (it has a larger index than the last - block of the firmware volume), the EraseBlock() function must return - EFI_INVALID_PARAMETER without modifying the contents of the firmware volume. - - @param[in] This Calling context - @param[in] ... Starting LBA followed by Number of Lba to erase. - a -1 to terminate the list. - - @retval EFI_SUCCESS The erase request was successfully completed - @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state - @retval EFI_DEVICE_ERROR The block device is not functioning correctly and - could not be written. Firmware device may have been - partially erased - -**/ -EFI_STATUS -EFIAPI -FvbProtocolEraseBlocks ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - ... - ) -{ - EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; - EFI_FW_VOL_INSTANCE *FwhInstance; - UINTN NumOfBlocks; - VA_LIST args; - EFI_LBA StartingLba; - UINTN NumOfLba; - EFI_STATUS Status; - EFI_FVB_ATTRIBUTES_2 Attributes; - - // - // Initialize data. - // - FvbDevice = FVB_DEVICE_FROM_THIS (This); - FwhInstance = GetFvbInstance (FvbDevice->Instance); - NumOfBlocks = FwhInstance->NumOfBlocks; - - // - // Check if this FV can be written to. - // - Attributes = FvbGetVolumeAttributes (FvbDevice->Instance); - if ((Attributes & EFI_FVB2_WRITE_STATUS) == 0) { - return EFI_ACCESS_DENIED; - } - - // - // Validate LBA information passed in by caller. - // - VA_START (args, This); - do { - // - // Check for last entry in variable argument list. - // - StartingLba = VA_ARG (args, EFI_LBA); - if (StartingLba == EFI_LBA_LIST_TERMINATOR) { - break; - } - - // - // Get parameter from stack. - // - NumOfLba = VA_ARG (args, UINT32); - - // - // Check input parameters - // - if (NumOfLba == 0) { - VA_END (args); - return EFI_INVALID_PARAMETER; - } - if ((StartingLba + NumOfLba) > NumOfBlocks) { - VA_END (args); - return EFI_INVALID_PARAMETER; - } - } while (1); - VA_END (args); - - // - // Perform erase operation on all selected LBA. - // - VA_START (args, This); - do { - // - // Check for last entry in variable argument list. - // - StartingLba = VA_ARG (args, EFI_LBA); - if (StartingLba == EFI_LBA_LIST_TERMINATOR) { - break; - } - - // - // Get parameter from stack. - // - NumOfLba = VA_ARG (args, UINT32); - - // - // Perform the erase operation for the specific LBA. - // - while (NumOfLba > 0) { - Status = FvbEraseBlock (FvbDevice->Instance, StartingLba); - if (EFI_ERROR (Status)) { - VA_END (args); - return Status; - } - StartingLba ++; - NumOfLba --; - } - } while (1); - VA_END (args); - - return EFI_SUCCESS; -} - -/** - Writes data beginning at Lba:Offset from FV. The write terminates either - when *NumBytes of data have been written, or when a block boundary is - reached. *NumBytes is updated to reflect the actual number of bytes - written. The write opertion does not include erase. This routine will - attempt to write only the specified bytes. If the writes do not stick, - it will return an error. - - @param[in] This Calling context - @param[in] Lba Block in which to begin write - @param[in] Offset Offset in the block at which to begin write - @param[in, out] NumBytes On input, indicates the requested write size. On - output, indicates the actual number of bytes written - @param[in] Buffer Buffer containing source data for the write. - - @retval EFI_SUCCESS The firmware volume was written successfully - @retval EFI_BAD_BUFFER_SIZE Write attempted across a LBA boundary. On output, - NumBytes contains the total number of bytes - actually written - @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state - @retval EFI_DEVICE_ERROR The block device is not functioning correctly and - could not be written - @retval EFI_INVALID_PARAMETER NumBytes or Buffer are NULL - -**/ -EFI_STATUS -EFIAPI -FvbProtocolWrite ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - IN EFI_LBA Lba, - IN UINTN Offset, - IN OUT UINTN *NumBytes, - IN UINT8 *Buffer - ) -{ - EFI_STATUS Status; - EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; - - FvbDevice = FVB_DEVICE_FROM_THIS (This); - Status = FvbWriteBlock (FvbDevice->Instance, Lba, Offset, NumBytes, Buffer); - - return Status; -} - -/** - Reads data beginning at Lba:Offset from FV. The Read terminates either - when *NumBytes of data have been read, or when a block boundary is - reached. *NumBytes is updated to reflect the actual number of bytes - written. The write opertion does not include erase. This routine will - attempt to write only the specified bytes. If the writes do not stick, - it will return an error. - - @param[in] This Calling context - @param[in] Lba Block in which to begin write - @param[in] Offset Offset in the block at which to begin write - @param[in, out] NumBytes On input, indicates the requested write size. On - output, indicates the actual number of bytes written - @param[in] Buffer Buffer containing source data for the write. - -Returns: - @retval EFI_SUCCESS The firmware volume was read successfully and - contents are in Buffer - @retval EFI_BAD_BUFFER_SIZE Read attempted across a LBA boundary. On output, - NumBytes contains the total number of bytes returned - in Buffer - @retval EFI_ACCESS_DENIED The firmware volume is in the ReadDisabled state - @retval EFI_DEVICE_ERROR The block device is not functioning correctly and - could not be read - @retval EFI_INVALID_PARAMETER NumBytes or Buffer are NULL - -**/ -EFI_STATUS -EFIAPI -FvbProtocolRead ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - IN EFI_LBA Lba, - IN UINTN Offset, - IN OUT UINTN *NumBytes, - OUT UINT8 *Buffer - ) -{ - - EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; - EFI_STATUS Status; - - FvbDevice = FVB_DEVICE_FROM_THIS (This); - Status = FvbReadBlock (FvbDevice->Instance, Lba, Offset, NumBytes, Buffer); - - return Status; -} - -/** - Check the integrity of firmware volume header - - @param[in] FwVolHeader A pointer to a firmware volume header - - @retval TRUE The firmware volume is consistent - @retval FALSE The firmware volume has corrupted. - -**/ -STATIC -BOOLEAN -IsFvHeaderValid ( - IN EFI_PHYSICAL_ADDRESS FvBase, - IN CONST EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader - ) -{ - UINT16 Checksum; - - if (FvBase == PcdGet32(PcdFlashNvStorageVariableBase)) { - if (CompareMem (&FwVolHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid, sizeof(EFI_GUID)) != 0 ) { - return FALSE; - } - } else { - if (CompareMem (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystem2Guid, sizeof(EFI_GUID)) != 0 ) { - return FALSE; - } - } - if ((FwVolHeader->Revision != EFI_FVH_REVISION) || - (FwVolHeader->Signature != EFI_FVH_SIGNATURE) || - (FwVolHeader->FvLength == ((UINTN) -1)) || - ((FwVolHeader->HeaderLength & 0x01 ) !=0)) { - return FALSE; - } - - Checksum = CalculateCheckSum16 ((UINT16 *) FwVolHeader, FwVolHeader->HeaderLength); - if (Checksum != 0) { - DEBUG (( DEBUG_ERROR, - "ERROR - Invalid Firmware Volume Header Checksum, change 0x%04x to 0x%04x\r\n", - FwVolHeader->Checksum, - (UINT16)( Checksum + FwVolHeader->Checksum ))); - return FALSE; - } - - return TRUE; -} - -/** - The driver entry point for Firmware Volume Block Driver. - - The function does the necessary initialization work - Firmware Volume Block Driver. - - @param[in] ImageHandle The firmware allocated handle for the UEFI image. - @param[in] SystemTable A pointer to the EFI system table. - - @retval EFI_SUCCESS This funtion always return EFI_SUCCESS. - It will ASSERT on errors. - -**/ -EFI_STATUS -FvbInitialize ( - ) -{ - EFI_FW_VOL_INSTANCE *FwhInstance; - EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; - EFI_FIRMWARE_VOLUME_HEADER *FvHeader; - EFI_FV_BLOCK_MAP_ENTRY *PtrBlockMapEntry; - EFI_PHYSICAL_ADDRESS BaseAddress; - EFI_STATUS Status; - UINTN BufferSize; - UINTN TmpHeaderLength; - UINTN Idx; - UINT32 MaxLbaSize; - BOOLEAN FvHeaderValid; - UINTN FvFlashLinearAddress; - EFI_BOOT_MODE BootMode; - UINT32 Index; - UINT32 PlatformFvBaseAddress[5]; - UINT32 PlatformFvBaseAddressCount; - UINT32 PlatformFvLockList[4]; - UINT32 PlatformFvLockListCount; - - // - // This platform driver knows there are 3 FVs on - // FD, which are FvRecovery, FvMain and FvNvStorage. - // - BootMode = GetBootModeHob (); - if (BootMode == BOOT_IN_RECOVERY_MODE) { - // - // On recovery boot, don't report any firmware FV images except payload, because their data can't be trusted. - // - PlatformFvBaseAddressCount = 2; - PlatformFvBaseAddress[0] = PcdGet32 (PcdFlashNvStorageVariableBase); - PlatformFvBaseAddress[1] = PcdGet32 (PcdFlashPayloadBase); - } else { - PlatformFvBaseAddressCount = 5; - PlatformFvBaseAddress[0] = PcdGet32 (PcdFlashFvMainBase); - PlatformFvBaseAddress[1] = PcdGet32 (PcdFlashNvStorageVariableBase); - PlatformFvBaseAddress[2] = PcdGet32 (PcdFlashFvRecoveryBase); - PlatformFvBaseAddress[3] = PcdGet32 (PcdFlashFvRecovery2Base); - PlatformFvBaseAddress[4] = PcdGet32 (PcdFlashPayloadBase); - } - - // - // List of FVs that should be write protected on normal boots. - // - PlatformFvLockListCount = 4; - PlatformFvLockList[0] = PcdGet32 (PcdFlashFvMainBase); - PlatformFvLockList[1] = PcdGet32 (PcdFlashFvRecoveryBase); - PlatformFvLockList[2] = PcdGet32 (PcdFlashFvRecovery2Base); - PlatformFvLockList[3] = PcdGet32 (PcdFlashPayloadBase); - - // - // Calculate the total size for all firmware volume block instances and - // allocate a buffer to store them in. - // - BufferSize = 0; - for (Idx = 0; Idx < PlatformFvBaseAddressCount; Idx++) { - FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PlatformFvBaseAddress[Idx]; - if (FvHeader == NULL) { - continue; - } - BufferSize += (FvHeader->HeaderLength + - sizeof (EFI_FW_VOL_INSTANCE) - - sizeof (EFI_FIRMWARE_VOLUME_HEADER) - ); - } - mFvbModuleGlobal.FvInstance = (EFI_FW_VOL_INSTANCE *) AllocateRuntimeZeroPool (BufferSize); - ASSERT (NULL != mFvbModuleGlobal.FvInstance); - - // - // Perform other variable initialization. - // - MaxLbaSize = 0; - FwhInstance = mFvbModuleGlobal.FvInstance; - mFvbModuleGlobal.NumFv = 0; - - for (Idx = 0; Idx < PlatformFvBaseAddressCount; Idx++) { - - if ((BootMode == BOOT_ASSUMING_NO_CONFIGURATION_CHANGES) && PlatformFvBaseAddress[Idx]!= PcdGet32 (PcdFlashNvStorageVariableBase) && PlatformFvBaseAddress[Idx]!= PcdGet32 (PcdFlashPayloadBase)) { - continue; - } - // - // Get base address information. - // - BaseAddress = PlatformFvBaseAddress[Idx]; - FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) BaseAddress; - if (FwVolHeader == NULL) { - continue; - } - // - // Find the flash linear address of the current FV. - // - FvFlashLinearAddress = (UINTN) FLASH_LINEAR_ADDRESS(BaseAddress); - - if (!IsFvHeaderValid (BaseAddress, FwVolHeader)) { - FvHeaderValid = FALSE; - - // - // If not valid, get FvbInfo from the information carried in - // FVB driver. - // - DEBUG ((EFI_D_ERROR, "Fvb: FV header @ 0x%lx invalid\n", BaseAddress)); - Status = GetFvbInfo (BaseAddress, &FwVolHeader); - ASSERT_EFI_ERROR(Status); - - // - // Write back a healthy FV header. - // - DEBUG ((EFI_D_INFO, "FwBlockService.c: Writing back healthy FV header\n")); - mSpiDeviceProtocol->SpiLock (FvFlashLinearAddress, FwVolHeader->BlockMap->Length, FALSE); - - Status = mSpiDeviceProtocol->SpiErase (FvFlashLinearAddress, FwVolHeader->BlockMap->Length); - - TmpHeaderLength = (UINTN) FwVolHeader->HeaderLength; - Status = mSpiDeviceProtocol->SpiWrite ( - FvFlashLinearAddress, - &TmpHeaderLength, - (UINT8 *) FwVolHeader - ); - - mSpiDeviceProtocol->SpiLock (FvFlashLinearAddress, FwVolHeader->BlockMap->Length, TRUE); - - WriteBackInvalidateDataCacheRange ( - (VOID *) (UINTN) BaseAddress, - FwVolHeader->BlockMap->Length - ); - - } - - // - // Copy FV header into local storage and assign base address. - // - CopyMem (&(FwhInstance->VolumeHeader), FwVolHeader, FwVolHeader->HeaderLength); - FwVolHeader = &(FwhInstance->VolumeHeader); - FwhInstance->FvBase = (UINTN)BaseAddress; - FwhInstance->FvFlashLinearAddress = FvFlashLinearAddress; - - // - // In some cases the Recovery and Main FVs should be considered locked from - // write access by this protocol. Only in the case of flash updates and - // configuration mode should they be left unlocked. - // - if (BootMode != BOOT_IN_RECOVERY_MODE && - BootMode != BOOT_ON_FLASH_UPDATE) { - for (Index = 0; Index < PlatformFvLockListCount; Index++) { - if (FwhInstance->FvBase == PlatformFvLockList[Index]) { - // - // For all FVs in the lock list we need to clear the write status bit - // and lock write status updates. This will make sure this protocol - // will not attempt to write to the FV. - // - FwhInstance->VolumeHeader.Attributes &= (UINT64) ~EFI_FVB2_WRITE_STATUS; - FwhInstance->VolumeHeader.Attributes |= (EFI_FVB2_LOCK_STATUS | EFI_FVB2_WRITE_LOCK_STATUS); - } - } - } - - // - // Process the block map for each FV - // - FwhInstance->NumOfBlocks = 0; - for (PtrBlockMapEntry = FwVolHeader->BlockMap; - PtrBlockMapEntry->NumBlocks != 0; - PtrBlockMapEntry++) { - // - // Get the maximum size of a block. - // - if (MaxLbaSize < PtrBlockMapEntry->Length) { - MaxLbaSize = PtrBlockMapEntry->Length; - } - FwhInstance->NumOfBlocks += PtrBlockMapEntry->NumBlocks; - } - - // - // Add a FVB Protocol Instance - // - mFvbModuleGlobal.NumFv++; - InstallFvbProtocol (FwhInstance, mFvbModuleGlobal.NumFv - 1); - - // - // Move on to the next FwhInstance - // - FwhInstance = (EFI_FW_VOL_INSTANCE *) ((UINTN)((UINT8 *)FwhInstance) + - FwVolHeader->HeaderLength + - (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))); - } - - if ((PcdGet32 (PcdFlashNvStorageFtwWorkingBase) == 0) || (PcdGet32 (PcdFlashNvStorageFtwSpareBase) == 0)) { - return EFI_SUCCESS; - } - - // - // Install FVB protocols for FTW spare space and FTW working space. - // These is no FV header for these 2 spaces. - // - mFvbModuleGlobal.FvInstance = (EFI_FW_VOL_INSTANCE *) ReallocateRuntimePool ( - BufferSize, - BufferSize + (sizeof (EFI_FW_VOL_INSTANCE) + sizeof (EFI_FV_BLOCK_MAP_ENTRY)) * 2, - mFvbModuleGlobal.FvInstance - ); - ASSERT (NULL != mFvbModuleGlobal.FvInstance); - PlatformFvBaseAddress[0] = PcdGet32 (PcdFlashNvStorageFtwWorkingBase); - PlatformFvBaseAddress[1] = PcdGet32 (PcdFlashNvStorageFtwSpareBase); - - for (Idx = 0; Idx < 2; Idx++) { - BaseAddress = PlatformFvBaseAddress[Idx]; - Status = GetFtwFvbInfo (BaseAddress, &FwVolHeader); - ASSERT_EFI_ERROR(Status); - - // - // Copy FV header into local storage and assign base address. - // - mFvbModuleGlobal.NumFv++; - FwhInstance = GetFvbInstance (mFvbModuleGlobal.NumFv - 1); - CopyMem (&(FwhInstance->VolumeHeader), FwVolHeader, FwVolHeader->HeaderLength); - FwVolHeader = &(FwhInstance->VolumeHeader); - - // - // Process the block map for each FV - // - FwhInstance->NumOfBlocks = 0; - for (PtrBlockMapEntry = FwVolHeader->BlockMap; - PtrBlockMapEntry->NumBlocks != 0; - PtrBlockMapEntry++) { - FwhInstance->NumOfBlocks += PtrBlockMapEntry->NumBlocks; - } - - FwhInstance->FvBase = (UINTN)BaseAddress; - FwhInstance->FvFlashLinearAddress = (UINTN) FLASH_LINEAR_ADDRESS(BaseAddress); - - InstallFvbProtocol (FwhInstance, mFvbModuleGlobal.NumFv - 1); - } - - return EFI_SUCCESS; -} - diff --git a/BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbService.h b/BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbService.h deleted file mode 100644 index ed9e579307..0000000000 --- a/BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbService.h +++ /dev/null @@ -1,187 +0,0 @@ -/** @file - The header file for Firmware volume block driver. - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _FW_BLOCK_SERVICE_H -#define _FW_BLOCK_SERVICE_H - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// -// Define two helper macro to extract the Capability field or Status field in FVB -// bit fields -// -#define EFI_FVB2_CAPABILITIES (EFI_FVB2_READ_DISABLED_CAP | \ - EFI_FVB2_READ_ENABLED_CAP | \ - EFI_FVB2_WRITE_DISABLED_CAP | \ - EFI_FVB2_WRITE_ENABLED_CAP | \ - EFI_FVB2_LOCK_CAP \ - ) - -#define EFI_FVB2_STATUS (EFI_FVB2_READ_STATUS | EFI_FVB2_WRITE_STATUS | EFI_FVB2_LOCK_STATUS) - -typedef struct { - UINTN FvBase; - UINTN NumOfBlocks; - UINTN FvFlashLinearAddress; - // - // Note!!!: VolumeHeader must be the last element - // of the structure. - // - EFI_FIRMWARE_VOLUME_HEADER VolumeHeader; -} EFI_FW_VOL_INSTANCE; - -typedef struct { - EFI_FW_VOL_INSTANCE *FvInstance; - UINT32 NumFv; -} FWB_GLOBAL; - -// -// Fvb Protocol instance data -// -#define FVB_DEVICE_FROM_THIS(a) CR(a, EFI_FW_VOL_BLOCK_DEVICE, FwVolBlockInstance, FVB_DEVICE_SIGNATURE) -#define FVB_EXTEND_DEVICE_FROM_THIS(a) CR(a, EFI_FW_VOL_BLOCK_DEVICE, FvbExtension, FVB_DEVICE_SIGNATURE) -#define FVB_DEVICE_SIGNATURE SIGNATURE_32('F','V','B','C') - -typedef struct { - MEDIA_FW_VOL_DEVICE_PATH FvDevPath; - EFI_DEVICE_PATH_PROTOCOL EndDevPath; -} FV_PIWG_DEVICE_PATH; - -typedef struct { - MEMMAP_DEVICE_PATH MemMapDevPath; - EFI_DEVICE_PATH_PROTOCOL EndDevPath; -} FV_MEMMAP_DEVICE_PATH; - -typedef struct { - UINT32 Signature; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - UINTN Instance; - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL FwVolBlockInstance; -} EFI_FW_VOL_BLOCK_DEVICE; - -EFI_STATUS -GetFvbInfo ( - IN EFI_PHYSICAL_ADDRESS FvBaseAddress, - OUT EFI_FIRMWARE_VOLUME_HEADER **FvbInfo - ); - -EFI_STATUS -GetFtwFvbInfo ( - IN EFI_PHYSICAL_ADDRESS FvBaseAddress, - OUT EFI_FIRMWARE_VOLUME_HEADER **FvbInfo - ); - -VOID -InstallFvbProtocol ( - IN EFI_FW_VOL_INSTANCE *FwhInstance, - IN UINTN InstanceNum - ); - -EFI_STATUS -FvbInitialize ( - ); - -EFI_FW_VOL_INSTANCE * -GetFvbInstance ( - IN UINTN Instance - ); - -// -// Protocol APIs -// -EFI_STATUS -EFIAPI -FvbProtocolGetAttributes ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - OUT EFI_FVB_ATTRIBUTES_2 *Attributes - ); - -EFI_STATUS -EFIAPI -FvbProtocolSetAttributes ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes - ); - -EFI_STATUS -EFIAPI -FvbProtocolGetPhysicalAddress ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - OUT EFI_PHYSICAL_ADDRESS *Address - ); - -EFI_STATUS -EFIAPI -FvbProtocolGetBlockSize ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - IN EFI_LBA Lba, - OUT UINTN *BlockSize, - OUT UINTN *NumOfBlocks - ); - -EFI_STATUS -EFIAPI -FvbProtocolRead ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - IN EFI_LBA Lba, - IN UINTN Offset, - IN OUT UINTN *NumBytes, - OUT UINT8 *Buffer - ); - -EFI_STATUS -EFIAPI -FvbProtocolWrite ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - IN EFI_LBA Lba, - IN UINTN Offset, - IN OUT UINTN *NumBytes, - IN UINT8 *Buffer - ); - -EFI_STATUS -EFIAPI -FvbProtocolEraseBlocks ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - ... - ); - -extern FWB_GLOBAL mFvbModuleGlobal; -extern EFI_FW_VOL_BLOCK_DEVICE mFvbDeviceTemplate; -extern FV_PIWG_DEVICE_PATH mFvPIWGDevicePathTemplate; -extern FV_MEMMAP_DEVICE_PATH mFvMemmapDevicePathTemplate; -extern SPI_DEVICE_PROTOCOL *mSpiDeviceProtocol; - -#endif - diff --git a/BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbServiceDxe.c b/BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbServiceDxe.c deleted file mode 100644 index 26effe7181..0000000000 --- a/BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbServiceDxe.c +++ /dev/null @@ -1,197 +0,0 @@ -/** @file - Firmware Volume Block Driver for Tunnel Mountain Platform. - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include -#include -#include -#include "FvbService.h" - -/** - Call back function on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event. - - Fixup internal data so that the driver is callable in EFI runtime - in virtual mode. Convert the mFvbModuleGlobal date items to there - virtual address. - - @param[in] Event Event whose notification function is being invoked. - @param[in] Context The context of the Notification context. Not used in - this call back function. - -**/ -VOID -EFIAPI -FvbVirtualddressChangeEvent ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - EFI_FW_VOL_INSTANCE *FwhInstance; - UINTN Index; - - // - // Convert the base address of all the instances - // - for (Index = 0; Index < mFvbModuleGlobal.NumFv; Index++) { - FwhInstance = GetFvbInstance (Index); - EfiConvertPointer (0, (VOID **) &FwhInstance->FvBase); - } - - EfiConvertPointer (0, (VOID **) &mFvbModuleGlobal.FvInstance); - - EfiConvertPointer (0, (VOID **)&mSpiDeviceProtocol); -} - -/** - The function installs EFI_FIRMWARE_VOLUME_BLOCK protocol - for each FV in the system. - - @param[in] FwhInstance The pointer to a FW volume instance structure, - which contains the information about one FV. - @param[in] InstanceNum The instance number which can be used as a ID - to locate this FwhInstance in other functions. - - @retval VOID - -**/ -VOID -InstallFvbProtocol ( - IN EFI_FW_VOL_INSTANCE *FwhInstance, - IN UINTN InstanceNum - ) -{ - EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; - EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; - EFI_STATUS Status; - EFI_HANDLE FwbHandle; - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *OldFwbInterface; - - FvbDevice = (EFI_FW_VOL_BLOCK_DEVICE *) AllocateRuntimeCopyPool ( - sizeof (EFI_FW_VOL_BLOCK_DEVICE), - &mFvbDeviceTemplate - ); - ASSERT (FvbDevice != NULL); - - FvbDevice->Instance = InstanceNum; - FwVolHeader = &FwhInstance->VolumeHeader; - - // - // Set up the devicepath - // - DEBUG ((EFI_D_INFO, "FwBlockService.c: Setting up DevicePath for 0x%lx:\n", FwhInstance->FvBase)); - if (FwVolHeader->ExtHeaderOffset == 0) { - // - // FV does not contains extension header, then produce MEMMAP_DEVICE_PATH - // - FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateRuntimeCopyPool (sizeof (FV_MEMMAP_DEVICE_PATH), &mFvMemmapDevicePathTemplate); - ((FV_MEMMAP_DEVICE_PATH *) FvbDevice->DevicePath)->MemMapDevPath.StartingAddress = FwhInstance->FvBase; - ((FV_MEMMAP_DEVICE_PATH *) FvbDevice->DevicePath)->MemMapDevPath.EndingAddress = FwhInstance->FvBase + FwVolHeader->FvLength - 1; - } else { - FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateRuntimeCopyPool (sizeof (FV_PIWG_DEVICE_PATH), &mFvPIWGDevicePathTemplate); - CopyGuid ( - &((FV_PIWG_DEVICE_PATH *)FvbDevice->DevicePath)->FvDevPath.FvName, - (GUID *)(UINTN)(FwhInstance->FvBase + FwVolHeader->ExtHeaderOffset) - ); - } - - // - // Find a handle with a matching device path that has supports FW Block protocol - // - Status = gBS->LocateDevicePath (&gEfiFirmwareVolumeBlockProtocolGuid, &FvbDevice->DevicePath, &FwbHandle); - if (EFI_ERROR (Status) ) { - // - // LocateDevicePath fails so install a new interface and device path - // - DEBUG ((EFI_D_INFO, "FwBlockService.c: LocateDevicePath failed, install new interface 0x%lx:\n", FwhInstance->FvBase)); - FwbHandle = NULL; - Status = gBS->InstallMultipleProtocolInterfaces ( - &FwbHandle, - &gEfiFirmwareVolumeBlockProtocolGuid, - &FvbDevice->FwVolBlockInstance, - &gEfiDevicePathProtocolGuid, - FvbDevice->DevicePath, - NULL - ); - ASSERT_EFI_ERROR (Status); - DEBUG ((EFI_D_INFO, "FwBlockService.c: IMPI FirmwareVolBlockProt, DevPath 0x%lx: %r\n", FwhInstance->FvBase, Status)); - - } else if (IsDevicePathEnd (FvbDevice->DevicePath)) { - // - // Device allready exists, so reinstall the FVB protocol - // - DEBUG ((EFI_D_INFO, "FwBlockService.c: LocateDevicePath succeeded, reinstall interface 0x%lx:\n", FwhInstance->FvBase)); - Status = gBS->HandleProtocol ( - FwbHandle, - &gEfiFirmwareVolumeBlockProtocolGuid, - (VOID **) &OldFwbInterface - ); - ASSERT_EFI_ERROR (Status); - - Status = gBS->ReinstallProtocolInterface ( - FwbHandle, - &gEfiFirmwareVolumeBlockProtocolGuid, - OldFwbInterface, - &FvbDevice->FwVolBlockInstance - ); - ASSERT_EFI_ERROR (Status); - - } else { - // - // There was a FVB protocol on an End Device Path node - // - ASSERT (FALSE); - } - -} - -EFI_STATUS -EFIAPI -DxeFvbInitialize ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - EFI_EVENT Event; - - // - // Register for a callback when virtual addressing is updated. - // - Status = gBS->CreateEventEx ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - FvbVirtualddressChangeEvent, - NULL, - &gEfiEventVirtualAddressChangeGuid, - &Event - ); - ASSERT_EFI_ERROR (Status); - - // - // Locate required protocol for access to flash. - // - Status = gBS->LocateProtocol ( - &gSpiDeviceProtocolGuid, - NULL, - (VOID **) &mSpiDeviceProtocol - ); - ASSERT_EFI_ERROR(Status); - - // - // Initialize the rest of the module. - // - Status = FvbInitialize (); - - return Status; -} diff --git a/BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbServiceSmm.c b/BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbServiceSmm.c deleted file mode 100644 index ffe101e08e..0000000000 --- a/BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbServiceSmm.c +++ /dev/null @@ -1,263 +0,0 @@ -/** @file - SMM Firmware Volume Block Driver for the Tunnel Creek Platform. - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include -#include -#include -#include "FvbSmmCommon.h" -#include "FvbService.h" - -/** - Communication service SMI Handler entry. - - This SMI handler provides communication services with the SMM FVB runtime driver. - - @param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister(). - @param[in] RegisterContext Points to an optional handler context which was specified when the - handler was registered. - @param[in, out] CommBuffer A pointer to a collection of data in memory that will - be conveyed from a non-SMM environment into an SMM environment. - @param[in, out] CommBufferSize The size of the CommBuffer. - - @retval EFI_SUCCESS The interrupt was handled successfully. - @retval EFI_UNSUPPORTED The request was not supported by the handler. - -**/ -EFI_STATUS -EFIAPI -FvbSmmHandler ( - IN EFI_HANDLE DispatchHandle, - IN CONST VOID *RegisterContext, - IN OUT VOID *CommBuffer, - IN OUT UINTN *CommBufferSize - ) -{ - EFI_STATUS Status; - SMM_FVB_COMMUNICATE_FUNCTION_HEADER *SmmFvbFunctionHeader; - SMM_FVB_ATTRIBUTES_HEADER *SmmFvbAttributesHeader; - SMM_FVB_PHYSICAL_ADDRESS_HEADER *SmmFvbPhysicalAddressHeader; - SMM_FVB_BLOCK_SIZE_HEADER *SmmFvbBlockSizeHeader; - SMM_FVB_READ_WRITE_HEADER *SmmFvbReadWriteHeader; - SMM_FVB_BLOCKS_HEADER *SmmFvbBlocksHeader; - - ASSERT (CommBuffer != NULL); - - // - // Determine the function that is being requested and execute it. - // - SmmFvbFunctionHeader = (SMM_FVB_COMMUNICATE_FUNCTION_HEADER *) CommBuffer; - switch (SmmFvbFunctionHeader->Function) { - case EFI_FUNCTION_GET_ATTRIBUTES: - SmmFvbAttributesHeader = (SMM_FVB_ATTRIBUTES_HEADER *) SmmFvbFunctionHeader->Data; - Status = FvbProtocolGetAttributes ( - SmmFvbAttributesHeader->SmmFvb, - &SmmFvbAttributesHeader->Attributes - ); - break; - case EFI_FUNCTION_SET_ATTRIBUTES: - SmmFvbAttributesHeader = (SMM_FVB_ATTRIBUTES_HEADER *) SmmFvbFunctionHeader->Data; - Status = FvbProtocolSetAttributes ( - SmmFvbAttributesHeader->SmmFvb, - &SmmFvbAttributesHeader->Attributes - ); - break; - case EFI_FUNCTION_GET_PHYSICAL_ADDRESS: - SmmFvbPhysicalAddressHeader = (SMM_FVB_PHYSICAL_ADDRESS_HEADER *) SmmFvbFunctionHeader->Data; - Status = FvbProtocolGetPhysicalAddress ( - SmmFvbPhysicalAddressHeader->SmmFvb, - &SmmFvbPhysicalAddressHeader->Address - ); - break; - case EFI_FUNCTION_GET_BLOCK_SIZE: - SmmFvbBlockSizeHeader = (SMM_FVB_BLOCK_SIZE_HEADER *) SmmFvbFunctionHeader->Data; - Status = FvbProtocolGetBlockSize ( - SmmFvbBlockSizeHeader->SmmFvb, - SmmFvbBlockSizeHeader->Lba, - &SmmFvbBlockSizeHeader->BlockSize, - &SmmFvbBlockSizeHeader->NumOfBlocks - ); - break; - case EFI_FUNCTION_READ: - SmmFvbReadWriteHeader = (SMM_FVB_READ_WRITE_HEADER *) SmmFvbFunctionHeader->Data; - Status = FvbProtocolRead ( - SmmFvbReadWriteHeader->SmmFvb, - SmmFvbReadWriteHeader->Lba, - SmmFvbReadWriteHeader->Offset, - &SmmFvbReadWriteHeader->NumBytes, - (UINT8 *) (SmmFvbReadWriteHeader + 1) - ); - break; - case EFI_FUNCTION_WRITE: - SmmFvbReadWriteHeader = (SMM_FVB_READ_WRITE_HEADER *) SmmFvbFunctionHeader->Data; - Status = FvbProtocolWrite ( - SmmFvbReadWriteHeader->SmmFvb, - SmmFvbReadWriteHeader->Lba, - SmmFvbReadWriteHeader->Offset, - &SmmFvbReadWriteHeader->NumBytes, - (UINT8 *) (SmmFvbReadWriteHeader + 1) - ); - break; - case EFI_FUNCTION_ERASE_BLOCKS: - SmmFvbBlocksHeader = (SMM_FVB_BLOCKS_HEADER *) SmmFvbFunctionHeader->Data; - Status = FvbProtocolEraseBlocks ( - SmmFvbBlocksHeader->SmmFvb, - SmmFvbBlocksHeader->StartLba, - SmmFvbBlocksHeader->NumOfLba, - EFI_LBA_LIST_TERMINATOR, - 0 - ); - break; - default: - ASSERT (FALSE); - Status = EFI_UNSUPPORTED; - } - - // - // Set the return value. - // - SmmFvbFunctionHeader->ReturnStatus = Status; - - return EFI_SUCCESS; -} - -/** - The function installs EFI_SMM_FIRMWARE_VOLUME_BLOCK protocol - for each FV in the system. - - @param[in] FwhInstance The pointer to a FW volume instance structure, - which contains the information about one FV. - @param[in] InstanceNum The instance number which can be used as a ID - to locate this FwhInstance in other functions. - - @retval VOID - -**/ -VOID -InstallFvbProtocol ( - IN EFI_FW_VOL_INSTANCE *FwhInstance, - IN UINTN InstanceNum - ) -{ - EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; - EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; - EFI_STATUS Status; - EFI_HANDLE FvbHandle; - - FvbDevice = (EFI_FW_VOL_BLOCK_DEVICE *) AllocateRuntimeCopyPool ( - sizeof (EFI_FW_VOL_BLOCK_DEVICE), - &mFvbDeviceTemplate - ); - ASSERT (FvbDevice != NULL); - - FvbDevice->Instance = InstanceNum; - FwVolHeader = &FwhInstance->VolumeHeader; - - // - // Set up the devicepath - // - if (FwVolHeader->ExtHeaderOffset == 0) { - // - // FV does not contains extension header, then produce MEMMAP_DEVICE_PATH - // - FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateRuntimeCopyPool (sizeof (FV_MEMMAP_DEVICE_PATH), &mFvMemmapDevicePathTemplate); - ((FV_MEMMAP_DEVICE_PATH *) FvbDevice->DevicePath)->MemMapDevPath.StartingAddress = FwhInstance->FvBase; - ((FV_MEMMAP_DEVICE_PATH *) FvbDevice->DevicePath)->MemMapDevPath.EndingAddress = FwhInstance->FvBase + FwVolHeader->FvLength - 1; - } else { - FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateRuntimeCopyPool (sizeof (FV_PIWG_DEVICE_PATH), &mFvPIWGDevicePathTemplate); - CopyGuid ( - &((FV_PIWG_DEVICE_PATH *)FvbDevice->DevicePath)->FvDevPath.FvName, - (GUID *)(UINTN)(FwhInstance->FvBase + FwVolHeader->ExtHeaderOffset) - ); - } - - // - // Install the SMM Firmware Volume Block Protocol and Device Path Protocol - // - FvbHandle = NULL; - Status = gSmst->SmmInstallProtocolInterface ( - &FvbHandle, - &gEfiSmmFirmwareVolumeBlockProtocolGuid, - EFI_NATIVE_INTERFACE, - &FvbDevice->FwVolBlockInstance - ); - ASSERT_EFI_ERROR (Status); - - Status = gSmst->SmmInstallProtocolInterface ( - &FvbHandle, - &gEfiDevicePathProtocolGuid, - EFI_NATIVE_INTERFACE, - FvbDevice->DevicePath - ); - ASSERT_EFI_ERROR (Status); - - // - // Notify the Fvb wrapper driver SMM fvb is ready - // - FvbHandle = NULL; - Status = gBS->InstallProtocolInterface ( - &FvbHandle, - &gEfiSmmFirmwareVolumeBlockProtocolGuid, - EFI_NATIVE_INTERFACE, - &FvbDevice->FwVolBlockInstance - ); -} - -/** - The driver entry point for SMM Firmware Volume Block Driver. - - The function does the necessary initialization work - Firmware Volume Block Driver. - - @param[in] ImageHandle The firmware allocated handle for the UEFI image. - @param[in] SystemTable A pointer to the EFI system table. - - @retval EFI_SUCCESS This funtion always return EFI_SUCCESS. - It will ASSERT on errors. - -**/ -EFI_STATUS -EFIAPI -FvbSmmInitialize ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - EFI_HANDLE FvbHandle; - - // - // Locate required protocol for access to flash. - // - Status = gSmst->SmmLocateProtocol ( - &gSmmSpiDeviceProtocolGuid, - NULL, - (VOID **) &mSpiDeviceProtocol - ); - ASSERT_EFI_ERROR(Status); - - // - // Initialize the rest of the module. - // - FvbInitialize (); - - // - // Register SMM variable SMI handler - // - Status = gSmst->SmiHandlerRegister (FvbSmmHandler, &gEfiSmmFirmwareVolumeBlockProtocolGuid, &FvbHandle); - ASSERT_EFI_ERROR (Status); - - return EFI_SUCCESS; -} - diff --git a/BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbSmm.inf b/BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbSmm.inf deleted file mode 100644 index a295cb512c..0000000000 --- a/BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbSmm.inf +++ /dev/null @@ -1,93 +0,0 @@ -## @file -# Firmware volume block service SMM driver. -# -# Provides the ability to perform read, write and erase operations on a Firmware -# Volume based on SMM. Read and write operations are possible at the byte level -# but the erase operation can only be done at the block level. -# -# Copyright (c) 2015, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php. -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010018 - BASE_NAME = FvbSmm - FILE_GUID = 564188F4-B6DD-48D0-A33A-F62507FA4FBF - MODULE_TYPE = DXE_SMM_DRIVER - VERSION_STRING = 1.0 - PI_SPECIFICATION_VERSION = 0x0001000A - ENTRY_POINT = FvbSmmInitialize - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 -# -# VIRTUAL_ADDRESS_MAP_CALLBACK = FvbVirtualddressChangeEvent -# - -[Sources] - FvbInfo.c - FvbService.h - FvbService.c - FvbServiceSmm.c - FvbSmmCommon.h - -[Packages] - MdeModulePkg/MdeModulePkg.dec - MdePkg/MdePkg.dec - BraswellPlatformPkg/BraswellPlatformPkg.dec - -[LibraryClasses] - PcdLib - MemoryAllocationLib - CacheMaintenanceLib - IoLib - BaseMemoryLib - DebugLib - BaseLib - UefiLib - UefiBootServicesTableLib - UefiDriverEntryPoint - SmmServicesTableLib - HobLib - -[Guids] - gEfiFirmwareFileSystem2Guid ## CONSUMES ## GUID - gEfiSystemNvDataFvGuid ## CONSUMES ## GUID - -[Protocols] - gEfiDevicePathProtocolGuid ## PRODUCES - gEfiSmmFirmwareVolumeBlockProtocolGuid ## PRODUCES # GUID value is also used to register an SMI Handler - gSmmSpiDeviceProtocolGuid ## CONSUMES - -[Pcd] - gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES - gPlatformModuleTokenSpaceGuid.PcdFlashFvMainBase ## CONSUMES - gPlatformModuleTokenSpaceGuid.PcdFlashFvMainSize ## CONSUMES - gPlatformModuleTokenSpaceGuid.PcdFlashFvRecoveryBase ## CONSUMES - gPlatformModuleTokenSpaceGuid.PcdFlashFvRecoverySize ## CONSUMES - gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Base ## CONSUMES - gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Size ## CONSUMES - gPlatformModuleTokenSpaceGuid.PcdFlashPayloadBase ## CONSUMES - gPlatformModuleTokenSpaceGuid.PcdFlashPayloadSize ## CONSUMES - - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize ## CONSUMES - gPlatformModuleTokenSpaceGuid.PcdFlashMinEraseSize ## CONSUMES - -[Depex] - gSmmSpiDeviceProtocolGuid - diff --git a/BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbSmmCommon.h b/BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbSmmCommon.h deleted file mode 100644 index a3c6f97829..0000000000 --- a/BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbSmmCommon.h +++ /dev/null @@ -1,75 +0,0 @@ -/** @file - The common header file for SMM FVB module and SMM FVB runtime Module. - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _SMM_FVB_COMMON_H_ -#define _SMM_FVB_COMMON_H_ - -#include - -#define EFI_FUNCTION_GET_ATTRIBUTES 1 -#define EFI_FUNCTION_SET_ATTRIBUTES 2 -#define EFI_FUNCTION_GET_PHYSICAL_ADDRESS 3 -#define EFI_FUNCTION_GET_BLOCK_SIZE 4 -#define EFI_FUNCTION_READ 5 -#define EFI_FUNCTION_WRITE 6 -#define EFI_FUNCTION_ERASE_BLOCKS 7 - -typedef struct { - UINTN Function; - EFI_STATUS ReturnStatus; - UINT8 Data[1]; -} SMM_FVB_COMMUNICATE_FUNCTION_HEADER; - -/// -/// Size of SMM communicate header, without including the payload. -/// -#define SMM_COMMUNICATE_HEADER_SIZE (OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)) - -/// -/// Size of SMM FVB communicate function header, without including the payload. -/// -#define SMM_FVB_COMMUNICATE_HEADER_SIZE (OFFSET_OF (SMM_FVB_COMMUNICATE_FUNCTION_HEADER, Data)) - -typedef struct { - EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; - EFI_FVB_ATTRIBUTES_2 Attributes; -} SMM_FVB_ATTRIBUTES_HEADER; - -typedef struct { - EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; - EFI_PHYSICAL_ADDRESS Address; -} SMM_FVB_PHYSICAL_ADDRESS_HEADER; - -typedef struct { - EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; - EFI_LBA Lba; - UINTN BlockSize; - UINTN NumOfBlocks; -} SMM_FVB_BLOCK_SIZE_HEADER; - -typedef struct { - EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; - EFI_LBA Lba; - UINTN Offset; - UINTN NumBytes; -} SMM_FVB_READ_WRITE_HEADER; - -typedef struct { - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; - EFI_LBA StartLba; - UINTN NumOfLba; -} SMM_FVB_BLOCKS_HEADER; - -#endif diff --git a/BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbSmmDxe.c b/BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbSmmDxe.c deleted file mode 100644 index c82be4ba40..0000000000 --- a/BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbSmmDxe.c +++ /dev/null @@ -1,933 +0,0 @@ -/** @file - Implement the Firmware Volume Block (FVB) services based on SMM FVB - module and install FVB protocol. - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "FvbSmmDxe.h" - -EFI_HANDLE mHandle = NULL; -EFI_SMM_COMMUNICATION_PROTOCOL *mSmmCommunication = NULL; - -// -// Template structure used when installing FVB protocol -// -EFI_FVB_DEVICE mFvbDeviceTemplate = { - FVB_DEVICE_SIGNATURE, - NULL, - { - FvbGetAttributes, - FvbSetAttributes, - FvbGetPhysicalAddress, - FvbGetBlockSize, - FvbRead, - FvbWrite, - FvbEraseBlocks, - NULL - }, - NULL -}; - -FV_MEMMAP_DEVICE_PATH mFvMemmapDevicePathTemplate = { - { - { - HARDWARE_DEVICE_PATH, - HW_MEMMAP_DP, - { - (UINT8)(sizeof (MEMMAP_DEVICE_PATH)), - (UINT8)(sizeof (MEMMAP_DEVICE_PATH) >> 8) - } - }, - EfiMemoryMappedIO, - (EFI_PHYSICAL_ADDRESS) 0, - (EFI_PHYSICAL_ADDRESS) 0, - }, - { - END_DEVICE_PATH_TYPE, - END_ENTIRE_DEVICE_PATH_SUBTYPE, - { - END_DEVICE_PATH_LENGTH, - 0 - } - } -}; - -FV_PIWG_DEVICE_PATH mFvPIWGDevicePathTemplate = { - { - { - MEDIA_DEVICE_PATH, - MEDIA_PIWG_FW_VOL_DP, - { - (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH)), - (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH) >> 8) - } - }, - { 0 } - }, - { - END_DEVICE_PATH_TYPE, - END_ENTIRE_DEVICE_PATH_SUBTYPE, - { - END_DEVICE_PATH_LENGTH, - 0 - } - } -}; - -/** - Initialize the communicate buffer using DataSize and Function. - - The communicate size is: SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + - DataSize. - - @param[out] CommunicateBuffer The communicate buffer. Caller should free it after use. - @param[out] DataPtr Points to the data in the communicate buffer. Caller should not free it. - @param[in] DataSize The payload size. - @param[in] Function The function number used to initialize the communicate header. - - @retval EFI_INVALID_PARAMETER The data size is too big. - @retval EFI_SUCCESS Find the specified variable. - -**/ -EFI_STATUS -InitCommunicateBuffer ( - OUT VOID **CommunicateBuffer, - OUT VOID **DataPtr, - IN UINTN DataSize, - IN UINTN Function - ) -{ - EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; - SMM_FVB_COMMUNICATE_FUNCTION_HEADER *SmmFvbFunctionHeader; - - // - // The whole buffer size: SMM_COMMUNICATE_HEADER_SIZE + SMM_FVB_COMMUNICATE_HEADER_SIZE + DataSize. - // - SmmCommunicateHeader = AllocatePool (DataSize + SMM_COMMUNICATE_HEADER_SIZE + SMM_FVB_COMMUNICATE_HEADER_SIZE); - ASSERT (SmmCommunicateHeader != NULL); - - // - // Prepare data buffer. - // - CopyGuid (&SmmCommunicateHeader->HeaderGuid, &gEfiSmmFirmwareVolumeBlockProtocolGuid); - SmmCommunicateHeader->MessageLength = DataSize + SMM_FVB_COMMUNICATE_HEADER_SIZE; - - SmmFvbFunctionHeader = (SMM_FVB_COMMUNICATE_FUNCTION_HEADER *) SmmCommunicateHeader->Data; - SmmFvbFunctionHeader->Function = Function; - - *CommunicateBuffer = SmmCommunicateHeader; - *DataPtr = SmmFvbFunctionHeader->Data; - - return EFI_SUCCESS; -} - -/** - Send the data in communicate buffer to SMM. - - @param[out] SmmCommunicateHeader The communicate buffer. - @param[in] DataSize The payload size. - -**/ -EFI_STATUS -SendCommunicateBuffer ( - IN EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader, - IN UINTN DataSize - ) -{ - EFI_STATUS Status; - UINTN CommSize; - SMM_FVB_COMMUNICATE_FUNCTION_HEADER *SmmFvbFunctionHeader; - - CommSize = DataSize + SMM_COMMUNICATE_HEADER_SIZE + SMM_FVB_COMMUNICATE_HEADER_SIZE; - Status = mSmmCommunication->Communicate (mSmmCommunication, SmmCommunicateHeader, &CommSize); - ASSERT_EFI_ERROR (Status); - - SmmFvbFunctionHeader = (SMM_FVB_COMMUNICATE_FUNCTION_HEADER *) SmmCommunicateHeader->Data; - - return SmmFvbFunctionHeader->ReturnStatus; -} - -/** - This function retrieves the attributes and current settings of the block. - - @param[in] This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. - - @param[out] Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the attributes - and current settings are returned. Type EFI_FVB_ATTRIBUTES_2 - is defined in EFI_FIRMWARE_VOLUME_HEADER. - - @retval EFI_SUCCESS The firmware volume attributes were returned. - @retval EFI_INVALID_PARAMETER Attributes is NULL -**/ -EFI_STATUS -EFIAPI -FvbGetAttributes ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - OUT EFI_FVB_ATTRIBUTES_2 *Attributes - ) -{ - EFI_STATUS Status; - UINTN PayloadSize; - EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; - SMM_FVB_ATTRIBUTES_HEADER *SmmFvbAttributesHeader; - EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; - EFI_FVB_DEVICE *FvbDevice; - - if (Attributes == NULL) { - return EFI_INVALID_PARAMETER; - } - - FvbDevice = FVB_DEVICE_FROM_THIS (This); - SmmFvb = FvbDevice->SmmFvbInstance; - - // - // Initialize the communicate buffer. - // - PayloadSize = sizeof (SMM_FVB_ATTRIBUTES_HEADER); - Status = InitCommunicateBuffer ((VOID **)&SmmCommunicateHeader, (VOID **)&SmmFvbAttributesHeader, PayloadSize, EFI_FUNCTION_GET_ATTRIBUTES); - if (EFI_ERROR (Status)) { - return Status; - } - - SmmFvbAttributesHeader->SmmFvb = SmmFvb; - SmmFvbAttributesHeader->Attributes = 0; - - // - // Send data to SMM. - // - Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize); - - // - // Get data from SMM - // - *Attributes = SmmFvbAttributesHeader->Attributes; - FreePool (SmmCommunicateHeader); - - return Status; -} - -/** - Sets Volume attributes. No polarity translations are done. - - @param[in] This Calling context - @param[out] Attributes Output buffer which contains attributes - - @retval EFI_SUCCESS Set the Attributes successfully. - @retval EFI_INVALID_PARAMETER Attributes is NULL - -**/ -EFI_STATUS -EFIAPI -FvbSetAttributes ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes - ) -{ - EFI_STATUS Status; - UINTN PayloadSize; - EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; - SMM_FVB_ATTRIBUTES_HEADER *SmmFvbAttributesHeader; - EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; - EFI_FVB_DEVICE *FvbDevice; - - if (Attributes == NULL) { - return EFI_INVALID_PARAMETER; - } - - FvbDevice = FVB_DEVICE_FROM_THIS (This); - SmmFvb = FvbDevice->SmmFvbInstance; - - // - // Initialize the communicate buffer. - // - PayloadSize = sizeof (SMM_FVB_ATTRIBUTES_HEADER); - Status = InitCommunicateBuffer ((VOID **)&SmmCommunicateHeader, (VOID **)&SmmFvbAttributesHeader, PayloadSize, EFI_FUNCTION_SET_ATTRIBUTES); - if (EFI_ERROR (Status)) { - return Status; - } - - SmmFvbAttributesHeader->SmmFvb = SmmFvb; - SmmFvbAttributesHeader->Attributes = *Attributes; - - // - // Send data to SMM. - // - Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize); - - // - // Get data from SMM - // - *Attributes = SmmFvbAttributesHeader->Attributes; - FreePool (SmmCommunicateHeader); - - return Status; -} - -/** - Retrieves the physical address of the FVB instance. - - @param[in] SmmFvb A pointer to EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL. - @param[out] Address Output buffer containing the address. - - @retval EFI_SUCCESS Get the address successfully. - @retval Others Failed to get address. - -**/ -EFI_STATUS -GetPhysicalAddress ( - IN EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb, - OUT EFI_PHYSICAL_ADDRESS *Address - ) -{ - EFI_STATUS Status; - UINTN PayloadSize; - EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; - SMM_FVB_PHYSICAL_ADDRESS_HEADER *SmmFvbPhysicalAddressHeader; - - // - // Initialize the communicate buffer. - // - PayloadSize = sizeof (SMM_FVB_PHYSICAL_ADDRESS_HEADER); - Status = InitCommunicateBuffer ((VOID **)&SmmCommunicateHeader, (VOID **)&SmmFvbPhysicalAddressHeader, PayloadSize, EFI_FUNCTION_GET_PHYSICAL_ADDRESS); - if (EFI_ERROR (Status)) { - return Status; - } - - SmmFvbPhysicalAddressHeader->SmmFvb = SmmFvb; - SmmFvbPhysicalAddressHeader->Address = 0; - - // - // Send data to SMM. - // - Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize); - - // - // Get data from SMM - // - *Address = SmmFvbPhysicalAddressHeader->Address; - FreePool (SmmCommunicateHeader); - - return Status; -} - -/** - Retrieves the physical address of the FVB instance. - - @param[in] This A pointer to EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL. - @param[out] Address Output buffer containing the address. - - @retval EFI_SUCCESS Get the address successfully. - @retval Others Failed to get the address. - -**/ -EFI_STATUS -EFIAPI -FvbGetPhysicalAddress ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - OUT EFI_PHYSICAL_ADDRESS *Address - ) -{ - EFI_STATUS Status; - EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; - EFI_FVB_DEVICE *FvbDevice; - - if (Address == NULL) { - return EFI_INVALID_PARAMETER; - } - - FvbDevice = FVB_DEVICE_FROM_THIS (This); - SmmFvb = FvbDevice->SmmFvbInstance; - - Status = GetPhysicalAddress (SmmFvb, Address); - - return Status; -} - -/** - Retrieve the size of a logical block - - @param[in] SmmFvb A pointer to EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL. - @param[in] Lba Indicates which block to return the size for. - @param[out] BlockSize A pointer to a caller allocated UINTN in which - the size of the block is returned - @param[out] NumOfBlocks A pointer to a caller allocated UINTN in which the - number of consecutive blocks starting with Lba is - returned. All blocks in this range have a size of - BlockSize - - @retval EFI_SUCCESS Get BlockSize and NumOfBlocks successfully. - @retval EFI_INVALID_PARAMETER BlockSize or NumOfBlocks are NULL. -**/ -EFI_STATUS -GetBlockSize ( - IN EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb, - IN EFI_LBA Lba, - OUT UINTN *BlockSize, - OUT UINTN *NumOfBlocks - ) -{ - EFI_STATUS Status; - UINTN PayloadSize; - EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; - SMM_FVB_BLOCK_SIZE_HEADER *SmmFvbBlockSizeHeader; - - if ((BlockSize == NULL) || (NumOfBlocks == NULL)) { - return EFI_INVALID_PARAMETER; - } - - // - // Initialize the communicate buffer. - // - PayloadSize = sizeof (SMM_FVB_BLOCK_SIZE_HEADER); - Status = InitCommunicateBuffer ((VOID **)&SmmCommunicateHeader, (VOID **)&SmmFvbBlockSizeHeader, PayloadSize, EFI_FUNCTION_GET_BLOCK_SIZE); - if (EFI_ERROR (Status)) { - return Status; - } - - SmmFvbBlockSizeHeader->SmmFvb = SmmFvb; - SmmFvbBlockSizeHeader->Lba = Lba; - - // - // Send data to SMM. - // - Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize); - - // - // Get data from SMM - // - *BlockSize = SmmFvbBlockSizeHeader->BlockSize; - *NumOfBlocks = SmmFvbBlockSizeHeader->NumOfBlocks; - FreePool (SmmCommunicateHeader); - - return Status; -} - -/** - Retrieve the size of a logical block - - @param[in] This Calling context - @param[in] Lba Indicates which block to return the size for. - @param[out] BlockSize A pointer to a caller allocated UINTN in which - the size of the block is returned - @param[out] NumOfBlocks A pointer to a caller allocated UINTN in which the - number of consecutive blocks starting with Lba is - returned. All blocks in this range have a size of - BlockSize - - @retval EFI_SUCCESS Get BlockSize and NumOfBlocks successfully. - @retval EFI_INVALID_PARAMETER BlockSize or NumOfBlocks are NULL. -**/ -EFI_STATUS -EFIAPI -FvbGetBlockSize ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - IN EFI_LBA Lba, - OUT UINTN *BlockSize, - OUT UINTN *NumOfBlocks - ) -{ - EFI_STATUS Status; - EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; - EFI_FVB_DEVICE *FvbDevice; - - FvbDevice = FVB_DEVICE_FROM_THIS (This); - SmmFvb = FvbDevice->SmmFvbInstance; - - Status = GetBlockSize (SmmFvb, Lba, BlockSize, NumOfBlocks); - return Status; -} - -/** - Reads data beginning at Lba:Offset from FV. The Read terminates either - when *NumBytes of data have been read, or when a block boundary is - reached. *NumBytes is updated to reflect the actual number of bytes - written. The write opertion does not include erase. This routine will - attempt to write only the specified bytes. If the writes do not stick, - it will return an error. - - @param[in] This Calling context - @param[in] Lba Block in which to begin write - @param[in] Offset Offset in the block at which to begin write - @param[in, out] NumBytes On input, indicates the requested write size. On - output, indicates the actual number of bytes written - @param[in] Buffer Buffer containing source data for the write. - -Returns: - @retval EFI_SUCCESS The firmware volume was read successfully and - contents are in Buffer - @retval EFI_BAD_BUFFER_SIZE Read attempted across a LBA boundary. On output, - NumBytes contains the total number of bytes returned - in Buffer - @retval EFI_ACCESS_DENIED The firmware volume is in the ReadDisabled state - @retval EFI_DEVICE_ERROR The block device is not functioning correctly and - could not be read - @retval EFI_INVALID_PARAMETER NumBytes or Buffer are NULL - -**/ -EFI_STATUS -EFIAPI -FvbRead ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - IN EFI_LBA Lba, - IN UINTN Offset, - IN OUT UINTN *NumBytes, - OUT UINT8 *Buffer - ) -{ - EFI_STATUS Status; - UINTN PayloadSize; - EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; - SMM_FVB_READ_WRITE_HEADER *SmmFvbReadWriteHeader; - EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; - EFI_FVB_DEVICE *FvbDevice; - - if ((NumBytes == NULL) || (Buffer == NULL)) { - return EFI_INVALID_PARAMETER; - } - - FvbDevice = FVB_DEVICE_FROM_THIS (This); - SmmFvb = FvbDevice->SmmFvbInstance; - - // - // Initialize the communicate buffer. - // - PayloadSize = sizeof (SMM_FVB_READ_WRITE_HEADER) + *NumBytes; - Status = InitCommunicateBuffer ((VOID **)&SmmCommunicateHeader, (VOID **)&SmmFvbReadWriteHeader, PayloadSize, EFI_FUNCTION_READ); - if (EFI_ERROR (Status)) { - return Status; - } - - SmmFvbReadWriteHeader->SmmFvb = SmmFvb; - SmmFvbReadWriteHeader->Lba = Lba; - SmmFvbReadWriteHeader->Offset = Offset; - SmmFvbReadWriteHeader->NumBytes = *NumBytes; - - // - // Send data to SMM. - // - Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize); - - // - // Get data from SMM - // - *NumBytes = SmmFvbReadWriteHeader->NumBytes; - if (!EFI_ERROR (Status)) { - CopyMem (Buffer, (UINT8 *)(SmmFvbReadWriteHeader + 1), *NumBytes); - } - FreePool (SmmCommunicateHeader); - - return Status; -} - -/** - Writes data beginning at Lba:Offset from FV. The write terminates either - when *NumBytes of data have been written, or when a block boundary is - reached. *NumBytes is updated to reflect the actual number of bytes - written. The write opertion does not include erase. This routine will - attempt to write only the specified bytes. If the writes do not stick, - it will return an error. - - @param[in] This Calling context - @param[in] Lba Block in which to begin write - @param[in] Offset Offset in the block at which to begin write - @param[in, out] NumBytes On input, indicates the requested write size. On - output, indicates the actual number of bytes written - @param[in] Buffer Buffer containing source data for the write. - - @retval EFI_SUCCESS The firmware volume was written successfully - @retval EFI_BAD_BUFFER_SIZE Write attempted across a LBA boundary. On output, - NumBytes contains the total number of bytes - actually written - @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state - @retval EFI_DEVICE_ERROR The block device is not functioning correctly and - could not be written - @retval EFI_INVALID_PARAMETER NumBytes or Buffer are NULL - -**/ -EFI_STATUS -EFIAPI -FvbWrite ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - IN EFI_LBA Lba, - IN UINTN Offset, - IN OUT UINTN *NumBytes, - IN UINT8 *Buffer - ) -{ - EFI_STATUS Status; - UINTN PayloadSize; - EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; - SMM_FVB_READ_WRITE_HEADER *SmmFvbReadWriteHeader; - EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; - EFI_FVB_DEVICE *FvbDevice; - - if ((NumBytes == NULL) || (Buffer == NULL)) { - return EFI_INVALID_PARAMETER; - } - - FvbDevice = FVB_DEVICE_FROM_THIS (This); - SmmFvb = FvbDevice->SmmFvbInstance; - - // - // Initialize the communicate buffer. - // - PayloadSize = sizeof (SMM_FVB_READ_WRITE_HEADER) + *NumBytes; - Status = InitCommunicateBuffer ((VOID **)&SmmCommunicateHeader, (VOID **)&SmmFvbReadWriteHeader, PayloadSize, EFI_FUNCTION_WRITE); - if (EFI_ERROR (Status)) { - return Status; - } - - SmmFvbReadWriteHeader->SmmFvb = SmmFvb; - SmmFvbReadWriteHeader->Lba = Lba; - SmmFvbReadWriteHeader->Offset = Offset; - SmmFvbReadWriteHeader->NumBytes = *NumBytes; - CopyMem ((UINT8 *)(SmmFvbReadWriteHeader + 1), Buffer, *NumBytes); - - // - // Send data to SMM. - // - Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize); - - // - // Get data from SMM - // - *NumBytes = SmmFvbReadWriteHeader->NumBytes; - FreePool (SmmCommunicateHeader); - - return Status; -} - -/** - The EraseBlock() function erases NumOfLba blocks started from StartingLba. - - @param[in] This Calling context - @param[in] StartingLba Starting LBA followed to erase. - @param[in] NumOfLba Number of block to erase. - - @retval EFI_SUCCESS The erase request was successfully completed - @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state - @retval EFI_DEVICE_ERROR The block device is not functioning correctly and - could not be written. Firmware device may have been - partially erased - -**/ -EFI_STATUS -EraseBlock ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - IN EFI_LBA StartingLba, - IN UINTN NumOfLba - ) -{ - EFI_STATUS Status; - UINTN PayloadSize; - EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; - SMM_FVB_BLOCKS_HEADER *SmmFvbBlocksHeader; - EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; - EFI_FVB_DEVICE *FvbDevice; - - FvbDevice = FVB_DEVICE_FROM_THIS (This); - SmmFvb = FvbDevice->SmmFvbInstance; - - // - // Initialize the communicate buffer. - // - PayloadSize = sizeof (SMM_FVB_BLOCKS_HEADER); - Status = InitCommunicateBuffer ((VOID **)&SmmCommunicateHeader, (VOID **)&SmmFvbBlocksHeader, PayloadSize, EFI_FUNCTION_ERASE_BLOCKS); - if (EFI_ERROR (Status)) { - return Status; - } - - SmmFvbBlocksHeader->SmmFvb = SmmFvb; - SmmFvbBlocksHeader->StartLba = StartingLba; - SmmFvbBlocksHeader->NumOfLba = NumOfLba; - - // - // Send data to SMM. - // - Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize); - - // - // Get data from SMM - // - FreePool (SmmCommunicateHeader); - - return Status; -} - -/** - The EraseBlocks() function erases one or more blocks as denoted by the - variable argument list. The entire parameter list of blocks must be verified - prior to erasing any blocks. If a block is requested that does not exist - within the associated firmware volume (it has a larger index than the last - block of the firmware volume), the EraseBlock() function must return - EFI_INVALID_PARAMETER without modifying the contents of the firmware volume. - - @param[in] This Calling context - @param[in] ... Starting LBA followed by Number of Lba to erase. - a -1 to terminate the list. - - @retval EFI_SUCCESS The erase request was successfully completed - @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state - @retval EFI_DEVICE_ERROR The block device is not functioning correctly and - could not be written. Firmware device may have been - partially erased - -**/ -EFI_STATUS -EFIAPI -FvbEraseBlocks ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - ... - ) -{ - EFI_STATUS Status; - VA_LIST Marker; - EFI_LBA StartingLba; - UINTN NumOfLba; - EFI_FVB_DEVICE *FvbDevice; - - FvbDevice = FVB_DEVICE_FROM_THIS (This); - Status = EFI_SUCCESS; - - // - // Check the parameter - // - VA_START (Marker, This); - do { - StartingLba = VA_ARG (Marker, EFI_LBA); - if (StartingLba == EFI_LBA_LIST_TERMINATOR) { - break; - } - - NumOfLba = VA_ARG (Marker, UINT32); - if (NumOfLba == 0) { - VA_END (Marker); - return EFI_INVALID_PARAMETER; - } - - if ((StartingLba + NumOfLba) > FvbDevice->NumOfBlocks) { - VA_END (Marker); - return EFI_INVALID_PARAMETER; - } - } while (1); - VA_END (Marker); - - // - // Erase the blocks - // - VA_START (Marker, This); - do { - StartingLba = VA_ARG (Marker, EFI_LBA); - if (StartingLba == EFI_LBA_LIST_TERMINATOR ) { - break; - } - NumOfLba = VA_ARG (Marker, UINT32); - Status = EraseBlock (This, StartingLba, NumOfLba); - if (EFI_ERROR (Status)) { - break; - } - } while (1); - VA_END (Marker); - - return Status; -} - -/** - Install the FVB protocol which based on SMM FVB protocol. - - @param[in] SmmFvb The SMM FVB protocol. - -**/ -VOID -InstallFvb ( - IN EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb - ) -{ - EFI_STATUS Status; - EFI_HANDLE FvbHandle; - EFI_FVB_DEVICE *FvbDevice; - EFI_FIRMWARE_VOLUME_HEADER *VolumeHeader; - EFI_PHYSICAL_ADDRESS Address; - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *OldFvbInterface; - UINTN BlockSize; - UINTN NumOfBlocks; - - FvbDevice = AllocateRuntimeCopyPool (sizeof (EFI_FVB_DEVICE), &mFvbDeviceTemplate); - ASSERT (FvbDevice != NULL); - FvbDevice->SmmFvbInstance = SmmFvb; - - Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &mSmmCommunication); - ASSERT_EFI_ERROR (Status); - - Status = GetBlockSize (SmmFvb, 0, &BlockSize, &NumOfBlocks); - ASSERT_EFI_ERROR (Status); - FvbDevice->NumOfBlocks = NumOfBlocks; - - Status = GetPhysicalAddress (SmmFvb, &Address); - ASSERT_EFI_ERROR (Status); - - VolumeHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN)Address; - - // - // Set up the devicepath - // - if (VolumeHeader->ExtHeaderOffset == 0) { - // - // FV does not contains extension header, then produce MEMMAP_DEVICE_PATH - // - FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateRuntimeCopyPool (sizeof (FV_MEMMAP_DEVICE_PATH), &mFvMemmapDevicePathTemplate); - ((FV_MEMMAP_DEVICE_PATH *) FvbDevice->DevicePath)->MemMapDevPath.StartingAddress = (UINTN)Address; - ((FV_MEMMAP_DEVICE_PATH *) FvbDevice->DevicePath)->MemMapDevPath.EndingAddress = (UINTN)Address + VolumeHeader->FvLength - 1; - } else { - FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateRuntimeCopyPool (sizeof (FV_PIWG_DEVICE_PATH), &mFvPIWGDevicePathTemplate); - CopyGuid ( - &((FV_PIWG_DEVICE_PATH *)FvbDevice->DevicePath)->FvDevPath.FvName, - (GUID *)(UINTN)((UINTN)Address + VolumeHeader->ExtHeaderOffset) - ); - } - - // - // Find a handle with a matching device path that has supports FW Block protocol - // - Status = gBS->LocateDevicePath (&gEfiFirmwareVolumeBlockProtocolGuid, &FvbDevice->DevicePath, &FvbHandle); - if (EFI_ERROR (Status) ) { - // - // LocateDevicePath fails so install a new interface and device path - // - FvbHandle = NULL; - Status = gBS->InstallMultipleProtocolInterfaces ( - &FvbHandle, - &gEfiFirmwareVolumeBlockProtocolGuid, - &FvbDevice->FvbInstance, - &gEfiDevicePathProtocolGuid, - FvbDevice->DevicePath, - NULL - ); - ASSERT_EFI_ERROR (Status); - } else if (IsDevicePathEnd (FvbDevice->DevicePath)) { - // - // Device allready exists, so reinstall the FVB protocol - // - Status = gBS->HandleProtocol ( - FvbHandle, - &gEfiFirmwareVolumeBlockProtocolGuid, - (VOID **) &OldFvbInterface - ); - ASSERT_EFI_ERROR (Status); - - Status = gBS->ReinstallProtocolInterface ( - FvbHandle, - &gEfiFirmwareVolumeBlockProtocolGuid, - OldFvbInterface, - &FvbDevice->FvbInstance - ); - ASSERT_EFI_ERROR (Status); - } else { - // - // There was a FVB protocol on an End Device Path node - // - ASSERT (FALSE); - } -} - -/** - SMM Firmware Volume Block Protocol notification event handler. - - Discover NV Variable Store and install Variable Write Arch Protocol. - - @param[in] Event Event whose notification function is being invoked. - @param[in] Context Pointer to the notification function's context. -**/ -VOID -EFIAPI -SmmFvbReady ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - EFI_STATUS Status; - EFI_HANDLE *HandleBuffer; - UINTN HandleCount; - UINTN Index; - EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; - - // - // Locate all handles of Smm Fvb protocol. - // - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiSmmFirmwareVolumeBlockProtocolGuid, - NULL, - &HandleCount, - &HandleBuffer - ); - if (EFI_ERROR (Status)) { - return ; - } - - // - // Install FVB protocol. - // - for (Index = 0; Index < HandleCount; Index++) { - SmmFvb = NULL; - Status = gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiSmmFirmwareVolumeBlockProtocolGuid, - (VOID **) &SmmFvb - ); - if (EFI_ERROR (Status)) { - break; - } - - InstallFvb (SmmFvb); - } - - FreePool (HandleBuffer); -} - -/** - The driver entry point for Firmware Volume Block Driver. - - The function does the necessary initialization work - Firmware Volume Block Driver. - - @param[in] ImageHandle The firmware allocated handle for the UEFI image. - @param[in] SystemTable A pointer to the EFI system table. - - @retval EFI_SUCCESS This funtion always return EFI_SUCCESS. - It will ASSERT on errors. - -**/ -EFI_STATUS -EFIAPI -FvbSmmDxeInitialize ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - VOID *SmmFvbRegistration; - - // - // Smm FVB driver is ready - // - EfiCreateProtocolNotifyEvent ( - &gEfiSmmFirmwareVolumeBlockProtocolGuid, - TPL_CALLBACK, - SmmFvbReady, - NULL, - &SmmFvbRegistration - ); - - return EFI_SUCCESS; -} - diff --git a/BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbSmmDxe.h b/BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbSmmDxe.h deleted file mode 100644 index cee43bae72..0000000000 --- a/BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbSmmDxe.h +++ /dev/null @@ -1,231 +0,0 @@ -/** @file - The internal header file includes the common header files, defines - internal structure and functions used by FVB module. - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _SMM_FVB_DXE_H_ -#define _SMM_FVB_DXE_H_ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "FvbSmmCommon.h" - -#define FVB_DEVICE_SIGNATURE SIGNATURE_32 ('F', 'V', 'B', 'S') -#define FVB_DEVICE_FROM_THIS(a) CR (a, EFI_FVB_DEVICE, FvbInstance, FVB_DEVICE_SIGNATURE) - -typedef struct { - MEDIA_FW_VOL_DEVICE_PATH FvDevPath; - EFI_DEVICE_PATH_PROTOCOL EndDevPath; -} FV_PIWG_DEVICE_PATH; - -typedef struct { - MEMMAP_DEVICE_PATH MemMapDevPath; - EFI_DEVICE_PATH_PROTOCOL EndDevPath; -} FV_MEMMAP_DEVICE_PATH; - -typedef struct { - UINTN Signature; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL FvbInstance; - EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvbInstance; - UINTN NumOfBlocks; -} EFI_FVB_DEVICE; - -/** - This function retrieves the attributes and current settings of the block. - - @param[in] This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. - - @param[out] Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the attributes - and current settings are returned. Type EFI_FVB_ATTRIBUTES_2 - is defined in EFI_FIRMWARE_VOLUME_HEADER. - - @retval EFI_SUCCESS The firmware volume attributes were returned. - -**/ -EFI_STATUS -EFIAPI -FvbGetAttributes ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - OUT EFI_FVB_ATTRIBUTES_2 *Attributes - ); - - /** - Sets Volume attributes. No polarity translations are done. - - @param[in] This Calling context - @param[out] Attributes Output buffer which contains attributes - - @retval EFI_SUCCESS The function always return successfully. - -**/ -EFI_STATUS -EFIAPI -FvbSetAttributes ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes - ); - -/** - Retrieves the physical address of the device. - - @param[in] This A pointer to EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL. - @param[out] Address Output buffer containing the address. - - @retval EFI_SUCCESS The function always return successfully. - -**/ -EFI_STATUS -EFIAPI -FvbGetPhysicalAddress ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - OUT EFI_PHYSICAL_ADDRESS *Address - ); - -/** - Retrieve the size of a logical block - - @param[in] This Calling context - @param[in] Lba Indicates which block to return the size for. - @param[out] BlockSize A pointer to a caller allocated UINTN in which - the size of the block is returned - @param[out] NumOfBlocks A pointer to a caller allocated UINTN in which the - number of consecutive blocks starting with Lba is - returned. All blocks in this range have a size of - BlockSize - - @retval EFI_SUCCESS The function always return successfully. - -**/ -EFI_STATUS -EFIAPI -FvbGetBlockSize ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - IN EFI_LBA Lba, - OUT UINTN *BlockSize, - OUT UINTN *NumOfBlocks - ); - -/** - Reads data beginning at Lba:Offset from FV. The Read terminates either - when *NumBytes of data have been read, or when a block boundary is - reached. *NumBytes is updated to reflect the actual number of bytes - written. The write opertion does not include erase. This routine will - attempt to write only the specified bytes. If the writes do not stick, - it will return an error. - - @param[in] This Calling context - @param[in] Lba Block in which to begin write - @param[in] Offset Offset in the block at which to begin write - @param[in, out] NumBytes On input, indicates the requested write size. On - output, indicates the actual number of bytes written - @param[in] Buffer Buffer containing source data for the write. - -Returns: - @retval EFI_SUCCESS The firmware volume was read successfully and - contents are in Buffer - @retval EFI_BAD_BUFFER_SIZE Read attempted across a LBA boundary. On output, - NumBytes contains the total number of bytes returned - in Buffer - @retval EFI_ACCESS_DENIED The firmware volume is in the ReadDisabled state - @retval EFI_DEVICE_ERROR The block device is not functioning correctly and - could not be read - @retval EFI_INVALID_PARAMETER NumBytes or Buffer are NULL - -**/ -EFI_STATUS -EFIAPI -FvbRead ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - IN EFI_LBA Lba, - IN UINTN Offset, - IN OUT UINTN *NumBytes, - OUT UINT8 *Buffer - ); - -/** - Writes data beginning at Lba:Offset from FV. The write terminates either - when *NumBytes of data have been written, or when a block boundary is - reached. *NumBytes is updated to reflect the actual number of bytes - written. The write opertion does not include erase. This routine will - attempt to write only the specified bytes. If the writes do not stick, - it will return an error. - - @param[in] This Calling context - @param[in] Lba Block in which to begin write - @param[in] Offset Offset in the block at which to begin write - @param[in, out] NumBytes On input, indicates the requested write size. On - output, indicates the actual number of bytes written - @param[in] Buffer Buffer containing source data for the write. - - @retval EFI_SUCCESS The firmware volume was written successfully - @retval EFI_BAD_BUFFER_SIZE Write attempted across a LBA boundary. On output, - NumBytes contains the total number of bytes - actually written - @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state - @retval EFI_DEVICE_ERROR The block device is not functioning correctly and - could not be written - @retval EFI_INVALID_PARAMETER NumBytes or Buffer are NULL - -**/ -EFI_STATUS -EFIAPI -FvbWrite ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - IN EFI_LBA Lba, - IN UINTN Offset, - IN OUT UINTN *NumBytes, - IN UINT8 *Buffer - ); - -/** - The EraseBlock() function erases one or more blocks as denoted by the - variable argument list. The entire parameter list of blocks must be verified - prior to erasing any blocks. If a block is requested that does not exist - within the associated firmware volume (it has a larger index than the last - block of the firmware volume), the EraseBlock() function must return - EFI_INVALID_PARAMETER without modifying the contents of the firmware volume. - - @param[in] This Calling context - @param[in] ... Starting LBA followed by Number of Lba to erase. - a -1 to terminate the list. - - @retval EFI_SUCCESS The erase request was successfully completed - @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state - @retval EFI_DEVICE_ERROR The block device is not functioning correctly and - could not be written. Firmware device may have been - partially erased - -**/ -EFI_STATUS -EFIAPI -FvbEraseBlocks ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - ... - ); - -#endif diff --git a/BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbSmmDxe.inf b/BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbSmmDxe.inf deleted file mode 100644 index d1ae766266..0000000000 --- a/BraswellPlatformPkg/Flash/FvbRuntimeDxe/FvbSmmDxe.inf +++ /dev/null @@ -1,57 +0,0 @@ -## @file -# SMM based Firmware Volume Block Dxe Driver -# -# This driver provides the Firmware Volume Block (FVB) services based on SMM -# FVB module and install FVB protocol. -# -# Copyright (c) 2015, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php. -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010018 - BASE_NAME = FvbSmmDxe - FILE_GUID = BEB88806-1143-4156-A2AF-4CA781EA313B - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - ENTRY_POINT = FvbSmmDxeInitialize -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 -# - -[Sources] - FvbSmmDxe.c - FvbSmmDxe.h - FvbSmmCommon.h - -[Packages] - MdeModulePkg/MdeModulePkg.dec - MdePkg/MdePkg.dec - BraswellPlatformPkg/BraswellPlatformPkg.dec - -[LibraryClasses] - BaseLib - UefiBootServicesTableLib - DebugLib - DxeServicesTableLib - UefiDriverEntryPoint - PcdLib - -[Protocols] - gEfiFirmwareVolumeBlockProtocolGuid ## PRODUCES - gEfiSmmCommunicationProtocolGuid ## CONSUMES - gEfiSmmFirmwareVolumeBlockProtocolGuid ## CONSUMES # GUID value is also used with SMM Communication Protocol to invoke an SMI Handler - -[Depex] - gEfiSmmCommunicationProtocolGuid - diff --git a/BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDevice.c b/BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDevice.c deleted file mode 100644 index d4eaced0d4..0000000000 --- a/BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDevice.c +++ /dev/null @@ -1,659 +0,0 @@ -/** @file - SPI Device driver for Braswell Platform. - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include -#include -#include "SpiDevice.h" - -EFI_SPI_PROTOCOL *mSpiProtocol; - -UINTN mNvStorageBase = 0; - -EFI_STATUS -EFIAPI -SpiRead ( - IN UINTN SpiOffset, - IN OUT UINTN *Size, - OUT UINT8 *Buffer - ) -{ - EFI_STATUS Status; - VOID *BiosMmioAddress; - UINTN RegionOffset; - UINTN Length; - UINTN RemainingBytes; - - // - // Validate parameters. - // - if (Size == NULL || Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - if (SpiOffset + *Size > PcdGet32 (PcdFlashAreaSize)) { - return EFI_INVALID_PARAMETER; - } - - // - // Check to see if the read is taking place in a memory mapped part of the flash. - // Some flash regions may not be mapped for runtime access by the OS and must - // be accessed through the controller and not MMIO. - // - if (ReadUsingMmio (SpiOffset)) { - // - // Convert BIOS region offset into an actual memory address. - // - BiosMmioAddress = (VOID*) (SpiOffset + PcdGet32 (PcdFlashAreaBaseAddress)); - - // - // Do memory copy instead of using SPI controller. - // - CopyMem ((VOID*) Buffer, BiosMmioAddress, *Size); - } else if ((SpiOffset >= VN_STORAGE_REGION_FLASH_OFFSET) && (SpiOffset < (VN_STORAGE_REGION_FLASH_OFFSET + PcdGet32 (PcdFlashAreaSize)))) { - // - // Convert the offset into a memory address into the NV Storage region. At - // runtime this is the only region of the flash that is mapped for runtime - // access. Prior to runtime the preceding case will cover MMIO flash access. - // - BiosMmioAddress = (VOID*) ((SpiOffset - VN_STORAGE_REGION_FLASH_OFFSET) + mNvStorageBase); - - // - // Do memory copy instead of using SPI controller. - // - CopyMem ((VOID*) Buffer, BiosMmioAddress, *Size); - } else { - Status = EFI_SUCCESS; - RemainingBytes = *Size; - RegionOffset = SpiOffset; - while (RemainingBytes > 0) { - if (RemainingBytes > SIZE_4KB) { - Length = SIZE_4KB; - } else { - Length = RemainingBytes; - } - Status = mSpiProtocol->Execute ( - mSpiProtocol, - SPI_READ, - 0, - TRUE, - TRUE, - FALSE, - (UINT32) RegionOffset, - (UINT32) Length, - Buffer, - EnumSpiRegionAll - ); - if (EFI_ERROR (Status)) { - DEBUG((EFI_D_ERROR, "Failed to read SPI region.\n")); - break; - } - RemainingBytes -= Length; - RegionOffset += Length; - Buffer += Length; - } - } - - return EFI_SUCCESS; -} - -EFI_STATUS -EFIAPI -SpiWrite ( - IN UINTN SpiOffset, - IN OUT UINTN *Size, - IN UINT8 *Buffer - ) -{ - EFI_STATUS Status; - UINTN RegionOffset; - UINTN Length; - UINTN RemainingBytes; - - // - // Validate the input parameters - // - if (Size == NULL || Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - if (SpiOffset + *Size > PcdGet32 (PcdFlashAreaSize)) { - return EFI_INVALID_PARAMETER; - } - - Status = EFI_SUCCESS; - RemainingBytes = *Size; - RegionOffset = SpiOffset; - - while (RemainingBytes > 0) { - if (RemainingBytes > SIZE_4KB) { - Length = SIZE_4KB; - } else { - Length = RemainingBytes; - } - Status = mSpiProtocol->Execute ( - mSpiProtocol, - SPI_PROG, - SPI_WREN, - TRUE, - TRUE, - TRUE, - (UINT32) RegionOffset, - (UINT32) Length, - Buffer, - EnumSpiRegionAll - ); - if (EFI_ERROR (Status)) { - DEBUG((EFI_D_ERROR, "Failed to write SPI region.\n")); - break; - } - RemainingBytes -= Length; - RegionOffset += Length; - Buffer += Length; - } - - return Status; -} - -EFI_STATUS -EFIAPI -SpiErase ( - IN UINTN SpiOffset, - IN OUT UINTN Size - ) -{ - EFI_STATUS Status; - UINTN RegionOffset; - UINTN BytesRemaining; - - // - // Validate the input parameters - // - Status = EFI_INVALID_PARAMETER; - if (SpiOffset + Size > PcdGet32 (PcdFlashAreaSize)) { - return EFI_INVALID_PARAMETER; - } - - // - // Force the minimal alignment of 4k. - // - BytesRemaining = Size; - RegionOffset = SpiOffset; - if (RegionOffset & (SIZE_4KB - 1)) { - DEBUG((EFI_D_INFO, "Forcing SPI Device Erase alignment to a 4k base.\n")); - BytesRemaining += (RegionOffset & (SIZE_4KB - 1)); - RegionOffset = RegionOffset & (SIZE_4KB - 1); - } - - // - // Perform as many erase operations as needed to erase requested region. - // - while (BytesRemaining > 0) { - Status = mSpiProtocol->Execute ( - mSpiProtocol, - SPI_SERASE, - SPI_WREN, - FALSE, - TRUE, - FALSE, - (UINT32) RegionOffset, - 0, - NULL, - EnumSpiRegionAll - ); - if (EFI_ERROR (Status)) { - DEBUG((EFI_D_ERROR, "Failed to erase SPI region.\n")); - break; - } - - // - // Update the number of bytes left to erase. - // - BytesRemaining -= SIZE_4KB; - RegionOffset += SIZE_4KB; - } - - return Status; -} - -EFI_STATUS -EFIAPI -SpiLock ( - IN UINTN SpiOffset, - IN OUT UINTN Size, - IN BOOLEAN Lock - ) -{ - // - // Block/Sector locking is not supported in this implementation. Use SpiSetRange - // and SpiLockRanges to protect areas of the flash. - // - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -SpiSetRange ( - IN UINTN SpiOffset, - IN UINTN Size, - IN BOOLEAN ReadLock, - IN BOOLEAN WriteLock - ) -{ - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -SpiLockRanges ( - ) -{ - // - // Call lock on the SPI interface. This will lock down further configuration - // changes in the SPI controller. - // - return mSpiProtocol->Lock (mSpiProtocol); -} - -/** - Get the JEDED ID from the SPI flash part. - - @param[in] Context Pointer to a context data structure - needed by the SPI controller driver - @param[in] Description Description of the flash device - @param[in] BufferLength Length of the JedecId buffer - @param[out] JedecId Pointer to a buffer to fill with - the JEDEC ID value - - @retval EFI_SUCCESS The JEDEC ID value is in the buffer - @retval EFI_INVALID_PARAMETER JedecId is NULL - @retval EFI_INVALID_PARAMETER Description is NULL - @retval EFI_INVALID_PARAMETER Too few opcode entries - @retval EFI_INVALID_PARAMETER JEDEC ID response buffer too small - @retval EFI_UNSUPPORTED JEDEC ID opcode not found - -**/ -EFI_STATUS -EFIAPI -JedecIdRead ( - IN VOID *Context, - IN CONST FLASH_PART_DESCRIPTION *Description, - IN UINTN BufferLength, - OUT UINT8 *JedecId - ) -{ - // - // Validate parameters. - // - if ((JedecId == NULL) - || (Description == NULL) - || (BufferLength < Description->JededIdResponseLengthInBytes)) { - return EFI_INVALID_PARAMETER; - } - - return mSpiProtocol->ReadId (mSpiProtocol, 0, JedecId); -} - -/** - Determine the flash size and description - - @param[in] PerformJedecIdOperation Callback routine to initiate - the JEDEC ID operation using - the SPI controller to identify - the flash part. - @param[in] Context Pointer to a context structure to pass - to PerformJedecIdOperation - @param[out] FlashDescription Pointer to a buffer to receive a - pointer to a FLASH_PART_DESCRIPTION - data structure containing the flash - part information. - - @return This routine returns the size of the flash part if it is - supported. Zero is returned if the flash part is not - supported. - -**/ -UINT64 -EFIAPI -FindFlashSupport ( - IN PERFORM_JEDEC_ID_OPERATION PerformJedecIdOperation, - IN VOID *Context, - OUT CONST FLASH_PART_DESCRIPTION **FlashDescription - ) -{ - UINTN BufferLength; - CONST FLASH_PART_DESCRIPTION *Description; - UINT64 FlashSize; - EFI_HANDLE *HandleArray; - UINTN HandleCount; - UINTN HandleIndex; - UINT8 *JedecId; - UINT32 MaxPriority; - UINT32 Priority; - SPI_FLASH_PART_PROTOCOL *Protocol; - SPI_FLASH_PART_PROTOCOL **SpiFlashPartProtocol; - EFI_STATUS Status; - - // - // Assume failure - // - FlashSize = 0; - HandleArray = NULL; - JedecId = NULL; - SpiFlashPartProtocol = NULL; - - // - // Locate handles containing SPI_FLASH_PART_PROTOCOLS - // - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gSpiFlashPartProtocolGuid, - NULL, - &HandleCount, - &HandleArray - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "ERROR - Failed to locate SPI_FLASH_PART_PROTOCOL, Status: %r\r\n", Status)); - } else { - // - // Allocate and fill in the protocol array - // - DEBUG ((DEBUG_INFO, "%d SPI flash part descriptions found\r\n", HandleCount)); - SpiFlashPartProtocol = AllocatePool (HandleCount * sizeof (*SpiFlashPartProtocol)); - if (SpiFlashPartProtocol == NULL) { - DEBUG ((DEBUG_ERROR, "ERROR - Failed to allocate SpiFlashDataProtocol buffer\r\n")); - } else { - for (HandleIndex = 0; HandleCount > HandleIndex; HandleIndex++) { - Status = gBS->OpenProtocol ( - HandleArray [HandleIndex], - &gSpiFlashPartProtocolGuid, - (VOID **) &SpiFlashPartProtocol [HandleIndex], - NULL, - NULL, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "ERROR - Failed to open SPI_FLASH_DATA_PROTOCOL, Status: %r\r\n", Status)); - break; - } - } - if (!EFI_ERROR (Status)) { - // - // Allocate the JEDEC ID buffer - // - BufferLength = 0; - for (HandleIndex = 0; HandleCount > HandleIndex; HandleIndex++) { - // - // Get the JEDEC ID opcode description - // - Protocol = SpiFlashPartProtocol [HandleIndex]; - Description = Protocol->GetFlashDescription ( - Protocol, - NULL, - NULL - ); - if (BufferLength < Description->JededIdResponseLengthInBytes) { - BufferLength = Description->JededIdResponseLengthInBytes; - } - } - JedecId = AllocatePool (BufferLength); - if (JedecId == NULL) { - DEBUG ((DEBUG_ERROR, "ERROR - Failed to allocate JedecId buffer\r\n")); - } else { - // - // Start with the first flash type description; - // - MaxPriority = 0xffffffff; - do { - // - // Determine the highest priority protocol - // - Priority = 0; - for (HandleIndex = 0; HandleCount > HandleIndex; HandleIndex++) { - Protocol = SpiFlashPartProtocol [HandleIndex]; - if ((MaxPriority >= Protocol->Priority) - && (Priority < Protocol->Priority)) - Priority = Protocol->Priority; - } - if (Priority == 0) { - // - // The flash is not supported - // - break; - } - - // - // Walk the handles containing the SPI flash part protocol - // - HandleIndex = 0; - do { - // - // Verify the description type matches and the opcode table - // supports the minimum number of entries required for the code - // - Protocol = SpiFlashPartProtocol [HandleIndex]; - if (Priority == Protocol->Priority) { - // - // Get the JEDEC ID opcode description - // - Description = Protocol->GetFlashDescription ( - Protocol, - NULL, - NULL - ); - if ((Description == NULL) - || (SPI_FLASH_PART_OPCODE_JEDEC_ID == Description->OpcodeTableEntries)) { - DEBUG ((DEBUG_ERROR, "ERROR - JEDEC ID opcode not available\r\n")); - } else { - // - // Display the flash part - // - DEBUG ((DEBUG_INFO, "Priority: 0x%08x, SPI Flash Part: %s\r\n", Priority, Description->PartNumber )); - - // - // Attempt to read the JEDEC ID - // - Status = PerformJedecIdOperation ( - Context, - Description, - Description->JededIdResponseLengthInBytes, - JedecId - ); - if (!EFI_ERROR (Status)) { - // - // Display the JEDEC ID - // - DEBUG_CODE_BEGIN (); - { - UINTN Index; - - DEBUG ((DEBUG_INFO, "JEDEC ID:")); - for (Index = 0; Description->JededIdResponseLengthInBytes > Index; Index++) { - DEBUG ((DEBUG_INFO, " 0x%02x", JedecId [Index])); - } - DEBUG ((DEBUG_INFO, "\r\n")); - } - DEBUG_CODE_END (); - - // - // Verify support and determine flash size - // - Description = Protocol->GetFlashDescription ( - Protocol, - JedecId, - &FlashSize - ); - if (Description != NULL) { - // - // The flash device is supported - // Return the table for this flash device - // - DEBUG ((DEBUG_INFO, "SPI flash device found: %s\r\n", Description->PartNumber)); - *FlashDescription = Description; - goto PartFound; - } - } - } - } - - // - // Set next handle - // - HandleIndex += 1; - } while (HandleCount > HandleIndex); - - // - // Set the next priority - // - MaxPriority = Priority - 1; - } while (Priority != 0); - - // - // No flash device found - // - DEBUG ((DEBUG_ERROR, "Matching SPI flash description not found\r\n")); - } - } - } - } - -PartFound: - // - // Free the buffers - // - if (JedecId != NULL) { - FreePool (JedecId); - } - if (SpiFlashPartProtocol != NULL) { - FreePool (SpiFlashPartProtocol); - } - if (HandleArray != NULL) { - FreePool (HandleArray); - } - - // - // Return the flash size - // Zero (0) indicates flash not found or not supported - // - return FlashSize; -} - -/** - Load opcode into the SPI controller for specific flash device - - @param[in] FlashDescription Description of the flash device - - @retval EFI_SUCCESS The opcode was successfully loaded - @retval EFI_UNSUPPORTED The opcode was not found - -**/ -EFI_STATUS -SpiFlashInit ( - IN CONST FLASH_PART_DESCRIPTION *FlashDescription - ) -{ - EFI_STATUS Status; - SPI_INIT_DATA SpiInitTable; - UINTN Index; - UINT8 CmdCfgIndex; - CONST UINT8 OpcodeMap [] = { - SPI_READ_ID, // SPI_FLASH_PART_OPCODE_JEDEC_ID - SPI_RDSR, // SPI_FLASH_PART_OPCODE_READ_STATUS - SPI_WRSR, // SPI_FLASH_PART_OPCODE_WRITE_STATUS - SPI_READ, // SPI_FLASH_PART_OPCODE_READ_BYTES - SPI_PROG, // SPI_FLASH_PART_OPCODE_WRITE_256_BYTE_PAGE - SPI_SERASE, // SPI_FLASH_PART_OPCODE_ERASE_4K_BYTE_BLOCK - SPI_BERASE, // SPI_FLASH_PART_OPCODE_ERASE_64K_BYTE_BLOCK - SPI_WRDI_SFDP // SPI_FLASH_PART_OPCODE_WRITE_DISABLE - }; - - Status = EFI_SUCCESS; - - ZeroMem (&SpiInitTable, sizeof (SPI_INIT_DATA)); - - SpiInitTable.PrefixOpcode[SPI_WREN] = FlashDescription->WriteEnable; - SpiInitTable.PrefixOpcode[SPI_EWSR] = FlashDescription->WriteStatusEnable; - - SpiInitTable.BiosStartOffset = (UINTN)BIOS_REGION_FLASH_OFFSET; - SpiInitTable.BiosSize = (UINTN)PcdGet32 (PcdBiosImageSize); - SpiInitTable.SpecialOpcodeEntry = NULL; - - ASSERT (FlashDescription->OpcodeTableEntries <= SPI_NUM_OPCODE); - - for (Index = 0;Index < FlashDescription->OpcodeTableEntries;Index++) { - CmdCfgIndex = OpcodeMap[Index]; - switch (FlashDescription->OpcodeTable[Index].MaxFrequency) { - case 20000000: - SpiInitTable.SpiCmdConfig[CmdCfgIndex].Frequency = EnumSpiCycle20MHz; - break; - - case 33000000: - SpiInitTable.SpiCmdConfig[CmdCfgIndex].Frequency = EnumSpiCycle33MHz; - break; - - case 50000000: - SpiInitTable.SpiCmdConfig[CmdCfgIndex].Frequency = EnumSpiCycle50MHz; - break; - - case 66000000: - SpiInitTable.SpiCmdConfig[CmdCfgIndex].Frequency = EnumSpiCycle66MHz; - break; - - default: - SpiInitTable.SpiCmdConfig[CmdCfgIndex].Frequency = EnumSpiCycle33MHz; - break; - } - - switch (FlashDescription->OpcodeTable[Index].OpcodeIndex) { - case SPI_FLASH_PART_OPCODE_JEDEC_ID: - SpiInitTable.SpiCmdConfig[CmdCfgIndex].Operation = EnumSpiOperationJedecId; - break; - - case SPI_FLASH_PART_OPCODE_READ_STATUS: - SpiInitTable.SpiCmdConfig[CmdCfgIndex].Operation = EnumSpiOperationReadStatus; - break; - - case SPI_FLASH_PART_OPCODE_WRITE_STATUS: - SpiInitTable.SpiCmdConfig[CmdCfgIndex].Operation = EnumSpiOperationWriteStatus; - break; - - case SPI_FLASH_PART_OPCODE_READ_BYTES: - SpiInitTable.SpiCmdConfig[CmdCfgIndex].Operation = EnumSpiOperationReadData; - break; - - case SPI_FLASH_PART_OPCODE_WRITE_256_BYTE_PAGE: - SpiInitTable.SpiCmdConfig[CmdCfgIndex].Operation = EnumSpiOperationProgramData_1_Byte; - break; - - case SPI_FLASH_PART_OPCODE_ERASE_4K_BYTE_BLOCK: - SpiInitTable.SpiCmdConfig[CmdCfgIndex].Operation = EnumSpiOperationErase_4K_Byte; - break; - - case SPI_FLASH_PART_OPCODE_ERASE_64K_BYTE_BLOCK: - SpiInitTable.SpiCmdConfig[CmdCfgIndex].Operation = EnumSpiOperationErase_64K_Byte; - break; - - case SPI_FLASH_PART_OPCODE_WRITE_DISABLE_DISCOVERY: - SpiInitTable.SpiCmdConfig[CmdCfgIndex].Operation = EnumSpiOperationWriteDisable; - break; - - default: - DEBUG ((DEBUG_ERROR, "Unrecognized opcode index\r\n")); - ASSERT(FALSE); - break; - } - } - - Status = mSpiProtocol->Init (mSpiProtocol, &SpiInitTable); - - return Status; -} diff --git a/BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDevice.h b/BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDevice.h deleted file mode 100644 index cb8229629d..0000000000 --- a/BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDevice.h +++ /dev/null @@ -1,211 +0,0 @@ -/** @file - SPI Device driver for Braswell Platform. - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _SPI_DEVICE_H_ -#define _SPI_DEVICE_H_ - -#include -#include -#include -#include -#include -#include -#include -#include - -// -// Defines the offset in the SPI device where the BIOS region starts. -// -#define BIOS_REGION_FLASH_OFFSET (PcdGet32 (PcdBiosImageBase) - PcdGet32 (PcdFlashAreaBaseAddress)) -#define VN_STORAGE_REGION_FLASH_OFFSET (PcdGet32 (PcdFlashNvStorageVariableBase) - PcdGet32 (PcdFlashAreaBaseAddress)) - -extern EFI_SPI_PROTOCOL *mSpiProtocol; -extern UINTN mNvStorageBase; - -// -// Prefix Opcode Index on the host SPI controller -// -typedef enum { - SPI_WREN, // Prefix Opcode 0: Write Enable - SPI_EWSR, // Prefix Opcode 1: Enable Write Status Register -} PREFIX_OPCODE_INDEX; - -// -// Opcode Menu Index on the host SPI controller -// -typedef enum { - SPI_READ_ID, // Opcode 0: READ ID, Read cycle with address - SPI_READ, // Opcode 1: READ, Read cycle with address - SPI_RDSR, // Opcode 2: Read Status Register, No address - SPI_WRDI_SFDP, // Opcode 3: Write Disable or Discovery Parameters, No address - SPI_SERASE, // Opcode 4: Sector Erase (4KB), Write cycle with address - SPI_BERASE, // Opcode 5: Block Erase (32KB), Write cycle with address - SPI_PROG, // Opcode 6: Byte Program, Write cycle with address - SPI_WRSR, // Opcode 7: Write Status Register, No address -} SPI_OPCODE_INDEX; - -EFI_STATUS -EFIAPI -InitSpiDevice ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ); - -EFI_STATUS -EFIAPI -SpiRead ( - IN UINTN SpiOffset, - IN OUT UINTN *Size, - OUT UINT8 *Buffer - ); - -EFI_STATUS -EFIAPI -SpiWrite ( - IN UINTN SpiOffset, - IN OUT UINTN *Size, - IN UINT8 *Buffer - ); - -EFI_STATUS -EFIAPI -SpiErase ( - IN UINTN SpiOffset, - IN OUT UINTN Size - ); - -EFI_STATUS -EFIAPI -SpiLock ( - IN UINTN SpiOffset, - IN OUT UINTN Size, - IN BOOLEAN Lock - ); - -EFI_STATUS -EFIAPI -SpiSetRange ( - IN UINTN SpiOffset, - IN UINTN Size, - IN BOOLEAN ReadLock, - IN BOOLEAN WriteLock - ); - -EFI_STATUS -EFIAPI -SpiLockRanges ( - ); - -BOOLEAN -ReadUsingMmio ( - IN UINTN SpiOffset - ); - -/** - Get the JEDED ID from the SPI flash part. - - @param[in] Context Pointer to a context data structure - needed by the SPI controller driver - @param[in] Description Description of the flash device - @param[in] BufferLength Length of the JedecId buffer - @param[out] JedecId Pointer to a buffer to fill with - the JEDEC ID value - - @retval EFI_SUCCESS The JEDEC ID value is in the buffer - @retval EFI_INVALID_PARAMETER JedecId is NULL - @retval EFI_INVALID_PARAMETER Description is NULL - @retval EFI_INVALID_PARAMETER Too few opcode entries - @retval EFI_INVALID_PARAMETER JEDEC ID response buffer too small - @retval EFI_UNSUPPORTED JEDEC ID opcode not found - -**/ -EFI_STATUS -EFIAPI -JedecIdRead ( - IN VOID *Context, - IN CONST FLASH_PART_DESCRIPTION *Description, - IN UINTN BufferLength, - OUT UINT8 *JedecId - ); - -/** - Get the JEDED ID from the SPI flash part. - - @param[in] Context Pointer to a context data structure - needed by the SPI controller driver - @param[in] Description Description of the flash device - @param[in] BufferLength Length of the JedecId buffer - @param[out] JedecId Pointer to a buffer to fill with - the JEDEC ID value - - @retval EFI_SUCCESS The JEDEC ID value is in the buffer - @retval EFI_INVALID_PARAMETER JedecId is NULL - @retval EFI_INVALID_PARAMETER Description is NULL - @retval EFI_INVALID_PARAMETER Too few opcode entries - @retval EFI_INVALID_PARAMETER JEDEC ID response buffer too small - -**/ -typedef -EFI_STATUS -(EFIAPI *PERFORM_JEDEC_ID_OPERATION) ( - IN VOID *Context, - IN CONST FLASH_PART_DESCRIPTION *Description, - IN UINTN BufferLength, - OUT UINT8 *JedecId - ); - -/** - Determine the flash size and description - - @param[in] PerformJedecIdOperation Callback routine to initiate - the JEDEC ID operation using - the SPI controller to identify - the flash part. - @param[in] Context Pointer to a context structure to pass - to PerformJedecIdOperation - @param[out] FlashDescription Pointer to a buffer to receive a - pointer to a FLASH_PART_DESCRIPTION - data structure containing the flash - part information. - - @return This routine returns the size of the flash part if it is - supported. Zero is returned if the flash part is not - supported. - -**/ -UINT64 -EFIAPI -FindFlashSupport ( - IN PERFORM_JEDEC_ID_OPERATION PerformJedecIdOperation, - IN VOID *Context, - OUT CONST FLASH_PART_DESCRIPTION **FlashDescription - ); - - -/** - Load opcode into the SPI controller for specific flash device - - @param[in] FlashDescription Description of the flash device - - @retval EFI_SUCCESS The opcode was successfully loaded - @retval EFI_UNSUPPORTED The opcode was not found - -**/ -EFI_STATUS -SpiFlashInit ( - IN CONST FLASH_PART_DESCRIPTION *FlashDescription - ); - -#endif diff --git a/BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDeviceDxe.c b/BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDeviceDxe.c deleted file mode 100644 index 907b8e9517..0000000000 --- a/BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDeviceDxe.c +++ /dev/null @@ -1,152 +0,0 @@ -/** @file - This driver for SPI Device initialization - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include -#include -#include -#include -#include -#include -#include -#include "SpiDevice.h" - -SPI_DEVICE_PROTOCOL mSpiDevProtocol = { - SpiRead, - SpiWrite, - SpiErase, - SpiLock, - SpiSetRange, - SpiLockRanges -}; - -VOID -EFIAPI -SpiDeviceVirtualAddressChangeEvent ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - // - // Update protocol pointer to the SPI Controller interface. - // - EfiConvertPointer (0x00, (VOID**) &(mSpiProtocol)); - - // - // Update the NV Storage location for runtime access. - // - EfiConvertPointer (0x00, (VOID**) &(mNvStorageBase)); - - // - // Take care of pointers in protocol. - // - EfiConvertPointer (0x00, (VOID**) &(mSpiDevProtocol.SpiRead)); - EfiConvertPointer (0x00, (VOID**) &(mSpiDevProtocol.SpiWrite)); - EfiConvertPointer (0x00, (VOID**) &(mSpiDevProtocol.SpiErase)); - EfiConvertPointer (0x00, (VOID**) &(mSpiDevProtocol.SpiLock)); -} - -EFI_STATUS -EFIAPI -InitSpiDevice ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_EVENT Event; - CONST FLASH_PART_DESCRIPTION *FlashDescription; - UINT64 FlashSize; - EFI_HANDLE Handle; - EFI_STATUS Status; - - mNvStorageBase = PcdGet32 (PcdFlashNvStorageVariableBase); - - // - // Locate the SPI controller protocol and save it for later. - // - DEBUG((EFI_D_INFO, "Locating SPI Controller Protocol.\n")); - Status = gBS->LocateProtocol ( - &gEfiSpiProtocolGuid, - NULL, - (VOID **) &mSpiProtocol - ); - ASSERT_EFI_ERROR(Status); - - // - // Loop through all the flash devices that are supported and see if one will - // initialize the SPI Controller interface. - // - FlashSize = FindFlashSupport ( - &JedecIdRead, - NULL, - &FlashDescription - ); - if (FlashSize == 0) { - DEBUG((EFI_D_ERROR, "No SPI flash part description found!\r\n")); - } else { - // - // Attempt to configure the SPI controller for this device. - // - DEBUG((EFI_D_INFO, "SPI flash size: %d MBytes\n", DivU64x32(FlashSize, 1024 * 1024 ))); - DEBUG((EFI_D_INFO, "Configuring SPI Controller.\n")); - - Status = SpiFlashInit (FlashDescription); - if (!EFI_ERROR (Status)) { - // - // Publish the SPI Device protocol. - // - DEBUG((EFI_D_INFO, "Installing SPI Device Protocol.\n")); - Handle = NULL; - Status = gBS->InstallMultipleProtocolInterfaces ( - &Handle, - &gSpiDeviceProtocolGuid, - &mSpiDevProtocol, - NULL - ); - if (EFI_ERROR (Status)) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Make sure we can handle virtual address changes. - // - Event = NULL; - Status = gBS->CreateEventEx ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - SpiDeviceVirtualAddressChangeEvent, - NULL, - &gEfiEventVirtualAddressChangeGuid, - &Event - ); - - return EFI_SUCCESS; - } - } - - // - // Unable to find a supported SPI device - // - DEBUG((EFI_D_ERROR, "Unable to configure SPI Controller for SPI device present.\n")); - - return EFI_UNSUPPORTED; -} - -BOOLEAN -ReadUsingMmio ( - IN UINTN SpiOffset - ) -{ - return (BOOLEAN) ((SpiOffset >= BIOS_REGION_FLASH_OFFSET) && (SpiOffset < (BIOS_REGION_FLASH_OFFSET + PcdGet32 (PcdBiosImageSize))) && (!EfiAtRuntime ())); -} diff --git a/BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDeviceDxe.inf b/BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDeviceDxe.inf deleted file mode 100644 index 9db458076c..0000000000 --- a/BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDeviceDxe.inf +++ /dev/null @@ -1,64 +0,0 @@ -## @file -# SPI Flash Device Driver -# -# Adds platform support to configure the SPI controller with the correct values -# to be used when using software sequencing. -# -# Copyright (c) 2015, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php. -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010018 - BASE_NAME = SpiDeviceDxe - FILE_GUID = DA28E378-C84B-4969-BD4D-90AA883C091A - MODULE_TYPE = DXE_RUNTIME_DRIVER - VERSION_STRING = 1.0 - ENTRY_POINT = InitSpiDevice - -[Sources] - SpiDeviceDxe.c - SpiDevice.c - SpiDevice.h - -[Packages] - ChvRefCodePkg/ChvRefCodePkg.dec - BraswellPlatformPkg/BraswellPlatformPkg.dec - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - -[LibraryClasses] - DebugLib - DxeServicesTableLib - UefiBootServicesTableLib - UefiDriverEntryPoint - UefiRuntimeLib - MemoryAllocationLib - -[Protocols] - gEfiSpiProtocolGuid ## CONSUMES - gSpiDeviceProtocolGuid ## PRODUCES - gSpiFlashPartProtocolGuid ## CONSUMES - gEfiSmmCommunicationProtocolGuid ## UNDEFINED - -[Guids] - gEfiEventVirtualAddressChangeGuid ## SOMETIMES_CONSUMES ## NOTIFY - -[Pcd] - gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES - gPlatformModuleTokenSpaceGuid.PcdFlashAreaSize ## CONSUMES - gPlatformModuleTokenSpaceGuid.PcdBiosImageBase ## CONSUMES - gPlatformModuleTokenSpaceGuid.PcdBiosImageSize ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase ## CONSUMES - -[Depex] - gEfiSpiProtocolGuid - diff --git a/BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDeviceSmm.c b/BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDeviceSmm.c deleted file mode 100644 index 7d02aff9d0..0000000000 --- a/BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDeviceSmm.c +++ /dev/null @@ -1,222 +0,0 @@ -/** @file - SMM driver for SPI Device initialization. - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include -#include -#include -#include -#include -#include "SpiDevice.h" -#include "SpiDeviceSmmComm.h" - -SPI_DEVICE_PROTOCOL mSpiDevProtocol = { - SpiRead, - SpiWrite, - SpiErase, - SpiLock, - SpiSetRange, - SpiLockRanges -}; - -EFI_STATUS -EFIAPI -SpiDeviceSmmHandler ( - IN EFI_HANDLE DispatchHandle, - IN CONST VOID *RegisterContext, - IN OUT VOID *CommBuffer, - IN OUT UINTN *CommBufferSize - ) -{ - EFI_STATUS Status; - SMM_SPI_DEV_COMMUNICATE_FUNCTION_HEADER *SpiDevCommHeader; - SMM_SPI_DEV_READ_WRITE_ERASE_HEADER *SpiDevDataOpHeader; - SMM_SPI_DEV_LOCK_HEADER *SpiDevLockHeader; - SMM_SPI_DEV_SET_RANGE_HEADER *SpiDevSetRangeHeader; - - ASSERT (CommBuffer != NULL); - - SpiDevCommHeader = (SMM_SPI_DEV_COMMUNICATE_FUNCTION_HEADER*) CommBuffer; - switch (SpiDevCommHeader->Function) { - case SPI_DEV_FUNCTION_READ: - SpiDevDataOpHeader = (SMM_SPI_DEV_READ_WRITE_ERASE_HEADER*) SpiDevCommHeader->Data; - Status = SpiRead ( - SpiDevDataOpHeader->Offset, - &SpiDevDataOpHeader->Size, - (UINT8*) (SpiDevDataOpHeader + 1) - ); - break; - case SPI_DEV_FUNCTION_WRITE: - SpiDevDataOpHeader = (SMM_SPI_DEV_READ_WRITE_ERASE_HEADER*) SpiDevCommHeader->Data; - Status = SpiWrite ( - SpiDevDataOpHeader->Offset, - &SpiDevDataOpHeader->Size, - (UINT8*) (SpiDevDataOpHeader + 1) - ); - break; - case SPI_DEV_FUNCTION_ERASE: - SpiDevDataOpHeader = (SMM_SPI_DEV_READ_WRITE_ERASE_HEADER*) SpiDevCommHeader->Data; - Status = SpiErase ( - SpiDevDataOpHeader->Offset, - SpiDevDataOpHeader->Size - ); - break; - case SPI_DEV_FUNCTION_LOCK: - SpiDevLockHeader = (SMM_SPI_DEV_LOCK_HEADER*) SpiDevCommHeader->Data; - Status = SpiLock ( - SpiDevLockHeader->Offset, - SpiDevLockHeader->Size, - SpiDevLockHeader->Lock - ); - break; - case SPI_DEV_FUNCTION_SET_RANGE: - SpiDevSetRangeHeader = (SMM_SPI_DEV_SET_RANGE_HEADER*) SpiDevCommHeader->Data; - Status = SpiSetRange ( - SpiDevSetRangeHeader->Offset, - SpiDevSetRangeHeader->Size, - SpiDevSetRangeHeader->ReadLock, - SpiDevSetRangeHeader->WriteLock - ); - break; - case SPI_DEV_FUNCTION_LOCK_RANGES: - Status = SpiLockRanges (); - break; - default: - ASSERT (FALSE); - Status = EFI_UNSUPPORTED; - break; - } - - // - // Set the return value. - // - SpiDevCommHeader->ReturnStatus = Status; - - return EFI_SUCCESS; -} - -EFI_STATUS -EFIAPI -InitSpiDevice ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - CONST FLASH_PART_DESCRIPTION *FlashDescription; - UINT64 FlashSize; - EFI_HANDLE Handle; - EFI_STATUS Status; - - //-------------------------------------------------- - // - // Note only this routine is able to make calls - // into the DXE environment since it is called - // synchronously from that environment and DXE - // is still executing in physical mode. - // - //-------------------------------------------------- - - mNvStorageBase = PcdGet32 (PcdFlashNvStorageVariableBase); - - // - // Locate the SPI controller protocol and save it for later. - // - DEBUG((EFI_D_INFO, "Locating SPI Controller Protocol.\n")); - Status = gSmst->SmmLocateProtocol ( - &gEfiSmmSpi2ProtocolGuid, - NULL, - (VOID **) &mSpiProtocol - ); - ASSERT_EFI_ERROR(Status); - - - // - // Loop through all the flash devices that are supported and see if one will - // initialize the SPI Controller interface. - // - FlashSize = FindFlashSupport ( - &JedecIdRead, - NULL, - &FlashDescription - ); - if (FlashSize == 0) { - DEBUG((EFI_D_ERROR, "No SPI flash part description found!\r\n")); - } else { - // - // Attempt to configure the SPI controller for this device. - // - DEBUG((EFI_D_INFO, "SPI flash size: %d MBytes\n", DivU64x32(FlashSize, 1024 * 1024 ))); - DEBUG((EFI_D_INFO, "Configuring SPI Controller.\n")); - Status = SpiFlashInit (FlashDescription); - if (!EFI_ERROR (Status)) { - // - // Publish the SMM SPI Device protocol for FVB service - // - DEBUG((EFI_D_INFO, "Installing SPI Device Protocol.\n")); - Handle = NULL; - Status = gSmst->SmmInstallProtocolInterface ( - &Handle, - &gSmmSpiDeviceProtocolGuid, - EFI_NATIVE_INTERFACE, - &mSpiDevProtocol - ); - if (EFI_ERROR (Status)) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Install protocol to inform other DXE drivers the SMM service is available. - // - Handle = NULL; - Status = gBS->InstallProtocolInterface ( - &Handle, - &gSmmSpiDeviceProtocolGuid, - EFI_NATIVE_INTERFACE, - &mSpiDevProtocol - ); - if (EFI_ERROR (Status)) { - DEBUG((EFI_D_ERROR, "Unable to install SMM SPI device protocol, Status: %r\n", Status)); - return Status; - } - - // - // Install communication handler. - // - Handle = NULL; - Status = gSmst->SmiHandlerRegister (SpiDeviceSmmHandler, &gSmmSpiDeviceProtocolGuid, &Handle); - if (EFI_ERROR (Status)) { - DEBUG((EFI_D_ERROR, "Unable to register SMM SPI handler, Status: %r\n", Status)); - return Status; - } - - DEBUG((EFI_D_INFO, "SPI flash controller configured successfully\n", Status)); - return EFI_SUCCESS; - } - } - - // - // Unable to find a supported SPI device - // - DEBUG((EFI_D_ERROR, "Unable to configure SPI Controller for SPI device present.\n")); - - return EFI_UNSUPPORTED; -} - -BOOLEAN -ReadUsingMmio ( - IN UINTN SpiOffset - ) -{ - return (BOOLEAN) ((SpiOffset >= BIOS_REGION_FLASH_OFFSET) && (SpiOffset < (BIOS_REGION_FLASH_OFFSET + PcdGet32 (PcdBiosImageSize)))); -} diff --git a/BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDeviceSmm.inf b/BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDeviceSmm.inf deleted file mode 100644 index d698f25159..0000000000 --- a/BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDeviceSmm.inf +++ /dev/null @@ -1,62 +0,0 @@ -## @file -# SPI Device SMM Driver -# -# Adds platform support to configure the SPI controller with the correct values -# to be used when using software sequencing. This driver initializes EMST* F25L016A -# SPI flash device and installs gSmmSpiDeviceProtocolGuid protocol. -# -# Copyright (c) 2015, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php. -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010018 - BASE_NAME = SpiDeviceSmm - FILE_GUID = 163774A8-917F-40E5-AB54-B4BFA11D41F9 - MODULE_TYPE = DXE_SMM_DRIVER - VERSION_STRING = 1.0 - PI_SPECIFICATION_VERSION = 0x0001000A - ENTRY_POINT = InitSpiDevice - -[Sources] - SpiDeviceSmm.c - SpiDevice.c - SpiDevice.h - -[Packages] - ChvRefCodePkg/ChvRefCodePkg.dec - BraswellPlatformPkg/BraswellPlatformPkg.dec - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - -[LibraryClasses] - UefiBootServicesTableLib - UefiDriverEntryPoint - DebugLib - SmmServicesTableLib - BaseLib - MemoryAllocationLib - -[Protocols] - gEfiSmmSpi2ProtocolGuid ## CONSUMES - gSmmSpiDeviceProtocolGuid ## PRODUCES - gSpiFlashPartProtocolGuid ## CONSUMES - -[Pcd] - gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES - gPlatformModuleTokenSpaceGuid.PcdFlashAreaSize ## CONSUMES - gPlatformModuleTokenSpaceGuid.PcdBiosImageBase ## CONSUMES - gPlatformModuleTokenSpaceGuid.PcdBiosImageSize ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase ## CONSUMES - -[Depex] - gEfiSmmSpi2ProtocolGuid - diff --git a/BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDeviceSmmComm.h b/BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDeviceSmmComm.h deleted file mode 100644 index ee2d0a42a4..0000000000 --- a/BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDeviceSmmComm.h +++ /dev/null @@ -1,73 +0,0 @@ -/** @file - SMM Communication formats for the SPI Device protocols. - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _SPI_DEVICE_SMM_COMM_H_ -#define _SPI_DEVICE_SMM_COMM_H_ - -#include - -// -// Define communication constants -// -#define SPI_DEV_FUNCTION_READ 1 -#define SPI_DEV_FUNCTION_WRITE 2 -#define SPI_DEV_FUNCTION_ERASE 3 -#define SPI_DEV_FUNCTION_LOCK 4 -#define SPI_DEV_FUNCTION_SET_RANGE 5 -#define SPI_DEV_FUNCTION_LOCK_RANGES 6 - -// -// Generic SPI Device communication structure header. -// -typedef struct { - UINTN Function; - EFI_STATUS ReturnStatus; - UINT8 Data[1]; -} SMM_SPI_DEV_COMMUNICATE_FUNCTION_HEADER; - -// -// Macros used to determine size of the headers without data size. -// -#define SMM_COMMUNICATE_HEADER_SIZE (OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)) -#define SMM_SPI_DEV_COMMUNICATE_FUNCTION_HEADER_SIZE (OFFSET_OF (SMM_SPI_DEV_COMMUNICATE_FUNCTION_HEADER, Data)) - -// -// SPI Read, Write and Erase Data. Erase will not have any extra data. -// -typedef struct { - UINTN Offset; - UINTN Size; -} SMM_SPI_DEV_READ_WRITE_ERASE_HEADER; - -// -// SPI Lock -// -typedef struct { - UINTN Offset; - UINTN Size; - BOOLEAN Lock; -} SMM_SPI_DEV_LOCK_HEADER; - -// -// SPI Set Range -// -typedef struct { - UINTN Offset; - UINTN Size; - BOOLEAN ReadLock; - BOOLEAN WriteLock; -} SMM_SPI_DEV_SET_RANGE_HEADER; - -#endif diff --git a/BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDeviceSmmDxe.c b/BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDeviceSmmDxe.c deleted file mode 100644 index 392c549a95..0000000000 --- a/BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDeviceSmmDxe.c +++ /dev/null @@ -1,437 +0,0 @@ -/** @file - Provides an interface to the SMM SPI Device driver. - - gSpiDeviceProtocolGuid (DXE: SpiDeviceSmmDxe) - | - | via gEfiSmmCommunicationProtocolGuid - V - gSmmSpiDeviceProtocolGuid (SMM: SpiDeviceSmm) - | - | - V - gEfiSmmSpi2ProtocolGuid (SMM: SpiSmm) - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include -#include -#include -#include -#include -#include -#include "SpiDevice.h" -#include "SpiDeviceSmmComm.h" - -EFI_SMM_COMMUNICATION_PROTOCOL *mSmmComm = NULL; - -SPI_DEVICE_PROTOCOL mSpiDevProtocol = { - SpiRead, - SpiWrite, - SpiErase, - SpiLock, - SpiSetRange, - SpiLockRanges -}; - -VOID -EFIAPI -SmmSpiDeviceReady ( - IN EFI_EVENT Event, - IN VOID *Context - ); - -EFI_STATUS -CreateCommBuffer ( - OUT VOID **CommBuffer, - OUT VOID **DataArea, - IN UINTN DataSize, - IN UINTN Function - ) -{ - EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; - SMM_SPI_DEV_COMMUNICATE_FUNCTION_HEADER *SmmSpiDevFunctionHeader; - - // - // Allocate communication buffer. - // - SmmCommunicateHeader = AllocatePool (DataSize + SMM_COMMUNICATE_HEADER_SIZE + SMM_SPI_DEV_COMMUNICATE_FUNCTION_HEADER_SIZE); - if (SmmCommunicateHeader == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Fill in new structure will data from caller. - // - CopyGuid (&SmmCommunicateHeader->HeaderGuid, &gSmmSpiDeviceProtocolGuid); - SmmCommunicateHeader->MessageLength = DataSize + SMM_SPI_DEV_COMMUNICATE_FUNCTION_HEADER_SIZE; - SmmSpiDevFunctionHeader = (SMM_SPI_DEV_COMMUNICATE_FUNCTION_HEADER*) SmmCommunicateHeader->Data; - SmmSpiDevFunctionHeader->Function = Function; - - // - // Assign return values. - // - *CommBuffer = SmmCommunicateHeader; - if (DataArea != NULL) { - *DataArea = SmmSpiDevFunctionHeader->Data; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -SendCommBuffer ( - IN OUT EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader, - IN UINTN DataSize - ) -{ - EFI_STATUS Status; - UINTN CommSize; - SMM_SPI_DEV_COMMUNICATE_FUNCTION_HEADER *SmmSpiDevFunctionHeader; - - // - // Compute actual size of communication data. - // - CommSize = DataSize + SMM_COMMUNICATE_HEADER_SIZE + SMM_SPI_DEV_COMMUNICATE_FUNCTION_HEADER_SIZE; - - // - // Send the message to be processed in SMM. - // - Status = mSmmComm->Communicate (mSmmComm, SmmCommunicateHeader, &CommSize); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Get the return value from the SMM function. - // - SmmSpiDevFunctionHeader = (SMM_SPI_DEV_COMMUNICATE_FUNCTION_HEADER*) SmmCommunicateHeader->Data; - - return SmmSpiDevFunctionHeader->ReturnStatus; -} - -EFI_STATUS -EFIAPI -SpiRead ( - IN UINTN SpiOffset, - IN OUT UINTN *Size, - OUT UINT8 *Buffer - ) -{ - EFI_STATUS Status; - UINTN DataSize; - EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; - SMM_SPI_DEV_READ_WRITE_ERASE_HEADER *SpiDevReadHeader; - - // - // Validate input parameters. - // - if (Size == NULL || Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // Determine the actual data size required for the transaction. - // - DataSize = *Size + sizeof(SMM_SPI_DEV_READ_WRITE_ERASE_HEADER); - - // - // Create the communication buffer. - // - Status = CreateCommBuffer ((VOID**) &SmmCommunicateHeader, (VOID**) &SpiDevReadHeader, DataSize, SPI_DEV_FUNCTION_READ); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Fill in communication buffer parameters. - // - SpiDevReadHeader->Offset = SpiOffset; - SpiDevReadHeader->Size = *Size; - - // - // Communicate request to SMM driver and fill in return values. - // - Status = SendCommBuffer (SmmCommunicateHeader, DataSize); - *Size = SpiDevReadHeader->Size; - if (!EFI_ERROR (Status)) { - CopyMem (Buffer, (UINT8*)(SpiDevReadHeader + 1), *Size); - } - - return Status; -} - -EFI_STATUS -EFIAPI -SpiWrite ( - IN UINTN SpiOffset, - IN OUT UINTN *Size, - IN UINT8 *Buffer - ) -{ - EFI_STATUS Status; - UINTN DataSize; - EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; - SMM_SPI_DEV_READ_WRITE_ERASE_HEADER *SpiDevWriteHeader; - - // - // Validate input parameters. - // - if (Size == NULL || Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // Determine the actual data size required for the transaction. - // - DataSize = *Size + sizeof(SMM_SPI_DEV_READ_WRITE_ERASE_HEADER); - - // - // Create the communication buffer. - // - Status = CreateCommBuffer ((VOID**) &SmmCommunicateHeader, (VOID**) &SpiDevWriteHeader, DataSize, SPI_DEV_FUNCTION_WRITE); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Fill in communication buffer parameters. - // - SpiDevWriteHeader->Offset = SpiOffset; - SpiDevWriteHeader->Size = *Size; - CopyMem ((UINT8*)(SpiDevWriteHeader + 1), Buffer, *Size); - - // - // Communicate request to SMM driver and fill in return values. - // - Status = SendCommBuffer (SmmCommunicateHeader, DataSize); - *Size = SpiDevWriteHeader->Size; - - return Status; -} - -EFI_STATUS -EFIAPI -SpiErase ( - IN UINTN SpiOffset, - IN OUT UINTN Size - ) -{ - EFI_STATUS Status; - UINTN DataSize; - EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; - SMM_SPI_DEV_READ_WRITE_ERASE_HEADER *SpiDevEraseHeader; - - // - // Determine the actual data size required for the transaction. - // - DataSize = sizeof(SMM_SPI_DEV_READ_WRITE_ERASE_HEADER); - - // - // Create the communication buffer. - // - Status = CreateCommBuffer ((VOID**) &SmmCommunicateHeader, (VOID**) &SpiDevEraseHeader, DataSize, SPI_DEV_FUNCTION_ERASE); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Fill in communication buffer parameters. - // - SpiDevEraseHeader->Offset = SpiOffset; - SpiDevEraseHeader->Size = Size; - - // - // Communicate request to SMM driver and fill in return values. - // - Status = SendCommBuffer (SmmCommunicateHeader, DataSize); - - return Status; -} - -EFI_STATUS -EFIAPI -SpiLock ( - IN UINTN SpiOffset, - IN OUT UINTN Size, - IN BOOLEAN Lock - ) -{ - EFI_STATUS Status; - UINTN DataSize; - EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; - SMM_SPI_DEV_LOCK_HEADER *SmmSpiDevLockHeader; - - // - // Compute data size required for the transaction. - // - DataSize = sizeof(SMM_SPI_DEV_LOCK_HEADER); - - // - // Create the communication buffer. - // - Status = CreateCommBuffer ((VOID**) &SmmCommunicateHeader, (VOID**) &SmmSpiDevLockHeader, DataSize, SPI_DEV_FUNCTION_LOCK); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Fill in communication buffer parameters. - // - SmmSpiDevLockHeader->Offset = SpiOffset; - SmmSpiDevLockHeader->Size = Size; - SmmSpiDevLockHeader->Lock = Lock; - - // - // Communicate request to SMM driver and fill in return values. - // - Status = SendCommBuffer (SmmCommunicateHeader, DataSize); - - return Status; -} - -EFI_STATUS -EFIAPI -SpiSetRange ( - IN UINTN SpiOffset, - IN UINTN Size, - IN BOOLEAN ReadLock, - IN BOOLEAN WriteLock - ) -{ - EFI_STATUS Status; - UINTN DataSize; - EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; - SMM_SPI_DEV_SET_RANGE_HEADER *SmmSpiDevSetRangeHeader; - - // - // Compute data size required for the transaction. - // - DataSize = sizeof(SMM_SPI_DEV_SET_RANGE_HEADER); - - // - // Create the communication buffer. - // - Status = CreateCommBuffer ((VOID**) &SmmCommunicateHeader, (VOID**) &SmmSpiDevSetRangeHeader, DataSize, SPI_DEV_FUNCTION_SET_RANGE); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Fill in communication buffer parameters. - // - SmmSpiDevSetRangeHeader->Offset = SpiOffset; - SmmSpiDevSetRangeHeader->Size = Size; - SmmSpiDevSetRangeHeader->ReadLock = ReadLock; - SmmSpiDevSetRangeHeader->WriteLock = WriteLock; - - // - // Communicate request to SMM driver and fill in return values. - // - Status = SendCommBuffer (SmmCommunicateHeader, DataSize); - - return Status; -} - -EFI_STATUS -EFIAPI -SpiLockRanges ( - ) -{ - EFI_STATUS Status; - EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; - - // - // Create the communication buffer. - // - Status = CreateCommBuffer ((VOID**) &SmmCommunicateHeader, NULL, 0, SPI_DEV_FUNCTION_LOCK_RANGES); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Communicate request to SMM driver and fill in return values. - // - Status = SendCommBuffer (SmmCommunicateHeader, 0); - - return Status; -} - -EFI_STATUS -EFIAPI -InitSpiDevice ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - VOID *SmmSpiDeviceReg; - - // - // Register for a callback when the SMM version of the SPI Device protocol - // is installed. - // - EfiCreateProtocolNotifyEvent ( - &gSmmSpiDeviceProtocolGuid, - TPL_CALLBACK, - SmmSpiDeviceReady, - NULL, - &SmmSpiDeviceReg - ); - - return EFI_SUCCESS; -} - -VOID -EFIAPI -SmmSpiDeviceReady ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - EFI_HANDLE Handle; - SPI_DEVICE_PROTOCOL *SmmSpiDevice; - EFI_STATUS Status; - - // - // Locate the protocol first just to make sure it was actually installed. - // - Status = gBS->LocateProtocol ( - &gSmmSpiDeviceProtocolGuid, - NULL, - (VOID **) &SmmSpiDevice - ); - if (EFI_ERROR (Status)) { - return; - } - - // - // SMM Service installed so get communication link to SMM - // - Status = gBS->LocateProtocol ( - &gEfiSmmCommunicationProtocolGuid, - NULL, - (VOID **) &mSmmComm - ); - ASSERT_EFI_ERROR (Status); - - // - // Install DXE protocol so it can be used by drivers. - // - Handle = NULL; - Status = gBS->InstallProtocolInterface ( - &Handle, - &gSpiDeviceProtocolGuid, - EFI_NATIVE_INTERFACE, - &mSpiDevProtocol - ); - ASSERT_EFI_ERROR (Status); -} diff --git a/BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDeviceSmmDxe.inf b/BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDeviceSmmDxe.inf deleted file mode 100644 index d7effc6668..0000000000 --- a/BraswellPlatformPkg/Flash/SpiDeviceDxe/SpiDeviceSmmDxe.inf +++ /dev/null @@ -1,51 +0,0 @@ -## @file -# SMM Based SPI Device Dxe Driver -# -# Adds platform support to configure the SPI controller with the correct values -# to be used when using software sequencing. This driver installs gSpiDeviceProtocolGuid -# protocol based on SMM based SPI device driver. -# -# Copyright (c) 2015, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php. -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010018 - BASE_NAME = SpiDeviceSmmDxe - FILE_GUID = D7AC2008-CFBE-44A4-AD92-573F1AB9DF45 - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - ENTRY_POINT = InitSpiDevice - -[Sources] - SpiDeviceSmmDxe.c - SpiDevice.h - -[Packages] - ChvRefCodePkg/ChvRefCodePkg.dec - BraswellPlatformPkg/BraswellPlatformPkg.dec - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - -[LibraryClasses] - DebugLib - DxeServicesTableLib - UefiBootServicesTableLib - UefiDriverEntryPoint - -[Protocols] - gSpiDeviceProtocolGuid ## PRODUCES - gSmmSpiDeviceProtocolGuid ## CONSUMES - gEfiSmmCommunicationProtocolGuid ## CONSUMES - -[Depex] - gEfiSmmCommunicationProtocolGuid - diff --git a/BraswellPlatformPkg/Flash/SpiFlashParts/MX25/MX25.c b/BraswellPlatformPkg/Flash/SpiFlashParts/MX25/MX25.c deleted file mode 100644 index 424dcc3186..0000000000 --- a/BraswellPlatformPkg/Flash/SpiFlashParts/MX25/MX25.c +++ /dev/null @@ -1,208 +0,0 @@ -/** @file - MACRONIX MX25*** family SPI flash support - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include -#include -#include -#include - -// -// Initialization data that can be used to identify SPI flash part -// DeviceId0 Device ID0 of the SPI device -// DeviceId1 Device ID1 of the SPI device -// -typedef struct _SPI_CHIP_ID { - UINT8 DeviceId0; - UINT8 DeviceId1; -} SPI_CHIP_ID; - -// -// Serial Flash VendorId and DeviceId -// -#define SF_VENDOR_ID_MACRONIX 0xC2 -#define SF_DEVICE_ID0_MX25LXX 0x20 -#define SF_DEVICE_ID0_MX25UXX 0x25 -#define SF_DEVICE_ID1_MX25L16 0x15 -#define SF_DEVICE_ID1_MX25L32 0x16 -#define SF_DEVICE_ID1_MX25L64 0x17 -#define SF_DEVICE_ID1_MX25L128 0x18 -#define SF_DEVICE_ID1_MX25U32 0x36 -#define SF_DEVICE_ID1_MX25U64 0x37 - -// -// Generic SPI flash part description -// -CONST FLASH_PART_DESCRIPTION mFlashDescription = { - L"MACRONIX MX25*** family", // Part number - 1, // Number of status bytes - 0x06, // Write enable - 0x50, // Write status enable - 3, // Length of JEDEC ID response - 8, // Number of opcodes in the table - - // Opcode table - { - {33000000, 3, FALSE, 0x9f, 0, SPI_FLASH_PART_OPCODE_JEDEC_ID}, - {50000000, 1, FALSE, 0x05, 0, SPI_FLASH_PART_OPCODE_READ_STATUS}, - {50000000, 1, TRUE, 0x01, 0, SPI_FLASH_PART_OPCODE_WRITE_STATUS}, - {33000000, 0xffffffff, FALSE, 0x03, 3, SPI_FLASH_PART_OPCODE_READ_BYTES}, - {50000000, 1, TRUE, 0x02, 3, SPI_FLASH_PART_OPCODE_WRITE_256_BYTE_PAGE}, - {50000000, 0, TRUE, 0x20, 3, SPI_FLASH_PART_OPCODE_ERASE_4K_BYTE_BLOCK}, - {50000000, 0, TRUE, 0xd8, 3, SPI_FLASH_PART_OPCODE_ERASE_64K_BYTE_BLOCK}, - {50000000, 0, TRUE, 0x5a, 0, SPI_FLASH_PART_OPCODE_WRITE_DISABLE_DISCOVERY} - } -}; - -SPI_CHIP_ID mSpiChipIdTable[] = { - { - SF_DEVICE_ID0_MX25LXX, // DeviceId 0 - SF_DEVICE_ID1_MX25L16 // DeviceId 1 - }, - { - SF_DEVICE_ID0_MX25LXX, // DeviceId 0 - SF_DEVICE_ID1_MX25L32 // DeviceId 1 - }, - { - SF_DEVICE_ID0_MX25LXX, // DeviceId 0 - SF_DEVICE_ID1_MX25L64 // DeviceId 1 - }, - { - SF_DEVICE_ID0_MX25LXX, // DeviceId 0 - SF_DEVICE_ID1_MX25L128 // DeviceId 1 - }, - { - SF_DEVICE_ID0_MX25UXX, // DeviceId 0 - SF_DEVICE_ID1_MX25U32 // DeviceId 1 - }, - { - SF_DEVICE_ID0_MX25UXX, // DeviceId 0 - SF_DEVICE_ID1_MX25U64 // DeviceId 1 - } -}; - -/** - Get the flash part size and opcode table. - - Validate support for this flash part and determine - the flash part size and opcode description table - from the JEDEC ID information provided. - - @param[in] This Pointer to a SPI_FLASH_DATA_PROTOCOL - data structure. - @param[in] JedecId Pointer to a three byte buffer containing - the JEDEC ID returned by the flash part. - If the input value is NULL then a - table containing the description for the - JEDEC ID opcode is returned by this - routine. - @param[out] FlashSize Pointer to receive the size of the flash - part in bytes. Zero (0) is returned when - JedecId is NULL. - @returns When JedecId is not NULL, this routine returns a pointer - to a FLASH_PART_DESCRIPTION data structure which supports - this flash part. The returned value is NULL if the flash - part is not supported. - When JedecId is NULL, this routine returns a pointer to - a FLASH_PART_DESCRIPTION structure which supports the - JEDEC ID command. This opcode description may be used - to determine the manufacture and product data for the - SPI flash part. - -**/ -CONST FLASH_PART_DESCRIPTION * -EFIAPI -GetFlashDescription ( - IN SPI_FLASH_PART_PROTOCOL *This, - IN UINT8 *JedecId OPTIONAL, - OUT UINT64 *FlashSize OPTIONAL - ) -{ - CONST FLASH_PART_DESCRIPTION *FlashDescription; - UINT8 Shift; - UINT64 Size; - UINTN Index; - - // - // Determine if the SPI flash device is supported - // - Size = 0; - FlashDescription = &mFlashDescription; - if (JedecId != NULL) { - FlashDescription = NULL; - if (JedecId [0] != SF_VENDOR_ID_MACRONIX) - return NULL; - - for (Index = 0;Index < (sizeof (mSpiChipIdTable) / sizeof (SPI_CHIP_ID));Index++) { - if ((JedecId [1] == mSpiChipIdTable[Index].DeviceId0) - && (JedecId [2] == mSpiChipIdTable[Index].DeviceId1)) - break; - } - - if (Index >= (sizeof (mSpiChipIdTable) / sizeof (SPI_CHIP_ID))) - return NULL; - - Shift = JedecId[2]; - - if (JedecId [1] == SF_DEVICE_ID0_MX25UXX) - Shift-= 0x20; - - if (Shift < 64) { - Size = LShiftU64 (1, Shift); - FlashDescription = &mFlashDescription; - } - } - - // - // Return the flash size - // - if (FlashSize != NULL) { - *FlashSize = Size; - } - - return FlashDescription; -} - -SPI_FLASH_PART_PROTOCOL mSpiFlashPartProtocol = { - 0xC0000000, /// SPI flash part family priority - GetFlashDescription -}; - -/** - Indicate that all the SPI devices are available - - @retval EFI_SUCCESS SPI flash part protocol installed successfully - -**/ -EFI_STATUS -EFIAPI -SpiFlashPart ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - // - // Install the SPI flash part protocol - // - Status = gBS->InstallMultipleProtocolInterfaces ( - &gImageHandle, - &gSpiFlashPartProtocolGuid, - &mSpiFlashPartProtocol, - NULL - ); - - return Status; -} diff --git a/BraswellPlatformPkg/Flash/SpiFlashParts/MX25/MX25.inf b/BraswellPlatformPkg/Flash/SpiFlashParts/MX25/MX25.inf deleted file mode 100644 index aae1c00e9e..0000000000 --- a/BraswellPlatformPkg/Flash/SpiFlashParts/MX25/MX25.inf +++ /dev/null @@ -1,41 +0,0 @@ -## @file -# MACRONIX* MX25*** family SPI flash support -# -# Copyright (c) 2015, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php. -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010018 - BASE_NAME = MX25XXX - FILE_GUID = FB7900FB-BC92-4a34-BFB6-8CC0E63B52FC - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - ENTRY_POINT = SpiFlashPart - -[Sources] - MX25.c - -[Packages] - MdePkg/MdePkg.dec - BraswellPlatformPkg/BraswellPlatformPkg.dec - -[LibraryClasses] - UefiDriverEntryPoint - BaseLib - UefiBootServicesTableLib - -[Protocols] - gSpiFlashPartProtocolGuid ## PRODUCES - -[Depex] - TRUE - diff --git a/BraswellPlatformPkg/Flash/SpiFlashParts/W25/W25.c b/BraswellPlatformPkg/Flash/SpiFlashParts/W25/W25.c deleted file mode 100644 index b23351d23d..0000000000 --- a/BraswellPlatformPkg/Flash/SpiFlashParts/W25/W25.c +++ /dev/null @@ -1,192 +0,0 @@ -/** @file - WINBOND W25*** family SPI flash support - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include -#include -#include -#include -#include - - -// -// Initialization data that can be used to identify SPI flash part -// DeviceId0 Device ID0 of the SPI device -// DeviceId1 Device ID1 of the SPI device -// -typedef struct _SPI_CHIP_ID { - UINT8 DeviceId0; - UINT8 DeviceId1; -} SPI_CHIP_ID; - -// -// Flash VendorId and DeviceId -// - -#define SF_VENDOR_ID_WINBOND 0xEF -#define SF_DEVICE_ID0_W25XXX 0x30 -#define SF_DEVICE_ID1_W25X32 0x16 -#define SF_DEVICE_ID1_W25X64 0x17 -#define SF_DEVICE_ID0_W25QXX 0x60 -#define SF_DEVICE_ID0_W25QXX2 0x40 -#define SF_DEVICE_ID1_W25Q16 0x15 -#define SF_DEVICE_ID1_W25Q32 0x16 -#define SF_DEVICE_ID1_W25Q64 0x17 -#define SF_DEVICE_ID1_W25Q128 0x18 - -// -// Generic SPI flash part description -// -CONST FLASH_PART_DESCRIPTION mFlashDescription = { - L"WINBOND W25Q*** family", // Part number - 1, // Number of status bytes - 0x06, // Write enable - 0x50, // Write status enable - 3, // Length of JEDEC ID response - 8, // Number of opcodes in the table - - // Opcode table - { - {33000000, 3, FALSE, 0x9f, 0, SPI_FLASH_PART_OPCODE_JEDEC_ID}, - {50000000, 1, FALSE, 0x05, 0, SPI_FLASH_PART_OPCODE_READ_STATUS}, - {50000000, 1, TRUE, 0x01, 0, SPI_FLASH_PART_OPCODE_WRITE_STATUS}, - {33000000, 0xffffffff, FALSE, 0x03, 3, SPI_FLASH_PART_OPCODE_READ_BYTES}, - {50000000, 1, TRUE, 0x02, 3, SPI_FLASH_PART_OPCODE_WRITE_256_BYTE_PAGE}, - {50000000, 0, TRUE, 0x20, 3, SPI_FLASH_PART_OPCODE_ERASE_4K_BYTE_BLOCK}, - {50000000, 0, TRUE, 0xd8, 3, SPI_FLASH_PART_OPCODE_ERASE_64K_BYTE_BLOCK}, - {50000000, 0, TRUE, 0x5a, 0, SPI_FLASH_PART_OPCODE_WRITE_DISABLE_DISCOVERY} - } -}; - -SPI_CHIP_ID mSpiChipIdTable[] = { - { - SF_DEVICE_ID0_W25QXX, // DeviceId 0 - SF_DEVICE_ID1_W25Q64 // DeviceId 1 - }, - { - SF_DEVICE_ID0_W25QXX2, // DeviceId 0 - SF_DEVICE_ID1_W25Q64 // DeviceId 1 - } -}; - -/** - Get the flash part size and opcode table. - - Validate support for this flash part and determine - the flash part size and opcode description table - from the JEDEC ID information provided. - - @param[in] This Pointer to a SPI_FLASH_DATA_PROTOCOL - data structure. - @param[in] JedecId Pointer to a three byte buffer containing - the JEDEC ID returned by the flash part. - If the input value is NULL then a - table containing the description for the - JEDEC ID opcode is returned by this - routine. - @param[out] FlashSize Pointer to receive the size of the flash - part in bytes. Zero (0) is returned when - JedecId is NULL. - @returns When JedecId is not NULL, this routine returns a pointer - to a FLASH_PART_DESCRIPTION data structure which supports - this flash part. The returned value is NULL if the flash - part is not supported. - When JedecId is NULL, this routine returns a pointer to - a FLASH_PART_DESCRIPTION structure which supports the - JEDEC ID command. This opcode description may be used - to determine the manufacture and product data for the - SPI flash part. - -**/ -CONST FLASH_PART_DESCRIPTION * -EFIAPI -GetFlashDescription ( - IN SPI_FLASH_PART_PROTOCOL *This, - IN UINT8 *JedecId OPTIONAL, - OUT UINT64 *FlashSize OPTIONAL - ) -{ - CONST FLASH_PART_DESCRIPTION *FlashDescription; - UINT8 Shift; - UINT64 Size; - UINTN Index; - - // - // Determine if the SPI flash device is supported - // - Size = 0; - FlashDescription = &mFlashDescription; - if (JedecId != NULL) { - FlashDescription = NULL; - if (JedecId [0] != SF_VENDOR_ID_WINBOND) - return NULL; - - for (Index = 0;Index < (sizeof (mSpiChipIdTable) / sizeof (SPI_CHIP_ID));Index++) { - if ((JedecId [1] == mSpiChipIdTable[Index].DeviceId0) - && (JedecId [2] == mSpiChipIdTable[Index].DeviceId1)) - break; - } - - if (Index >= (sizeof (mSpiChipIdTable) / sizeof (SPI_CHIP_ID))) - return NULL; - - Shift = JedecId[2]; - if (Shift < 64) { - Size = LShiftU64 (1, Shift); - FlashDescription = &mFlashDescription; - } - } - - // - // Return the flash size - // - if (FlashSize != NULL) { - *FlashSize = Size; - } - - return FlashDescription; -} - -SPI_FLASH_PART_PROTOCOL mSpiFlashPartProtocol = { - 0xC0000000, /// SPI flash part family priority - GetFlashDescription -}; - -/** - Indicate that all the SPI devices are available - - @retval EFI_SUCCESS SPI flash part protocol installed successfully - -**/ -EFI_STATUS -EFIAPI -SpiFlashPart ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - // - // Install the SPI flash part protocol - // - Status = gBS->InstallMultipleProtocolInterfaces ( - &gImageHandle, - &gSpiFlashPartProtocolGuid, - &mSpiFlashPartProtocol, - NULL - ); - - return Status; -} diff --git a/BraswellPlatformPkg/Flash/SpiFlashParts/W25/W25.inf b/BraswellPlatformPkg/Flash/SpiFlashParts/W25/W25.inf deleted file mode 100644 index d48ca15a09..0000000000 --- a/BraswellPlatformPkg/Flash/SpiFlashParts/W25/W25.inf +++ /dev/null @@ -1,41 +0,0 @@ -## @file -# WINBOND W25*** family SPI flash support -# -# Copyright (c) 2015, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php. -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010018 - BASE_NAME = W25XXX - FILE_GUID = 1EAFA124-4F73-45B3-B749-8E7F80741CE4 - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - ENTRY_POINT = SpiFlashPart - -[Sources] - W25.c - -[Packages] - MdePkg/MdePkg.dec - BraswellPlatformPkg/BraswellPlatformPkg.dec - -[LibraryClasses] - UefiDriverEntryPoint - BaseLib - UefiBootServicesTableLib - -[Protocols] - gSpiFlashPartProtocolGuid ## PRODUCES - -[Depex] - TRUE - -- cgit v1.2.3