From owner-dev-commits-src-all@freebsd.org Tue Feb 16 14:27:19 2021 Return-Path: Delivered-To: dev-commits-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 1542453A19F; Tue, 16 Feb 2021 14:27:19 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Dg3Fx6lpqz3wQF; Tue, 16 Feb 2021 14:27:17 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id B68E412A9F; Tue, 16 Feb 2021 14:27:16 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 11GERGSm080051; Tue, 16 Feb 2021 14:27:16 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 11GERGIX080050; Tue, 16 Feb 2021 14:27:16 GMT (envelope-from git) Date: Tue, 16 Feb 2021 14:27:16 GMT Message-Id: <202102161427.11GERGIX080050@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Roger Pau Monné Subject: git: 27d3902679cd - main - efirt: add hooks for diverging EFI implementations MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: royger X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 27d3902679cd6df6404cd402ffc85a9763c449b1 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for all branches of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 16 Feb 2021 14:27:19 -0000 The branch main has been updated by royger: URL: https://cgit.FreeBSD.org/src/commit/?id=27d3902679cd6df6404cd402ffc85a9763c449b1 commit 27d3902679cd6df6404cd402ffc85a9763c449b1 Author: Roger Pau Monné AuthorDate: 2021-02-12 11:11:58 +0000 Commit: Roger Pau Monné 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 */