Home | History | Annotate | Download | only in RamDiskDxe
      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