/** @file The driver entry point for RamDiskDxe driver. Copyright (c) 2016, Intel Corporation. All rights reserved.
Copyright (c) Microsoft Corporation.
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 (( DEBUG_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 (( DEBUG_INFO, "RamDiskAcpiCheck: Cannot locate the EFI ACPI Sdt Protocol, " "unable to publish RAM disks to NFIT.\n" )); mAcpiTableProtocol = NULL; return; } BASE_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 ((DEBUG_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; } // // Initialize the list of registered RAM disks maintained by the driver // before installing the protocol // InitializeListHead (&RegisteredRamDisks); // // 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; } 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; }