]> git.proxmox.com Git - mirror_edk2.git/blob - Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibDxeRuntimeSmm.c
Vlv2TbltDevicePkg/FlashDeviceLib: Add DXE flash device lib.
[mirror_edk2.git] / Vlv2TbltDevicePkg / Library / FlashDeviceLib / FlashDeviceLibDxeRuntimeSmm.c
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