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) 29typedef 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 36STATIC 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**/ 73EFI_STATUS 74XenIoMmioInstall ( 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 118FreeXenIo: 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**/ 136EFI_STATUS 137XenIoMmioUninstall ( 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