1 /** @file 2 3 Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR> 4 5 This program and the accompanying materials are licensed and made available under 6 the terms and conditions of the BSD License that accompanies this distribution. 7 The full text of the license may be found at 8 http://opensource.org/licenses/bsd-license.php. 9 10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12 13 14 15 **/ 16 17 #include <PiDxe.h> 18 19 #include <Library/FlashDeviceLib.h> 20 #include <Library/DebugLib.h> 21 #include <Library/BaseLib.h> 22 #include <Library/UefiBootServicesTableLib.h> 23 #include <Library/UefiRuntimeServicesTableLib.h> 24 #include <Library/BaseMemoryLib.h> 25 #include <Library/UefiRuntimeLib.h> 26 #include <Protocol/SmmBase2.h> 27 #include <Guid/EventGroup.h> 28 #include "SpiChipDefinitions.h" 29 30 extern UINTN FlashDeviceBase; 31 32 extern EFI_SPI_PROTOCOL *mSpiProtocol; 33 34 VOID 35 EFIAPI 36 LibFvbFlashDeviceVirtualAddressChangeNotifyEvent ( 37 IN EFI_EVENT Event, 38 IN VOID *Context 39 ) 40 { 41 gRT->ConvertPointer (0, (VOID **) &mSpiProtocol); 42 gRT->ConvertPointer (0, (VOID **) &FlashDeviceBase); 43 } 44 45 46 /** 47 The library constructuor. 48 49 The function does the necessary initialization work for this library 50 instance. Please put all initialization works in it. 51 52 @param[in] ImageHandle The firmware allocated handle for the UEFI image. 53 @param[in] SystemTable A pointer to the EFI system table. 54 55 @retval EFI_SUCCESS The function always return EFI_SUCCESS for now. 56 It will ASSERT on error for debug version. 57 @retval EFI_ERROR Please reference LocateProtocol for error code details. 58 59 **/ 60 EFI_STATUS 61 EFIAPI 62 LibFvbFlashDeviceSupportInit ( 63 IN EFI_HANDLE ImageHandle, 64 IN EFI_SYSTEM_TABLE *SystemTable 65 ) 66 { 67 EFI_STATUS Status; 68 EFI_EVENT Event; 69 UINT8 SfId[3]; 70 UINT8 FlashIndex; 71 UINT8 SpiReadError; 72 UINT8 SpiNotMatchError; 73 EFI_SMM_BASE2_PROTOCOL *SmmBase; 74 BOOLEAN InSmm; 75 76 SpiReadError = 0x00; 77 SpiNotMatchError = 0x00; 78 79 InSmm = FALSE; 80 Status = gBS->LocateProtocol ( 81 &gEfiSmmBase2ProtocolGuid, 82 NULL, 83 (void **)&SmmBase 84 ); 85 if (!EFI_ERROR(Status)) { 86 Status = SmmBase->InSmm(SmmBase, &InSmm); 87 if (EFI_ERROR(Status)) { 88 InSmm = FALSE; 89 } 90 } 91 92 if (!InSmm) { 93 Status = gBS->LocateProtocol ( 94 &gEfiSpiProtocolGuid, 95 NULL, 96 (VOID **)&mSpiProtocol 97 ); 98 ASSERT_EFI_ERROR (Status); 99 100 Status = gBS->CreateEventEx ( 101 EVT_NOTIFY_SIGNAL, 102 TPL_NOTIFY, 103 LibFvbFlashDeviceVirtualAddressChangeNotifyEvent, 104 NULL, 105 &gEfiEventVirtualAddressChangeGuid, 106 &Event 107 ); 108 ASSERT_EFI_ERROR (Status); 109 110 } else { 111 Status = gBS->LocateProtocol ( 112 &gEfiSmmSpiProtocolGuid, 113 NULL, 114 (VOID **)&mSpiProtocol 115 ); 116 ASSERT_EFI_ERROR (Status); 117 } 118 119 120 for (FlashIndex = EnumSpiFlashW25Q64; FlashIndex < EnumSpiFlashMax; FlashIndex++) { 121 Status = mSpiProtocol->Init (mSpiProtocol, &(mInitTable[FlashIndex])); 122 if (!EFI_ERROR (Status)) { 123 // 124 // Read Vendor/Device IDs to check if the driver supports the Serial Flash device. 125 // 126 Status = mSpiProtocol->Execute ( 127 mSpiProtocol, 128 SPI_READ_ID, 129 SPI_WREN, 130 TRUE, 131 FALSE, 132 FALSE, 133 0, 134 3, 135 SfId, 136 EnumSpiRegionAll 137 ); 138 if (!EFI_ERROR (Status)) { 139 if ((SfId[0] == mInitTable[FlashIndex].VendorId) && 140 (SfId[1] == mInitTable[FlashIndex].DeviceId0) && 141 (SfId[2] == mInitTable[FlashIndex].DeviceId1)) { 142 // 143 // Found a matching SPI device, FlashIndex now contains flash device. 144 // 145 DEBUG ((EFI_D_ERROR, "OK - Found SPI Flash Type in SPI Flash Driver, Device Type ID 0 = 0x%02x!\n", mInitTable[FlashIndex].DeviceId0)); 146 DEBUG ((EFI_D_ERROR, "Device Type ID 1 = 0x%02x!\n", mInitTable[FlashIndex].DeviceId1)); 147 148 if (mInitTable[FlashIndex].BiosStartOffset == (UINTN) (-1)) { 149 DEBUG ((EFI_D_ERROR, "ERROR - The size of BIOS image is bigger than SPI Flash device!\n")); 150 CpuDeadLoop (); 151 } 152 break; 153 } else { 154 SpiNotMatchError++; 155 } 156 } else { 157 SpiReadError++; 158 } 159 } 160 } 161 162 DEBUG ((EFI_D_ERROR, "SPI flash chip VID = 0x%X, DID0 = 0x%X, DID1 = 0x%X\n", SfId[0], SfId[1], SfId[2])); 163 164 if (FlashIndex < EnumSpiFlashMax) { 165 return EFI_SUCCESS; 166 } else { 167 if (SpiReadError != 0) { 168 DEBUG ((EFI_D_ERROR, "ERROR - SPI Read ID execution failed! Error Count = %d\n", SpiReadError)); 169 } 170 else { 171 if (SpiNotMatchError != 0) { 172 DEBUG ((EFI_D_ERROR, "ERROR - No supported SPI flash chip found! Error Count = %d\n", SpiNotMatchError)); 173 DEBUG ((EFI_D_ERROR, "SPI flash chip VID = 0x%X, DID0 = 0x%X, DID1 = 0x%X\n", SfId[0], SfId[1], SfId[2])); 174 } 175 } 176 return EFI_UNSUPPORTED; 177 } 178 } 179 180