]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDriver.c
MdeModulePkg/RamDiskDxe: Init list head before registering RamDisk protocol
[mirror_edk2.git] / MdeModulePkg / Universal / Disk / RamDiskDxe / RamDiskDriver.c
1 /** @file
2 The driver entry point for RamDiskDxe driver.
3
4 Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
5 Copyright (c) Microsoft Corporation.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include "RamDiskImpl.h"
11
12 //
13 // Handle for the EFI_RAM_DISK_PROTOCOL instance
14 //
15 EFI_HANDLE mRamDiskHandle = NULL;
16
17 //
18 // The EFI_RAM_DISK_PROTOCOL instances that is installed onto the driver
19 // handle
20 //
21 EFI_RAM_DISK_PROTOCOL mRamDiskProtocol = {
22 RamDiskRegister,
23 RamDiskUnregister
24 };
25
26 //
27 // RamDiskDxe driver maintains a list of registered RAM disks.
28 //
29 LIST_ENTRY RegisteredRamDisks;
30
31 //
32 // Pointers to the EFI_ACPI_TABLE_PROTOCOL and EFI_ACPI_SDT_PROTOCOL.
33 //
34 EFI_ACPI_TABLE_PROTOCOL *mAcpiTableProtocol = NULL;
35 EFI_ACPI_SDT_PROTOCOL *mAcpiSdtProtocol = NULL;
36
37
38 /**
39 Check whether EFI_ACPI_TABLE_PROTOCOL and EFI_ACPI_SDT_PROTOCOL are produced.
40 If both protocols are produced, publish all the reserved memory type RAM
41 disks to the NVDIMM Firmware Interface Table (NFIT).
42
43 @param[in] Event Event whose notification function is being invoked.
44 @param[in] Context The pointer to the notification function's context,
45 which is implementation-dependent.
46
47 **/
48 VOID
49 EFIAPI
50 RamDiskAcpiCheck (
51 IN EFI_EVENT Event,
52 IN VOID *Context
53 )
54 {
55 EFI_STATUS Status;
56 LIST_ENTRY *Entry;
57 RAM_DISK_PRIVATE_DATA *PrivateData;
58
59 gBS->CloseEvent (Event);
60
61 //
62 // Locate the EFI_ACPI_TABLE_PROTOCOL.
63 //
64 Status = gBS->LocateProtocol (
65 &gEfiAcpiTableProtocolGuid,
66 NULL,
67 (VOID **)&mAcpiTableProtocol
68 );
69 if (EFI_ERROR (Status)) {
70 DEBUG ((
71 EFI_D_INFO,
72 "RamDiskAcpiCheck: Cannot locate the EFI ACPI Table Protocol, "
73 "unable to publish RAM disks to NFIT.\n"
74 ));
75 return;
76 }
77
78 //
79 // Locate the EFI_ACPI_SDT_PROTOCOL.
80 //
81 Status = gBS->LocateProtocol (
82 &gEfiAcpiSdtProtocolGuid,
83 NULL,
84 (VOID **)&mAcpiSdtProtocol
85 );
86 if (EFI_ERROR (Status)) {
87 DEBUG ((
88 EFI_D_INFO,
89 "RamDiskAcpiCheck: Cannot locate the EFI ACPI Sdt Protocol, "
90 "unable to publish RAM disks to NFIT.\n"
91 ));
92 mAcpiTableProtocol = NULL;
93 return;
94 }
95
96 BASE_LIST_FOR_EACH (Entry, &RegisteredRamDisks) {
97 PrivateData = RAM_DISK_PRIVATE_FROM_THIS (Entry);
98 RamDiskPublishNfit (PrivateData);
99 }
100 }
101
102
103 /**
104 The entry point for RamDiskDxe driver.
105
106 @param[in] ImageHandle The image handle of the driver.
107 @param[in] SystemTable The system table.
108
109 @retval EFI_ALREADY_STARTED The driver already exists in system.
110 @retval EFI_OUT_OF_RESOURCES Fail to execute entry point due to lack of
111 resources.
112 @retval EFI_SUCCES All the related protocols are installed on
113 the driver.
114
115 **/
116 EFI_STATUS
117 EFIAPI
118 RamDiskDxeEntryPoint (
119 IN EFI_HANDLE ImageHandle,
120 IN EFI_SYSTEM_TABLE *SystemTable
121 )
122 {
123 EFI_STATUS Status;
124 RAM_DISK_CONFIG_PRIVATE_DATA *ConfigPrivate;
125 VOID *DummyInterface;
126 EFI_EVENT Event;
127
128 //
129 // If already started, return.
130 //
131 Status = gBS->LocateProtocol (
132 &gEfiRamDiskProtocolGuid,
133 NULL,
134 &DummyInterface
135 );
136 if (!EFI_ERROR (Status)) {
137 DEBUG ((EFI_D_INFO, "Driver already started!\n"));
138 return EFI_ALREADY_STARTED;
139 }
140
141 //
142 // Create a private data structure.
143 //
144 ConfigPrivate = AllocateCopyPool (sizeof (RAM_DISK_CONFIG_PRIVATE_DATA), &mRamDiskConfigPrivateDataTemplate);
145 if (ConfigPrivate == NULL) {
146 return EFI_OUT_OF_RESOURCES;
147 }
148
149 //
150 // Install RAM disk configuration form
151 //
152 Status = InstallRamDiskConfigForm (ConfigPrivate);
153 if (EFI_ERROR (Status)) {
154 goto ErrorExit;
155 }
156
157 //
158 // Initialize the list of registered RAM disks maintained by the driver
159 // before installing the protocol
160 //
161 InitializeListHead (&RegisteredRamDisks);
162
163 //
164 // Install the EFI_RAM_DISK_PROTOCOL and RAM disk private data onto a
165 // new handle
166 //
167 Status = gBS->InstallMultipleProtocolInterfaces (
168 &mRamDiskHandle,
169 &gEfiRamDiskProtocolGuid,
170 &mRamDiskProtocol,
171 &gEfiCallerIdGuid,
172 ConfigPrivate,
173 NULL
174 );
175 if (EFI_ERROR (Status)) {
176 goto ErrorExit;
177 }
178
179 Status = EfiCreateEventReadyToBootEx (
180 TPL_CALLBACK,
181 RamDiskAcpiCheck,
182 NULL,
183 &Event
184 );
185 ASSERT_EFI_ERROR (Status);
186
187 return EFI_SUCCESS;
188
189 ErrorExit:
190 if (ConfigPrivate != NULL) {
191 UninstallRamDiskConfigForm (ConfigPrivate);
192 }
193
194 return Status;
195 }
196
197
198 /**
199 Unload the RamDiskDxe driver and its configuration form.
200
201 @param[in] ImageHandle The driver's image handle.
202
203 @retval EFI_SUCCESS The RamDiskDxe driver and its configuration
204 form is unloaded.
205 @retval Others Failed to unload the form.
206
207 **/
208 EFI_STATUS
209 EFIAPI
210 RamDiskDxeUnload (
211 IN EFI_HANDLE ImageHandle
212 )
213 {
214 EFI_STATUS Status;
215 RAM_DISK_CONFIG_PRIVATE_DATA *ConfigPrivate;
216
217 Status = gBS->HandleProtocol (
218 mRamDiskHandle,
219 &gEfiCallerIdGuid,
220 (VOID **) &ConfigPrivate
221 );
222 if (EFI_ERROR (Status)) {
223 return Status;
224 }
225
226 ASSERT (ConfigPrivate->Signature == RAM_DISK_CONFIG_PRIVATE_DATA_SIGNATURE);
227
228 //
229 // Unregister all registered RAM disks
230 //
231 UnregisterAllRamDisks ();
232
233 gBS->UninstallMultipleProtocolInterfaces (
234 mRamDiskHandle,
235 &gEfiRamDiskProtocolGuid,
236 &mRamDiskProtocol,
237 &gEfiCallerIdGuid,
238 ConfigPrivate,
239 NULL
240 );
241
242 UninstallRamDiskConfigForm (ConfigPrivate);
243
244 return EFI_SUCCESS;
245 }