Home | History | Annotate | Download | only in XenIoMmioLib
      1 /** @file
      2 *  Manage XenBus device path and I/O handles
      3 *
      4 *  Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>
      5 *
      6 *  This program and the accompanying materials are
      7 *  licensed and made available under the terms and conditions of the BSD License
      8 *  which accompanies this distribution.  The full text of the license may be found at
      9 *  http://opensource.org/licenses/bsd-license.php
     10 *
     11 *  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     12 *  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     13 *
     14 **/
     15 
     16 #include <Library/BaseLib.h>
     17 #include <Library/UefiBootServicesTableLib.h>
     18 #include <Library/DebugLib.h>
     19 #include <Library/UefiLib.h>
     20 #include <Library/BaseMemoryLib.h>
     21 #include <Library/MemoryAllocationLib.h>
     22 #include <Library/DevicePathLib.h>
     23 #include <Library/XenIoMmioLib.h>
     24 
     25 #include <Protocol/XenIo.h>
     26 #include <Guid/XenBusRootDevice.h>
     27 
     28 #pragma pack (1)
     29 typedef struct {
     30   VENDOR_DEVICE_PATH                  Vendor;
     31   EFI_PHYSICAL_ADDRESS                GrantTableAddress;
     32   EFI_DEVICE_PATH_PROTOCOL            End;
     33 } XENBUS_ROOT_DEVICE_PATH;
     34 #pragma pack ()
     35 
     36 STATIC CONST XENBUS_ROOT_DEVICE_PATH mXenBusRootDevicePathTemplate = {
     37   {
     38     {
     39       HARDWARE_DEVICE_PATH,
     40       HW_VENDOR_DP,
     41       { sizeof (VENDOR_DEVICE_PATH) + sizeof (EFI_PHYSICAL_ADDRESS), 0 }
     42     },
     43     XENBUS_ROOT_DEVICE_GUID,
     44   },
     45   0,
     46   {
     47     END_DEVICE_PATH_TYPE,
     48     END_ENTIRE_DEVICE_PATH_SUBTYPE,
     49     { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 }
     50   }
     51 };
     52 
     53 /**
     54 
     55   Install the XENBUS_ROOT_DEVICE_PATH and XENIO_PROTOCOL protocols on
     56   the handle pointed to by @Handle, or on a new handle if it points to
     57   NULL
     58 
     59   @param  Handle                Pointer to the handle to install the protocols
     60                                 on, may point to a NULL handle.
     61 
     62   @param  GrantTableAddress     The address of the Xen grant table
     63 
     64   @retval EFI_SUCCESS           Protocols were installed successfully
     65 
     66   @retval EFI_OUT_OF_RESOURCES  The function failed to allocate memory required
     67                                 by the XenIo MMIO and device path protocols
     68 
     69   @return                       Status code returned by the boot service
     70                                 InstallMultipleProtocolInterfaces ()
     71 
     72 **/
     73 EFI_STATUS
     74 XenIoMmioInstall (
     75   IN OUT   EFI_HANDLE              *Handle,
     76   IN       EFI_PHYSICAL_ADDRESS    GrantTableAddress
     77   )
     78 {
     79   EFI_STATUS                     Status;
     80   XENIO_PROTOCOL                 *XenIo;
     81   XENBUS_ROOT_DEVICE_PATH        *XenBusDevicePath;
     82   EFI_HANDLE                     OutHandle;
     83 
     84   ASSERT (Handle != NULL);
     85 
     86   OutHandle = *Handle;
     87 
     88   XenIo = AllocateZeroPool (sizeof *XenIo);
     89   if (!XenIo) {
     90     return EFI_OUT_OF_RESOURCES;
     91   }
     92   XenIo->GrantTableAddress = GrantTableAddress;
     93 
     94   XenBusDevicePath = AllocateCopyPool (sizeof *XenBusDevicePath,
     95                        &mXenBusRootDevicePathTemplate);
     96   if (!XenBusDevicePath) {
     97     DEBUG ((EFI_D_ERROR, "%a: Out of memory\n", __FUNCTION__));
     98     Status = EFI_OUT_OF_RESOURCES;
     99     goto FreeXenIo;
    100   }
    101   XenBusDevicePath->GrantTableAddress = GrantTableAddress;
    102 
    103   Status = gBS->InstallMultipleProtocolInterfaces (&OutHandle,
    104                   &gEfiDevicePathProtocolGuid, XenBusDevicePath,
    105                   &gXenIoProtocolGuid, XenIo,
    106                   NULL);
    107   if (!EFI_ERROR (Status)) {
    108     *Handle = OutHandle;
    109     return EFI_SUCCESS;
    110   }
    111 
    112   DEBUG ((EFI_D_ERROR, "%a: Failed to install the EFI_DEVICE_PATH and "
    113     "XENIO_PROTOCOL protocols on handle %p (Status == %r)\n",
    114     __FUNCTION__, OutHandle, Status));
    115 
    116   FreePool (XenBusDevicePath);
    117 
    118 FreeXenIo:
    119   FreePool (XenIo);
    120   return Status;
    121 }
    122 
    123 /**
    124 
    125   Uninstall the XENBUS_ROOT_DEVICE_PATH and XENIO_PROTOCOL protocols
    126 
    127   @param  Handle          Handle onto which the protocols have been installed
    128                           earlier by XenIoMmioInstall ()
    129 
    130   @retval EFI_SUCCESS     Protocols were uninstalled successfully
    131 
    132   @return                 Status code returned by the boot service
    133                           UninstallMultipleProtocolInterfaces ()
    134 
    135 **/
    136 EFI_STATUS
    137 XenIoMmioUninstall (
    138   IN       EFI_HANDLE              Handle
    139   )
    140 {
    141   EFI_STATUS    Status;
    142   VOID          *XenIo;
    143   VOID          *XenBusDevicePath;
    144 
    145   XenBusDevicePath = NULL;
    146   gBS->OpenProtocol (Handle, &gEfiDevicePathProtocolGuid, &XenBusDevicePath,
    147          NULL, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
    148 
    149   XenIo = NULL;
    150   gBS->OpenProtocol (Handle, &gXenIoProtocolGuid, &XenIo,
    151          NULL, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
    152 
    153   Status = gBS->UninstallMultipleProtocolInterfaces (Handle,
    154                   &gEfiDevicePathProtocolGuid, XenBusDevicePath,
    155                   &gXenIoProtocolGuid, XenIo,
    156                   NULL);
    157 
    158   if (EFI_ERROR (Status)) {
    159     return Status;
    160   }
    161 
    162   FreePool (XenBusDevicePath);
    163   FreePool (XenIo);
    164 
    165   return EFI_SUCCESS;
    166 }
    167