/** @file | |
The driver entry point for RamDiskDxe driver. | |
Copyright (c) 2016, Intel Corporation. All rights reserved.<BR> | |
SPDX-License-Identifier: BSD-2-Clause-Patent | |
**/ | |
#include "RamDiskImpl.h" | |
// | |
// Handle for the EFI_RAM_DISK_PROTOCOL instance | |
// | |
EFI_HANDLE mRamDiskHandle = NULL; | |
// | |
// The EFI_RAM_DISK_PROTOCOL instances that is installed onto the driver | |
// handle | |
// | |
EFI_RAM_DISK_PROTOCOL mRamDiskProtocol = { | |
RamDiskRegister, | |
RamDiskUnregister | |
}; | |
// | |
// RamDiskDxe driver maintains a list of registered RAM disks. | |
// | |
LIST_ENTRY RegisteredRamDisks; | |
// | |
// Pointers to the EFI_ACPI_TABLE_PROTOCOL and EFI_ACPI_SDT_PROTOCOL. | |
// | |
EFI_ACPI_TABLE_PROTOCOL *mAcpiTableProtocol = NULL; | |
EFI_ACPI_SDT_PROTOCOL *mAcpiSdtProtocol = NULL; | |
/** | |
Check whether EFI_ACPI_TABLE_PROTOCOL and EFI_ACPI_SDT_PROTOCOL are produced. | |
If both protocols are produced, publish all the reserved memory type RAM | |
disks to the NVDIMM Firmware Interface Table (NFIT). | |
@param[in] Event Event whose notification function is being invoked. | |
@param[in] Context The pointer to the notification function's context, | |
which is implementation-dependent. | |
**/ | |
VOID | |
EFIAPI | |
RamDiskAcpiCheck ( | |
IN EFI_EVENT Event, | |
IN VOID *Context | |
) | |
{ | |
EFI_STATUS Status; | |
LIST_ENTRY *Entry; | |
RAM_DISK_PRIVATE_DATA *PrivateData; | |
gBS->CloseEvent (Event); | |
// | |
// Locate the EFI_ACPI_TABLE_PROTOCOL. | |
// | |
Status = gBS->LocateProtocol ( | |
&gEfiAcpiTableProtocolGuid, | |
NULL, | |
(VOID **)&mAcpiTableProtocol | |
); | |
if (EFI_ERROR (Status)) { | |
DEBUG (( | |
EFI_D_INFO, | |
"RamDiskAcpiCheck: Cannot locate the EFI ACPI Table Protocol, " | |
"unable to publish RAM disks to NFIT.\n" | |
)); | |
return; | |
} | |
// | |
// Locate the EFI_ACPI_SDT_PROTOCOL. | |
// | |
Status = gBS->LocateProtocol ( | |
&gEfiAcpiSdtProtocolGuid, | |
NULL, | |
(VOID **)&mAcpiSdtProtocol | |
); | |
if (EFI_ERROR (Status)) { | |
DEBUG (( | |
EFI_D_INFO, | |
"RamDiskAcpiCheck: Cannot locate the EFI ACPI Sdt Protocol, " | |
"unable to publish RAM disks to NFIT.\n" | |
)); | |
mAcpiTableProtocol = NULL; | |
return; | |
} | |
EFI_LIST_FOR_EACH (Entry, &RegisteredRamDisks) { | |
PrivateData = RAM_DISK_PRIVATE_FROM_THIS (Entry); | |
RamDiskPublishNfit (PrivateData); | |
} | |
} | |
/** | |
The entry point for RamDiskDxe driver. | |
@param[in] ImageHandle The image handle of the driver. | |
@param[in] SystemTable The system table. | |
@retval EFI_ALREADY_STARTED The driver already exists in system. | |
@retval EFI_OUT_OF_RESOURCES Fail to execute entry point due to lack of | |
resources. | |
@retval EFI_SUCCES All the related protocols are installed on | |
the driver. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
RamDiskDxeEntryPoint ( | |
IN EFI_HANDLE ImageHandle, | |
IN EFI_SYSTEM_TABLE *SystemTable | |
) | |
{ | |
EFI_STATUS Status; | |
RAM_DISK_CONFIG_PRIVATE_DATA *ConfigPrivate; | |
VOID *DummyInterface; | |
EFI_EVENT Event; | |
// | |
// If already started, return. | |
// | |
Status = gBS->LocateProtocol ( | |
&gEfiRamDiskProtocolGuid, | |
NULL, | |
&DummyInterface | |
); | |
if (!EFI_ERROR (Status)) { | |
DEBUG ((EFI_D_INFO, "Driver already started!\n")); | |
return EFI_ALREADY_STARTED; | |
} | |
// | |
// Create a private data structure. | |
// | |
ConfigPrivate = AllocateCopyPool (sizeof (RAM_DISK_CONFIG_PRIVATE_DATA), &mRamDiskConfigPrivateDataTemplate); | |
if (ConfigPrivate == NULL) { | |
return EFI_OUT_OF_RESOURCES; | |
} | |
// | |
// Install RAM disk configuration form | |
// | |
Status = InstallRamDiskConfigForm (ConfigPrivate); | |
if (EFI_ERROR (Status)) { | |
goto ErrorExit; | |
} | |
// | |
// Install the EFI_RAM_DISK_PROTOCOL and RAM disk private data onto a | |
// new handle | |
// | |
Status = gBS->InstallMultipleProtocolInterfaces ( | |
&mRamDiskHandle, | |
&gEfiRamDiskProtocolGuid, | |
&mRamDiskProtocol, | |
&gEfiCallerIdGuid, | |
ConfigPrivate, | |
NULL | |
); | |
if (EFI_ERROR (Status)) { | |
goto ErrorExit; | |
} | |
// | |
// Initialize the list of registered RAM disks maintained by the driver | |
// | |
InitializeListHead (&RegisteredRamDisks); | |
Status = EfiCreateEventReadyToBootEx ( | |
TPL_CALLBACK, | |
RamDiskAcpiCheck, | |
NULL, | |
&Event | |
); | |
ASSERT_EFI_ERROR (Status); | |
return EFI_SUCCESS; | |
ErrorExit: | |
if (ConfigPrivate != NULL) { | |
UninstallRamDiskConfigForm (ConfigPrivate); | |
} | |
return Status; | |
} | |
/** | |
Unload the RamDiskDxe driver and its configuration form. | |
@param[in] ImageHandle The driver's image handle. | |
@retval EFI_SUCCESS The RamDiskDxe driver and its configuration | |
form is unloaded. | |
@retval Others Failed to unload the form. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
RamDiskDxeUnload ( | |
IN EFI_HANDLE ImageHandle | |
) | |
{ | |
EFI_STATUS Status; | |
RAM_DISK_CONFIG_PRIVATE_DATA *ConfigPrivate; | |
Status = gBS->HandleProtocol ( | |
mRamDiskHandle, | |
&gEfiCallerIdGuid, | |
(VOID **) &ConfigPrivate | |
); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
ASSERT (ConfigPrivate->Signature == RAM_DISK_CONFIG_PRIVATE_DATA_SIGNATURE); | |
// | |
// Unregister all registered RAM disks | |
// | |
UnregisterAllRamDisks (); | |
gBS->UninstallMultipleProtocolInterfaces ( | |
mRamDiskHandle, | |
&gEfiRamDiskProtocolGuid, | |
&mRamDiskProtocol, | |
&gEfiCallerIdGuid, | |
ConfigPrivate, | |
NULL | |
); | |
UninstallRamDiskConfigForm (ConfigPrivate); | |
return EFI_SUCCESS; | |
} |