aboutsummaryrefslogtreecommitdiff
path: root/sys/sys
diff options
context:
space:
mode:
authorRoger Pau Monné <royger@FreeBSD.org>2021-02-12 11:11:58 +0000
committerRoger Pau Monné <royger@FreeBSD.org>2021-02-16 14:26:11 +0000
commit27d3902679cd6df6404cd402ffc85a9763c449b1 (patch)
tree2e59a985f5b2d5e0f78e156aa6edf3fd8b35da79 /sys/sys
parenta2495c36678cb16597758ce150da5456cdd90331 (diff)
downloadsrc-27d3902679cd6df6404cd402ffc85a9763c449b1.tar.gz
src-27d3902679cd6df6404cd402ffc85a9763c449b1.zip
efirt: add hooks for diverging EFI implementations
Introduce a set of hooks for MI EFI public functions, so that a new implementation can be done. This will be used to implement the Xen PV EFI interface that's used when running FreeBSD as a Xen dom0 from UEFI firmware. Also make the efi_status_to_errno non-static since it will be used to evaluate status return values from the PV interface. No functional change indented. Sponsored by: Citrix Systems R&D Reviewed by: kib, imp Differential revision: https://reviews.freebsd.org/D28620
Diffstat (limited to 'sys/sys')
-rw-r--r--sys/sys/efi.h106
1 files changed, 95 insertions, 11 deletions
diff --git a/sys/sys/efi.h b/sys/sys/efi.h
index 220509853cb2..f7a1fe790d23 100644
--- a/sys/sys/efi.h
+++ b/sys/sys/efi.h
@@ -180,18 +180,102 @@ int efi_rt_arch_call(struct efirt_callinfo *);
bool efi_create_1t1_map(struct efi_md *, int, int);
void efi_destroy_1t1_map(void);
+struct efi_ops {
+ /*
+ * The EFI calls might be virtualized in some environments, requiring
+ * FreeBSD to use a different interface (ie: hypercalls) in order to
+ * access them.
+ */
+ int (*rt_ok)(void);
+ int (*get_table)(struct uuid *, void **);
+ int (*get_time)(struct efi_tm *);
+ int (*get_time_capabilities)(struct efi_tmcap *);
+ int (*reset_system)(enum efi_reset);
+ int (*set_time)(struct efi_tm *);
+ int (*var_get)(uint16_t *, struct uuid *, uint32_t *, size_t *,
+ void *);
+ int (*var_nextname)(size_t *, uint16_t *, struct uuid *);
+ int (*var_set)(uint16_t *, struct uuid *, uint32_t, size_t, void *);
+};
+extern const struct efi_ops *active_efi_ops;
+
/* Public MI EFI functions */
-int efi_rt_ok(void);
-int efi_get_table(struct uuid *uuid, void **ptr);
-int efi_get_time(struct efi_tm *tm);
-int efi_get_time_capabilities(struct efi_tmcap *tmcap);
-int efi_reset_system(enum efi_reset type);
-int efi_set_time(struct efi_tm *tm);
-int efi_var_get(uint16_t *name, struct uuid *vendor, uint32_t *attrib,
- size_t *datasize, void *data);
-int efi_var_nextname(size_t *namesize, uint16_t *name, struct uuid *vendor);
-int efi_var_set(uint16_t *name, struct uuid *vendor, uint32_t attrib,
- size_t datasize, void *data);
+static inline int efi_rt_ok(void)
+{
+
+ if(active_efi_ops->rt_ok == NULL)
+ return (ENXIO);
+ return (active_efi_ops->rt_ok());
+}
+
+static inline int efi_get_table(struct uuid *uuid, void **ptr)
+{
+
+ if (active_efi_ops->get_table == NULL)
+ return (ENXIO);
+ return (active_efi_ops->get_table(uuid, ptr));
+}
+
+static inline int efi_get_time(struct efi_tm *tm)
+{
+
+ if (active_efi_ops->get_time == NULL)
+ return (ENXIO);
+ return (active_efi_ops->get_time(tm));
+}
+
+static inline int efi_get_time_capabilities(struct efi_tmcap *tmcap)
+{
+
+ if (active_efi_ops->get_time_capabilities == NULL)
+ return (ENXIO);
+ return (active_efi_ops->get_time_capabilities(tmcap));
+}
+
+static inline int efi_reset_system(enum efi_reset type)
+{
+
+ if (active_efi_ops->reset_system == NULL)
+ return (ENXIO);
+ return (active_efi_ops->reset_system(type));
+}
+
+static inline int efi_set_time(struct efi_tm *tm)
+{
+
+ if (active_efi_ops->set_time == NULL)
+ return (ENXIO);
+ return (active_efi_ops->set_time(tm));
+}
+
+static inline int efi_var_get(uint16_t *name, struct uuid *vendor,
+ uint32_t *attrib, size_t *datasize, void *data)
+{
+
+ if (active_efi_ops->var_get == NULL)
+ return (ENXIO);
+ return (active_efi_ops->var_get(name, vendor, attrib, datasize, data));
+}
+
+static inline int efi_var_nextname(size_t *namesize, uint16_t *name,
+ struct uuid *vendor)
+{
+
+ if (active_efi_ops->var_nextname == NULL)
+ return (ENXIO);
+ return (active_efi_ops->var_nextname(namesize, name, vendor));
+}
+
+static inline int efi_var_set(uint16_t *name, struct uuid *vendor,
+ uint32_t attrib, size_t datasize, void *data)
+{
+
+ if (active_efi_ops->var_set == NULL)
+ return (ENXIO);
+ return (active_efi_ops->var_set(name, vendor, attrib, datasize, data));
+}
+
+int efi_status_to_errno(efi_status status);
#endif /* _KERNEL */