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>
32 #include <asm/xen/hypercall.h>
34 #define INIT_EFI_OP(name) \
35 {.cmd = XENPF_efi_runtime_call, \
36 .u.efi_runtime_call.function = XEN_EFI_##name, \
37 .u.efi_runtime_call.misc = 0}
39 #define efi_data(op) (op.u.efi_runtime_call)
41 efi_status_t
xen_efi_get_time(efi_time_t
*tm
, efi_time_cap_t
*tc
)
43 struct xen_platform_op op
= INIT_EFI_OP(get_time
);
45 if (HYPERVISOR_platform_op(&op
) < 0)
46 return EFI_UNSUPPORTED
;
49 BUILD_BUG_ON(sizeof(*tm
) != sizeof(efi_data(op
).u
.get_time
.time
));
50 memcpy(tm
, &efi_data(op
).u
.get_time
.time
, sizeof(*tm
));
54 tc
->resolution
= efi_data(op
).u
.get_time
.resolution
;
55 tc
->accuracy
= efi_data(op
).u
.get_time
.accuracy
;
56 tc
->sets_to_zero
= !!(efi_data(op
).misc
&
57 XEN_EFI_GET_TIME_SET_CLEARS_NS
);
60 return efi_data(op
).status
;
62 EXPORT_SYMBOL_GPL(xen_efi_get_time
);
64 efi_status_t
xen_efi_set_time(efi_time_t
*tm
)
66 struct xen_platform_op op
= INIT_EFI_OP(set_time
);
68 BUILD_BUG_ON(sizeof(*tm
) != sizeof(efi_data(op
).u
.set_time
));
69 memcpy(&efi_data(op
).u
.set_time
, tm
, sizeof(*tm
));
71 if (HYPERVISOR_platform_op(&op
) < 0)
72 return EFI_UNSUPPORTED
;
74 return efi_data(op
).status
;
76 EXPORT_SYMBOL_GPL(xen_efi_set_time
);
78 efi_status_t
xen_efi_get_wakeup_time(efi_bool_t
*enabled
, efi_bool_t
*pending
,
81 struct xen_platform_op op
= INIT_EFI_OP(get_wakeup_time
);
83 if (HYPERVISOR_platform_op(&op
) < 0)
84 return EFI_UNSUPPORTED
;
87 BUILD_BUG_ON(sizeof(*tm
) != sizeof(efi_data(op
).u
.get_wakeup_time
));
88 memcpy(tm
, &efi_data(op
).u
.get_wakeup_time
, sizeof(*tm
));
92 *enabled
= !!(efi_data(op
).misc
& XEN_EFI_GET_WAKEUP_TIME_ENABLED
);
95 *pending
= !!(efi_data(op
).misc
& XEN_EFI_GET_WAKEUP_TIME_PENDING
);
97 return efi_data(op
).status
;
99 EXPORT_SYMBOL_GPL(xen_efi_get_wakeup_time
);
101 efi_status_t
xen_efi_set_wakeup_time(efi_bool_t enabled
, efi_time_t
*tm
)
103 struct xen_platform_op op
= INIT_EFI_OP(set_wakeup_time
);
105 BUILD_BUG_ON(sizeof(*tm
) != sizeof(efi_data(op
).u
.set_wakeup_time
));
107 efi_data(op
).misc
= XEN_EFI_SET_WAKEUP_TIME_ENABLE
;
109 memcpy(&efi_data(op
).u
.set_wakeup_time
, tm
, sizeof(*tm
));
111 efi_data(op
).misc
|= XEN_EFI_SET_WAKEUP_TIME_ENABLE_ONLY
;
113 if (HYPERVISOR_platform_op(&op
) < 0)
114 return EFI_UNSUPPORTED
;
116 return efi_data(op
).status
;
118 EXPORT_SYMBOL_GPL(xen_efi_set_wakeup_time
);
120 efi_status_t
xen_efi_get_variable(efi_char16_t
*name
, efi_guid_t
*vendor
,
121 u32
*attr
, unsigned long *data_size
,
124 struct xen_platform_op op
= INIT_EFI_OP(get_variable
);
126 set_xen_guest_handle(efi_data(op
).u
.get_variable
.name
, name
);
127 BUILD_BUG_ON(sizeof(*vendor
) !=
128 sizeof(efi_data(op
).u
.get_variable
.vendor_guid
));
129 memcpy(&efi_data(op
).u
.get_variable
.vendor_guid
, vendor
, sizeof(*vendor
));
130 efi_data(op
).u
.get_variable
.size
= *data_size
;
131 set_xen_guest_handle(efi_data(op
).u
.get_variable
.data
, data
);
133 if (HYPERVISOR_platform_op(&op
) < 0)
134 return EFI_UNSUPPORTED
;
136 *data_size
= efi_data(op
).u
.get_variable
.size
;
138 *attr
= efi_data(op
).misc
;
140 return efi_data(op
).status
;
142 EXPORT_SYMBOL_GPL(xen_efi_get_variable
);
144 efi_status_t
xen_efi_get_next_variable(unsigned long *name_size
,
148 struct xen_platform_op op
= INIT_EFI_OP(get_next_variable_name
);
150 efi_data(op
).u
.get_next_variable_name
.size
= *name_size
;
151 set_xen_guest_handle(efi_data(op
).u
.get_next_variable_name
.name
, name
);
152 BUILD_BUG_ON(sizeof(*vendor
) !=
153 sizeof(efi_data(op
).u
.get_next_variable_name
.vendor_guid
));
154 memcpy(&efi_data(op
).u
.get_next_variable_name
.vendor_guid
, vendor
,
157 if (HYPERVISOR_platform_op(&op
) < 0)
158 return EFI_UNSUPPORTED
;
160 *name_size
= efi_data(op
).u
.get_next_variable_name
.size
;
161 memcpy(vendor
, &efi_data(op
).u
.get_next_variable_name
.vendor_guid
,
164 return efi_data(op
).status
;
166 EXPORT_SYMBOL_GPL(xen_efi_get_next_variable
);
168 efi_status_t
xen_efi_set_variable(efi_char16_t
*name
, efi_guid_t
*vendor
,
169 u32 attr
, unsigned long data_size
,
172 struct xen_platform_op op
= INIT_EFI_OP(set_variable
);
174 set_xen_guest_handle(efi_data(op
).u
.set_variable
.name
, name
);
175 efi_data(op
).misc
= attr
;
176 BUILD_BUG_ON(sizeof(*vendor
) !=
177 sizeof(efi_data(op
).u
.set_variable
.vendor_guid
));
178 memcpy(&efi_data(op
).u
.set_variable
.vendor_guid
, vendor
, sizeof(*vendor
));
179 efi_data(op
).u
.set_variable
.size
= data_size
;
180 set_xen_guest_handle(efi_data(op
).u
.set_variable
.data
, data
);
182 if (HYPERVISOR_platform_op(&op
) < 0)
183 return EFI_UNSUPPORTED
;
185 return efi_data(op
).status
;
187 EXPORT_SYMBOL_GPL(xen_efi_set_variable
);
189 efi_status_t
xen_efi_query_variable_info(u32 attr
, u64
*storage_space
,
190 u64
*remaining_space
,
191 u64
*max_variable_size
)
193 struct xen_platform_op op
= INIT_EFI_OP(query_variable_info
);
195 if (efi
.runtime_version
< EFI_2_00_SYSTEM_TABLE_REVISION
)
196 return EFI_UNSUPPORTED
;
198 efi_data(op
).u
.query_variable_info
.attr
= attr
;
200 if (HYPERVISOR_platform_op(&op
) < 0)
201 return EFI_UNSUPPORTED
;
203 *storage_space
= efi_data(op
).u
.query_variable_info
.max_store_size
;
204 *remaining_space
= efi_data(op
).u
.query_variable_info
.remain_store_size
;
205 *max_variable_size
= efi_data(op
).u
.query_variable_info
.max_size
;
207 return efi_data(op
).status
;
209 EXPORT_SYMBOL_GPL(xen_efi_query_variable_info
);
211 efi_status_t
xen_efi_get_next_high_mono_count(u32
*count
)
213 struct xen_platform_op op
= INIT_EFI_OP(get_next_high_monotonic_count
);
215 if (HYPERVISOR_platform_op(&op
) < 0)
216 return EFI_UNSUPPORTED
;
218 *count
= efi_data(op
).misc
;
220 return efi_data(op
).status
;
222 EXPORT_SYMBOL_GPL(xen_efi_get_next_high_mono_count
);
224 efi_status_t
xen_efi_update_capsule(efi_capsule_header_t
**capsules
,
225 unsigned long count
, unsigned long sg_list
)
227 struct xen_platform_op op
= INIT_EFI_OP(update_capsule
);
229 if (efi
.runtime_version
< EFI_2_00_SYSTEM_TABLE_REVISION
)
230 return EFI_UNSUPPORTED
;
232 set_xen_guest_handle(efi_data(op
).u
.update_capsule
.capsule_header_array
,
234 efi_data(op
).u
.update_capsule
.capsule_count
= count
;
235 efi_data(op
).u
.update_capsule
.sg_list
= sg_list
;
237 if (HYPERVISOR_platform_op(&op
) < 0)
238 return EFI_UNSUPPORTED
;
240 return efi_data(op
).status
;
242 EXPORT_SYMBOL_GPL(xen_efi_update_capsule
);
244 efi_status_t
xen_efi_query_capsule_caps(efi_capsule_header_t
**capsules
,
245 unsigned long count
, u64
*max_size
,
248 struct xen_platform_op op
= INIT_EFI_OP(query_capsule_capabilities
);
250 if (efi
.runtime_version
< EFI_2_00_SYSTEM_TABLE_REVISION
)
251 return EFI_UNSUPPORTED
;
253 set_xen_guest_handle(efi_data(op
).u
.query_capsule_capabilities
.capsule_header_array
,
255 efi_data(op
).u
.query_capsule_capabilities
.capsule_count
= count
;
257 if (HYPERVISOR_platform_op(&op
) < 0)
258 return EFI_UNSUPPORTED
;
260 *max_size
= efi_data(op
).u
.query_capsule_capabilities
.max_capsule_size
;
261 *reset_type
= efi_data(op
).u
.query_capsule_capabilities
.reset_type
;
263 return efi_data(op
).status
;
265 EXPORT_SYMBOL_GPL(xen_efi_query_capsule_caps
);