Hi,

I'm running NetBSD/amd64 on a Lenovo Thinkpad X230i. This machine run
under an EFI. When the EFI is configured to work in legacy-only mode
(i.e., BIOS), NetBSD successfully locate the ACPI RSDT. This is not
the case when configured to work in EFI-only mode (with CSM disabled).

My understanding is that under EFI, locating the RSDT consist in
walking through the EFI System Table. The physical address of this
table being passed by the bootloader to NetBSD (I don't know of a way
to locate it without the help of the bootloader).

As this machine use GRUB as bootloader, I
experimented as follow:
- patched GRUB to pass the EFI System Table PA to NetBSD via the
  knetbsd command (grub-knetbsd-efi-systbl.patch);
- and made NetBSD use this information in acpi_md_OsGetRootPointer
  to attempt to locate the RSDT but falling back to the actual
  behaviour if missing/broken (efi.patch).

I attached the the patches and the dmesg.

To improve the GRUB part of the solution, I suppose I would need to
make NetBSD/amd64 comply to the multiboot specification. Isn't
NetBSD/i386 compliant?

To improve the NetBSd part of the solution I wonder if I shouldn't dig
into the CFATTACH and make it a pseudo-device like mainbus0 is.

Anyway all comments are welcome :)

Regards,
--
Sheda
diff -ur grub2-2.00/grub-core/commands/efi/lsefisystab.c patched-grub2-2.00/grub-core/commands/efi/lsefisystab.c
--- grub2-2.00/grub-core/commands/efi/lsefisystab.c	2011-04-11 21:39:12.000000000 +0200
+++ patched-grub2-2.00/grub-core/commands/efi/lsefisystab.c	2014-05-14 23:10:25.947655143 +0200
@@ -51,7 +51,10 @@
   const grub_efi_system_table_t *st = grub_efi_system_table;
   grub_efi_configuration_table_t *t;
   unsigned int i;
+  grub_uint64_t pa;
+  memcpy(&pa, &st, sizeof(pa));
 
