4 * Copyright (C) 1999 VA Linux Systems
5 * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
6 * Copyright (C) 1999-2002 Hewlett-Packard Co.
7 * David Mosberger-Tang <davidm@hpl.hp.com>
8 * Stephane Eranian <eranian@hpl.hp.com>
9 * Copyright (C) 2005-2008 Intel Co.
10 * Fenghua Yu <fenghua.yu@intel.com>
11 * Bibo Mao <bibo.mao@intel.com>
12 * Chandramouli Narayanan <mouli@linux.intel.com>
13 * Huang Ying <ying.huang@intel.com>
14 * Copyright (C) 2011 Novell Co.
15 * Jan Beulich <JBeulich@suse.com>
16 * Copyright (C) 2011-2012 Oracle Co.
17 * Liang Tang <liang.tang@oracle.com>
18 * Copyright (c) 2014 Oracle Co., Daniel Kiper
21 #include <linux/bug.h>
22 #include <linux/efi.h>
23 #include <linux/init.h>
24 #include <linux/string.h>
26 #include <xen/interface/xen.h>
27 #include <xen/interface/platform.h>
29 #include <xen/xen-ops.h>
33 #include <asm/xen/hypercall.h>
35 #define INIT_EFI_OP(name) \
36 {.cmd = XENPF_efi_runtime_call, \
37 .u.efi_runtime_call.function = XEN_EFI_##name, \
38 .u.efi_runtime_call.misc = 0}
40 #define efi_data(op) (op.u.efi_runtime_call)
42 efi_status_t
xen_efi_get_time(efi_time_t
*tm
, efi_time_cap_t
*tc
)
44 struct xen_platform_op op
= INIT_EFI_OP(get_time
);
46 if (HYPERVISOR_platform_op(&op
) < 0)
47 return EFI_UNSUPPORTED
;
50 BUILD_BUG_ON(sizeof(*tm
) != sizeof(efi_data(op
).u
.get_time
.time
));
51 memcpy(tm
, &efi_data(op
).u
.get_time
.time
, sizeof(*tm
));
55 tc
->resolution
= efi_data(op
).u
.get_time
.resolution
;
56 tc
->accuracy
= efi_data(op
).u
.get_time
.accuracy
;
57 tc
->sets_to_zero
= !!(efi_data(op
).misc
&
58 XEN_EFI_GET_TIME_SET_CLEARS_NS
);
61 return efi_data(op
).status
;
63 EXPORT_SYMBOL_GPL(xen_efi_get_time
);
65 efi_status_t
xen_efi_set_time(efi_time_t
*tm
)
67 struct xen_platform_op op
= INIT_EFI_OP(set_time
);
69 BUILD_BUG_ON(sizeof(*tm
) != sizeof(efi_data(op
).u
.set_time
));
70 memcpy(&efi_data(op
).u
.set_time
, tm
, sizeof(*tm
));
72 if (HYPERVISOR_platform_op(&op
) < 0)
73 return EFI_UNSUPPORTED
;
75 return efi_data(op
).status
;
77 EXPORT_SYMBOL_GPL(xen_efi_set_time
);
79 efi_status_t
xen_efi_get_wakeup_time(efi_bool_t
*enabled
, efi_bool_t
*pending
,
82 struct xen_platform_op op
= INIT_EFI_OP(get_wakeup_time
);
84 if (HYPERVISOR_platform_op(&op
) < 0)
85 return EFI_UNSUPPORTED
;
88 BUILD_BUG_ON(sizeof(*tm
) != sizeof(efi_data(op
).u
.get_wakeup_time
));
89 memcpy(tm
, &efi_data(op
).u
.get_wakeup_time
, sizeof(*tm
));
93 *enabled
= !!(efi_data(op
).misc
& XEN_EFI_GET_WAKEUP_TIME_ENABLED
);
96 *pending
= !!(efi_data(op
).misc
& XEN_EFI_GET_WAKEUP_TIME_PENDING
);
98 return efi_data(op
).status
;
100 EXPORT_SYMBOL_GPL(xen_efi_get_wakeup_time
);
102 efi_status_t
xen_efi_set_wakeup_time(efi_bool_t enabled
, efi_time_t
*tm
)
104 struct xen_platform_op op
= INIT_EFI_OP(set_wakeup_time
);
106 BUILD_BUG_ON(sizeof(*tm
) != sizeof(efi_data(op
).u
.set_wakeup_time
));
108 efi_data(op
).misc
= XEN_EFI_SET_WAKEUP_TIME_ENABLE
;
110 memcpy(&efi_data(op
).u
.set_wakeup_time
, tm
, sizeof(*tm
));
112 efi_data(op
).misc
|= XEN_EFI_SET_WAKEUP_TIME_ENABLE_ONLY
;
114 if (HYPERVISOR_platform_op(&op
) < 0)
115 return EFI_UNSUPPORTED
;
117 return efi_data(op
).status
;
119 EXPORT_SYMBOL_GPL(xen_efi_set_wakeup_time
);
121 efi_status_t
xen_efi_get_variable(efi_char16_t
*name
, efi_guid_t
*vendor
,
122 u32
*attr
, unsigned long *data_size
,
125 struct xen_platform_op op
= INIT_EFI_OP(get_variable
);
127 set_xen_guest_handle(efi_data(op
).u
.get_variable
.name
, name
);
128 BUILD_BUG_ON(sizeof(*vendor
) !=
129 sizeof(efi_data(op
).u
.get_variable
.vendor_guid
));
130 memcpy(&efi_data(op
).u
.get_variable
.vendor_guid
, vendor
, sizeof(*vendor
));
131 efi_data(op
).u
.get_variable
.size
= *data_size
;
132 set_xen_guest_handle(efi_data(op
).u
.get_variable
.data
, data
);
134 if (HYPERVISOR_platform_op(&op
) < 0)
135 return EFI_UNSUPPORTED
;
137 *data_size
= efi_data(op
).u
.get_variable
.size
;
139 *attr
= efi_data(op
).misc
;
141 return efi_data(op
).status
;
143 EXPORT_SYMBOL_GPL(xen_efi_get_variable
);
145 efi_status_t
xen_efi_get_next_variable(unsigned long *name_size
,
149 struct xen_platform_op op
= INIT_EFI_OP(get_next_variable_name
);
151 efi_data(op
).u
.get_next_variable_name
.size
= *name_size
;
152 set_xen_guest_handle(efi_data(op
).u
.get_next_variable_name
.name
, name
);
153 BUILD_BUG_ON(sizeof(*vendor
) !=
154 sizeof(efi_data(op
).u
.get_next_variable_name
.vendor_guid
));
155 memcpy(&efi_data(op
).u
.get_next_variable_name
.vendor_guid
, vendor
,
158 if (HYPERVISOR_platform_op(&op
) < 0)
159 return EFI_UNSUPPORTED
;
161 *name_size
= efi_data(op
).u
.get_next_variable_name
.size
;
162 memcpy(vendor
, &efi_data(op
).u
.get_next_variable_name
.vendor_guid
,
165 return efi_data(op
).status
;
167 EXPORT_SYMBOL_GPL(xen_efi_get_next_variable
);
169 efi_status_t
xen_efi_set_variable(efi_char16_t
*name
, efi_guid_t
*vendor
,
170 u32 attr
, unsigned long data_size
,
173 struct xen_platform_op op
= INIT_EFI_OP(set_variable
);
175 set_xen_guest_handle(efi_data(op
).u
.set_variable
.name
, name
);
176 efi_data(op
).misc
= attr
;
177 BUILD_BUG_ON(sizeof(*vendor
) !=
178 sizeof(efi_data(op
).u
.set_variable
.vendor_guid
));
179 memcpy(&efi_data(op
).u
.set_variable
.vendor_guid
, vendor
, sizeof(*vendor
));
180 efi_data(op
).u
.set_variable
.size
= data_size
;
181 set_xen_guest_handle(efi_data(op
).u
.set_variable
.data
, data
);
183 if (HYPERVISOR_platform_op(&op
) < 0)
184 return EFI_UNSUPPORTED
;
186 return efi_data(op
).status
;
188 EXPORT_SYMBOL_GPL(xen_efi_set_variable
);
190 efi_status_t
xen_efi_query_variable_info(u32 attr
, u64
*storage_space
,
191 u64
*remaining_space
,
192 u64
*max_variable_size
)
194 struct xen_platform_op op
= INIT_EFI_OP(query_variable_info
);
196 if (efi
.runtime_version
< EFI_2_00_SYSTEM_TABLE_REVISION
)
197 return EFI_UNSUPPORTED
;
199 efi_data(op
).u
.query_variable_info
.attr
= attr
;
201 if (HYPERVISOR_platform_op(&op
) < 0)
202 return EFI_UNSUPPORTED
;
204 *storage_space
= efi_data(op
).u
.query_variable_info
.max_store_size
;
205 *remaining_space
= efi_data(op
).u
.query_variable_info
.remain_store_size
;
206 *max_variable_size
= efi_data(op
).u
.query_variable_info
.max_size
;
208 return efi_data(op
).status
;
210 EXPORT_SYMBOL_GPL(xen_efi_query_variable_info
);
212 efi_status_t
xen_efi_get_next_high_mono_count(u32
*count
)
214 struct xen_platform_op op
= INIT_EFI_OP(get_next_high_monotonic_count
);
216 if (HYPERVISOR_platform_op(&op
) < 0)
217 return EFI_UNSUPPORTED
;
219 *count
= efi_data(op
).misc
;
221 return efi_data(op
).status
;
223 EXPORT_SYMBOL_GPL(xen_efi_get_next_high_mono_count
);
225 efi_status_t
xen_efi_update_capsule(efi_capsule_header_t
**capsules
,
226 unsigned long count
, unsigned long sg_list
)
228 struct xen_platform_op op
= INIT_EFI_OP(update_capsule
);
230 if (efi
.runtime_version
< EFI_2_00_SYSTEM_TABLE_REVISION
)
231 return EFI_UNSUPPORTED
;
233 set_xen_guest_handle(efi_data(op
).u
.update_capsule
.capsule_header_array
,
235 efi_data(op
).u
.update_capsule
.capsule_count
= count
;
236 efi_data(op
).u
.update_capsule
.sg_list
= sg_list
;
238 if (HYPERVISOR_platform_op(&op
) < 0)
239 return EFI_UNSUPPORTED
;
241 return efi_data(op
).status
;
243 EXPORT_SYMBOL_GPL(xen_efi_update_capsule
);
245 efi_status_t
xen_efi_query_capsule_caps(efi_capsule_header_t
**capsules
,
246 unsigned long count
, u64
*max_size
,
249 struct xen_platform_op op
= INIT_EFI_OP(query_capsule_capabilities
);
251 if (efi
.runtime_version
< EFI_2_00_SYSTEM_TABLE_REVISION
)
252 return EFI_UNSUPPORTED
;
254 set_xen_guest_handle(efi_data(op
).u
.query_capsule_capabilities
.capsule_header_array
,
256 efi_data(op
).u
.query_capsule_capabilities
.capsule_count
= count
;
258 if (HYPERVISOR_platform_op(&op
) < 0)
259 return EFI_UNSUPPORTED
;
261 *max_size
= efi_data(op
).u
.query_capsule_capabilities
.max_capsule_size
;
262 *reset_type
= efi_data(op
).u
.query_capsule_capabilities
.reset_type
;
264 return efi_data(op
).status
;
266 EXPORT_SYMBOL_GPL(xen_efi_query_capsule_caps
);
268 void xen_efi_reset_system(int reset_type
, efi_status_t status
,
269 unsigned long data_size
, efi_char16_t
*data
)
271 switch (reset_type
) {
274 xen_reboot(SHUTDOWN_reboot
);
276 case EFI_RESET_SHUTDOWN
:
277 xen_reboot(SHUTDOWN_poweroff
);
283 EXPORT_SYMBOL_GPL(xen_efi_reset_system
);