TianoCore EDK2 master
Loading...
Searching...
No Matches
SpiNorFlashJedecSfdpSmm.c
Go to the documentation of this file.
1
17#include <Base.h>
18#include <Library/DebugLib.h>
23#include <Protocol/SpiIo.h>
25#include "SpiNorFlash.h"
27
39 IN EFI_HANDLE SpiIoHandle
40 )
41{
42 EFI_STATUS Status;
43 SPI_NOR_FLASH_INSTANCE *Instance;
44
45 // Allocate SPI_NOR_FLASH_INSTANCE Instance.
46 Instance = AllocateZeroPool (sizeof (SPI_NOR_FLASH_INSTANCE));
47 ASSERT (Instance != NULL);
48 if (Instance == NULL) {
49 return EFI_OUT_OF_RESOURCES;
50 }
51
52 // Locate the SPI IO Protocol.
53 Status = gSmst->SmmHandleProtocol (
54 SpiIoHandle,
55 &gEdk2JedecSfdpSpiSmmDriverGuid,
56 (VOID **)&Instance->SpiIo
57 );
58 ASSERT_EFI_ERROR (Status);
59 if (EFI_ERROR (Status)) {
60 DEBUG ((DEBUG_ERROR, "%a: Fail to locate SPI I/O protocol.\n", __func__));
61 FreePool (Instance);
62 } else {
63 Status = InitialSpiNorFlashSfdpInstance (Instance);
64 ASSERT_EFI_ERROR (Status);
65 if (EFI_ERROR (Status)) {
66 DEBUG ((DEBUG_ERROR, "%a: Fail to initial SPI_NOR_FLASH_INSTANCE.\n", __func__));
67 FreePool (Instance);
68 } else {
69 // Install SPI NOR Flash Protocol.
71 &Instance->Handle,
72 &gEfiSpiSmmNorFlashProtocolGuid,
74 &Instance->Protocol
75 );
76 if (EFI_ERROR (Status)) {
77 DEBUG ((DEBUG_ERROR, "%a: Fail to Install gEfiSpiSmmNorFlashProtocolGuid protocol.\n", __func__));
78 FreePool (Instance);
79 }
80 }
81 }
82
83 return Status;
84}
85
98EFIAPI
100 IN CONST EFI_GUID *Protocol,
101 IN VOID *Interface,
102 IN EFI_HANDLE Handle
103 )
104{
105 EFI_STATUS Status;
106
107 DEBUG ((DEBUG_INFO, "%a: Entry.\n", __func__));
108 Status = CreateSpiNorFlashSfdpInstance (Handle);
109 return Status;
110}
111
122 VOID
123 )
124{
125 EFI_STATUS Status;
126 VOID *Registration;
127
128 Status = gSmst->SmmRegisterProtocolNotify (
129 &gEdk2JedecSfdpSpiSmmDriverGuid,
131 &Registration
132 );
133 if (EFI_ERROR (Status)) {
134 DEBUG ((DEBUG_ERROR, "%a: Fail to register event for the SPI I/O Protocol installation.", __func__));
135 } else {
136 DEBUG ((DEBUG_INFO, "%a: Notification for SPI I/O Protocol installation was registered.", __func__));
137 }
138
139 return Status;
140}
141
156EFIAPI
158 IN EFI_HANDLE ImageHandle,
159 IN EFI_SYSTEM_TABLE *SystemTable
160 )
161{
162 EFI_STATUS Status;
163 EFI_HANDLE *InstanceBuffer;
164 UINTN InstanceIndex;
165 UINTN InstanceBufferSize;
166
167 DEBUG ((DEBUG_INFO, "%a - ENTRY.\n", __func__));
168
169 //
170 // Register notification for the later SPI I/O protocol installation.
171 //
173 DEBUG ((DEBUG_INFO, "Check if there were already some gEdk2JedecSfdpSpiSmmDriverGuid handles installed.\n"));
174 //
175 // Check if there were already some gEdk2JedecSfdpSpiSmmDriverGuid
176 // handles installed.
177 //
178 // Locate the SPI I/O Protocol for the SPI flash part
179 // that supports JEDEC SFDP specification.
180 //
181 InstanceBufferSize = 0;
182 InstanceBuffer = NULL;
183 Status = gSmst->SmmLocateHandle (
185 &gEdk2JedecSfdpSpiSmmDriverGuid,
186 NULL,
187 &InstanceBufferSize,
188 InstanceBuffer
189 );
190 if (Status == EFI_NOT_FOUND) {
191 DEBUG ((
192 DEBUG_INFO,
193 "No gEdk2JedecSfdpSpiSmmDriverGuid handles found at the moment, wait for the notification of SPI I/O protocol installation.\n"
194 ));
195 DEBUG ((DEBUG_INFO, "%a: EXIT - Status=%r\n", __func__, Status));
196 return EFI_SUCCESS;
197 } else if (Status == EFI_BUFFER_TOO_SMALL) {
198 InstanceBuffer = (EFI_HANDLE *)AllocateZeroPool (InstanceBufferSize);
199 ASSERT (InstanceBuffer != NULL);
200 if (InstanceBuffer == NULL) {
201 DEBUG ((DEBUG_ERROR, "Not enough resource for gEdk2JedecSfdpSpiSmmDriverGuid handles.\n"));
202 DEBUG ((DEBUG_INFO, "%a: EXIT - Status=%r\n", __func__, Status));
203 return EFI_OUT_OF_RESOURCES;
204 }
205 } else if (EFI_ERROR (Status)) {
206 DEBUG ((DEBUG_ERROR, "Error to locate gEdk2JedecSfdpSpiSmmDriverGuid - Status = %r.\n", Status));
207 DEBUG ((DEBUG_INFO, "%a: EXIT - Status=%r\n", __func__, Status));
208 return Status;
209 }
210
211 Status = gSmst->SmmLocateHandle (
213 &gEdk2JedecSfdpSpiSmmDriverGuid,
214 NULL,
215 &InstanceBufferSize,
216 InstanceBuffer
217 );
218 if (EFI_ERROR (Status)) {
219 DEBUG ((DEBUG_ERROR, "Fail to locate all gEdk2JedecSfdpSpiSmmDriverGuid handles.\n"));
220 DEBUG ((DEBUG_INFO, "%a: EXIT - Status=%r\n", __func__, Status));
221 return Status;
222 }
223
224 DEBUG ((DEBUG_INFO, "%d of gEdk2JedecSfdpSpiSmmDriverGuid handles are found.\n", InstanceBufferSize / sizeof (EFI_HANDLE)));
225 for (InstanceIndex = 0; InstanceIndex < InstanceBufferSize / sizeof (EFI_HANDLE); InstanceIndex++) {
226 Status = CreateSpiNorFlashSfdpInstance (*(InstanceBuffer + InstanceIndex));
227 if (EFI_ERROR (Status)) {
228 DEBUG ((DEBUG_ERROR, "Fail to create SPI NOR Flash SFDP instance #%d.\n", InstanceIndex));
229 }
230 }
231
232 DEBUG ((DEBUG_INFO, "%a: EXIT - Status=%r\n", __func__, Status));
233 return Status;
234}
UINT64 UINTN
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define IN
Definition: Base.h:279
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
EFI_SMM_SYSTEM_TABLE2 * gSmst
EFI_STATUS InitialSpiNorFlashSfdpInstance(IN SPI_NOR_FLASH_INSTANCE *Instance)
EFI_STATUS RegisterSpioProtocolNotification(VOID)
EFI_STATUS EFIAPI SpiIoProtocolInstalledCallback(IN CONST EFI_GUID *Protocol, IN VOID *Interface, IN EFI_HANDLE Handle)
EFI_STATUS EFIAPI SpiNorFlashJedecSfdpSmmEntry(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
EFI_STATUS CreateSpiNorFlashSfdpInstance(IN EFI_HANDLE SpiIoHandle)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
@ EFI_NATIVE_INTERFACE
Definition: UefiSpec.h:1193
@ ByProtocol
Definition: UefiSpec.h:1518
EFI_INSTALL_PROTOCOL_INTERFACE SmmInstallProtocolInterface
Definition: PiSmmCis.h:185
Definition: Base.h:213