Re: EFI runtime services support on amd64

2022-10-12 Thread Mark Kettenis
So krw@ found an issue with the diff on an x230.  The diff
inadvertedly made us always use the EFI runtime services to access the
RTC.  And that is busted on the x230.  Fortunately I committed the
diff that allows us to have a quality indicater for RTCs.  So I
synched up the amd64 code with the arm64 such that we only use the EFI
interface as a last resort.

Ken, does this fix the issues you were seeing?

ok?


Index: arch/amd64/amd64/bios.c
===
RCS file: /cvs/src/sys/arch/amd64/amd64/bios.c,v
retrieving revision 1.45
diff -u -p -r1.45 bios.c
--- arch/amd64/amd64/bios.c 21 Feb 2022 11:03:39 -  1.45
+++ arch/amd64/amd64/bios.c 12 Oct 2022 23:11:19 -
@@ -30,6 +30,7 @@
 #include 
 
 #include "acpi.h"
+#include "efi.h"
 #include "mpbios.h"
 #include "pci.h"
 
@@ -189,6 +190,18 @@ out:
break;
}
}
+
+#if NEFI > 0
+   if (bios_efiinfo != NULL) {
+   struct bios_attach_args ba;
+
+   memset(, 0, sizeof(ba));
+   ba.ba_name = "efi";
+   ba.ba_memt = X86_BUS_SPACE_MEM;
+
+   config_found(self, , bios_print);
+   }
+#endif
 
 #if NACPI > 0
{
Index: arch/amd64/amd64/efi_machdep.c
===
RCS file: arch/amd64/amd64/efi_machdep.c
diff -N arch/amd64/amd64/efi_machdep.c
--- /dev/null   1 Jan 1970 00:00:00 -
+++ arch/amd64/amd64/efi_machdep.c  12 Oct 2022 23:11:19 -
@@ -0,0 +1,301 @@
+/* $OpenBSD$   */
+
+/*
+ * Copyright (c) 2022 Mark Kettenis 
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+extern paddr_t cr3_reuse_pcid;
+
+#include 
+
+#include 
+
+extern EFI_MEMORY_DESCRIPTOR *mmap;
+
+struct efi_softc {
+   struct device   sc_dev;
+   struct pmap *sc_pm;
+   EFI_RUNTIME_SERVICES *sc_rs;
+   u_long  sc_psw;
+   uint64_tsc_cr3;
+
+   struct todr_chip_handle sc_todr;
+};
+
+intefi_match(struct device *, void *, void *);
+void   efi_attach(struct device *, struct device *, void *);
+
+const struct cfattach efi_ca = {
+   sizeof(struct efi_softc), efi_match, efi_attach
+};
+
+struct cfdriver efi_cd = {
+   NULL, "efi", DV_DULL
+};
+
+void   efi_map_runtime(struct efi_softc *);
+void   efi_enter(struct efi_softc *);
+void   efi_leave(struct efi_softc *);
+intefi_gettime(struct todr_chip_handle *, struct timeval *);
+intefi_settime(struct todr_chip_handle *, struct timeval *);
+
+int
+efi_match(struct device *parent, void *match, void *aux)
+{
+   struct bios_attach_args *ba = aux;
+   struct cfdata *cf = match;
+
+   if (strcmp(ba->ba_name, cf->cf_driver->cd_name) == 0 &&
+   bios_efiinfo->system_table != 0)
+   return 1;
+
+   return 0;
+}
+
+void
+efi_attach(struct device *parent, struct device *self, void *aux)
+{
+   struct efi_softc *sc = (struct efi_softc *)self;
+   struct bios_attach_args *ba = aux;
+   uint32_t mmap_desc_ver = bios_efiinfo->mmap_desc_ver;
+   uint64_t system_table;
+   bus_space_handle_t memh;
+   EFI_SYSTEM_TABLE *st;
+   EFI_TIME time;
+   EFI_STATUS status;
+   uint16_t major, minor;
+   int i;
+
+   if (mmap_desc_ver != EFI_MEMORY_DESCRIPTOR_VERSION) {
+   printf(": unsupported memory descriptor version %d\n",
+   mmap_desc_ver);
+   return;
+   }
+
+   system_table = bios_efiinfo->system_table;
+   KASSERT(system_table);
+
+   if (bus_space_map(ba->ba_memt, system_table, sizeof(EFI_SYSTEM_TABLE),
+   BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_CACHEABLE, )) {
+   printf(": can't map system table\n");
+   return;
+   }
+
+   st = bus_space_vaddr(ba->ba_memt, memh);
+   sc->sc_rs = st->RuntimeServices;
+
+   major = st->Hdr.Revision >> 16;
+   minor = st->Hdr.Revision & 0x;
+   printf(": UEFI %d.%d", major, minor / 10);
+   if (minor % 10)
+   printf(".%d", minor % 10);
+   printf("\n");
+
+   if ((bios_efiinfo->flags & BEI_64BIT) == 0)
+   

Re: EFI runtime services support on amd64

2022-10-12 Thread Mark Kettenis
> From: Dave Voutila 
> Date: Mon, 10 Oct 2022 14:08:57 -0400
> 
> Mark Kettenis  writes:
> 
> > Here is a diff that implements EFI runtime services support on amd64
> > in much the same way as we already do on arm64.  This will be used in
> > the future to implement support for EFI variables.
> >
> > Some initial testing among OpenBSD developers did not uncover any
> > issues.  So I'd like to move ahead with this.  If this ends up
> > breaking machines we can always disable the
> >
> > ok?
> 
> Tests fine on my Go3 and X13gen1. Code looks ok to me but 2 little nits
> below:
> 
> >
> >
> > Index: arch/amd64/amd64/bios.c
> > ===
> > RCS file: /cvs/src/sys/arch/amd64/amd64/bios.c,v
> > retrieving revision 1.45
> > diff -u -p -r1.45 bios.c
> > --- arch/amd64/amd64/bios.c 21 Feb 2022 11:03:39 -  1.45
> > +++ arch/amd64/amd64/bios.c 8 Oct 2022 16:07:02 -
> > @@ -30,6 +30,7 @@
> >  #include 
> >
> >  #include "acpi.h"
> > +#include "efi.h"
> >  #include "mpbios.h"
> >  #include "pci.h"
> >
> > @@ -189,6 +190,18 @@ out:
> > break;
> > }
> > }
> > +
> > +#if NEFI > 0
> > +   if (bios_efiinfo != NULL) {
> > +   struct bios_attach_args ba;
> > +
> > +   memset(, 0, sizeof(ba));
> > +   ba.ba_name = "efi";
> > +   ba.ba_memt = X86_BUS_SPACE_MEM;
> > +
> > +   config_found(self, , bios_print);
> > +   }
> > +#endif
> >
> >  #if NACPI > 0
> > {
> > Index: arch/amd64/amd64/efi_machdep.c
> > ===
> > RCS file: arch/amd64/amd64/efi_machdep.c
> > diff -N arch/amd64/amd64/efi_machdep.c
> > --- /dev/null   1 Jan 1970 00:00:00 -
> > +++ arch/amd64/amd64/efi_machdep.c  8 Oct 2022 16:07:02 -
> > @@ -0,0 +1,296 @@
> > +/* $OpenBSD$   */
> > +
> > +/*
> > + * Copyright (c) 2022 Mark Kettenis 
> > + *
> > + * Permission to use, copy, modify, and distribute this software for any
> > + * purpose with or without fee is hereby granted, provided that the above
> > + * copyright notice and this permission notice appear in all copies.
> > + *
> > + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> > + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> > + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> > + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> > + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> > + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> > + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include 
> > +
> > +#include 
> > +extern paddr_t cr3_reuse_pcid;
> > +
> > +#include 
> > +
> > +#include 
> > +
> > +extern todr_chip_handle_t todr_handle;
> > +
> > +extern EFI_MEMORY_DESCRIPTOR *mmap;
> > +
> > +struct efi_softc {
> > +   struct device   sc_dev;
> > +   struct pmap *sc_pm;
> > +   EFI_RUNTIME_SERVICES *sc_rs;
> > +   u_long  sc_psw;
> > +   uint64_tsc_cr3;
> > +
> > +   struct todr_chip_handle sc_todr;
> > +};
> > +
> > +intefi_match(struct device *, void *, void *);
> > +void   efi_attach(struct device *, struct device *, void *);
> > +
> > +const struct cfattach efi_ca = {
> > +   sizeof(struct efi_softc), efi_match, efi_attach
> > +};
> > +
> > +struct cfdriver efi_cd = {
> > +   NULL, "efi", DV_DULL
> > +};
> > +
> > +void   efi_map_runtime(struct efi_softc *);
> > +void   efi_enter(struct efi_softc *);
> > +void   efi_leave(struct efi_softc *);
> > +intefi_gettime(struct todr_chip_handle *, struct timeval *);
> > +intefi_settime(struct todr_chip_handle *, struct timeval *);
> > +
> > +int
> > +efi_match(struct device *parent, void *match, void *aux)
> > +{
> > +   struct bios_attach_args *ba = aux;
> > +   struct cfdata *cf = match;
> > +
> > +   if (strcmp(ba->ba_name, cf->cf_driver->cd_name) 

Re: EFI runtime services support on amd64

2022-10-10 Thread Dave Voutila


Mark Kettenis  writes:

> Here is a diff that implements EFI runtime services support on amd64
> in much the same way as we already do on arm64.  This will be used in
> the future to implement support for EFI variables.
>
> Some initial testing among OpenBSD developers did not uncover any
> issues.  So I'd like to move ahead with this.  If this ends up
> breaking machines we can always disable the
>
> ok?

Tests fine on my Go3 and X13gen1. Code looks ok to me but 2 little nits
below:

>
>
> Index: arch/amd64/amd64/bios.c
> ===
> RCS file: /cvs/src/sys/arch/amd64/amd64/bios.c,v
> retrieving revision 1.45
> diff -u -p -r1.45 bios.c
> --- arch/amd64/amd64/bios.c   21 Feb 2022 11:03:39 -  1.45
> +++ arch/amd64/amd64/bios.c   8 Oct 2022 16:07:02 -
> @@ -30,6 +30,7 @@
>  #include 
>
>  #include "acpi.h"
> +#include "efi.h"
>  #include "mpbios.h"
>  #include "pci.h"
>
> @@ -189,6 +190,18 @@ out:
>   break;
>   }
>   }
> +
> +#if NEFI > 0
> + if (bios_efiinfo != NULL) {
> + struct bios_attach_args ba;
> +
> + memset(, 0, sizeof(ba));
> + ba.ba_name = "efi";
> + ba.ba_memt = X86_BUS_SPACE_MEM;
> +
> + config_found(self, , bios_print);
> + }
> +#endif
>
>  #if NACPI > 0
>   {
> Index: arch/amd64/amd64/efi_machdep.c
> ===
> RCS file: arch/amd64/amd64/efi_machdep.c
> diff -N arch/amd64/amd64/efi_machdep.c
> --- /dev/null 1 Jan 1970 00:00:00 -
> +++ arch/amd64/amd64/efi_machdep.c8 Oct 2022 16:07:02 -
> @@ -0,0 +1,296 @@
> +/*   $OpenBSD$   */
> +
> +/*
> + * Copyright (c) 2022 Mark Kettenis 
> + *
> + * Permission to use, copy, modify, and distribute this software for any
> + * purpose with or without fee is hereby granted, provided that the above
> + * copyright notice and this permission notice appear in all copies.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +
> +#include 
> +extern paddr_t cr3_reuse_pcid;
> +
> +#include 
> +
> +#include 
> +
> +extern todr_chip_handle_t todr_handle;
> +
> +extern EFI_MEMORY_DESCRIPTOR *mmap;
> +
> +struct efi_softc {
> + struct device   sc_dev;
> + struct pmap *sc_pm;
> + EFI_RUNTIME_SERVICES *sc_rs;
> + u_long  sc_psw;
> + uint64_tsc_cr3;
> +
> + struct todr_chip_handle sc_todr;
> +};
> +
> +int  efi_match(struct device *, void *, void *);
> +void efi_attach(struct device *, struct device *, void *);
> +
> +const struct cfattach efi_ca = {
> + sizeof(struct efi_softc), efi_match, efi_attach
> +};
> +
> +struct cfdriver efi_cd = {
> + NULL, "efi", DV_DULL
> +};
> +
> +void efi_map_runtime(struct efi_softc *);
> +void efi_enter(struct efi_softc *);
> +void efi_leave(struct efi_softc *);
> +int  efi_gettime(struct todr_chip_handle *, struct timeval *);
> +int  efi_settime(struct todr_chip_handle *, struct timeval *);
> +
> +int
> +efi_match(struct device *parent, void *match, void *aux)
> +{
> + struct bios_attach_args *ba = aux;
> + struct cfdata *cf = match;
> +
> + if (strcmp(ba->ba_name, cf->cf_driver->cd_name) == 0 &&
> + bios_efiinfo->system_table != 0)
> + return 1;
> +
> + return 0;
> +}
> +
> +void
> +efi_attach(struct device *parent, struct device *self, void *aux)
> +{
> + struct efi_softc *sc = (struct efi_softc *)self;
> + struct bios_attach_args *ba = aux;
> + uint32_t mmap_desc_ver = bios_efiinfo->mmap_desc_ver;
> + uint64_t system_table;
> + bus_space_handle_t memh;
> + EFI_SYSTEM_TABLE *st;
> + EFI_TIME time;
> + EFI_STATUS status;
> + uint16_t major, minor;
> + int i;
> +
> + if (mmap_desc_ver != EFI_MEMORY_DESCRIPTOR_VERSION) {
> + print

Re: EFI runtime services support on amd64

2022-10-08 Thread Theo de Raadt
I'm not worried until it gets exposed to userland.

Mark Kettenis  wrote:

> Here is a diff that implements EFI runtime services support on amd64
> in much the same way as we already do on arm64.  This will be used in
> the future to implement support for EFI variables.
> 
> Some initial testing among OpenBSD developers did not uncover any
> issues.  So I'd like to move ahead with this.  If this ends up
> breaking machines we can always disable the 
> 
> ok?
> 
> 
> Index: arch/amd64/amd64/bios.c
> ===
> RCS file: /cvs/src/sys/arch/amd64/amd64/bios.c,v
> retrieving revision 1.45
> diff -u -p -r1.45 bios.c
> --- arch/amd64/amd64/bios.c   21 Feb 2022 11:03:39 -  1.45
> +++ arch/amd64/amd64/bios.c   8 Oct 2022 16:07:02 -
> @@ -30,6 +30,7 @@
>  #include 
>  
>  #include "acpi.h"
> +#include "efi.h"
>  #include "mpbios.h"
>  #include "pci.h"
>  
> @@ -189,6 +190,18 @@ out:
>   break;
>   }
>   }
> +
> +#if NEFI > 0
> + if (bios_efiinfo != NULL) {
> + struct bios_attach_args ba;
> +
> + memset(, 0, sizeof(ba));
> + ba.ba_name = "efi";
> + ba.ba_memt = X86_BUS_SPACE_MEM;
> +
> + config_found(self, , bios_print);
> + }
> +#endif
>  
>  #if NACPI > 0
>   {
> Index: arch/amd64/amd64/efi_machdep.c
> ===
> RCS file: arch/amd64/amd64/efi_machdep.c
> diff -N arch/amd64/amd64/efi_machdep.c
> --- /dev/null 1 Jan 1970 00:00:00 -
> +++ arch/amd64/amd64/efi_machdep.c8 Oct 2022 16:07:02 -
> @@ -0,0 +1,296 @@
> +/*   $OpenBSD$   */
> +
> +/*
> + * Copyright (c) 2022 Mark Kettenis 
> + *
> + * Permission to use, copy, modify, and distribute this software for any
> + * purpose with or without fee is hereby granted, provided that the above
> + * copyright notice and this permission notice appear in all copies.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +
> +#include 
> +extern paddr_t cr3_reuse_pcid;
> +
> +#include 
> +
> +#include 
> +
> +extern todr_chip_handle_t todr_handle;
> +
> +extern EFI_MEMORY_DESCRIPTOR *mmap;
> +
> +struct efi_softc {
> + struct device   sc_dev;
> + struct pmap *sc_pm;
> + EFI_RUNTIME_SERVICES *sc_rs;
> + u_long  sc_psw;
> + uint64_tsc_cr3;
> +
> + struct todr_chip_handle sc_todr;
> +};
> +
> +int  efi_match(struct device *, void *, void *);
> +void efi_attach(struct device *, struct device *, void *);
> +
> +const struct cfattach efi_ca = {
> + sizeof(struct efi_softc), efi_match, efi_attach
> +};
> +
> +struct cfdriver efi_cd = {
> + NULL, "efi", DV_DULL
> +};
> +
> +void efi_map_runtime(struct efi_softc *);
> +void efi_enter(struct efi_softc *);
> +void efi_leave(struct efi_softc *);
> +int  efi_gettime(struct todr_chip_handle *, struct timeval *);
> +int  efi_settime(struct todr_chip_handle *, struct timeval *);
> +
> +int
> +efi_match(struct device *parent, void *match, void *aux)
> +{
> + struct bios_attach_args *ba = aux;
> + struct cfdata *cf = match;
> +
> + if (strcmp(ba->ba_name, cf->cf_driver->cd_name) == 0 &&
> + bios_efiinfo->system_table != 0)
> + return 1;
> +
> + return 0;
> +}
> +
> +void
> +efi_attach(struct device *parent, struct device *self, void *aux)
> +{
> + struct efi_softc *sc = (struct efi_softc *)self;
> + struct bios_attach_args *ba = aux;
> + uint32_t mmap_desc_ver = bios_efiinfo->mmap_desc_ver;
> + uint64_t system_table;
> + bus_space_handle_t memh;
> + EFI_SYSTEM_TABLE *st;
> + EFI_TIME time;
> + EFI_STATUS status;
> + uint16_t major, minor;
> + int i;
> +
> + if (mmap_desc_ver != EFI_MEMORY_DESCRIPTOR_VERSION) {
> + printf(": unsupported me

EFI runtime services support on amd64

2022-10-08 Thread Mark Kettenis
Here is a diff that implements EFI runtime services support on amd64
in much the same way as we already do on arm64.  This will be used in
the future to implement support for EFI variables.

Some initial testing among OpenBSD developers did not uncover any
issues.  So I'd like to move ahead with this.  If this ends up
breaking machines we can always disable the 

ok?


Index: arch/amd64/amd64/bios.c
===
RCS file: /cvs/src/sys/arch/amd64/amd64/bios.c,v
retrieving revision 1.45
diff -u -p -r1.45 bios.c
--- arch/amd64/amd64/bios.c 21 Feb 2022 11:03:39 -  1.45
+++ arch/amd64/amd64/bios.c 8 Oct 2022 16:07:02 -
@@ -30,6 +30,7 @@
 #include 
 
 #include "acpi.h"
+#include "efi.h"
 #include "mpbios.h"
 #include "pci.h"
 
@@ -189,6 +190,18 @@ out:
break;
}
}
+
+#if NEFI > 0
+   if (bios_efiinfo != NULL) {
+   struct bios_attach_args ba;
+
+   memset(, 0, sizeof(ba));
+   ba.ba_name = "efi";
+   ba.ba_memt = X86_BUS_SPACE_MEM;
+
+   config_found(self, , bios_print);
+   }
+#endif
 
 #if NACPI > 0
{
Index: arch/amd64/amd64/efi_machdep.c
===
RCS file: arch/amd64/amd64/efi_machdep.c
diff -N arch/amd64/amd64/efi_machdep.c
--- /dev/null   1 Jan 1970 00:00:00 -
+++ arch/amd64/amd64/efi_machdep.c  8 Oct 2022 16:07:02 -
@@ -0,0 +1,296 @@
+/* $OpenBSD$   */
+
+/*
+ * Copyright (c) 2022 Mark Kettenis 
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+extern paddr_t cr3_reuse_pcid;
+
+#include 
+
+#include 
+
+extern todr_chip_handle_t todr_handle;
+
+extern EFI_MEMORY_DESCRIPTOR *mmap;
+
+struct efi_softc {
+   struct device   sc_dev;
+   struct pmap *sc_pm;
+   EFI_RUNTIME_SERVICES *sc_rs;
+   u_long  sc_psw;
+   uint64_tsc_cr3;
+
+   struct todr_chip_handle sc_todr;
+};
+
+intefi_match(struct device *, void *, void *);
+void   efi_attach(struct device *, struct device *, void *);
+
+const struct cfattach efi_ca = {
+   sizeof(struct efi_softc), efi_match, efi_attach
+};
+
+struct cfdriver efi_cd = {
+   NULL, "efi", DV_DULL
+};
+
+void   efi_map_runtime(struct efi_softc *);
+void   efi_enter(struct efi_softc *);
+void   efi_leave(struct efi_softc *);
+intefi_gettime(struct todr_chip_handle *, struct timeval *);
+intefi_settime(struct todr_chip_handle *, struct timeval *);
+
+int
+efi_match(struct device *parent, void *match, void *aux)
+{
+   struct bios_attach_args *ba = aux;
+   struct cfdata *cf = match;
+
+   if (strcmp(ba->ba_name, cf->cf_driver->cd_name) == 0 &&
+   bios_efiinfo->system_table != 0)
+   return 1;
+
+   return 0;
+}
+
+void
+efi_attach(struct device *parent, struct device *self, void *aux)
+{
+   struct efi_softc *sc = (struct efi_softc *)self;
+   struct bios_attach_args *ba = aux;
+   uint32_t mmap_desc_ver = bios_efiinfo->mmap_desc_ver;
+   uint64_t system_table;
+   bus_space_handle_t memh;
+   EFI_SYSTEM_TABLE *st;
+   EFI_TIME time;
+   EFI_STATUS status;
+   uint16_t major, minor;
+   int i;
+
+   if (mmap_desc_ver != EFI_MEMORY_DESCRIPTOR_VERSION) {
+   printf(": unsupported memory descriptor version %d\n",
+   mmap_desc_ver);
+   return;
+   }
+
+   system_table = bios_efiinfo->system_table;
+   KASSERT(system_table);
+
+   if (bus_space_map(ba->ba_memt, system_table, sizeof(EFI_SYSTEM_TABLE),
+   BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_CACHEABLE, )) {
+   printf(": can't map system table\n");
+   return;
+   }
+
+   st = bus_space_vaddr(ba->ba_memt, memh);
+   sc->sc_rs = st->RuntimeServices;
+
+   major = st->Hdr.Revision >> 16;
+   minor = st->Hdr.Revision & 0x;
+   printf(": UEFI %d.%d", major, minor / 10);
+