]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / ArmPlatformPkg / Drivers / NorFlashDxe / NorFlashDxe.c
diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c
deleted file mode 100644 (file)
index 41cdd1c..0000000
+++ /dev/null
@@ -1,477 +0,0 @@
-/** @file  NorFlashDxe.c\r
-\r
-  Copyright (c) 2011 - 2020, Arm Limited. All rights reserved.<BR>\r
-\r
-  SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include <Library/UefiLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/PcdLib.h>\r
-#include <Library/HobLib.h>\r
-#include <Library/DxeServicesTableLib.h>\r
-\r
-#include "NorFlash.h"\r
-\r
-STATIC EFI_EVENT mNorFlashVirtualAddrChangeEvent;\r
-\r
-//\r
-// Global variable declarations\r
-//\r
-NOR_FLASH_INSTANCE **mNorFlashInstances;\r
-UINT32               mNorFlashDeviceCount;\r
-UINTN                mFlashNvStorageVariableBase;\r
-EFI_EVENT            mFvbVirtualAddrChangeEvent;\r
-\r
-NOR_FLASH_INSTANCE  mNorFlashInstanceTemplate = {\r
-  NOR_FLASH_SIGNATURE, // Signature\r
-  NULL, // Handle ... NEED TO BE FILLED\r
-\r
-  0, // DeviceBaseAddress ... NEED TO BE FILLED\r
-  0, // RegionBaseAddress ... NEED TO BE FILLED\r
-  0, // Size ... NEED TO BE FILLED\r
-  0, // StartLba\r
-\r
-  {\r
-    EFI_BLOCK_IO_PROTOCOL_REVISION2, // Revision\r
-    NULL, // Media ... NEED TO BE FILLED\r
-    NorFlashBlockIoReset, // Reset;\r
-    NorFlashBlockIoReadBlocks,          // ReadBlocks\r
-    NorFlashBlockIoWriteBlocks,         // WriteBlocks\r
-    NorFlashBlockIoFlushBlocks          // FlushBlocks\r
-  }, // BlockIoProtocol\r
-\r
-  {\r
-    0, // MediaId ... NEED TO BE FILLED\r
-    FALSE, // RemovableMedia\r
-    TRUE, // MediaPresent\r
-    FALSE, // LogicalPartition\r
-    FALSE, // ReadOnly\r
-    FALSE, // WriteCaching;\r
-    0, // BlockSize ... NEED TO BE FILLED\r
-    4, //  IoAlign\r
-    0, // LastBlock ... NEED TO BE FILLED\r
-    0, // LowestAlignedLba\r
-    1, // LogicalBlocksPerPhysicalBlock\r
-  }, //Media;\r
-\r
-  {\r
-    EFI_DISK_IO_PROTOCOL_REVISION, // Revision\r
-    NorFlashDiskIoReadDisk,        // ReadDisk\r
-    NorFlashDiskIoWriteDisk        // WriteDisk\r
-  },\r
-\r
-  {\r
-    FvbGetAttributes, // GetAttributes\r
-    FvbSetAttributes, // SetAttributes\r
-    FvbGetPhysicalAddress,  // GetPhysicalAddress\r
-    FvbGetBlockSize,  // GetBlockSize\r
-    FvbRead,  // Read\r
-    FvbWrite, // Write\r
-    FvbEraseBlocks, // EraseBlocks\r
-    NULL, //ParentHandle\r
-  }, //  FvbProtoccol;\r
-  NULL, // ShadowBuffer\r
-  {\r
-    {\r
-      {\r
-        HARDWARE_DEVICE_PATH,\r
-        HW_VENDOR_DP,\r
-        {\r
-          (UINT8)(OFFSET_OF (NOR_FLASH_DEVICE_PATH, End)),\r
-          (UINT8)(OFFSET_OF (NOR_FLASH_DEVICE_PATH, End) >> 8)\r
-        }\r
-      },\r
-      { 0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } }, // GUID ... NEED TO BE FILLED\r
-    },\r
-    0, // Index\r
-    {\r
-      END_DEVICE_PATH_TYPE,\r
-      END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
-      { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 }\r
-    }\r
-    } // DevicePath\r
-};\r
-\r
-EFI_STATUS\r
-NorFlashCreateInstance (\r
-  IN UINTN                  NorFlashDeviceBase,\r
-  IN UINTN                  NorFlashRegionBase,\r
-  IN UINTN                  NorFlashSize,\r
-  IN UINT32                 Index,\r
-  IN UINT32                 BlockSize,\r
-  IN BOOLEAN                SupportFvb,\r
-  OUT NOR_FLASH_INSTANCE**  NorFlashInstance\r
-  )\r
-{\r
-  EFI_STATUS Status;\r
-  NOR_FLASH_INSTANCE* Instance;\r
-\r
-  ASSERT(NorFlashInstance != NULL);\r
-\r
-  Instance = AllocateRuntimeCopyPool (sizeof(NOR_FLASH_INSTANCE),&mNorFlashInstanceTemplate);\r
-  if (Instance == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  Instance->DeviceBaseAddress = NorFlashDeviceBase;\r
-  Instance->RegionBaseAddress = NorFlashRegionBase;\r
-  Instance->Size = NorFlashSize;\r
-\r
-  Instance->BlockIoProtocol.Media = &Instance->Media;\r
-  Instance->Media.MediaId = Index;\r
-  Instance->Media.BlockSize = BlockSize;\r
-  Instance->Media.LastBlock = (NorFlashSize / BlockSize)-1;\r
-\r
-  CopyGuid (&Instance->DevicePath.Vendor.Guid, &gEfiCallerIdGuid);\r
-  Instance->DevicePath.Index = (UINT8)Index;\r
-\r
-  Instance->ShadowBuffer = AllocateRuntimePool (BlockSize);;\r
-  if (Instance->ShadowBuffer == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  if (SupportFvb) {\r
-    NorFlashFvbInitialize (Instance);\r
-\r
-    Status = gBS->InstallMultipleProtocolInterfaces (\r
-                  &Instance->Handle,\r
-                  &gEfiDevicePathProtocolGuid, &Instance->DevicePath,\r
-                  &gEfiBlockIoProtocolGuid,  &Instance->BlockIoProtocol,\r
-                  &gEfiFirmwareVolumeBlockProtocolGuid, &Instance->FvbProtocol,\r
-                  NULL\r
-                  );\r
-    if (EFI_ERROR(Status)) {\r
-      FreePool (Instance);\r
-      return Status;\r
-    }\r
-  } else {\r
-    Status = gBS->InstallMultipleProtocolInterfaces (\r
-                    &Instance->Handle,\r
-                    &gEfiDevicePathProtocolGuid, &Instance->DevicePath,\r
-                    &gEfiBlockIoProtocolGuid,  &Instance->BlockIoProtocol,\r
-                    &gEfiDiskIoProtocolGuid, &Instance->DiskIoProtocol,\r
-                    NULL\r
-                    );\r
-    if (EFI_ERROR(Status)) {\r
-      FreePool (Instance);\r
-      return Status;\r
-    }\r
-  }\r
-\r
-  *NorFlashInstance = Instance;\r
-  return Status;\r
-}\r
-\r
-/**\r
- * This function unlock and erase an entire NOR Flash block.\r
- **/\r
-EFI_STATUS\r
-NorFlashUnlockAndEraseSingleBlock (\r
-  IN NOR_FLASH_INSTANCE     *Instance,\r
-  IN UINTN                  BlockAddress\r
-  )\r
-{\r
-  EFI_STATUS      Status;\r
-  UINTN           Index;\r
-  EFI_TPL         OriginalTPL;\r
-\r
-  if (!EfiAtRuntime ()) {\r
-    // Raise TPL to TPL_HIGH to stop anyone from interrupting us.\r
-    OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
-  } else {\r
-    // This initialization is only to prevent the compiler to complain about the\r
-    // use of uninitialized variables\r
-    OriginalTPL = TPL_HIGH_LEVEL;\r
-  }\r
-\r
-  Index = 0;\r
-  // The block erase might fail a first time (SW bug ?). Retry it ...\r
-  do {\r
-    // Unlock the block if we have to\r
-    Status = NorFlashUnlockSingleBlockIfNecessary (Instance, BlockAddress);\r
-    if (EFI_ERROR (Status)) {\r
-      break;\r
-    }\r
-    Status = NorFlashEraseSingleBlock (Instance, BlockAddress);\r
-    Index++;\r
-  } while ((Index < NOR_FLASH_ERASE_RETRY) && (Status == EFI_WRITE_PROTECTED));\r
-\r
-  if (Index == NOR_FLASH_ERASE_RETRY) {\r
-    DEBUG((EFI_D_ERROR,"EraseSingleBlock(BlockAddress=0x%08x: Block Locked Error (try to erase %d times)\n", BlockAddress,Index));\r
-  }\r
-\r
-  if (!EfiAtRuntime ()) {\r
-    // Interruptions can resume.\r
-    gBS->RestoreTPL (OriginalTPL);\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-EFI_STATUS\r
-NorFlashWriteFullBlock (\r
-  IN NOR_FLASH_INSTANCE     *Instance,\r
-  IN EFI_LBA                Lba,\r
-  IN UINT32                 *DataBuffer,\r
-  IN UINT32                 BlockSizeInWords\r
-  )\r
-{\r
-  EFI_STATUS    Status;\r
-  UINTN         WordAddress;\r
-  UINT32        WordIndex;\r
-  UINTN         BufferIndex;\r
-  UINTN         BlockAddress;\r
-  UINTN         BuffersInBlock;\r
-  UINTN         RemainingWords;\r
-  EFI_TPL       OriginalTPL;\r
-  UINTN         Cnt;\r
-\r
-  Status = EFI_SUCCESS;\r
-\r
-  // Get the physical address of the block\r
-  BlockAddress = GET_NOR_BLOCK_ADDRESS (Instance->RegionBaseAddress, Lba, BlockSizeInWords * 4);\r
-\r
-  // Start writing from the first address at the start of the block\r
-  WordAddress = BlockAddress;\r
-\r
-  if (!EfiAtRuntime ()) {\r
-    // Raise TPL to TPL_HIGH to stop anyone from interrupting us.\r
-    OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
-  } else {\r
-    // This initialization is only to prevent the compiler to complain about the\r
-    // use of uninitialized variables\r
-    OriginalTPL = TPL_HIGH_LEVEL;\r
-  }\r
-\r
-  Status = NorFlashUnlockAndEraseSingleBlock (Instance, BlockAddress);\r
-  if (EFI_ERROR(Status)) {\r
-    DEBUG((EFI_D_ERROR, "WriteSingleBlock: ERROR - Failed to Unlock and Erase the single block at 0x%X\n", BlockAddress));\r
-    goto EXIT;\r
-  }\r
-\r
-  // To speed up the programming operation, NOR Flash is programmed using the Buffered Programming method.\r
-\r
-  // Check that the address starts at a 32-word boundary, i.e. last 7 bits must be zero\r
-  if ((WordAddress & BOUNDARY_OF_32_WORDS) == 0x00) {\r
-\r
-    // First, break the entire block into buffer-sized chunks.\r
-    BuffersInBlock = (UINTN)(BlockSizeInWords * 4) / P30_MAX_BUFFER_SIZE_IN_BYTES;\r
-\r
-    // Then feed each buffer chunk to the NOR Flash\r
-    // If a buffer does not contain any data, don't write it.\r
-    for(BufferIndex=0;\r
-         BufferIndex < BuffersInBlock;\r
-         BufferIndex++, WordAddress += P30_MAX_BUFFER_SIZE_IN_BYTES, DataBuffer += P30_MAX_BUFFER_SIZE_IN_WORDS\r
-      ) {\r
-      // Check the buffer to see if it contains any data (not set all 1s).\r
-      for (Cnt = 0; Cnt < P30_MAX_BUFFER_SIZE_IN_WORDS; Cnt++) {\r
-        if (~DataBuffer[Cnt] != 0 ) {\r
-          // Some data found, write the buffer.\r
-          Status = NorFlashWriteBuffer (Instance, WordAddress, P30_MAX_BUFFER_SIZE_IN_BYTES,\r
-                                        DataBuffer);\r
-          if (EFI_ERROR(Status)) {\r
-            goto EXIT;\r
-          }\r
-          break;\r
-        }\r
-      }\r
-    }\r
-\r
-    // Finally, finish off any remaining words that are less than the maximum size of the buffer\r
-    RemainingWords = BlockSizeInWords % P30_MAX_BUFFER_SIZE_IN_WORDS;\r
-\r
-    if(RemainingWords != 0) {\r
-      Status = NorFlashWriteBuffer (Instance, WordAddress, (RemainingWords * 4), DataBuffer);\r
-      if (EFI_ERROR(Status)) {\r
-        goto EXIT;\r
-      }\r
-    }\r
-\r
-  } else {\r
-    // For now, use the single word programming algorithm\r
-    // It is unlikely that the NOR Flash will exist in an address which falls within a 32 word boundary range,\r
-    // i.e. which ends in the range 0x......01 - 0x......7F.\r
-    for(WordIndex=0; WordIndex<BlockSizeInWords; WordIndex++, DataBuffer++, WordAddress = WordAddress + 4) {\r
-      Status = NorFlashWriteSingleWord (Instance, WordAddress, *DataBuffer);\r
-      if (EFI_ERROR(Status)) {\r
-        goto EXIT;\r
-      }\r
-    }\r
-  }\r
-\r
-EXIT:\r
-  if (!EfiAtRuntime ()) {\r
-    // Interruptions can resume.\r
-    gBS->RestoreTPL (OriginalTPL);\r
-  }\r
-\r
-  if (EFI_ERROR(Status)) {\r
-    DEBUG((EFI_D_ERROR, "NOR FLASH Programming [WriteSingleBlock] failed at address 0x%08x. Exit Status = \"%r\".\n", WordAddress, Status));\r
-  }\r
-  return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-NorFlashInitialise (\r
-  IN EFI_HANDLE         ImageHandle,\r
-  IN EFI_SYSTEM_TABLE   *SystemTable\r
-  )\r
-{\r
-  EFI_STATUS              Status;\r
-  UINT32                  Index;\r
-  NOR_FLASH_DESCRIPTION*  NorFlashDevices;\r
-  BOOLEAN                 ContainVariableStorage;\r
-\r
-  Status = NorFlashPlatformInitialization ();\r
-  if (EFI_ERROR(Status)) {\r
-    DEBUG((EFI_D_ERROR,"NorFlashInitialise: Fail to initialize Nor Flash devices\n"));\r
-    return Status;\r
-  }\r
-\r
-  Status = NorFlashPlatformGetDevices (&NorFlashDevices, &mNorFlashDeviceCount);\r
-  if (EFI_ERROR(Status)) {\r
-    DEBUG((EFI_D_ERROR,"NorFlashInitialise: Fail to get Nor Flash devices\n"));\r
-    return Status;\r
-  }\r
-\r
-  mNorFlashInstances = AllocateRuntimePool (sizeof(NOR_FLASH_INSTANCE*) * mNorFlashDeviceCount);\r
-\r
-  for (Index = 0; Index < mNorFlashDeviceCount; Index++) {\r
-    // Check if this NOR Flash device contain the variable storage region\r
-    ContainVariableStorage =\r
-        (NorFlashDevices[Index].RegionBaseAddress <= PcdGet32 (PcdFlashNvStorageVariableBase)) &&\r
-        (PcdGet32 (PcdFlashNvStorageVariableBase) + PcdGet32 (PcdFlashNvStorageVariableSize) <= NorFlashDevices[Index].RegionBaseAddress + NorFlashDevices[Index].Size);\r
-\r
-    Status = NorFlashCreateInstance (\r
-      NorFlashDevices[Index].DeviceBaseAddress,\r
-      NorFlashDevices[Index].RegionBaseAddress,\r
-      NorFlashDevices[Index].Size,\r
-      Index,\r
-      NorFlashDevices[Index].BlockSize,\r
-      ContainVariableStorage,\r
-      &mNorFlashInstances[Index]\r
-    );\r
-    if (EFI_ERROR(Status)) {\r
-      DEBUG((EFI_D_ERROR,"NorFlashInitialise: Fail to create instance for NorFlash[%d]\n",Index));\r
-    }\r
-  }\r
-\r
-  //\r
-  // Register for the virtual address change event\r
-  //\r
-  Status = gBS->CreateEventEx (\r
-                  EVT_NOTIFY_SIGNAL,\r
-                  TPL_NOTIFY,\r
-                  NorFlashVirtualNotifyEvent,\r
-                  NULL,\r
-                  &gEfiEventVirtualAddressChangeGuid,\r
-                  &mNorFlashVirtualAddrChangeEvent\r
-                  );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-NorFlashFvbInitialize (\r
-  IN NOR_FLASH_INSTANCE* Instance\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-  UINT32      FvbNumLba;\r
-  EFI_BOOT_MODE BootMode;\r
-  UINTN       RuntimeMmioRegionSize;\r
-\r
-  DEBUG((DEBUG_BLKIO,"NorFlashFvbInitialize\n"));\r
-  ASSERT((Instance != NULL));\r
-\r
-  //\r
-  // Declare the Non-Volatile storage as EFI_MEMORY_RUNTIME\r
-  //\r
-\r
-  // Note: all the NOR Flash region needs to be reserved into the UEFI Runtime memory;\r
-  //       even if we only use the small block region at the top of the NOR Flash.\r
-  //       The reason is when the NOR Flash memory is set into program mode, the command\r
-  //       is written as the base of the flash region (ie: Instance->DeviceBaseAddress)\r
-  RuntimeMmioRegionSize = (Instance->RegionBaseAddress - Instance->DeviceBaseAddress) + Instance->Size;\r
-\r
-  Status = gDS->AddMemorySpace (\r
-      EfiGcdMemoryTypeMemoryMappedIo,\r
-      Instance->DeviceBaseAddress, RuntimeMmioRegionSize,\r
-      EFI_MEMORY_UC | EFI_MEMORY_RUNTIME\r
-      );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  Status = gDS->SetMemorySpaceAttributes (\r
-      Instance->DeviceBaseAddress, RuntimeMmioRegionSize,\r
-      EFI_MEMORY_UC | EFI_MEMORY_RUNTIME);\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  mFlashNvStorageVariableBase = PcdGet32 (PcdFlashNvStorageVariableBase);\r
-\r
-  // Set the index of the first LBA for the FVB\r
-  Instance->StartLba = (PcdGet32 (PcdFlashNvStorageVariableBase) - Instance->RegionBaseAddress) / Instance->Media.BlockSize;\r
-\r
-  BootMode = GetBootModeHob ();\r
-  if (BootMode == BOOT_WITH_DEFAULT_SETTINGS) {\r
-    Status = EFI_INVALID_PARAMETER;\r
-  } else {\r
-    // Determine if there is a valid header at the beginning of the NorFlash\r
-    Status = ValidateFvHeader (Instance);\r
-  }\r
-\r
-  // Install the Default FVB header if required\r
-  if (EFI_ERROR(Status)) {\r
-    // There is no valid header, so time to install one.\r
-    DEBUG ((DEBUG_INFO, "%a: The FVB Header is not valid.\n", __FUNCTION__));\r
-    DEBUG ((DEBUG_INFO, "%a: Installing a correct one for this volume.\n",\r
-      __FUNCTION__));\r
-\r
-    // Erase all the NorFlash that is reserved for variable storage\r
-    FvbNumLba = (PcdGet32(PcdFlashNvStorageVariableSize) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) + PcdGet32(PcdFlashNvStorageFtwSpareSize)) / Instance->Media.BlockSize;\r
-\r
-    Status = FvbEraseBlocks (&Instance->FvbProtocol, (EFI_LBA)0, FvbNumLba, EFI_LBA_LIST_TERMINATOR);\r
-    if (EFI_ERROR(Status)) {\r
-      return Status;\r
-    }\r
-\r
-    // Install all appropriate headers\r
-    Status = InitializeFvAndVariableStoreHeaders (Instance);\r
-    if (EFI_ERROR(Status)) {\r
-      return Status;\r
-    }\r
-  }\r
-\r
-  //\r
-  // The driver implementing the variable read service can now be dispatched;\r
-  // the varstore headers are in place.\r
-  //\r
-  Status = gBS->InstallProtocolInterface (\r
-                  &gImageHandle,\r
-                  &gEdkiiNvVarStoreFormattedGuid,\r
-                  EFI_NATIVE_INTERFACE,\r
-                  NULL\r
-                  );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  //\r
-  // Register for the virtual address change event\r
-  //\r
-  Status = gBS->CreateEventEx (\r
-                  EVT_NOTIFY_SIGNAL,\r
-                  TPL_NOTIFY,\r
-                  FvbVirtualNotifyEvent,\r
-                  NULL,\r
-                  &gEfiEventVirtualAddressChangeGuid,\r
-                  &mFvbVirtualAddrChangeEvent\r
-                  );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  return Status;\r
-}\r