+  grub_printf ("Address: %016" PRIxGRUB_UINT64_T "\n", pa);
   grub_printf ("Signature: %016" PRIxGRUB_UINT64_T " revision: %08x\n",
 	       st->hdr.signature, st->hdr.revision);
   {
diff -ur grub2-2.00/grub-core/loader/i386/bsd.c patched-grub2-2.00/grub-core/loader/i386/bsd.c
--- grub2-2.00/grub-core/loader/i386/bsd.c	2014-05-14 22:54:34.000000000 +0200
+++ patched-grub2-2.00/grub-core/loader/i386/bsd.c	2014-04-20 13:53:35.253846209 +0200
@@ -1129,6 +1129,16 @@
   if (err)
     return err;
 
+/* XXX */
+#ifdef GRUB_MACHINE_EFI
+{
+  err = grub_bsd_add_meta (NETBSD_BTINFO_EFI, 
+                           &grub_efi_system_table, sizeof(void *));
+  if (err)
+    return err;
+}
+#endif
+
   {
     struct bsd_tag *tag;
     tag_buf_len = 0;
diff -ur grub2-2.00/include/grub/i386/netbsd_bootinfo.h patched-grub2-2.00/include/grub/i386/netbsd_bootinfo.h
--- grub2-2.00/include/grub/i386/netbsd_bootinfo.h	2011-11-09 15:05:40.000000000 +0100
+++ patched-grub2-2.00/include/grub/i386/netbsd_bootinfo.h	2014-04-20 07:25:30.927413596 +0200
@@ -58,6 +58,8 @@
 #define NETBSD_BTINFO_BOOTWEDGE		10
 #define NETBSD_BTINFO_MODULES		11
 #define NETBSD_BTINFO_FRAMEBUF		12
+#define NETBSD_BTINFO_USERCONFCOMMANDS  13
+#define NETBSD_BTINFO_EFI	        14
 
 struct grub_netbsd_bootinfo
 {
@@ -146,4 +148,9 @@
 
 #define GRUB_NETBSD_MAX_ROOTDEVICE_LEN 16
 
+struct grub_netbsd_btinfo_efi
+{
+  void *pa_systbl;  /* Physical address of the EFI System Table */
+};
+
 #endif
Index: arch/amd64/amd64/mainbus.c
===================================================================
RCS file: /cvsroot/src/sys/arch/amd64/amd64/mainbus.c,v
retrieving revision 1.34
diff -u -r1.34 mainbus.c
--- arch/amd64/amd64/mainbus.c	31 Jul 2013 14:05:33 -0000	1.34
+++ arch/amd64/amd64/mainbus.c	21 May 2014 20:05:56 -0000
@@ -54,6 +54,7 @@
 #include "opt_mpbios.h"
 #include "opt_pcifixup.h"
 
+#include <machine/bootinfo.h>
 #include <machine/cpuvar.h>
 #include <machine/i82093var.h>
 #include <machine/mpbiosvar.h>
@@ -169,6 +170,7 @@
 
 	aprint_naive("\n");
 	aprint_normal("\n");
+	aprint_bootinfo();
 
 #ifdef MPBIOS
 	mpbios_present = mpbios_probe(self);
Index: arch/amd64/conf/files.amd64
===================================================================
RCS file: /cvsroot/src/sys/arch/amd64/conf/files.amd64,v
retrieving revision 1.83
diff -u -r1.83 files.amd64
--- arch/amd64/conf/files.amd64	20 Feb 2014 03:48:06 -0000	1.83
+++ arch/amd64/conf/files.amd64	21 May 2014 20:05:56 -0000
@@ -47,6 +47,9 @@
 file	arch/amd64/amd64/lock_stubs.S
 file	dev/cons.c
 
+# EFI Support
+file	arch/x86/x86/efi.c
+
 file	arch/amd64/amd64/mptramp.S        multiprocessor
 
 #
Index: arch/amd64/include/efi.h
===================================================================
RCS file: arch/amd64/include/efi.h
diff -N arch/amd64/include/efi.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ arch/amd64/include/efi.h	21 May 2014 20:05:56 -0000
@@ -0,0 +1 @@
+#include <x86/efi.h>
Index: arch/x86/acpi/acpi_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/acpi/acpi_machdep.c,v
retrieving revision 1.8
diff -u -r1.8 acpi_machdep.c
--- arch/x86/acpi/acpi_machdep.c	12 May 2014 11:51:34 -0000	1.8
+++ arch/x86/acpi/acpi_machdep.c	21 May 2014 20:06:01 -0000
@@ -61,6 +61,7 @@
 #include <machine/i82093reg.h>
 #include <machine/i82093var.h>
 #include <machine/pic.h>
+#include <machine/efi.h>
 
 #include <dev/pci/pcivar.h>
 
@@ -83,13 +84,25 @@
 acpi_md_OsGetRootPointer(void)
 {
 	ACPI_PHYSICAL_ADDRESS PhysicalAddress;
-	ACPI_STATUS Status;
 
-	Status = AcpiFindRootPointer(&PhysicalAddress);
+	PhysicalAddress = 0;
 
-	if (ACPI_FAILURE(Status))
-		PhysicalAddress = 0;
+	/* If EFI is available, attempt to use it to locate the ACPI table. */
+	if (efi_probe()) {
+		PhysicalAddress = efi_getcfgtblpa(&EFI_UUID_ACPI20);
+		if (!PhysicalAddress) {
+			PhysicalAddress = efi_getcfgtblpa(&EFI_UUID_ACPI10);
+		}
+	}
+
+	if (!PhysicalAddress) {
+		ACPI_STATUS Status;
 
+		Status = AcpiFindRootPointer(&PhysicalAddress);
+
+		if (ACPI_FAILURE(Status))
+			PhysicalAddress = 0;
+	}
 	return PhysicalAddress;
 }
 
Index: arch/x86/include/bootinfo.h
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/include/bootinfo.h,v
retrieving revision 1.23
diff -u -r1.23 bootinfo.h
--- arch/x86/include/bootinfo.h	30 Aug 2013 16:42:17 -0000	1.23
+++ arch/x86/include/bootinfo.h	21 May 2014 20:06:01 -0000
@@ -38,6 +38,7 @@
 #define BTINFO_MODULELIST	11
 #define BTINFO_FRAMEBUFFER	12
 #define BTINFO_USERCONFCOMMANDS	13
+#define BTINFO_EFI		14
 
 #ifndef _LOCORE
 
@@ -213,6 +214,12 @@
 	/* bi_userconfcommand list follows */
 };
 
+/* EFI Information */
+struct btinfo_efi {
+	struct btinfo_common common;
+	paddr_t              bi_systbl; /* Physical address of the EFI System Table */
+};
+
 #endif /* _LOCORE */
 
 #ifdef _KERNEL
@@ -237,6 +244,7 @@
 extern struct bootinfo bootinfo;
 
 void *lookup_bootinfo(int);
+void  aprint_bootinfo(void);
 #endif /* _LOCORE */
 
 #endif /* _KERNEL */
Index: arch/x86/include/efi.h
===================================================================
RCS file: arch/x86/include/efi.h
diff -N arch/x86/include/efi.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ arch/x86/include/efi.h	21 May 2014 20:06:01 -0000
@@ -0,0 +1,175 @@
+/*	$NetBSD: efi.h,v 1.1 2006/04/07 14:21:18 cherry Exp $	*/
+
+/*-
+ * Copyright (c) 2004 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/* This file is mainly ia64/include/efi.h with little modifications. */
+
+#ifndef _MACHINE_EFI_H_
+#define _MACHINE_EFI_H_
+
+#include <sys/uuid.h>
+
+#define	EFI_PAGE_SHIFT		12
+#define	EFI_PAGE_SIZE		(1 << EFI_PAGE_SHIFT)
+#define	EFI_PAGE_MASK		(EFI_PAGE_SIZE - 1)
+
+extern const struct uuid EFI_UUID_ACPI20;
+extern const struct uuid EFI_UUID_ACPI10;
+
+#define	EFI_TABLE_SAL				\
+	{0xeb9d2d32,0x2d88,0x11d3,0x9a,0x16,{0x00,0x90,0x27,0x3f,0xc1,0x4d}}
+
+enum efi_reset {
+	EFI_RESET_COLD,
+	EFI_RESET_WARM
+};
+
+typedef uint16_t	efi_char;
+typedef unsigned long efi_status;
+
+
+struct efi_cfgtbl {
+	struct uuid	ct_uuid;
+	uint64_t	ct_data;
+};
+struct efi_md {
+	uint32_t	md_type;
+#define	EFI_MD_TYPE_NULL	0
+#define	EFI_MD_TYPE_CODE	1	/* Loader text. */
+#define	EFI_MD_TYPE_DATA	2	/* Loader data. */
+#define	EFI_MD_TYPE_BS_CODE	3	/* Boot services text. */
+#define	EFI_MD_TYPE_BS_DATA	4	/* Boot services data. */
+#define	EFI_MD_TYPE_RT_CODE	5	/* Runtime services text. */
+#define	EFI_MD_TYPE_RT_DATA	6	/* Runtime services data. */
+#define	EFI_MD_TYPE_FREE	7	/* Unused/free memory. */
+#define	EFI_MD_TYPE_BAD		8	/* Bad memory */
+#define	EFI_MD_TYPE_RECLAIM	9	/* ACPI reclaimable memory. */
+#define	EFI_MD_TYPE_FIRMWARE	10	/* ACPI NV memory */
+#define	EFI_MD_TYPE_IOMEM	11	/* Memory-mapped I/O. */
+#define	EFI_MD_TYPE_IOPORT	12	/* I/O port space. */
+#define	EFI_MD_TYPE_PALCODE	13	/* PAL */
+	uint32_t	__pad;
+	uint64_t	md_phys;
+	void		*md_virt;
+	uint64_t	md_pages;
+	uint64_t	md_attr;
+#define	EFI_MD_ATTR_UC		0x0000000000000001UL
+#define	EFI_MD_ATTR_WC		0x0000000000000002UL
+#define	EFI_MD_ATTR_WT		0x0000000000000004UL
+#define	EFI_MD_ATTR_WB		0x0000000000000008UL
+#define	EFI_MD_ATTR_UCE		0x0000000000000010UL
+#define	EFI_MD_ATTR_WP		0x0000000000001000UL
+#define	EFI_MD_ATTR_RP		0x0000000000002000UL
+#define	EFI_MD_ATTR_XP		0x0000000000004000UL
+#define	EFI_MD_ATTR_RT		0x8000000000000000UL
+};
+
+struct efi_tm {
+	uint16_t	tm_year;		/* 1998 - 20XX */
+	uint8_t		tm_mon;			/* 1 - 12 */
+	uint8_t		tm_mday;		/* 1 - 31 */
+	uint8_t		tm_hour;		/* 0 - 23 */
+	uint8_t		tm_min;			/* 0 - 59 */
+	uint8_t		tm_sec;			/* 0 - 59 */
+	uint8_t		__pad1;
+	uint32_t	tm_nsec;		/* 0 - 999,999,999 */
+	int16_t		tm_tz;			/* -1440 to 1440 or 2047 */
+	uint8_t		tm_dst;
+	uint8_t		__pad2;
+};
+
+struct efi_tmcap {
+	uint32_t	tc_res;		/* 1e-6 parts per million */
+	uint32_t	tc_prec;	/* hertz */
+	uint8_t		tc_stz;		/* Set clears sub-second time */
+};
+
+struct efi_tblhdr {
+	uint64_t	th_sig;
+	uint32_t	th_rev;
+	uint32_t	th_hdrsz;
+	uint32_t	th_crc32;
+	uint32_t	__res;
+};
+
+struct efi_rt {
+	struct efi_tblhdr rt_hdr;
+	efi_status	(*rt_gettime)(struct efi_tm *, struct efi_tmcap *);
+	efi_status	(*rt_settime)(struct efi_tm *);
+	efi_status	(*rt_getwaketime)(uint8_t *, uint8_t *,
+	    struct efi_tm *);
+	efi_status	(*rt_setwaketime)(uint8_t, struct efi_tm *);
+	efi_status	(*rt_setvirtual)(u_long, u_long, uint32_t,
+	    struct efi_md *);
+	efi_status	(*rt_cvtptr)(u_long, void **);
+	efi_status	(*rt_getvar)(efi_char *, struct uuid *, uint32_t *,
+	    u_long *, void *);
+	efi_status	(*rt_scanvar)(u_long *, efi_char *, struct uuid *);
+	efi_status	(*rt_setvar)(efi_char *, struct uuid *, uint32_t,
+	    u_long, void *);
+	efi_status	(*rt_gethicnt)(uint32_t *);
+	efi_status	(*rt_reset)(enum efi_reset, efi_status, u_long,
+	    efi_char *);
+};
+
+struct efi_systbl {
+	struct efi_tblhdr st_hdr;
+#define	EFI_SYSTBL_SIG	0x5453595320494249UL
+	efi_char	*st_fwvendor;
+	uint32_t	st_fwrev;
+	uint32_t	__pad;
+	void		*st_cin;
+	void		*st_cinif;
+	void		*st_cout;
+	void		*st_coutif;
+	void		*st_cerr;
+	void		*st_cerrif;
+	uint64_t	st_rt;
+	void		*st_bs;
+	u_long		st_entries;
+	uint64_t	st_cfgtbl;
+};
+
+bool               efi_probe(void);
+paddr_t            efi_getsystblpa(void);
+struct efi_systbl *efi_getsystbl(void);
+paddr_t            efi_getcfgtblpa(const struct uuid*);
+void              *efi_getcfgtbl(const struct uuid*);
+/*
+void efi_boot_finish(void);
+int efi_boot_minimal(uint64_t);
+void *efi_get_table(struct uuid *);
+void efi_get_time(struct efi_tm *);
+struct efi_md *efi_md_first(void);
+struct efi_md *efi_md_next(struct efi_md *);
+void efi_reset_system(void);
+efi_status efi_set_time(struct efi_tm *);
+*/
+
+#endif /* _MACHINE_EFI_H_ */
Index: arch/x86/x86/efi.c
===================================================================
RCS file: arch/x86/x86/efi.c
diff -N arch/x86/x86/efi.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ arch/x86/x86/efi.c	21 May 2014 20:06:01 -0000
@@ -0,0 +1,254 @@
+#include <sys/cdefs.h>
+#include <sys/kmem.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/uuid.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <machine/bootinfo.h>
+#include <machine/efi.h>
+
+#include <dev/mm.h>
+
+const struct uuid EFI_UUID_ACPI20 = {
+	.time_low = 0x8868e871,
+	.time_mid = 0xe4f1, 
+	.time_hi_and_version = 0x11d3,
+	.clock_seq_hi_and_reserved = 0xbc,
+	.clock_seq_low =0x22,
+	.node = { 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 }
+};
+const struct uuid EFI_UUID_ACPI10 = { 
+	.time_low = 0xeb9d2d30,
+	.time_mid = 0x2d88,
+	.time_hi_and_version =  0x11d3,
+    	.clock_seq_hi_and_reserved = 0x9a,
+	.clock_seq_low = 0x16, 
+	.node = { 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d }
+};
+
+vaddr_t            efi_getva(paddr_t);
+void               efi_relva(vaddr_t);
+struct efi_cfgtbl *efi_getcfgtblhead(void);
+void               efi_aprintcfgtbl(void);
+void               efi_aprintuuid(const struct uuid *);
+bool		   efi_uuideq(const struct uuid *, const struct uuid *);
+
+static struct efi_systbl *efi_systbl_va = NULL;
+static struct efi_cfgtbl *efi_cfgtblhead_va = NULL;
+
+/*
+ * Map a physical address (PA) to a newly allocated virtual address (VA). 
+ * The VA must be freed using efi_relva().
+ */
+vaddr_t
+efi_getva(paddr_t pa)
+{
+	vaddr_t va;
+
+#ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS
+	mm_md_direct_mapped_phys(pa, &va);
+#else
+	/* XXX This code path is not tested. */
+	va = uvm_km_alloc(kernel_map, PAGE_SIZE, 0,
+       	                  UVM_KMF_VAONLY | UVM_KMF_WAITVA);
+	if (va == 0) {
+		aprint_debug("efi: unable to allocate va\n");
+		return NULL;
+	}
+	pmap_kenter_pa(va, pa, VM_PROT_READ, 0);
+	pmap_update( pmap_kernel() );
+#endif
+	return va;
+}
+
+/*
+ * Free a virtual address (VA) allocated using efi_getva().
+ */
+void
+efi_relva(vaddr_t va)
+{
+#ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS
+	/* XXX Should we free the va? */
+#else
+	/* XXX This code path is not tested. */
+	uvm_km_free(kernel_map, va, PAGE_SIZE, UVM_KMF_VAONLY);
+#endif
+}
+
+/*
+ * Test if 2 UUIDs matches.
+ */
+bool
+efi_uuideq(const struct uuid *a, const struct uuid *b)
+{
+	return !memcmp(a, b, sizeof(struct uuid));
+}
+
+/*
+ * Print an UUID in a human-readable manner.
+ */
+void
+efi_aprintuuid(const struct uuid *uuid)
+{
+	int i;
+
+	aprint_debug(" %08"PRIx32"", uuid->time_low);
+	aprint_debug("-%04"PRIx16"", uuid->time_mid);
+ 	aprint_debug("-%04"PRIx16"", uuid->time_hi_and_version);
+   	aprint_debug("-%02"PRIx8"",  uuid->clock_seq_hi_and_reserved);
+       	aprint_debug("-%02"PRIx8"",  uuid->clock_seq_low);
+       	aprint_debug("-");
+	for (i = 0; i < _UUID_NODE_LEN; i++) {
+       		aprint_debug("%02"PRIx8"", uuid->node[i]);
+	}
+	/* If known, also print the human-readable name */
+	if (efi_uuideq(uuid, &EFI_UUID_ACPI20)) {
+		aprint_debug(" ACPI 2.0");
+	} else if (efi_uuideq(uuid, &EFI_UUID_ACPI10)) {
+		aprint_debug(" ACPI 1.0");
+	}
+}
+
+/* 
+ * Return the VA of the cfgtbl. Must be freed using efi_relva().
+ */
+struct efi_cfgtbl *
+efi_getcfgtblhead(void)
+{
+	if (efi_cfgtblhead_va == NULL) {
+		paddr_t pa;
+		vaddr_t va;
+
+		pa = (paddr_t)efi_systbl_va->st_cfgtbl;
+		aprint_debug("efi: cfgtbl at pa %"PRIx64"\n", pa);
+		va = efi_getva(pa);
+		aprint_debug("efi: cfgtbl mapped at va %"PRIx64"\n", va);
+		efi_cfgtblhead_va = (struct efi_cfgtbl *)va;
+		efi_aprintcfgtbl();
+	}
+	return efi_cfgtblhead_va;
+}
+
+/*
+ * Print the config tables.
+ */
+void
+efi_aprintcfgtbl(void)
+{
+	struct efi_cfgtbl *ct;
+	unsigned long      count;
+
+	ct    = efi_cfgtblhead_va;
+	count = efi_systbl_va->st_entries;
+        aprint_debug("efi: %lu cfgtbl entries:\n", count);
+	for (; count; count--, ct++) {
+    		aprint_debug("efi: %16"PRIx64"", ct->ct_data);
+		efi_aprintuuid(&ct->ct_uuid);
+       		aprint_debug("\n");
+	}
+}
+
+/*
+ * Return the VA of the config table with the given UUID if found.
+ * The VA must be freed using efi_relva().
+ */
+void *
+efi_getcfgtbl(const struct uuid *uuid)
+{
+	paddr_t pa;
+	vaddr_t va;
+
+	pa = efi_getcfgtblpa(uuid);
+	if (pa == 0) {
+		return NULL;
+	}
+	va = efi_getva(pa);
+	return (void *)va;
+}
+
+/*
+ * Return the PA of the first config table.
+ */
+paddr_t
+efi_getcfgtblpa(const struct uuid *uuid)
+{
+	struct efi_cfgtbl *ct;
+	unsigned long      count;
+
+	ct    = efi_cfgtblhead_va;
+	count = efi_systbl_va->st_entries;
+	for (; count; count--, ct++) {
+		if (efi_uuideq(&ct->ct_uuid, uuid)) {
+			return (paddr_t)ct->ct_data;
+		}
+	}
+	return 0; /* Not found. */
+}
+
+/* Return the PA of the EFI System Table. */
+paddr_t
+efi_getsystblpa(void)
+{
+	struct btinfo_efi *bi;
+	paddr_t            pa;
+
+	bi = lookup_bootinfo(BTINFO_EFI);
+	if (bi == NULL) {
+		/* Unable to locate the EFI System Table. */
+		return 0;
+	}
+	pa = bi->bi_systbl;
+	return pa;
+}
+
+/* 
+ * Return a pointer to the EFI System Table. The pointer must be 
+ * freed using efi_relva(). 
+ */
+struct efi_systbl *
+efi_getsystbl(void)
+{
+	if (!efi_systbl_va) {
+		paddr_t pa;
+		vaddr_t va;
+		struct efi_systbl *systbl;
+
+		pa = efi_getsystblpa();
+		if (pa == 0)
+			return NULL;
+		aprint_normal("efi: systbl at pa %"PRIx64"\n", pa);
+		va = efi_getva(pa);
+		aprint_debug("efi: systbl mapped at va %"PRIx64"\n", va);
+		systbl = (struct efi_systbl *)va;
+		/* XXX Check the signature and the CRC32 */
+		aprint_debug("efi: signature %"PRIx64" revision %"PRIx32" crc32 %"PRIx32"\n", 
+		     	     systbl->st_hdr.th_sig, systbl->st_hdr.th_rev, 
+		     	     systbl->st_hdr.th_crc32);
+		aprint_debug("efi: firmware revision %"PRIx32"\n", systbl->st_fwrev);
+		/* XXX Also print fwvendor, which is an UCS-2 string (use some UTF-16 routine?) */
+		aprint_debug("efi: runtime services at pa %"PRIx64"\n", systbl->st_rt);
+		aprint_debug("efi: boot services at pa %"PRIx64"\n", (uint64_t)systbl->st_bs);
+		efi_systbl_va = systbl;
+	}
+	return efi_systbl_va;
+}
+
+/* 
+ * EFI is available if we are able to locate the EFI System Table. 
+ */
+bool
+efi_probe(void)
+{
+	if (efi_getsystbl() == 0) {
+		aprint_debug("efi: missing or invalid systbl");
+		return false;
+	}
+	if (efi_getcfgtblhead() == 0) {
+		aprint_debug("efi: missing or invalid cfgtbl");
+		efi_relva((vaddr_t)efi_systbl_va);
+		return false;
+	}
+	return true;
+}
Index: arch/x86/x86/x86_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/x86/x86_machdep.c,v
retrieving revision 1.64
diff -u -r1.64 x86_machdep.c
--- arch/x86/x86/x86_machdep.c	1 Apr 2014 07:16:18 -0000	1.64
+++ arch/x86/x86/x86_machdep.c	21 May 2014 20:06:01 -0000
@@ -121,6 +121,67 @@
 }
 
 /*
+ * List the available bootinfo entries.
+ */
+void
+aprint_bootinfo(void)
+{
+	int i;
+	struct btinfo_common *bic;
+
+	aprint_normal("bootinfo:");
+	bic = (struct btinfo_common *)(bootinfo.bi_data);
+	for (i = 0; i < bootinfo.bi_nentries; i++) {
+		switch (bic->type) {
+		case BTINFO_BOOTPATH:    
+			aprint_normal(" bootpath");
+			break;
+		case BTINFO_ROOTDEVICE:  
+			aprint_normal(" rootdevice");
+			break;
+		case BTINFO_BOOTDISK:    
+			aprint_normal(" bootdisk");
+			break;
+		case BTINFO_NETIF:       
+			aprint_normal(" netif");
+			break;
+		case BTINFO_CONSOLE:     
+			aprint_normal(" console");
+			break;
+		case BTINFO_BIOSGEOM:    
+			aprint_normal(" biosgeom");
+			break;
+		case BTINFO_SYMTAB:      
+			aprint_normal(" symtab");
+			break;
+		case BTINFO_MEMMAP:      
+			aprint_normal(" memmap");
+			break;
+		case BTINFO_BOOTWEDGE:   
+			aprint_normal(" bootwedge");
+			break;
+		case BTINFO_MODULELIST:
+			aprint_normal(" modulelist");
+			break;
+		case BTINFO_FRAMEBUFFER:
+			aprint_normal(" framebuffer");
+			break;
+		case BTINFO_USERCONFCOMMANDS: 
+			aprint_normal(" userconfcommands");
+			break;
+		case BTINFO_EFI: 
+			aprint_normal(" efi");
+			break;
+		default:
+			aprint_normal(" %d", bic->type);
+		}
+		bic = (struct btinfo_common *)
+	  	    ((uint8_t *)bic + bic->len);
+	}
+	aprint_normal("\n");
+}
+
+/*
  * mm_md_physacc: check if given pa is accessible.
  */
 int

Attachment: dmesg-generic.out
Description: Binary data

Attachment: dmesg-current.out
Description: Binary data

Reply via email to