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 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 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 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