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