NorFlashSmm.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /** @file NorFlashSmm.c
  2. Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
  3. Copyright (c) 2017, Socionext Inc. All rights reserved.<BR>
  4. Copyright (c) 2017, Linaro, Ltd. All rights reserved.<BR>
  5. SPDX-License-Identifier: BSD-2-Clause-Patent
  6. **/
  7. #include <PiMm.h>
  8. #include <Library/MemoryAllocationLib.h>
  9. #include <Library/MmServicesTableLib.h>
  10. #include "NorFlash.h"
  11. //
  12. // Global variable declarations
  13. //
  14. STATIC NOR_FLASH_INSTANCE **mNorFlashInstances;
  15. STATIC UINT32 mNorFlashDeviceCount;
  16. EFI_STATUS
  17. EFIAPI
  18. NorFlashFvbInitialize (
  19. IN NOR_FLASH_INSTANCE* Instance
  20. )
  21. {
  22. EFI_STATUS Status;
  23. UINT32 FvbNumLba;
  24. UINTN BlockSize;
  25. DEBUG ((DEBUG_BLKIO,"NorFlashFvbInitialize\n"));
  26. BlockSize = Instance->BlockSize;
  27. // FirmwareVolumeHeader->FvLength is declared to have the Variable area
  28. // AND the FTW working area AND the FTW Spare contiguous.
  29. ASSERT (PcdGet32 (PcdFlashNvStorageVariableBase) +
  30. PcdGet32 (PcdFlashNvStorageVariableSize) ==
  31. PcdGet32 (PcdFlashNvStorageFtwWorkingBase));
  32. ASSERT (PcdGet32 (PcdFlashNvStorageFtwWorkingBase) +
  33. PcdGet32 (PcdFlashNvStorageFtwWorkingSize) ==
  34. PcdGet32 (PcdFlashNvStorageFtwSpareBase));
  35. // Check if the size of the area is at least one block size
  36. ASSERT ((PcdGet32 (PcdFlashNvStorageVariableSize) > 0) &&
  37. (PcdGet32 (PcdFlashNvStorageVariableSize) / BlockSize > 0));
  38. ASSERT ((PcdGet32 (PcdFlashNvStorageFtwWorkingSize) > 0) &&
  39. (PcdGet32 (PcdFlashNvStorageFtwWorkingSize) / BlockSize > 0));
  40. ASSERT ((PcdGet32 (PcdFlashNvStorageFtwSpareSize) > 0) &&
  41. (PcdGet32 (PcdFlashNvStorageFtwSpareSize) / BlockSize > 0));
  42. // Ensure the Variable areas are aligned on block size boundaries
  43. ASSERT ((PcdGet32 (PcdFlashNvStorageVariableBase) % BlockSize) == 0);
  44. ASSERT ((PcdGet32 (PcdFlashNvStorageFtwWorkingBase) % BlockSize) == 0);
  45. ASSERT ((PcdGet32 (PcdFlashNvStorageFtwSpareBase) % BlockSize) == 0);
  46. Instance->Initialized = TRUE;
  47. mFlashNvStorageVariableBase = FixedPcdGet32 (PcdFlashNvStorageVariableBase);
  48. // Set the index of the first LBA for the FVB
  49. Instance->StartLba = (PcdGet32 (PcdFlashNvStorageVariableBase) -
  50. Instance->RegionBaseAddress) / BlockSize;
  51. // Determine if there is a valid header at the beginning of the NorFlash
  52. Status = ValidateFvHeader (Instance);
  53. if (EFI_ERROR (Status)) {
  54. // There is no valid header, so time to install one.
  55. DEBUG ((DEBUG_INFO, "%a: The FVB Header is not valid.\n", __FUNCTION__));
  56. DEBUG ((DEBUG_INFO, "%a: Installing a correct one for this volume.\n",
  57. __FUNCTION__));
  58. // Erase all the NorFlash that is reserved for variable storage
  59. FvbNumLba = (PcdGet32(PcdFlashNvStorageVariableSize) +
  60. PcdGet32(PcdFlashNvStorageFtwWorkingSize) +
  61. PcdGet32(PcdFlashNvStorageFtwSpareSize)) /
  62. Instance->BlockSize;
  63. Status = FvbEraseBlocks (&Instance->FvbProtocol, (EFI_LBA)0, FvbNumLba,
  64. EFI_LBA_LIST_TERMINATOR);
  65. if (EFI_ERROR (Status)) {
  66. return Status;
  67. }
  68. // Install all appropriate headers
  69. Status = InitializeFvAndVariableStoreHeaders (Instance);
  70. if (EFI_ERROR (Status)) {
  71. return Status;
  72. }
  73. }
  74. return EFI_SUCCESS;
  75. }
  76. EFI_STATUS
  77. EFIAPI
  78. NorFlashInitialise (
  79. IN EFI_HANDLE ImageHandle,
  80. IN EFI_MM_SYSTEM_TABLE *MmSystemTable
  81. )
  82. {
  83. EFI_STATUS Status;
  84. UINT32 Index;
  85. NOR_FLASH_DESCRIPTION* NorFlashDevices;
  86. BOOLEAN ContainVariableStorage;
  87. // Initialize NOR flash instances
  88. Status = NorFlashPlatformGetDevices (&NorFlashDevices, &mNorFlashDeviceCount);
  89. if (EFI_ERROR (Status)) {
  90. DEBUG ((DEBUG_ERROR,"NorFlashInitialise: Fail to get Nor Flash devices\n"));
  91. return Status;
  92. }
  93. mNorFlashInstances = AllocatePool (sizeof(NOR_FLASH_INSTANCE*) *
  94. mNorFlashDeviceCount);
  95. for (Index = 0; Index < mNorFlashDeviceCount; Index++) {
  96. // Check if this NOR Flash device contain the variable storage region
  97. ContainVariableStorage =
  98. (NorFlashDevices[Index].RegionBaseAddress <=
  99. PcdGet32 (PcdFlashNvStorageVariableBase)) &&
  100. (PcdGet32 (PcdFlashNvStorageVariableBase) +
  101. PcdGet32 (PcdFlashNvStorageVariableSize) <=
  102. NorFlashDevices[Index].RegionBaseAddress + NorFlashDevices[Index].Size);
  103. Status = NorFlashCreateInstance (
  104. PcdGet32 (PcdFip006DxeRegBaseAddress),
  105. NorFlashDevices[Index].DeviceBaseAddress,
  106. NorFlashDevices[Index].RegionBaseAddress,
  107. NorFlashDevices[Index].Size,
  108. Index,
  109. NorFlashDevices[Index].BlockSize,
  110. ContainVariableStorage,
  111. &mNorFlashInstances[Index]
  112. );
  113. if (EFI_ERROR (Status)) {
  114. DEBUG ((DEBUG_ERROR,
  115. "NorFlashInitialise: Fail to create instance for NorFlash[%d]\n",
  116. Index));
  117. continue;
  118. }
  119. Status = gMmst->MmInstallProtocolInterface (
  120. &mNorFlashInstances[Index]->Handle,
  121. &gEfiSmmFirmwareVolumeBlockProtocolGuid,
  122. EFI_NATIVE_INTERFACE,
  123. &mNorFlashInstances[Index]->FvbProtocol
  124. );
  125. ASSERT_EFI_ERROR (Status);
  126. }
  127. return Status;
  128. }
  129. VOID
  130. EFIAPI
  131. NorFlashLock (
  132. NOR_FLASH_LOCK_CONTEXT *Context
  133. )
  134. {
  135. }
  136. VOID
  137. EFIAPI
  138. NorFlashUnlock (
  139. NOR_FLASH_LOCK_CONTEXT *Context
  140. )
  141. {
  142. }