Date: Tue, 16 Feb 2021 14:27:16 GMT From: Roger Pau Monné <royger@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 27d3902679cd - main - efirt: add hooks for diverging EFI implementations Message-ID: <202102161427.11GERGIX080050@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by royger: URL: https://cgit.FreeBSD.org/src/commit/?id=27d3902679cd6df6404cd402ffc85a9763c449b1 commit 27d3902679cd6df6404cd402ffc85a9763c449b1 Author: Roger Pau Monné <royger@FreeBSD.org> AuthorDate: 2021-02-12 11:11:58 +0000 Commit: Roger Pau Monné <royger@FreeBSD.org> CommitDate: 2021-02-16 14:26:11 +0000 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 --- sys/dev/efidev/efirt.c | 51 +++++++++++++++--------- sys/sys/efi.h | 106 ++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 127 insertions(+), 30 deletions(-) diff --git a/sys/dev/efidev/efirt.c b/sys/dev/efidev/efirt.c index fbb8f605c202..f28b9981919c 100644 --- a/sys/dev/efidev/efirt.c +++ b/sys/dev/efidev/efirt.c @@ -99,7 +99,7 @@ static int efi_status2err[25] = { static int efi_enter(void); static void efi_leave(void); -static int +int efi_status_to_errno(efi_status status) { u_long code; @@ -262,8 +262,8 @@ efi_uninit(void) mtx_destroy(&efi_lock); } -int -efi_rt_ok(void) +static int +rt_ok(void) { if (efi_runtime == NULL) @@ -309,8 +309,8 @@ efi_leave(void) PMAP_UNLOCK(curpmap); } -int -efi_get_table(struct uuid *uuid, void **ptr) +static int +get_table(struct uuid *uuid, void **ptr) { struct efi_cfgtbl *ct; u_long count; @@ -419,8 +419,8 @@ efi_get_time_locked(struct efi_tm *tm, struct efi_tmcap *tmcap) return (efi_call(&ec)); } -int -efi_get_time(struct efi_tm *tm) +static int +get_time(struct efi_tm *tm) { struct efi_tmcap dummy; int error; @@ -439,8 +439,8 @@ efi_get_time(struct efi_tm *tm) return (error); } -int -efi_get_time_capabilities(struct efi_tmcap *tmcap) +static int +get_time_capabilities(struct efi_tmcap *tmcap) { struct efi_tm dummy; int error; @@ -453,8 +453,8 @@ efi_get_time_capabilities(struct efi_tmcap *tmcap) return (error); } -int -efi_reset_system(enum efi_reset type) +static int +reset_system(enum efi_reset type) { struct efirt_callinfo ec; @@ -495,8 +495,8 @@ efi_set_time_locked(struct efi_tm *tm) return (efi_call(&ec)); } -int -efi_set_time(struct efi_tm *tm) +static int +set_time(struct efi_tm *tm) { int error; @@ -508,8 +508,8 @@ efi_set_time(struct efi_tm *tm) return (error); } -int -efi_var_get(efi_char *name, struct uuid *vendor, uint32_t *attrib, +static int +var_get(efi_char *name, struct uuid *vendor, uint32_t *attrib, size_t *datasize, void *data) { struct efirt_callinfo ec; @@ -528,8 +528,8 @@ efi_var_get(efi_char *name, struct uuid *vendor, uint32_t *attrib, return (efi_call(&ec)); } -int -efi_var_nextname(size_t *namesize, efi_char *name, struct uuid *vendor) +static int +var_nextname(size_t *namesize, efi_char *name, struct uuid *vendor) { struct efirt_callinfo ec; @@ -545,8 +545,8 @@ efi_var_nextname(size_t *namesize, efi_char *name, struct uuid *vendor) return (efi_call(&ec)); } -int -efi_var_set(efi_char *name, struct uuid *vendor, uint32_t attrib, +static int +var_set(efi_char *name, struct uuid *vendor, uint32_t attrib, size_t datasize, void *data) { struct efirt_callinfo ec; @@ -565,6 +565,19 @@ efi_var_set(efi_char *name, struct uuid *vendor, uint32_t attrib, return (efi_call(&ec)); } +const static struct efi_ops efi_ops = { + .rt_ok = rt_ok, + .get_table = get_table, + .get_time = get_time, + .get_time_capabilities = get_time_capabilities, + .reset_system = reset_system, + .set_time = set_time, + .var_get = var_get, + .var_nextname = var_nextname, + .var_set = var_set, +}; +const struct efi_ops *active_efi_ops = &efi_ops; + static int efirt_modevents(module_t m, int event, void *arg __unused) { 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 */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202102161427.11GERGIX080050>