15e9e1c799a814b84e08e7db11b4ce638992f1e1
[mirror_edk2.git] / OvmfPkg / XenBusDxe / XenHypercall.c
1 /** @file
2 Functions to make Xen hypercalls.
3
4 Copyright (C) 2014, Citrix Ltd.
5
6 This program and the accompanying materials
7 are 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 <PiDxe.h>
17 #include <Library/HobLib.h>
18 #include <Guid/XenInfo.h>
19
20 #include "XenBusDxe.h"
21 #include "XenHypercall.h"
22
23 #include <IndustryStandard/Xen/hvm/params.h>
24 #include <IndustryStandard/Xen/memory.h>
25
26 EFI_STATUS
27 XenHyperpageInit (
28 IN OUT XENBUS_DEVICE *Dev
29 )
30 {
31 EFI_HOB_GUID_TYPE *GuidHob;
32 EFI_XEN_INFO *XenInfo;
33
34 GuidHob = GetFirstGuidHob (&gEfiXenInfoGuid);
35 if (GuidHob == NULL) {
36 return EFI_NOT_FOUND;
37 }
38 XenInfo = (EFI_XEN_INFO *) GET_GUID_HOB_DATA (GuidHob);
39 Dev->Hyperpage = XenInfo->HyperPages;
40 return EFI_SUCCESS;
41 }
42
43 UINT64
44 XenHypercallHvmGetParam (
45 IN XENBUS_DEVICE *Dev,
46 IN UINT32 Index
47 )
48 {
49 xen_hvm_param_t Parameter;
50 INTN Error;
51
52 ASSERT (Dev->Hyperpage != NULL);
53
54 Parameter.domid = DOMID_SELF;
55 Parameter.index = Index;
56 Error = XenHypercall2 (Dev->Hyperpage + __HYPERVISOR_hvm_op * 32,
57 HVMOP_get_param, (INTN) &Parameter);
58 if (Error != 0) {
59 DEBUG ((EFI_D_ERROR,
60 "XenHypercall: Error %d trying to get HVM parameter %d\n",
61 Error, Index));
62 return 0;
63 }
64 return Parameter.value;
65 }
66
67 INTN
68 XenHypercallMemoryOp (
69 IN XENBUS_DEVICE *Dev,
70 IN UINTN Operation,
71 IN OUT VOID *Arguments
72 )
73 {
74 ASSERT (Dev->Hyperpage != NULL);
75 return XenHypercall2 (Dev->Hyperpage + __HYPERVISOR_memory_op * 32,
76 Operation, (INTN) Arguments);
77 }
78
79 INTN
80 XenHypercallEventChannelOp (
81 IN XENBUS_DEVICE *Dev,
82 IN INTN Operation,
83 IN OUT VOID *Arguments
84 )
85 {
86 ASSERT (Dev->Hyperpage != NULL);
87 return XenHypercall2 (Dev->Hyperpage + __HYPERVISOR_event_channel_op * 32,
88 Operation, (INTN) Arguments);
89 }
90
91 EFI_STATUS
92 XenGetSharedInfoPage (
93 IN OUT XENBUS_DEVICE *Dev
94 )
95 {
96 xen_add_to_physmap_t Parameter;
97
98 ASSERT (Dev->SharedInfo == NULL);
99
100 Parameter.domid = DOMID_SELF;
101 Parameter.space = XENMAPSPACE_shared_info;
102 Parameter.idx = 0;
103
104 //
105 // using reserved page because the page is not released when Linux is
106 // starting because of the add_to_physmap. QEMU might try to access the
107 // page, and fail because it have no right to do so (segv).
108 //
109 Dev->SharedInfo = AllocateReservedPages (1);
110 Parameter.gpfn = (UINTN) Dev->SharedInfo >> EFI_PAGE_SHIFT;
111 if (XenHypercallMemoryOp (Dev, XENMEM_add_to_physmap, &Parameter) != 0) {
112 FreePages (Dev->SharedInfo, 1);
113 Dev->SharedInfo = NULL;
114 return EFI_LOAD_ERROR;
115 }
116
117 return EFI_SUCCESS;
118 }