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