diff --git a/sys/dev/efidev/efirt.c b/sys/dev/efidev/efirt.c --- a/sys/dev/efidev/efirt.c +++ b/sys/dev/efidev/efirt.c @@ -99,7 +99,7 @@ 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 @@ mtx_destroy(&efi_lock); } -int -efi_rt_ok(void) +static int +rt_ok(void) { if (efi_runtime == NULL) @@ -309,8 +309,8 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 --- a/sys/sys/efi.h +++ b/sys/sys/efi.h @@ -180,18 +180,102 @@ 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 */