TianoCore EDK2 master
Loading...
Searching...
No Matches
SpiNorFlashJedecSfdpDxe.c
Go to the documentation of this file.
1
18#include <Base.h>
19#include <Library/DebugLib.h>
24#include <Protocol/SpiIo.h>
26#include "SpiNorFlash.h"
28
40 IN EFI_HANDLE SpiIoHandle
41 )
42{
43 EFI_STATUS Status;
44 SPI_NOR_FLASH_INSTANCE *Instance;
45
46 // Allocate SPI_NOR_FLASH_INSTANCE Instance.
47 Instance = AllocateZeroPool (sizeof (SPI_NOR_FLASH_INSTANCE));
48 ASSERT (Instance != NULL);
49 if (Instance == NULL) {
50 return EFI_OUT_OF_RESOURCES;
51 }
52
53 // Locate the SPI IO Protocol
54 Status = gBS->HandleProtocol (
55 SpiIoHandle,
56 &gEdk2JedecSfdpSpiDxeDriverGuid,
57 (VOID **)&Instance->SpiIo
58 );
59 ASSERT_EFI_ERROR (Status);
60 if (EFI_ERROR (Status)) {
61 DEBUG ((DEBUG_ERROR, "%a: Fail to locate SPI I/O protocol\n", __func__));
62 FreePool (Instance);
63 } else {
64 Status = InitialSpiNorFlashSfdpInstance (Instance);
65 ASSERT_EFI_ERROR (Status);
66 if (EFI_ERROR (Status)) {
67 DEBUG ((DEBUG_ERROR, "%a: Fail to initial SPI_NOR_FLASH_INSTANCE.\n", __func__));
68 FreePool (Instance);
69 } else {
70 // Install SPI NOR Flash Protocol.
71 Status = gBS->InstallProtocolInterface (
72 &Instance->Handle,
73 &gEfiSpiNorFlashProtocolGuid,
75 &Instance->Protocol
76 );
77 if (EFI_ERROR (Status)) {
78 DEBUG ((DEBUG_ERROR, "%a: Fail to Install gEfiSpiNorFlashProtocolGuid protocol.\n", __func__));
79 FreePool (Instance);
80 }
81 }
82 }
83
84 return Status;
85}
86
95VOID
96EFIAPI
98 IN EFI_EVENT Event,
99 OUT VOID *Context
100 )
101{
102 EFI_STATUS Status;
103 UINTN InstanceBufferSize;
104 EFI_HANDLE InstanceBuffer;
105
106 DEBUG ((DEBUG_INFO, "%a: Entry.\n", __func__));
107 InstanceBufferSize = sizeof (EFI_HANDLE);
108 Status = gBS->LocateHandle (
110 (EFI_GUID *)Context,
111 NULL,
112 &InstanceBufferSize,
113 &InstanceBuffer
114 );
115 if (EFI_ERROR (Status)) {
116 DEBUG ((DEBUG_ERROR, "Can't locate SPI I/O protocol.\n"));
117 DEBUG ((DEBUG_INFO, "%a: Exit.\n", __func__));
118 return;
119 }
120
121 CreateSpiNorFlashSfdpInstance (InstanceBuffer);
122 DEBUG ((DEBUG_INFO, "%a: Exit.\n", __func__));
123 return;
124}
125
135 VOID
136 )
137{
138 EFI_EVENT Event;
139 EFI_STATUS Status;
140 VOID *Registration;
141
142 Status = gBS->CreateEvent (
143 EVT_NOTIFY_SIGNAL,
144 TPL_CALLBACK,
146 NULL,
147 &Event
148 );
149 if (EFI_ERROR (Status)) {
150 DEBUG ((DEBUG_ERROR, "%a: Fail to create event for the SPI I/O Protocol installation.", __func__));
151 return Status;
152 }
153
154 Status = gBS->RegisterProtocolNotify (
155 &gEdk2JedecSfdpSpiDxeDriverGuid,
156 Event,
157 &Registration
158 );
159 if (EFI_ERROR (Status)) {
160 DEBUG ((DEBUG_ERROR, "%a: Fail to register event for the SPI I/O Protocol installation.", __func__));
161 } else {
162 DEBUG ((DEBUG_INFO, "%a: Notification for SPI I/O Protocol installation was registered.", __func__));
163 }
164
165 return Status;
166}
167
182EFIAPI
184 IN EFI_HANDLE ImageHandle,
185 IN EFI_SYSTEM_TABLE *SystemTable
186 )
187{
188 EFI_STATUS Status;
189 EFI_HANDLE *InstanceBuffer;
190 UINTN InstanceIndex;
191 UINTN InstanceBufferSize;
192
193 DEBUG ((DEBUG_INFO, "%a - ENTRY\n", __func__));
194
195 //
196 // Register notification for the later SPI I/O protocol installation.
197 //
199 DEBUG ((DEBUG_INFO, "Check if there were already some gEdk2JedecSfdpSpiDxeDriverGuid handles installed.\n"));
200
201 //
202 // Check if there were already some gEdk2JedecSfdpSpiDxeDriverGuid
203 // handles installed.
204 //
205 // Locate the SPI I/O Protocol for the SPI flash part
206 // that supports JEDEC SFDP specification.
207 //
208 InstanceBufferSize = 0;
209 InstanceBuffer = NULL;
210 Status = gBS->LocateHandle (
212 &gEdk2JedecSfdpSpiDxeDriverGuid,
213 NULL,
214 &InstanceBufferSize,
215 InstanceBuffer
216 );
217 if (Status == EFI_NOT_FOUND) {
218 DEBUG ((
219 DEBUG_INFO,
220 "No gEdk2JedecSfdpSpiSmmDriverGuid handles found at the moment, wait for the notification of SPI I/O protocol installation.\n"
221 ));
222 DEBUG ((DEBUG_INFO, "%a: EXIT - Status=%r\n", __func__, Status));
223 return EFI_SUCCESS;
224 } else if (Status == EFI_BUFFER_TOO_SMALL) {
225 InstanceBuffer = (EFI_HANDLE *)AllocateZeroPool (InstanceBufferSize);
226 ASSERT (InstanceBuffer != NULL);
227 if (InstanceBuffer == NULL) {
228 DEBUG ((DEBUG_ERROR, "Not enough resource for gEdk2JedecSfdpSpiDxeDriverGuid handles.\n"));
229 DEBUG ((DEBUG_INFO, "%a: EXIT - Status=%r\n", __func__, Status));
230 return EFI_OUT_OF_RESOURCES;
231 }
232 } else if (EFI_ERROR (Status)) {
233 DEBUG ((DEBUG_ERROR, "Error to locate gEdk2JedecSfdpSpiDxeDriverGuid - Status = %r.\n", Status));
234 DEBUG ((DEBUG_INFO, "%a: EXIT - Status=%r\n", __func__, Status));
235 return Status;
236 }
237
238 Status = gBS->LocateHandle (
240 &gEdk2JedecSfdpSpiDxeDriverGuid,
241 NULL,
242 &InstanceBufferSize,
243 InstanceBuffer
244 );
245 if (EFI_ERROR (Status)) {
246 DEBUG ((DEBUG_ERROR, "Fail to locate all gEdk2JedecSfdpSpiDxeDriverGuid handles.\n"));
247 DEBUG ((DEBUG_INFO, "%a: EXIT - Status=%r\n", __func__, Status));
248 return Status;
249 }
250
251 DEBUG ((DEBUG_INFO, "%d of gEdk2JedecSfdpSpiDxeDriverGuid are found.\n", InstanceBufferSize / sizeof (EFI_HANDLE)));
252 for (InstanceIndex = 0; InstanceIndex < InstanceBufferSize / sizeof (EFI_HANDLE); InstanceIndex++) {
253 Status = CreateSpiNorFlashSfdpInstance (*(InstanceBuffer + InstanceIndex));
254 if (EFI_ERROR (Status)) {
255 DEBUG ((DEBUG_ERROR, "Fail to create SPI NOR Flash SFDP instance #%d.\n", InstanceIndex));
256 }
257 }
258
259 DEBUG ((DEBUG_INFO, "%a: EXIT - Status=%r\n", __func__, Status));
260 return Status;
261}
UINT64 UINTN
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
EFI_STATUS InitialSpiNorFlashSfdpInstance(IN SPI_NOR_FLASH_INSTANCE *Instance)
EFI_STATUS RegisterSpioProtocolNotification(VOID)
EFI_STATUS CreateSpiNorFlashSfdpInstance(IN EFI_HANDLE SpiIoHandle)
VOID EFIAPI SpiIoProtocolInstalledCallback(IN EFI_EVENT Event, OUT VOID *Context)
EFI_STATUS EFIAPI SpiNorFlashJedecSfdpDxeEntry(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
@ EFI_NATIVE_INTERFACE
Definition: UefiSpec.h:1193
@ ByProtocol
Definition: UefiSpec.h:1518
@ ByRegisterNotify
Definition: UefiSpec.h:1513
Definition: Base.h:213