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