/** @file NorFlashSmm.c
Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.
Copyright (c) 2017, Socionext Inc. All rights reserved.
Copyright (c) 2017, Linaro, Ltd. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include
#include
#include
#include "NorFlash.h"
//
// Global variable declarations
//
STATIC NOR_FLASH_INSTANCE **mNorFlashInstances;
STATIC UINT32 mNorFlashDeviceCount;
EFI_STATUS
EFIAPI
NorFlashFvbInitialize (
IN NOR_FLASH_INSTANCE* Instance
)
{
EFI_STATUS Status;
UINT32 FvbNumLba;
UINTN BlockSize;
DEBUG ((DEBUG_BLKIO,"NorFlashFvbInitialize\n"));
BlockSize = Instance->BlockSize;
// FirmwareVolumeHeader->FvLength is declared to have the Variable area
// AND the FTW working area AND the FTW Spare contiguous.
ASSERT (PcdGet32 (PcdFlashNvStorageVariableBase) +
PcdGet32 (PcdFlashNvStorageVariableSize) ==
PcdGet32 (PcdFlashNvStorageFtwWorkingBase));
ASSERT (PcdGet32 (PcdFlashNvStorageFtwWorkingBase) +
PcdGet32 (PcdFlashNvStorageFtwWorkingSize) ==
PcdGet32 (PcdFlashNvStorageFtwSpareBase));
// Check if the size of the area is at least one block size
ASSERT ((PcdGet32 (PcdFlashNvStorageVariableSize) > 0) &&
(PcdGet32 (PcdFlashNvStorageVariableSize) / BlockSize > 0));
ASSERT ((PcdGet32 (PcdFlashNvStorageFtwWorkingSize) > 0) &&
(PcdGet32 (PcdFlashNvStorageFtwWorkingSize) / BlockSize > 0));
ASSERT ((PcdGet32 (PcdFlashNvStorageFtwSpareSize) > 0) &&
(PcdGet32 (PcdFlashNvStorageFtwSpareSize) / BlockSize > 0));
// Ensure the Variable areas are aligned on block size boundaries
ASSERT ((PcdGet32 (PcdFlashNvStorageVariableBase) % BlockSize) == 0);
ASSERT ((PcdGet32 (PcdFlashNvStorageFtwWorkingBase) % BlockSize) == 0);
ASSERT ((PcdGet32 (PcdFlashNvStorageFtwSpareBase) % BlockSize) == 0);
Instance->Initialized = TRUE;
mFlashNvStorageVariableBase = FixedPcdGet32 (PcdFlashNvStorageVariableBase);
// Set the index of the first LBA for the FVB
Instance->StartLba = (PcdGet32 (PcdFlashNvStorageVariableBase) -
Instance->RegionBaseAddress) / BlockSize;
// Determine if there is a valid header at the beginning of the NorFlash
Status = ValidateFvHeader (Instance);
if (EFI_ERROR (Status)) {
// There is no valid header, so time to install one.
DEBUG ((DEBUG_INFO, "%a: The FVB Header is not valid.\n", __FUNCTION__));
DEBUG ((DEBUG_INFO, "%a: Installing a correct one for this volume.\n",
__FUNCTION__));
// Erase all the NorFlash that is reserved for variable storage
FvbNumLba = (PcdGet32(PcdFlashNvStorageVariableSize) +
PcdGet32(PcdFlashNvStorageFtwWorkingSize) +
PcdGet32(PcdFlashNvStorageFtwSpareSize)) /
Instance->BlockSize;
Status = FvbEraseBlocks (&Instance->FvbProtocol, (EFI_LBA)0, FvbNumLba,
EFI_LBA_LIST_TERMINATOR);
if (EFI_ERROR (Status)) {
return Status;
}
// Install all appropriate headers
Status = InitializeFvAndVariableStoreHeaders (Instance);
if (EFI_ERROR (Status)) {
return Status;
}
}
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
NorFlashInitialise (
IN EFI_HANDLE ImageHandle,
IN EFI_MM_SYSTEM_TABLE *MmSystemTable
)
{
EFI_STATUS Status;
UINT32 Index;
NOR_FLASH_DESCRIPTION* NorFlashDevices;
BOOLEAN ContainVariableStorage;
// Initialize NOR flash instances
Status = NorFlashPlatformGetDevices (&NorFlashDevices, &mNorFlashDeviceCount);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR,"NorFlashInitialise: Fail to get Nor Flash devices\n"));
return Status;
}
mNorFlashInstances = AllocatePool (sizeof(NOR_FLASH_INSTANCE*) *
mNorFlashDeviceCount);
for (Index = 0; Index < mNorFlashDeviceCount; Index++) {
// Check if this NOR Flash device contain the variable storage region
ContainVariableStorage =
(NorFlashDevices[Index].RegionBaseAddress <=
PcdGet32 (PcdFlashNvStorageVariableBase)) &&
(PcdGet32 (PcdFlashNvStorageVariableBase) +
PcdGet32 (PcdFlashNvStorageVariableSize) <=
NorFlashDevices[Index].RegionBaseAddress + NorFlashDevices[Index].Size);
Status = NorFlashCreateInstance (
PcdGet32 (PcdFip006DxeRegBaseAddress),
NorFlashDevices[Index].DeviceBaseAddress,
NorFlashDevices[Index].RegionBaseAddress,
NorFlashDevices[Index].Size,
Index,
NorFlashDevices[Index].BlockSize,
ContainVariableStorage,
&mNorFlashInstances[Index]
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR,
"NorFlashInitialise: Fail to create instance for NorFlash[%d]\n",
Index));
continue;
}
Status = gMmst->MmInstallProtocolInterface (
&mNorFlashInstances[Index]->Handle,
&gEfiSmmFirmwareVolumeBlockProtocolGuid,
EFI_NATIVE_INTERFACE,
&mNorFlashInstances[Index]->FvbProtocol
);
ASSERT_EFI_ERROR (Status);
}
return Status;
}
VOID
EFIAPI
NorFlashLock (
NOR_FLASH_LOCK_CONTEXT *Context
)
{
}
VOID
EFIAPI
NorFlashUnlock (
NOR_FLASH_LOCK_CONTEXT *Context
)
{
}