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