]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.c
Vlv2TbltDevicePkg: Sync FLASH libraries from UDK2017 branch
[mirror_edk2.git] / Vlv2TbltDevicePkg / Library / FlashDeviceLib / FlashDeviceLib.c
index 8e6e5b47289bc49873192e93022e44e742d5ba78..392ad1c14b7c459571382ff2fe6c20ab36ad4b31 100644 (file)
 #include <Library/FlashDeviceLib.h>\r
 #include <Library/DebugLib.h>\r
 #include <Library/BaseLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
 #include <Library/BaseMemoryLib.h>\r
+#include <Library/UefiRuntimeLib.h>\r
+#include <Protocol/SmmBase2.h>\r
 #include <Guid/EventGroup.h>\r
-#include <Library/SpiFlash.H>\r
+#include "SpiChipDefinitions.h"\r
 \r
-#define FLASH_SIZE  0x400000\r
-\r
-#define FLASH_DEVICE_BASE_ADDRESS (0xFFFFFFFF-FLASH_SIZE+1)\r
 UINTN FlashDeviceBase = FLASH_DEVICE_BASE_ADDRESS;\r
 \r
 EFI_SPI_PROTOCOL *mSpiProtocol = NULL;\r
@@ -77,11 +78,11 @@ SpiFlashBlockErase (
   UINT32              SpiAddress;\r
 \r
   SpiAddress = (UINT32)(UINTN)(BaseAddress) - (UINT32)FlashDeviceBase;\r
-  SectorSize = SECTOR_SIZE_64KB;\r
+  SectorSize = SECTOR_SIZE_4KB;\r
   while ( (NumBytes > 0) && (NumBytes <= MAX_FWH_SIZE) ) {\r
     Status = mSpiProtocol->Execute (\r
                              mSpiProtocol,\r
-                             SPI_BERASE,\r
+                             SPI_SERASE,\r
                              SPI_WREN,\r
                              FALSE,\r
                              TRUE,\r
@@ -319,3 +320,148 @@ LibFvbFlashDeviceBlockLock (
   return Status;\r
 }\r
 \r
+VOID\r
+EFIAPI\r
+LibFvbFlashDeviceVirtualAddressChangeNotifyEvent (\r
+  IN EFI_EVENT        Event,\r
+  IN VOID             *Context\r
+  )\r
+{\r
+  gRT->ConvertPointer (0, (VOID **) &mSpiProtocol);\r
+  gRT->ConvertPointer (0, (VOID **) &FlashDeviceBase);\r
+}\r
+\r
+\r
+/**\r
+  The library constructuor.\r
+\r
+  The function does the necessary initialization work for this library\r
+  instance. Please put all initialization works in it.\r
+\r
+  @param[in]  ImageHandle       The firmware allocated handle for the UEFI image.\r
+  @param[in]  SystemTable       A pointer to the EFI system table.\r
+\r
+  @retval     EFI_SUCCESS       The function always return EFI_SUCCESS for now.\r
+                                It will ASSERT on error for debug version.\r
+  @retval     EFI_ERROR         Please reference LocateProtocol for error code details.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+LibFvbFlashDeviceSupportInit (\r
+  IN EFI_HANDLE         ImageHandle,\r
+  IN EFI_SYSTEM_TABLE   *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+  EFI_EVENT  Event;\r
+  UINT8                         SfId[3];\r
+  UINT8                         FlashIndex;\r
+  UINT8                         SpiReadError;\r
+  UINT8                         SpiNotMatchError;\r
+  EFI_SMM_BASE2_PROTOCOL       *SmmBase;\r
+  BOOLEAN                       InSmm;\r
+\r
+  SpiReadError     = 0x00;\r
+  SpiNotMatchError = 0x00;\r
+\r
+  InSmm = FALSE;\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiSmmBase2ProtocolGuid,\r
+                  NULL,\r
+                  (void **)&SmmBase\r
+                  );\r
+  if (!EFI_ERROR(Status)) {\r
+    Status = SmmBase->InSmm(SmmBase, &InSmm);\r
+    if (EFI_ERROR(Status)) {\r
+      InSmm = FALSE;\r
+    }\r
+  }\r
+\r
+  if (!InSmm) {\r
+    Status = gBS->LocateProtocol (\r
+                  &gEfiSpiProtocolGuid,\r
+                  NULL,\r
+                  (VOID **)&mSpiProtocol\r
+                  );\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    Status = gBS->CreateEventEx (\r
+                  EVT_NOTIFY_SIGNAL,\r
+                  TPL_NOTIFY,\r
+                  LibFvbFlashDeviceVirtualAddressChangeNotifyEvent,\r
+                  NULL,\r
+                  &gEfiEventVirtualAddressChangeGuid,\r
+                  &Event\r
+                  );\r
+    ASSERT_EFI_ERROR (Status);\r
+  } else {\r
+    Status = gBS->LocateProtocol (\r
+                    &gEfiSmmSpiProtocolGuid,\r
+                    NULL,\r
+                    (VOID **)&mSpiProtocol\r
+                    );\r
+    ASSERT_EFI_ERROR (Status);\r
+  }\r
+\r
+\r
+  for (FlashIndex = EnumSpiFlashW25Q64; FlashIndex < EnumSpiFlashMax; FlashIndex++) {\r
+    Status = mSpiProtocol->Init (mSpiProtocol, &(mInitTable[FlashIndex]));\r
+    if (!EFI_ERROR (Status)) {\r
+      //\r
+      // Read Vendor/Device IDs to check if the driver supports the Serial Flash device.\r
+      //\r
+      Status = mSpiProtocol->Execute (\r
+                               mSpiProtocol,\r
+                               SPI_READ_ID,\r
+                               SPI_WREN,\r
+                               TRUE,\r
+                               FALSE,\r
+                               FALSE,\r
+                               0,\r
+                               3,\r
+                               SfId,\r
+                               EnumSpiRegionAll\r
+                               );\r
+      if (!EFI_ERROR (Status)) {\r
+        if ((SfId[0] == mInitTable[FlashIndex].VendorId)  &&\r
+            (SfId[1] == mInitTable[FlashIndex].DeviceId0) &&\r
+            (SfId[2] == mInitTable[FlashIndex].DeviceId1)) {\r
+            //\r
+            // Found a matching SPI device, FlashIndex now contains flash device.\r
+            //\r
+            DEBUG ((DEBUG_ERROR, "OK - Found SPI Flash Type in SPI Flash Driver, Device Type ID 0 = 0x%02x!\n", mInitTable[FlashIndex].DeviceId0));\r
+            DEBUG ((DEBUG_ERROR, "Device Type ID 1 = 0x%02x!\n", mInitTable[FlashIndex].DeviceId1));\r
+\r
+            if (mInitTable[FlashIndex].BiosStartOffset == (UINTN) (-1)) {\r
+              DEBUG ((DEBUG_ERROR, "ERROR - The size of BIOS image is bigger than SPI Flash device!\n"));\r
+              CpuDeadLoop ();\r
+            }\r
+            break;\r
+        } else {\r
+          SpiNotMatchError++;\r
+        }\r
+      } else {\r
+        SpiReadError++;\r
+      }\r
+    }\r
+  }\r
+\r
+  DEBUG ((DEBUG_ERROR, "SPI flash chip VID = 0x%X, DID0 = 0x%X, DID1 = 0x%X\n", SfId[0], SfId[1], SfId[2]));\r
+\r
+  if (FlashIndex < EnumSpiFlashMax)  {\r
+    return EFI_SUCCESS;\r
+  } else {\r
+  if (SpiReadError != 0) {\r
+      DEBUG ((DEBUG_ERROR, "ERROR - SPI Read ID execution failed! Error Count = %d\n", SpiReadError));\r
+   }\r
+    else {\r
+      if (SpiNotMatchError != 0) {\r
+        DEBUG ((DEBUG_ERROR, "ERROR - No supported SPI flash chip found! Error Count = %d\n", SpiNotMatchError));\r
+        DEBUG ((DEBUG_ERROR, "SPI flash chip VID = 0x%X, DID0 = 0x%X, DID1 = 0x%X\n", SfId[0], SfId[1], SfId[2]));\r
+      }\r
+    }\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+}\r
+\r