Module Name: src
Committed By: nonaka
Date: Tue Jan 24 11:09:15 UTC 2017
Modified Files:
src/distrib/sets/lists/base: md.amd64
src/sys/arch/i386/stand: Makefile
src/sys/arch/i386/stand/lib: biosdisk.c bootinfo_biosgeom.c diskbuf.c
exec.c libi386.h vbe.c
src/sys/arch/x86/acpi: acpi_machdep.c
src/sys/arch/x86/include: bootinfo.h efi.h
src/sys/arch/x86/x86: efi.c x86_machdep.c
src/sys/lib/libgnuefi: Makefile Makefile.inc
Added Files:
src/sys/arch/i386/stand/efiboot: Makefile Makefile.efiboot boot.c
conf.c devopen.c devopen.h efiboot.c efiboot.h eficons.c efidelay.c
efidisk.c efidisk.h efidisk_ll.c efigetsecs.c efimemory.c panic.c
self_reloc.c version
src/sys/arch/i386/stand/efiboot/bootia32: Makefile efiboot_machdep.h
efibootia32.c ldscript start.S
src/sys/arch/i386/stand/efiboot/bootx64: Makefile efiboot_machdep.h
efibootx64.c ldscript start.S startprog64.S
src/sys/lib/libgnuefi/arch/i386: Makefile.inc
src/sys/lib/libgnuefi/arch/x86_64: Makefile.inc
Log Message:
Initial commit of native amd64 EFI boot loader.
To generate a diff of this commit:
cvs rdiff -u -r1.267 -r1.268 src/distrib/sets/lists/base/md.amd64
cvs rdiff -u -r1.27 -r1.28 src/sys/arch/i386/stand/Makefile
cvs rdiff -u -r0 -r1.1 src/sys/arch/i386/stand/efiboot/Makefile \
src/sys/arch/i386/stand/efiboot/Makefile.efiboot \
src/sys/arch/i386/stand/efiboot/boot.c \
src/sys/arch/i386/stand/efiboot/conf.c \
src/sys/arch/i386/stand/efiboot/devopen.c \
src/sys/arch/i386/stand/efiboot/devopen.h \
src/sys/arch/i386/stand/efiboot/efiboot.c \
src/sys/arch/i386/stand/efiboot/efiboot.h \
src/sys/arch/i386/stand/efiboot/eficons.c \
src/sys/arch/i386/stand/efiboot/efidelay.c \
src/sys/arch/i386/stand/efiboot/efidisk.c \
src/sys/arch/i386/stand/efiboot/efidisk.h \
src/sys/arch/i386/stand/efiboot/efidisk_ll.c \
src/sys/arch/i386/stand/efiboot/efigetsecs.c \
src/sys/arch/i386/stand/efiboot/efimemory.c \
src/sys/arch/i386/stand/efiboot/panic.c \
src/sys/arch/i386/stand/efiboot/self_reloc.c \
src/sys/arch/i386/stand/efiboot/version
cvs rdiff -u -r0 -r1.1 src/sys/arch/i386/stand/efiboot/bootia32/Makefile \
src/sys/arch/i386/stand/efiboot/bootia32/efiboot_machdep.h \
src/sys/arch/i386/stand/efiboot/bootia32/efibootia32.c \
src/sys/arch/i386/stand/efiboot/bootia32/ldscript \
src/sys/arch/i386/stand/efiboot/bootia32/start.S
cvs rdiff -u -r0 -r1.1 src/sys/arch/i386/stand/efiboot/bootx64/Makefile \
src/sys/arch/i386/stand/efiboot/bootx64/efiboot_machdep.h \
src/sys/arch/i386/stand/efiboot/bootx64/efibootx64.c \
src/sys/arch/i386/stand/efiboot/bootx64/ldscript \
src/sys/arch/i386/stand/efiboot/bootx64/start.S \
src/sys/arch/i386/stand/efiboot/bootx64/startprog64.S
cvs rdiff -u -r1.45 -r1.46 src/sys/arch/i386/stand/lib/biosdisk.c
cvs rdiff -u -r1.22 -r1.23 src/sys/arch/i386/stand/lib/bootinfo_biosgeom.c
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/i386/stand/lib/diskbuf.c
cvs rdiff -u -r1.62 -r1.63 src/sys/arch/i386/stand/lib/exec.c
cvs rdiff -u -r1.40 -r1.41 src/sys/arch/i386/stand/lib/libi386.h
cvs rdiff -u -r1.8 -r1.9 src/sys/arch/i386/stand/lib/vbe.c
cvs rdiff -u -r1.14 -r1.15 src/sys/arch/x86/acpi/acpi_machdep.c
cvs rdiff -u -r1.24 -r1.25 src/sys/arch/x86/include/bootinfo.h
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/x86/include/efi.h
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/x86/x86/efi.c
cvs rdiff -u -r1.81 -r1.82 src/sys/arch/x86/x86/x86_machdep.c
cvs rdiff -u -r1.4 -r1.5 src/sys/lib/libgnuefi/Makefile
cvs rdiff -u -r1.3 -r1.4 src/sys/lib/libgnuefi/Makefile.inc
cvs rdiff -u -r0 -r1.1 src/sys/lib/libgnuefi/arch/i386/Makefile.inc
cvs rdiff -u -r0 -r1.1 src/sys/lib/libgnuefi/arch/x86_64/Makefile.inc
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/distrib/sets/lists/base/md.amd64
diff -u src/distrib/sets/lists/base/md.amd64:1.267 src/distrib/sets/lists/base/md.amd64:1.268
--- src/distrib/sets/lists/base/md.amd64:1.267 Sat Sep 26 01:46:14 2015
+++ src/distrib/sets/lists/base/md.amd64 Tue Jan 24 11:09:14 2017
@@ -1,4 +1,4 @@
-# $NetBSD: md.amd64,v 1.267 2015/09/26 01:46:14 christos Exp $
+# $NetBSD: md.amd64,v 1.268 2017/01/24 11:09:14 nonaka Exp $
./dev/lms0 base-obsolete obsolete
./dev/mms0 base-obsolete obsolete
./libexec/ld.elf_so-i386 base-sys-shlib compat,pic
@@ -30,6 +30,8 @@
./usr/mdec/biosboot_com0_57600.sym base-obsolete obsolete
./usr/mdec/biosboot_com0_9600.sym base-obsolete obsolete
./usr/mdec/boot base-sysutil-bin
+./usr/mdec/bootia32.efi base-sysutil-bin
+./usr/mdec/bootx64.efi base-sysutil-bin
./usr/mdec/bootxx_cd9660 base-sysutil-bin
./usr/mdec/bootxx_dosfs base-obsolete obsolete
./usr/mdec/bootxx_ext2fs base-sysutil-bin
Index: src/sys/arch/i386/stand/Makefile
diff -u src/sys/arch/i386/stand/Makefile:1.27 src/sys/arch/i386/stand/Makefile:1.28
--- src/sys/arch/i386/stand/Makefile:1.27 Fri Jan 27 08:41:35 2012
+++ src/sys/arch/i386/stand/Makefile Tue Jan 24 11:09:14 2017
@@ -1,8 +1,11 @@
-# $NetBSD: Makefile,v 1.27 2012/01/27 08:41:35 jnemeth Exp $
+# $NetBSD: Makefile,v 1.28 2017/01/24 11:09:14 nonaka Exp $
SUBDIR= mbr boot
SUBDIR+= bootxx cdboot fatboot
SUBDIR+= dosboot misc
SUBDIR+= pxeboot
+.if ${MACHINE} == "amd64"
+SUBDIR+= efiboot
+.endif
.include <bsd.subdir.mk>
Index: src/sys/arch/i386/stand/lib/biosdisk.c
diff -u src/sys/arch/i386/stand/lib/biosdisk.c:1.45 src/sys/arch/i386/stand/lib/biosdisk.c:1.46
--- src/sys/arch/i386/stand/lib/biosdisk.c:1.45 Sun Jun 5 14:06:31 2016
+++ src/sys/arch/i386/stand/lib/biosdisk.c Tue Jan 24 11:09:14 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: biosdisk.c,v 1.45 2016/06/05 14:06:31 maxv Exp $ */
+/* $NetBSD: biosdisk.c,v 1.46 2017/01/24 11:09:14 nonaka Exp $ */
/*
* Copyright (c) 1996, 1998
@@ -102,6 +102,13 @@ struct biosdisk {
daddr_t offset;
daddr_t size;
int fstype;
+#ifdef EFIBOOT
+ const struct gpt_part {
+ const struct uuid *guid;
+ const char *name;
+ } *guid;
+ uint64_t attr;
+#endif
} part[BIOSDISKNPART];
#endif
};
@@ -111,6 +118,55 @@ const struct uuid GET_nbsd_raid = GPT_EN
const struct uuid GET_nbsd_ffs = GPT_ENT_TYPE_NETBSD_FFS;
const struct uuid GET_nbsd_lfs = GPT_ENT_TYPE_NETBSD_LFS;
const struct uuid GET_nbsd_swap = GPT_ENT_TYPE_NETBSD_SWAP;
+const struct uuid GET_nbsd_ccd = GPT_ENT_TYPE_NETBSD_CCD;
+const struct uuid GET_nbsd_cgd = GPT_ENT_TYPE_NETBSD_CGD;
+#ifdef EFIBOOT
+const struct uuid GET_efi = GPT_ENT_TYPE_EFI;
+const struct uuid GET_mbr = GPT_ENT_TYPE_MBR;
+const struct uuid GET_fbsd = GPT_ENT_TYPE_FREEBSD;
+const struct uuid GET_fbsd_swap = GPT_ENT_TYPE_FREEBSD_SWAP;
+const struct uuid GET_fbsd_ufs = GPT_ENT_TYPE_FREEBSD_UFS;
+const struct uuid GET_fbsd_vinum = GPT_ENT_TYPE_FREEBSD_VINUM;
+const struct uuid GET_fbsd_zfs = GPT_ENT_TYPE_FREEBSD_ZFS;
+const struct uuid GET_ms_rsvd = GPT_ENT_TYPE_MS_RESERVED;
+const struct uuid GET_ms_basic_data = GPT_ENT_TYPE_MS_BASIC_DATA;
+const struct uuid GET_ms_ldm_metadata = GPT_ENT_TYPE_MS_LDM_METADATA;
+const struct uuid GET_ms_ldm_data = GPT_ENT_TYPE_MS_LDM_DATA;
+const struct uuid GET_linux_data = GPT_ENT_TYPE_LINUX_DATA;
+const struct uuid GET_linux_raid = GPT_ENT_TYPE_LINUX_RAID;
+const struct uuid GET_linux_swap = GPT_ENT_TYPE_LINUX_SWAP;
+const struct uuid GET_linux_lvm = GPT_ENT_TYPE_LINUX_LVM;
+const struct uuid GET_apple_hfs = GPT_ENT_TYPE_APPLE_HFS;
+const struct uuid GET_apple_ufs = GPT_ENT_TYPE_APPLE_UFS;
+const struct uuid GET_bios = GPT_ENT_TYPE_BIOS;
+
+const struct gpt_part gpt_parts[] = {
+ { &GET_nbsd_raid, "NetBSD RAID" },
+ { &GET_nbsd_ffs, "NetBSD FFS" },
+ { &GET_nbsd_lfs, "NetBSD LFS" },
+ { &GET_nbsd_swap, "NetBSD Swap" },
+ { &GET_nbsd_ccd, "NetBSD ccd" },
+ { &GET_nbsd_cgd, "NetBSD cgd" },
+ { &GET_efi, "EFI System" },
+ { &GET_mbr, "MBR" },
+ { &GET_fbsd, "FreeBSD" },
+ { &GET_fbsd_swap, "FreeBSD Swap" },
+ { &GET_fbsd_ufs, "FreeBSD UFS" },
+ { &GET_fbsd_vinum, "FreeBSD Vinum" },
+ { &GET_fbsd_zfs, "FreeBSD ZFS" },
+ { &GET_ms_rsvd, "Microsoft Reserved" },
+ { &GET_ms_basic_data, "Microsoft Basic data" },
+ { &GET_ms_ldm_metadata, "Microsoft LDM metadata" },
+ { &GET_ms_ldm_data, "Microsoft LDM data" },
+ { &GET_linux_data, "Linux data" },
+ { &GET_linux_raid, "Linux RAID" },
+ { &GET_linux_swap, "Linux Swap" },
+ { &GET_linux_lvm, "Linux LVM" },
+ { &GET_apple_hfs, "Apple HFS" },
+ { &GET_apple_ufs, "Apple UFS" },
+ { &GET_bios, "BIOS Boot (GRUB)" },
+};
+#endif
#endif /* NO_GPT */
#ifdef _STANDALONE
@@ -273,7 +329,7 @@ check_gpt(struct biosdisk *d, daddr_t se
entblk += sectors;
crc = crc32(crc, (const void *)d->buf, size);
- for (i = 0; j < BIOSDISKNPART && i < entries; i++, j++) {
+ for (i = 0; j < BIOSDISKNPART && i < entries; i++) {
u = (const struct uuid *)ep[i].ent_type;
if (!guid_is_nil(u)) {
d->part[j].offset = ep[i].ent_lba_start;
@@ -287,8 +343,22 @@ check_gpt(struct biosdisk *d, daddr_t se
d->part[j].fstype = FS_RAID;
else if (guid_is_equal(u, &GET_nbsd_swap))
d->part[j].fstype = FS_SWAP;
+ else if (guid_is_equal(u, &GET_nbsd_ccd))
+ d->part[j].fstype = FS_CCD;
+ else if (guid_is_equal(u, &GET_nbsd_cgd))
+ d->part[j].fstype = FS_CGD;
else
d->part[j].fstype = FS_OTHER;
+#ifdef EFIBOOT
+ for (int k = 0;
+ k < __arraycount(gpt_parts);
+ k++) {
+ if (guid_is_equal(u, gpt_parts[k].guid))
+ d->part[j].guid = &gpt_parts[k];
+ }
+ d->part[j].attr = ep[i].ent_attr;
+#endif
+ j++;
}
}
@@ -649,6 +719,11 @@ biosdisk_probe(void)
first = 0;
}
printf(" hd%d%c(", d.ll.dev & 0x7f, part + 'a');
+#ifdef EFIBOOT
+ if (d.part[part].guid != NULL)
+ printf("%s", d.part[part].guid->name);
+ else
+#endif
if (d.part[part].fstype < FSMAXTYPES)
printf("%s",
fstypenames[d.part[part].fstype]);
@@ -674,6 +749,10 @@ biosdisk_findpartition(int biosdev, dadd
#else
struct biosdisk *d;
int partition = 0;
+#ifdef EFIBOOT
+ int candidate = 0;
+#endif
+
#ifdef DISK_DEBUG
printf("looking for partition device %x, sector %"PRId64"\n", biosdev, sector);
#endif
@@ -687,9 +766,31 @@ biosdisk_findpartition(int biosdev, dadd
for (partition = (BIOSDISKNPART-1); --partition;) {
if (d->part[partition].fstype == FS_UNUSED)
continue;
+#ifdef EFIBOOT
+ if (d->part[partition].attr & GPT_ENT_ATTR_BOOTME) {
+ switch (d->part[partition].fstype) {
+ case FS_BSDFFS:
+ case FS_BSDLFS:
+ case FS_RAID:
+ case FS_CCD:
+ case FS_CGD:
+ break;
+
+ default:
+ candidate = partition;
+ continue;
+ }
+ break;
+ }
+#else
if (d->part[partition].offset == sector)
break;
+#endif
}
+#ifdef EFIBOOT
+ if (partition == 0 && candidate != 0)
+ partition = candidate;
+#endif
}
dealloc(d, sizeof(*d));
Index: src/sys/arch/i386/stand/lib/bootinfo_biosgeom.c
diff -u src/sys/arch/i386/stand/lib/bootinfo_biosgeom.c:1.22 src/sys/arch/i386/stand/lib/bootinfo_biosgeom.c:1.23
--- src/sys/arch/i386/stand/lib/bootinfo_biosgeom.c:1.22 Thu May 16 19:06:44 2013
+++ src/sys/arch/i386/stand/lib/bootinfo_biosgeom.c Tue Jan 24 11:09:14 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: bootinfo_biosgeom.c,v 1.22 2013/05/16 19:06:44 christos Exp $ */
+/* $NetBSD: bootinfo_biosgeom.c,v 1.23 2017/01/24 11:09:14 nonaka Exp $ */
/*
* Copyright (c) 1997
@@ -78,7 +78,6 @@ bi_getbiosgeom(void)
return;
for (i = nvalid = 0; i < MAX_BIOSDISKS && nvalid < nhd; i++) {
-
d.dev = 0x80 + i;
if (set_geometry(&d, &ed))
Index: src/sys/arch/i386/stand/lib/diskbuf.c
diff -u src/sys/arch/i386/stand/lib/diskbuf.c:1.6 src/sys/arch/i386/stand/lib/diskbuf.c:1.7
--- src/sys/arch/i386/stand/lib/diskbuf.c:1.6 Sun Dec 11 12:17:48 2005
+++ src/sys/arch/i386/stand/lib/diskbuf.c Tue Jan 24 11:09:14 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: diskbuf.c,v 1.6 2005/12/11 12:17:48 christos Exp $ */
+/* $NetBSD: diskbuf.c,v 1.7 2017/01/24 11:09:14 nonaka Exp $ */
/*
* Copyright (c) 1996
@@ -28,6 +28,8 @@
/* data buffer for BIOS disk / DOS I/O */
+#include <sys/inttypes.h>
+
#include <lib/libsa/stand.h>
#include "diskbuf.h"
@@ -48,10 +50,12 @@ alloc_diskbuf(const void *user)
diskbuf_user = user;
if (!diskbufp) {
diskbufp = alloc(DISKBUFSIZE);
- if (((int)diskbufp & 0xffff) + DISKBUFSIZE > 0x10000) {
- printf("diskbufp %x\n", (unsigned)diskbufp);
+#ifndef EFIBOOT
+ if (((uintptr_t)diskbufp & 0xffff) + DISKBUFSIZE > 0x10000) {
+ printf("diskbufp %" PRIxPTR "\n", (uintptr_t)diskbufp);
panic("diskbuf crosses 64k boundary");
}
+#endif
}
return diskbufp;
}
Index: src/sys/arch/i386/stand/lib/exec.c
diff -u src/sys/arch/i386/stand/lib/exec.c:1.62 src/sys/arch/i386/stand/lib/exec.c:1.63
--- src/sys/arch/i386/stand/lib/exec.c:1.62 Sun Dec 4 08:21:08 2016
+++ src/sys/arch/i386/stand/lib/exec.c Tue Jan 24 11:09:14 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: exec.c,v 1.62 2016/12/04 08:21:08 maxv Exp $ */
+/* $NetBSD: exec.c,v 1.63 2017/01/24 11:09:14 nonaka Exp $ */
/*
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -109,6 +109,11 @@
#ifdef SUPPORT_PS2
#include "biosmca.h"
#endif
+#ifdef EFIBOOT
+#include "efiboot.h"
+#undef DEBUG /* XXX */
+static u_long efi_loadaddr;
+#endif
#define BOOT_NARGS 6
@@ -295,6 +300,31 @@ common_load_kernel(const char *file, u_l
return ENOMEM;
}
#endif
+#ifdef EFIBOOT
+ {
+ EFI_STATUS status;
+ EFI_PHYSICAL_ADDRESS addr;
+ UINTN kernsize;
+
+ marks[MARK_START] = loadaddr;
+ if ((fd = loadfile(file, marks, COUNT_KERNEL)) == -1)
+ return EIO;
+ close(fd);
+
+ /* Allocate temporary arena. */
+ addr = EFI_ALLOCATE_MAX_ADDRESS;
+ kernsize = marks[MARK_END] - loadaddr;
+ kernsize += 1 * 1024 * 1024; /* XXX: kernel size COUNT_KERNEL vs LOAD_KERNL (lacked some SYMTAB?) */
+ kernsize = EFI_SIZE_TO_PAGES(kernsize);
+ status = uefi_call_wrapper(BS->AllocatePages, 4,
+ AllocateMaxAddress, EfiLoaderData, kernsize, &addr);
+ if (EFI_ERROR(status))
+ return ENOMEM;
+ efi_loadaddr = loadaddr = addr;
+
+ memset(marks, 0, sizeof(marks[0]) * MARK_MAX);
+ }
+#endif
marks[MARK_START] = loadaddr;
if ((fd = loadfile(file, marks,
LOAD_KERNEL & ~(floppy ? LOAD_BACKWARDS : 0))) == -1)
@@ -332,6 +362,15 @@ common_load_kernel(const char *file, u_l
ppbcopy(loadaddr, origaddr, marks[MARK_END]);
}
#endif
+#ifdef EFIBOOT
+ marks[MARK_START] -= loadaddr;
+ marks[MARK_ENTRY] -= loadaddr;
+ marks[MARK_DATA] -= loadaddr;
+ /* MARK_NSYM */
+ marks[MARK_SYM] -= loadaddr;
+ marks[MARK_END] -= loadaddr;
+ /* Copy the kernel to original load address later. */
+#endif
marks[MARK_END] = (((u_long) marks[MARK_END] + sizeof(int) - 1)) &
(-sizeof(int));
image_end = marks[MARK_END];
@@ -349,6 +388,7 @@ exec_netbsd(const char *file, physaddr_t
struct btinfo_symtab btinfo_symtab;
u_long extmem;
u_long basemem;
+ int error;
#ifdef DEBUG
printf("exec: file=%s loadaddr=0x%lx\n", file ? file : "NULL",
@@ -363,8 +403,12 @@ exec_netbsd(const char *file, physaddr_t
memset(marks, 0, sizeof(marks));
- if (common_load_kernel(file, &basemem, &extmem, loadaddr, floppy, marks))
+ error = common_load_kernel(file, &basemem, &extmem, loadaddr, floppy,
+ marks);
+ if (error) {
+ errno = error;
goto out;
+ }
boot_argv[0] = boothowto;
boot_argv[1] = 0;
@@ -404,6 +448,12 @@ exec_netbsd(const char *file, physaddr_t
if (callback != NULL)
(*callback)();
+#ifdef EFIBOOT
+ /* Copy the kernel to original load address. */
+ memmove((void *)marks[MARK_START],
+ (void *)(efi_loadaddr + marks[MARK_START]),
+ marks[MARK_END] - marks[MARK_START]);
+#endif
startprog(marks[MARK_ENTRY], BOOT_NARGS, boot_argv,
x86_trunc_page(basemem * 1024));
panic("exec returned");
Index: src/sys/arch/i386/stand/lib/libi386.h
diff -u src/sys/arch/i386/stand/lib/libi386.h:1.40 src/sys/arch/i386/stand/lib/libi386.h:1.41
--- src/sys/arch/i386/stand/lib/libi386.h:1.40 Sun Nov 24 17:20:00 2013
+++ src/sys/arch/i386/stand/lib/libi386.h Tue Jan 24 11:09:14 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: libi386.h,v 1.40 2013/11/24 17:20:00 jakllsch Exp $ */
+/* $NetBSD: libi386.h,v 1.41 2017/01/24 11:09:14 nonaka Exp $ */
/*
* Copyright (c) 1996
@@ -26,6 +26,9 @@
*
*/
+#ifndef __I386_STAND_LIBI386_H__
+#define __I386_STAND_LIBI386_H__
+
typedef unsigned long physaddr_t;
/* this is in startup code */
@@ -144,3 +147,5 @@ void userconf_add(char *);
struct btinfo_framebuffer;
void framebuffer_configure(struct btinfo_framebuffer *);
+
+#endif /* __I386_STAND_LIBI386_H__ */
Index: src/sys/arch/i386/stand/lib/vbe.c
diff -u src/sys/arch/i386/stand/lib/vbe.c:1.8 src/sys/arch/i386/stand/lib/vbe.c:1.9
--- src/sys/arch/i386/stand/lib/vbe.c:1.8 Fri May 31 15:11:07 2013
+++ src/sys/arch/i386/stand/lib/vbe.c Tue Jan 24 11:09:14 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: vbe.c,v 1.8 2013/05/31 15:11:07 tsutsui Exp $ */
+/* $NetBSD: vbe.c,v 1.9 2017/01/24 11:09:14 nonaka Exp $ */
/*-
* Copyright (c) 2009 Jared D. McNeill <[email protected]>
@@ -145,6 +145,7 @@ vbe_set_mode(int modenum)
for (i = 0; i < 256; i++)
vbe_set_palette(&rasops_cmap[i * 3], i);
+ memset(&fb, 0, sizeof(fb));
fb.physaddr = (uint64_t)mi.PhysBasePtr & 0xffffffff;
fb.width = mi.XResolution;
fb.height = mi.YResolution;
Index: src/sys/arch/x86/acpi/acpi_machdep.c
diff -u src/sys/arch/x86/acpi/acpi_machdep.c:1.14 src/sys/arch/x86/acpi/acpi_machdep.c:1.15
--- src/sys/arch/x86/acpi/acpi_machdep.c:1.14 Sat Oct 15 16:46:14 2016
+++ src/sys/arch/x86/acpi/acpi_machdep.c Tue Jan 24 11:09:14 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_machdep.c,v 1.14 2016/10/15 16:46:14 jdolecek Exp $ */
+/* $NetBSD: acpi_machdep.c,v 1.15 2017/01/24 11:09:14 nonaka Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@@ -40,7 +40,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_machdep.c,v 1.14 2016/10/15 16:46:14 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_machdep.c,v 1.15 2017/01/24 11:09:14 nonaka Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -366,30 +366,63 @@ acpi_md_ncpus(void)
static bool
acpi_md_mcfg_validate(uint64_t addr, int bus_start, int *bus_end)
{
- struct btinfo_memmap *bim;
+ union {
+ struct btinfo_common *common;
+ struct btinfo_memmap *bios;
+ struct btinfo_efimemmap *efi;
+ } bim;
uint64_t size, mapaddr, mapsize;
uint32_t type;
- int i, n;
+ int i, n, num;
+ bool efimemmap;
- bim = lookup_bootinfo(BTINFO_MEMMAP);
- if (bim == NULL)
- return false;
+ bim.common = lookup_bootinfo(BTINFO_EFIMEMMAP);
+ if (bim.common == NULL) {
+ bim.common = lookup_bootinfo(BTINFO_MEMMAP);
+ if (bim.common == NULL)
+ return false;
+ }
+ efimemmap = bim.common->type == BTINFO_EFIMEMMAP;
+ num = efimemmap ? bim.efi->num : bim.bios->num;
size = *bus_end - bus_start + 1;
size *= ACPIMCFG_SIZE_PER_BUS;
- for (i = 0; i < bim->num; i++) {
- mapaddr = bim->entry[i].addr;
- mapsize = bim->entry[i].size;
- type = bim->entry[i].type;
-
- aprint_debug("MCFG: MEMMAP: 0x%016" PRIx64 "-0x%016" PRIx64
- ", size=0x%016" PRIx64 ", type=%d(%s)\n",
- mapaddr, mapaddr + mapsize - 1, mapsize, type,
- (type == BIM_Memory) ? "Memory" :
- (type == BIM_Reserved) ? "Reserved" :
- (type == BIM_ACPI) ? "ACPI" :
- (type == BIM_NVS) ? "NVS" :
- "unknown");
+ for (i = 0; i < num; i++) {
+#ifndef XEN
+ if (efimemmap) {
+ struct efi_md *md = (struct efi_md *)
+ (bim.efi->memmap + bim.efi->size * i);
+ mapaddr = md->md_phys;
+ mapsize = md->md_pages * EFI_PAGE_SIZE;
+ type = efi_getbiosmemtype(md->md_type, md->md_attr);
+
+ aprint_debug("MCFG: MEMMAP: "
+ "p0x%016" PRIx64 "-0x%016" PRIx64
+ ", v0x%016" PRIx64 "-0x%016" PRIx64
+ ", size=0x%016" PRIx64 ", attr=0x%016" PRIx64
+ ", type=%d(%s)\n",
+ mapaddr, mapaddr + mapsize - 1,
+ (uint64_t)(u_long)md->md_virt,
+ (uint64_t)(u_long)md->md_virt + mapsize - 1,
+ size, md->md_attr, md->md_type,
+ efi_getmemtype_str(md->md_type));
+ } else
+#endif
+ {
+ mapaddr = bim.bios->entry[i].addr;
+ mapsize = bim.bios->entry[i].size;
+ type = bim.bios->entry[i].type;
+
+ aprint_debug("MCFG: MEMMAP: 0x%016" PRIx64
+ "-0x%016" PRIx64 ", size=0x%016" PRIx64
+ ", type=%d(%s)\n",
+ mapaddr, mapaddr + mapsize - 1, mapsize, type,
+ (type == BIM_Memory) ? "Memory" :
+ (type == BIM_Reserved) ? "Reserved" :
+ (type == BIM_ACPI) ? "ACPI" :
+ (type == BIM_NVS) ? "NVS" :
+ "unknown");
+ }
switch (type) {
case BIM_ACPI:
Index: src/sys/arch/x86/include/bootinfo.h
diff -u src/sys/arch/x86/include/bootinfo.h:1.24 src/sys/arch/x86/include/bootinfo.h:1.25
--- src/sys/arch/x86/include/bootinfo.h:1.24 Thu Jan 28 01:09:56 2016
+++ src/sys/arch/x86/include/bootinfo.h Tue Jan 24 11:09:14 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: bootinfo.h,v 1.24 2016/01/28 01:09:56 christos Exp $ */
+/* $NetBSD: bootinfo.h,v 1.25 2017/01/24 11:09:14 nonaka Exp $ */
/*
* Copyright (c) 1997
@@ -39,10 +39,11 @@
#define BTINFO_FRAMEBUFFER 12
#define BTINFO_USERCONFCOMMANDS 13
#define BTINFO_EFI 14
+#define BTINFO_EFIMEMMAP 15
#define BTINFO_STR "bootpath", "rootdevice", "bootdisk", "netif", \
"console", "biosgeom", "symtab", "memmap", "bootwedge", "modulelist", \
- "framebuffer", "userconfcommands", "efi",
+ "framebuffer", "userconfcommands", "efi", "efimemmap",
#ifndef _LOCORE
@@ -221,7 +222,18 @@ struct btinfo_userconfcommands {
/* EFI Information */
struct btinfo_efi {
struct btinfo_common common;
- paddr_t bi_systbl; /* Physical address of the EFI System Table */
+ uint64_t systblpa; /* Physical address of the EFI System Table */
+ uint32_t flags;
+#define BI_EFI_32BIT __BIT(0) /* 32bit UEFI */
+ uint8_t reserved[12];
+};
+
+struct btinfo_efimemmap {
+ struct btinfo_common common;
+ uint32_t num; /* number of memory descriptor */
+ uint32_t version; /* version of memory descriptor */
+ uint32_t size; /* size of memory descriptor */
+ uint8_t memmap[1]; /* whole memory descriptors */
};
#endif /* _LOCORE */
Index: src/sys/arch/x86/include/efi.h
diff -u src/sys/arch/x86/include/efi.h:1.1 src/sys/arch/x86/include/efi.h:1.2
--- src/sys/arch/x86/include/efi.h:1.1 Thu Jan 28 01:09:56 2016
+++ src/sys/arch/x86/include/efi.h Tue Jan 24 11:09:14 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: efi.h,v 1.1 2016/01/28 01:09:56 christos Exp $ */
+/* $NetBSD: efi.h,v 1.2 2017/01/24 11:09:14 nonaka Exp $ */
/*-
* Copyright (c) 2004 Marcel Moolenaar
@@ -56,7 +56,7 @@ typedef unsigned long efi_status;
struct efi_cfgtbl {
struct uuid ct_uuid;
- uint64_t ct_data;
+ void *ct_data;
};
struct efi_md {
uint32_t md_type;
@@ -143,17 +143,19 @@ struct efi_systbl {
#define EFI_SYSTBL_SIG 0x5453595320494249UL
efi_char *st_fwvendor;
uint32_t st_fwrev;
+#ifdef __amd64__
uint32_t __pad;
+#endif
void *st_cin;
void *st_cinif;
void *st_cout;
void *st_coutif;
void *st_cerr;
void *st_cerrif;
- uint64_t st_rt;
+ struct efi_rt *st_rt;
void *st_bs;
u_long st_entries;
- uint64_t st_cfgtbl;
+ struct efi_cfgtbl *st_cfgtbl;
};
bool efi_probe(void);
@@ -161,6 +163,8 @@ paddr_t efi_getsystblpa(void)
struct efi_systbl *efi_getsystbl(void);
paddr_t efi_getcfgtblpa(const struct uuid*);
void *efi_getcfgtbl(const struct uuid*);
+int efi_getbiosmemtype(uint32_t, uint64_t);
+const char *efi_getmemtype_str(uint32_t);
/*
void efi_boot_finish(void);
int efi_boot_minimal(uint64_t);
Index: src/sys/arch/x86/x86/efi.c
diff -u src/sys/arch/x86/x86/efi.c:1.4 src/sys/arch/x86/x86/efi.c:1.5
--- src/sys/arch/x86/x86/efi.c:1.4 Wed Aug 24 10:27:23 2016
+++ src/sys/arch/x86/x86/efi.c Tue Jan 24 11:09:14 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: efi.c,v 1.4 2016/08/24 10:27:23 nonaka Exp $ */
+/* $NetBSD: efi.c,v 1.5 2017/01/24 11:09:14 nonaka Exp $ */
/*-
* Copyright (c) 2016 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -25,7 +25,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: efi.c,v 1.4 2016/08/24 10:27:23 nonaka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: efi.c,v 1.5 2017/01/24 11:09:14 nonaka Exp $");
#include <sys/kmem.h>
#include <sys/param.h>
#include <sys/systm.h>
@@ -62,6 +62,7 @@ void efi_aprintcfgtbl(void);
void efi_aprintuuid(const struct uuid *);
bool efi_uuideq(const struct uuid *, const struct uuid *);
+static bool efi_is32bit = false;
static struct efi_systbl *efi_systbl_va = NULL;
static struct efi_cfgtbl *efi_cfgtblhead_va = NULL;
@@ -173,7 +174,7 @@ efi_aprintcfgtbl(void)
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);
+ aprint_debug("efi: %p", ct->ct_data);
efi_aprintuuid(&ct->ct_uuid);
aprint_debug("\n");
}
@@ -226,7 +227,15 @@ efi_getsystblpa(void)
/* Unable to locate the EFI System Table. */
return 0;
}
- pa = bi->bi_systbl;
+ if (bi->common.len > 16 && (bi->flags & BI_EFI_32BIT)) {
+ /* 32Bit UEFI */
+ if (sizeof(paddr_t) == 4 &&
+ (bi->systblpa & 0xffffffff00000000ULL))
+ /* Unable to access EFI System Table. */
+ return 0;
+ efi_is32bit = true;
+ }
+ pa = (paddr_t)bi->systblpa;
return pa;
}
@@ -259,7 +268,7 @@ efi_getsystbl(void)
* XXX Also print fwvendor, which is an UCS-2 string (use
* some UTF-16 routine?)
*/
- aprint_debug("efi: runtime services at pa %" PRIx64 "\n",
+ aprint_debug("efi: runtime services at pa %p\n",
systbl->st_rt);
aprint_debug("efi: boot services at pa %p\n",
systbl->st_bs);
@@ -285,3 +294,58 @@ efi_probe(void)
}
return true;
}
+
+int
+efi_getbiosmemtype(uint32_t type, uint64_t attr)
+{
+
+ switch (type) {
+ case EFI_MD_TYPE_CODE:
+ case EFI_MD_TYPE_DATA:
+ case EFI_MD_TYPE_BS_CODE:
+ case EFI_MD_TYPE_BS_DATA:
+ case EFI_MD_TYPE_FREE:
+ return (attr & EFI_MD_ATTR_WB) ? BIM_Memory : BIM_Reserved;
+
+ case EFI_MD_TYPE_RECLAIM:
+ return BIM_ACPI;
+
+ case EFI_MD_TYPE_FIRMWARE:
+ return BIM_NVS;
+
+ case EFI_MD_TYPE_NULL:
+ case EFI_MD_TYPE_RT_CODE:
+ case EFI_MD_TYPE_RT_DATA:
+ case EFI_MD_TYPE_BAD:
+ case EFI_MD_TYPE_IOMEM:
+ case EFI_MD_TYPE_IOPORT:
+ case EFI_MD_TYPE_PALCODE:
+ return BIM_Reserved;
+ }
+ return BIM_Reserved;
+}
+
+const char *
+efi_getmemtype_str(uint32_t type)
+{
+ static const char *efimemtypes[] = {
+ "Reserved",
+ "LoaderCode",
+ "LoaderData",
+ "BootServicesCode",
+ "BootServicesData",
+ "RuntimeServicesCode",
+ "RuntimeServicesData",
+ "ConventionalMemory",
+ "UnusableMemory",
+ "ACPIReclaimMemory",
+ "ACPIMemoryNVS",
+ "MemoryMappedIO",
+ "MemoryMappedIOPortSpace",
+ "PalCode",
+ };
+
+ if (type < __arraycount(efimemtypes))
+ return efimemtypes[type];
+ return "unknown";
+}
Index: src/sys/arch/x86/x86/x86_machdep.c
diff -u src/sys/arch/x86/x86/x86_machdep.c:1.81 src/sys/arch/x86/x86/x86_machdep.c:1.82
--- src/sys/arch/x86/x86/x86_machdep.c:1.81 Tue Jan 10 09:48:22 2017
+++ src/sys/arch/x86/x86/x86_machdep.c Tue Jan 24 11:09:14 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: x86_machdep.c,v 1.81 2017/01/10 09:48:22 cherry Exp $ */
+/* $NetBSD: x86_machdep.c,v 1.82 2017/01/24 11:09:14 nonaka Exp $ */
/*-
* Copyright (c) 2002, 2006, 2007 YAMAMOTO Takashi,
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.81 2017/01/10 09:48:22 cherry Exp $");
+__KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.82 2017/01/24 11:09:14 nonaka Exp $");
#include "opt_modular.h"
#include "opt_physmem.h"
@@ -54,6 +54,7 @@ __KERNEL_RCSID(0, "$NetBSD: x86_machdep.
#include <x86/cpuvar.h>
#include <x86/cputypes.h>
+#include <x86/efi.h>
#include <x86/machdep.h>
#include <x86/nmi.h>
#include <x86/pio.h>
@@ -628,28 +629,63 @@ x86_add_cluster(struct extent *iomem_ex,
}
static int
-x86_parse_clusters(struct btinfo_memmap *bim, struct extent *iomem_ex)
+x86_parse_clusters(struct btinfo_common *bi, struct extent *iomem_ex)
{
+ union {
+ struct btinfo_common *common;
+ struct btinfo_memmap *bios;
+ struct btinfo_efimemmap *efi;
+ } bim;
uint64_t seg_start, seg_end;
uint64_t addr, size;
uint32_t type;
- int x;
+ int x, num;
+ bool efimemmap;
- KASSERT(bim != NULL);
- KASSERT(bim->num > 0);
+ KASSERT(bi != NULL);
+ bim.common = bi;
+ efimemmap = bi->type == BTINFO_EFIMEMMAP;
+ num = efimemmap ? bim.efi->num : bim.bios->num;
+ KASSERT(num > 0);
#ifdef DEBUG_MEMLOAD
- printf("BIOS MEMORY MAP (%d ENTRIES):\n", bim->num);
+ printf("MEMMAP: %s MEMORY MAP (%d ENTRIES):\n",
+ efimemmap ? "UEFI" : "BIOS", num);
#endif
- for (x = 0; x < bim->num; x++) {
- addr = bim->entry[x].addr;
- size = bim->entry[x].size;
- type = bim->entry[x].type;
+ for (x = 0; x < num; x++) {
+ if (efimemmap) {
+ struct efi_md *md = (struct efi_md *)
+ (bim.efi->memmap + bim.efi->size * x);
+ addr = md->md_phys;
+ size = md->md_pages * EFI_PAGE_SIZE;
+ type = efi_getbiosmemtype(md->md_type, md->md_attr);
#ifdef DEBUG_MEMLOAD
- printf(" addr 0x%"PRIx64" size 0x%"PRIx64" type 0x%x\n",
- addr, size, type);
+ printf("MEMMAP: p0x%016" PRIx64 "-0x%016" PRIx64
+ ", v0x%016" PRIx64 "-0x%016" PRIx64
+ ", size=0x%016" PRIx64 ", attr=0x%016" PRIx64
+ ", type=%d(%s)\n",
+ addr, addr + size - 1,
+ (uint64_t)md->md_virt,
+ (uint64_t)md->md_virt + size - 1,
+ size, md->md_attr, md->md_type,
+ efi_getmemtype_str(md->md_type));
#endif
+ } else {
+ addr = bim.bios->entry[x].addr;
+ size = bim.bios->entry[x].size;
+ type = bim.bios->entry[x].type;
+#ifdef DEBUG_MEMLOAD
+ printf("MEMMAP: 0x%016" PRIx64 "-0x%016" PRIx64
+ ", size=0x%016" PRIx64 ", type=%d(%s)\n",
+ addr, addr + size - 1, size, type,
+ (type == BIM_Memory) ? "Memory" :
+ (type == BIM_Reserved) ? "Reserved" :
+ (type == BIM_ACPI) ? "ACPI" :
+ (type == BIM_NVS) ? "NVS" :
+ "unknown");
+#endif
+ }
/* If the segment is not memory, skip it. */
switch (type) {
@@ -808,7 +844,8 @@ void
init_x86_clusters(void)
{
extern struct extent *iomem_ex;
- struct btinfo_memmap *bim;
+ struct btinfo_memmap *bim = NULL;
+ struct btinfo_efimemmap *biem;
/*
* Check to see if we have a memory map from the BIOS (passed to us by
@@ -816,17 +853,23 @@ init_x86_clusters(void)
*/
#ifdef i386
extern int biosmem_implicit;
- bim = lookup_bootinfo(BTINFO_MEMMAP);
+ biem = lookup_bootinfo(BTINFO_EFIMEMMAP);
+ if (biem == NULL)
+ bim = lookup_bootinfo(BTINFO_MEMMAP);
if ((biosmem_implicit || (biosbasemem == 0 && biosextmem == 0)) &&
- bim != NULL && bim->num > 0)
- x86_parse_clusters(bim, iomem_ex);
+ ((bim != NULL && bim->num > 0) || (biem != NULL && biem->num > 0)))
+ x86_parse_clusters(biem != NULL ? &biem->common : &bim->common,
+ iomem_ex);
#else
#if !defined(REALBASEMEM) && !defined(REALEXTMEM)
- bim = lookup_bootinfo(BTINFO_MEMMAP);
- if (bim != NULL && bim->num > 0)
- x86_parse_clusters(bim, iomem_ex);
+ biem = lookup_bootinfo(BTINFO_EFIMEMMAP);
+ if (biem == NULL)
+ bim = lookup_bootinfo(BTINFO_MEMMAP);
+ if ((bim != NULL && bim->num > 0) || (biem != NULL && biem->num > 0))
+ x86_parse_clusters(biem != NULL ? &biem->common : &bim->common,
+ iomem_ex);
#else
- (void)bim, (void)iomem_ex;
+ (void)bim, (void)biem, (void)iomem_ex;
#endif
#endif
Index: src/sys/lib/libgnuefi/Makefile
diff -u src/sys/lib/libgnuefi/Makefile:1.4 src/sys/lib/libgnuefi/Makefile:1.5
--- src/sys/lib/libgnuefi/Makefile:1.4 Tue Mar 22 08:25:23 2016
+++ src/sys/lib/libgnuefi/Makefile Tue Jan 24 11:09:14 2017
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.4 2016/03/22 08:25:23 mrg Exp $
+# $NetBSD: Makefile,v 1.5 2017/01/24 11:09:14 nonaka Exp $
LIB= gnuefi
LIBISPRIVATE?= yes
@@ -8,21 +8,47 @@ GNUEFI_INCLUDE_NET?= yes # Netboot via
GNUEFI_USE_LOADFILE?= no # Generic executable loading support
GNUEFI_ENABLE_LS_OP?= no # Filesystems ls operation
+GNUEFIDIST= ${GNUEFIDIR}/../../external/bsd/gnu-efi/dist
+
CPPFLAGS= -I${GNUEFIDIR} ${GNUEFICPPFLAGS} ${GNUEFIMISCCPPFLAGS}
-.if ${MACHINE_ARCH} == "i386"
+.if defined(GNUEFI_EXTRADIR)
+.-include "${GNUEFI_EXTRADIR}/Makefile.inc"
+.endif
+
+.include <bsd.own.mk>
+
+LIBGNUEFI_ARCH?= ${MACHINE_ARCH}
+LIBGNUEFI_CPU?= ${MACHINE_CPU}
+
+.if ${LIBGNUEFI_ARCH} == "i386"
GNUEFIARCH=ia32
.else
-GNUEFIARCH=${MACHINE_ARCH}
+GNUEFIARCH=${LIBGNUEFI_ARCH}
.endif
-.if defined(GNUEFI_EXTRADIR)
-.-include "${GNUEFI_EXTRADIR}/Makefile.inc"
+.if defined(LIBGNUEFI_ARCH) && !empty(LIBGNUEFI_ARCH) && \
+ exists(${GNUEFIDIR}/arch/${LIBGNUEFI_ARCH})
+ARCHSUBDIR= ${LIBGNUEFI_ARCH}
+.elif defined(MACHINE_ARCH) && !empty(MACHINE_ARCH) && \
+ exists(${GNUEFIDIR}/arch/${MACHINE_ARCH})
+ARCHSUBDIR= ${MACHINE_ARCH}
+.elif defined(MACHINE_CPU) && !empty(MACHINE_CPU) && \
+ exists(${GNUEFIDIR}/arch/${MACHINE_CPU})
+ARCHSUBDIR= ${MACHINE_CPU}
.endif
-.include <bsd.own.mk>
+M= ${GNUEFIDIR}/arch/${ARCHSUBDIR}
+
+.if exists($M/Makefile.inc)
+CPPFLAGS+= -I$M
+.PATH.c: $M
+.PATH.S: $M
+.include "$M/Makefile.inc"
+.endif
-.PATH.c: ${GNUEFIDIR} ${GNUEFIDIR}/../../external/bsd/gnu-efi/dist/lib/${GNUEFIARCH} ${GNUEFIDIR}/../../external/bsd/gnu-efi/dist/lib ${GNUEFIDIR}/../../external/bsd/gnu-efi/dist/lib/runtime
+.PATH.c: ${GNUEFIDIR} ${GNUEFIDIST}/lib/${GNUEFIARCH} ${GNUEFIDIST}/lib ${GNUEFIDIST}/lib/runtime
+.PATH.S: ${GNUEFIDIR} ${GNUEFIDIST}/lib/${GNUEFIARCH} ${GNUEFIDIST}/lib ${GNUEFIDIST}/lib/runtime
SRCS+= boxdraw.c smbios.c console.c crc.c data.c debug.c dpath.c \
error.c event.c guid.c hand.c hw.c init.c lock.c \
@@ -33,9 +59,11 @@ SRCS+= boxdraw.c smbios.c console.c crc.
COPTS.boxdraw.c= -Wno-missing-field-initializers
COPTS.guid.c= -Wno-missing-field-initializers
COPTS.smbios.c= -Wno-int-to-pointer-cast
-COPTS.dpath.c= -Wno-missing-prototypes
+COPTS.dpath.c= -Wno-missing-prototypes -Wno-unused-but-set-variable
COPTS.print.c= -Wno-missing-prototypes
-COPTS.hw.c= -Wno-shadow
+COPTS.hw.c= -Wno-shadow -Wno-unused-but-set-variable
+COPTS.event.c= -Wno-unused-but-set-variable
+COPTS.hand.c= -Wno-unused-but-set-variable
.include <bsd.lib.mk>
Index: src/sys/lib/libgnuefi/Makefile.inc
diff -u src/sys/lib/libgnuefi/Makefile.inc:1.3 src/sys/lib/libgnuefi/Makefile.inc:1.4
--- src/sys/lib/libgnuefi/Makefile.inc:1.3 Tue Mar 22 08:25:23 2016
+++ src/sys/lib/libgnuefi/Makefile.inc Tue Jan 24 11:09:14 2017
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile.inc,v 1.3 2016/03/22 08:25:23 mrg Exp $
+# $NetBSD: Makefile.inc,v 1.4 2017/01/24 11:09:14 nonaka Exp $
#
# Configuration variables (default values are below):
#
@@ -47,6 +47,7 @@ GNUEFIMAKE= \
MACHINE=${MACHINE} MACHINE_ARCH=${MACHINE_ARCH:Q} \
GNUEFICPPFLAGS=${CPPFLAGS:S@^-I.@-I${GNUEFIDOTDIR}@g:Q} \
GNUEFIMISCCPPFLAGS=${GNUEFIMISCCPPFLAGS:Q} \
+ LIBGNUEFI_ARCH=${LIBGNUEFI_ARCH:Q} \
${GNUEFIMISCMAKEFLAGS}
${GNUEFILIB}: .NOTMAIN .MAKE __always_make_gnuefilib
Added files:
Index: src/sys/arch/i386/stand/efiboot/Makefile
diff -u /dev/null src/sys/arch/i386/stand/efiboot/Makefile:1.1
--- /dev/null Tue Jan 24 11:09:15 2017
+++ src/sys/arch/i386/stand/efiboot/Makefile Tue Jan 24 11:09:14 2017
@@ -0,0 +1,6 @@
+# $NetBSD: Makefile,v 1.1 2017/01/24 11:09:14 nonaka Exp $
+
+SUBDIR= bootx64
+SUBDIR+= bootia32
+
+.include <bsd.subdir.mk>
Index: src/sys/arch/i386/stand/efiboot/Makefile.efiboot
diff -u /dev/null src/sys/arch/i386/stand/efiboot/Makefile.efiboot:1.1
--- /dev/null Tue Jan 24 11:09:15 2017
+++ src/sys/arch/i386/stand/efiboot/Makefile.efiboot Tue Jan 24 11:09:14 2017
@@ -0,0 +1,133 @@
+# $NetBSD: Makefile.efiboot,v 1.1 2017/01/24 11:09:14 nonaka Exp $
+
+S= ${.CURDIR}/../../../../..
+
+NOMAN= # defined
+PROG?= boot.efi
+NEWVERSWHAT?= "EFI Boot"
+VERSIONFILE?= ${.CURDIR}/../version
+
+AFLAGS.start.S= ${${ACTIVE_CC} == "clang":?-no-integrated-as:}
+
+SOURCES?= start.S conf.c devopen.c efiboot.c self_reloc.c
+LIBI386SRCS= boot.c biosdisk.c bootinfo.c bootinfo_biosgeom.c
+LIBI386SRCS+= bootmenu.c boot_params.S diskbuf.c exec.c menuutils.c
+LIBI386SRCS+= panic.c parseutils.c pread.c
+LIBI386SRCS+= eficons.c efidelay.c efidisk.c efidisk_ll.c efigetsecs.c
+LIBI386SRCS+= efimemory.c
+SRCS= ${SOURCES} ${EXTRA_SOURCES} ${LIBI386SRCS}
+.if !make(depend)
+SRCS+= vers.c
+.endif
+
+PIE_CFLAGS=
+PIE_LDFLAGS=
+PIE_AFLAGS=
+
+.include <bsd.own.mk>
+
+STRIPFLAG= # nothing
+
+LIBCRT0= # nothing
+LIBCRTI= # nothing
+LIBCRTBEGIN= # nothing
+LIBCRTEND= # nothing
+LIBC= # nothing
+
+BINDIR=/usr/mdec
+BINMODE=444
+
+.PATH: ${.CURDIR} ${.CURDIR}/..
+.PATH: ${.CURDIR}/../../lib
+
+LDSCRIPT?= ${.CURDIR}/ldscript
+LDFLAGS+= -nostdlib -T${LDSCRIPT} -Bsymbolic -shared -nocombreloc
+CPPFLAGS+= -I$S -I${.CURDIR} -I${.CURDIR}/.. -I$S/lib/libsa
+CPPFLAGS+= -I${.OBJDIR}
+CPPFLAGS+= -I${.CURDIR}/../../lib
+
+COPTS+= -ffreestanding -fPIC -fshort-wchar -fno-strict-aliasing -fno-builtin
+COPTS+= -fno-stack-protector -falign-functions=16
+CPPFLAGS+= -nostdinc -D_STANDALONE
+CPPFLAGS+= -DEFIBOOT
+
+CPPFLAGS+= -Wall -Wmissing-prototypes
+CPPFLAGS+= -Wno-pointer-sign
+
+CPPFLAGS+= -DEFI_ALLOCATE_MAX_ADDRESS=0x100000000ULL
+CPPFLAGS+= -DHEAP_VARIABLE
+CPPFLAGS+= -DSUPPORT_CD9660
+CPPFLAGS+= -DSUPPORT_DOSFS
+CPPFLAGS+= -DSUPPORT_EXT2FS
+CPPFLAGS+= -DPASS_BIOSGEOM
+CPPFLAGS+= -DPASS_MEMMAP
+CPPFLAGS+= -DLIBSA_ENABLE_LS_OP
+
+EFIDIR= ${S}/external/bsd/gnu-efi/dist
+GNUEFIARCH?= ${MACHINE_CPU}
+CPPFLAGS+= -I${EFIDIR}/inc -I${EFIDIR}/inc/${GNUEFIARCH}
+CPPFLAGS+= -I${EFIDIR}/inc/protocol
+
+SAMISCCPPFLAGS+= -DLIBSA_PRINTF_LONGLONG_SUPPORT
+SAMISCCPPFLAGS+= -DLIBSA_PRINTF_WIDTH_SUPPORT
+SAMISCMAKEFLAGS+= SA_USE_CREAD=yes # Read compressed kernels
+SAMISCMAKEFLAGS+= SA_INCLUDE_NET=no # Netboot via TFTP, NFS
+
+### find out what to use for libsa
+SA_AS= library
+SAMISCMAKEFLAGS+="SA_USE_LOADFILE=yes"
+SAMISCMAKEFLAGS+="SA_ENABLE_LS_OP=yes"
+.include "${S}/lib/libsa/Makefile.inc"
+LIBSA= ${SALIB}
+
+### find out what to use for libkern
+KERN_AS= library
+LIBKERN_ARCH?= ${MACHINE_ARCH}
+KERNMISCMAKEFLAGS+="LIBKERN_ARCH=${LIBKERN_ARCH}"
+.include "${S}/lib/libkern/Makefile.inc"
+LIBKERN= ${KERNLIB}
+
+### find out what to use for libz
+Z_AS= library
+.include "${S}/lib/libz/Makefile.inc"
+LIBZ= ${ZLIB}
+
+### find out what to use for libgnuefi
+GNUEFI_AS= library
+LIBGNUEFI_ARCH?= ${MACHINE_ARCH}
+GNUEFIMISCMAKEFLAGS+="LIBGNUEFI_ARCH=${LIBGNUEFI_ARCH}"
+GNUEFIMISCCPPFLAGS+= -I${EFIDIR}/lib
+.include "${S}/lib/libgnuefi/Makefile.inc"
+LIBGNUEFI= ${GNUEFILIB}
+
+cleandir distclean: .WAIT cleanlibdir
+
+cleanlibdir:
+ -rm -rf lib
+
+LIBLIST= ${LIBGNUEFI} ${LIBSA} ${LIBZ} ${LIBKERN} ${LIBSA}
+
+CLEANFILES+= vers.c
+
+vers.c: ${VERSIONFILE} ${SOURCES} ${LIBLIST} ${.CURDIR}/../Makefile.efiboot
+ ${HOST_SH} ${S}/conf/newvers_stand.sh ${VERSIONFILE} x86 ${NEWVERSWHAT}
+
+CLEANFILES+= ${PROG}.so ${PROG}.tmp
+
+${PROG}: ${PROG}.so
+ ${OBJCOPY} -j .text -j .sdata -j .data -j .dynamic -j .dynsym \
+ -j .rel -j .rel.* -j .rela -j .rela.* -j .reloc \
+ --subsystem efi-app --target=${OBJFMT} ${PROG}.so ${.TARGET}
+
+.include <bsd.prog.mk>
+
+${PROG}.so: ${OBJS} ${LIBLIST} ${LDSCRIPT} ${.CURDIR}/../Makefile.efiboot
+ ${LD} ${LDFLAGS} -o ${.TARGET}.tmp ${OBJS} ${LIBLIST}
+ @if ${OBJDUMP} -t ${.TARGET}.tmp | grep 'UND'; then \
+ (echo Undefined symbols; false); \
+ fi
+ rm -f ${.TARGET}
+ mv ${.TARGET}.tmp ${.TARGET}
+
+KLINK_MACHINE?= ${MACHINE}
+.include <bsd.klinks.mk>
Index: src/sys/arch/i386/stand/efiboot/boot.c
diff -u /dev/null src/sys/arch/i386/stand/efiboot/boot.c:1.1
--- /dev/null Tue Jan 24 11:09:15 2017
+++ src/sys/arch/i386/stand/efiboot/boot.c Tue Jan 24 11:09:14 2017
@@ -0,0 +1,619 @@
+/* $NetBSD: boot.c,v 1.1 2017/01/24 11:09:14 nonaka Exp $ */
+
+/*-
+ * Copyright (c) 2016 Kimihiro Nonaka <[email protected]>
+ * 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 REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ */
+
+#include "efiboot.h"
+
+#include <sys/bootblock.h>
+#include <sys/boot_flag.h>
+
+#include <lib/libsa/bootcfg.h>
+
+#include <bootmod.h>
+#include <bootmenu.h>
+#include "devopen.h"
+
+int errno;
+int boot_biosdev;
+daddr_t boot_biossector;
+
+extern const char bootprog_name[], bootprog_rev[], bootprog_kernrev[];
+
+extern struct x86_boot_params boot_params;
+extern char twiddle_toggle;
+
+static const char * const names[][2] = {
+ { "netbsd", "netbsd.gz" },
+ { "onetbsd", "onetbsd.gz" },
+ { "netbsd.old", "netbsd.old.gz" },
+};
+
+#define NUMNAMES __arraycount(names)
+#define DEFFILENAME names[0][0]
+
+#define MAXDEVNAME 16
+
+void command_help(char *);
+void command_quit(char *);
+void command_boot(char *);
+void command_consdev(char *);
+void command_dev(char *);
+void command_devpath(char *);
+void command_efivar(char *);
+void command_gop(char *);
+#if LIBSA_ENABLE_LS_OP
+void command_ls(char *);
+#endif
+void command_memmap(char *);
+#ifndef SMALL
+void command_menu(char *);
+#endif
+void command_modules(char *);
+void command_multiboot(char *);
+void command_text(char *);
+void command_version(char *);
+
+const struct bootblk_command commands[] = {
+ { "help", command_help },
+ { "?", command_help },
+ { "quit", command_quit },
+ { "boot", command_boot },
+ { "consdev", command_consdev },
+ { "dev", command_dev },
+ { "devpath", command_devpath },
+ { "efivar", command_efivar },
+ { "fs", fs_add },
+ { "gop", command_gop },
+ { "load", module_add },
+#if LIBSA_ENABLE_LS_OP
+ { "ls", command_ls },
+#endif
+ { "memmap", command_memmap },
+#ifndef SMALL
+ { "menu", command_menu },
+#endif
+ { "modules", command_modules },
+ { "multiboot", command_multiboot },
+ { "rndseed", rnd_add },
+ { "splash", splash_add },
+ { "text", command_text },
+ { "userconf", userconf_add },
+ { "version", command_version },
+ { NULL, NULL },
+};
+
+static char *default_devname;
+static int default_unit, default_partition;
+static const char *default_filename;
+
+static char *sprint_bootsel(const char *);
+static void bootit(const char *, int);
+
+int
+parsebootfile(const char *fname, char **fsname, char **devname, int *unit,
+ int *partition, const char **file)
+{
+ const char *col;
+
+ *fsname = "ufs";
+ *devname = default_devname;
+ *unit = default_unit;
+ *partition = default_partition;
+ *file = default_filename;
+
+ if (fname == NULL)
+ return 0;
+
+ if ((col = strchr(fname, ':')) != NULL) { /* device given */
+ static char savedevname[MAXDEVNAME+1];
+ int devlen;
+ int u = 0, p = 0;
+ int i = 0;
+
+ devlen = col - fname;
+ if (devlen > MAXDEVNAME)
+ return EINVAL;
+
+#define isvalidname(c) ((c) >= 'a' && (c) <= 'z')
+ if (!isvalidname(fname[i]))
+ return EINVAL;
+ do {
+ savedevname[i] = fname[i];
+ i++;
+ } while (isvalidname(fname[i]));
+ savedevname[i] = '\0';
+
+#define isnum(c) ((c) >= '0' && (c) <= '9')
+ if (i < devlen) {
+ if (!isnum(fname[i]))
+ return EUNIT;
+ do {
+ u *= 10;
+ u += fname[i++] - '0';
+ } while (isnum(fname[i]));
+ }
+
+#define isvalidpart(c) ((c) >= 'a' && (c) <= 'z')
+ if (i < devlen) {
+ if (!isvalidpart(fname[i]))
+ return EPART;
+ p = fname[i++] - 'a';
+ }
+
+ if (i != devlen)
+ return ENXIO;
+
+ *devname = savedevname;
+ *unit = u;
+ *partition = p;
+ fname = col + 1;
+ }
+
+ if (*fname)
+ *file = fname;
+
+ return 0;
+}
+
+static char *
+sprint_bootsel(const char *filename)
+{
+ char *fsname, *devname;
+ int unit, partition;
+ const char *file;
+ static char buf[80];
+
+ if (parsebootfile(filename, &fsname, &devname, &unit,
+ &partition, &file) == 0) {
+ snprintf(buf, sizeof(buf), "%s%d%c:%s", devname, unit,
+ 'a' + partition, file);
+ return buf;
+ }
+ return "(invalid)";
+}
+
+void
+clearit(void)
+{
+
+ if (bootcfg_info.clear)
+ clear_pc_screen();
+}
+
+static void
+bootit(const char *filename, int howto)
+{
+
+ if (howto & AB_VERBOSE)
+ printf("booting %s (howto 0x%x)\n", sprint_bootsel(filename),
+ howto);
+
+ if (exec_netbsd(filename, 0, howto, 0, efi_cleanup) < 0)
+ printf("boot: %s: %s\n", sprint_bootsel(filename),
+ strerror(errno));
+ else
+ printf("boot returned\n");
+}
+
+void
+print_banner(void)
+{
+ int n;
+
+ clearit();
+ if (bootcfg_info.banner[0]) {
+ for (n = 0; n < BOOTCFG_MAXBANNER && bootcfg_info.banner[n];
+ n++)
+ printf("%s\n", bootcfg_info.banner[n]);
+ } else
+ command_version("short");
+}
+
+void
+boot(void)
+{
+ int currname;
+ int c;
+
+ boot_modules_enabled = !(boot_params.bp_flags & X86_BP_FLAGS_NOMODULES);
+
+ /* try to set default device to what BIOS tells us */
+ bios2dev(boot_biosdev, boot_biossector, &default_devname, &default_unit,
+ &default_partition);
+
+ /* if the user types "boot" without filename */
+ default_filename = DEFFILENAME;
+
+ if (!(boot_params.bp_flags & X86_BP_FLAGS_NOBOOTCONF)) {
+ parsebootconf(BOOTCFG_FILENAME);
+ } else {
+ bootcfg_info.timeout = boot_params.bp_timeout;
+ }
+
+ /*
+ * If console set in boot.cfg, switch to it.
+ * This will print the banner, so we don't need to explicitly do it
+ */
+ if (bootcfg_info.consdev)
+ command_consdev(bootcfg_info.consdev);
+ else
+ print_banner();
+
+ /* Display the menu, if applicable */
+ twiddle_toggle = 0;
+ if (bootcfg_info.nummenu > 0) {
+ /* Does not return */
+ doboottypemenu();
+ }
+
+ printf("Press return to boot now, any other key for boot menu\n");
+ for (currname = 0; currname < NUMNAMES; currname++) {
+ printf("booting %s - starting in ",
+ sprint_bootsel(names[currname][0]));
+
+ c = awaitkey((bootcfg_info.timeout < 0) ? 0
+ : bootcfg_info.timeout, 1);
+ if ((c != '\r') && (c != '\n') && (c != '\0')) {
+ if ((boot_params.bp_flags & X86_BP_FLAGS_PASSWORD) == 0) {
+ /* do NOT ask for password */
+ bootmenu(); /* does not return */
+ } else {
+ /* DO ask for password */
+ if (check_password((char *)boot_params.bp_password)) {
+ /* password ok */
+ printf("type \"?\" or \"help\" for help.\n");
+ bootmenu(); /* does not return */
+ } else {
+ /* bad password */
+ printf("Wrong password.\n");
+ currname = 0;
+ continue;
+ }
+ }
+ }
+
+ /*
+ * try pairs of names[] entries, foo and foo.gz
+ */
+ /* don't print "booting..." again */
+ bootit(names[currname][0], 0);
+ /* since it failed, try compressed bootfile. */
+ bootit(names[currname][1], AB_VERBOSE);
+ }
+
+ bootmenu(); /* does not return */
+}
+
+/* ARGSUSED */
+void
+command_help(char *arg)
+{
+
+ printf("commands are:\n"
+ "boot [xdNx:][filename] [-12acdqsvxz]\n"
+ " (ex. \"hd0a:netbsd.old -s\"\n"
+ "dev [xd[N[x]]:]\n"
+ "consdev {pc|com[0123]|com[0123]kbd|auto}\n"
+ "devpath\n"
+ "efivar\n"
+ "gop [{modenum|list}]\n"
+ "load {path_to_module}\n"
+#if LIBSA_ENABLE_LS_OP
+ "ls [path]\n"
+#endif
+ "memmap [{sorted|unsorted}]\n"
+#ifndef SMALL
+ "menu (reenters boot menu, if defined in boot.cfg)\n"
+#endif
+ "modules {on|off|enabled|disabled}\n"
+ "multiboot [xdNx:][filename] [<args>]\n"
+ "rndseed {path_to_rndseed_file}\n"
+ "splash {path_to_image_file}\n"
+ "text [{modenum|list}]\n"
+ "userconf {command}\n"
+ "version\n"
+ "help|?\n"
+ "quit\n");
+}
+
+#if LIBSA_ENABLE_LS_OP
+void
+command_ls(char *arg)
+{
+ const char *save = default_filename;
+
+ default_filename = "/";
+ ls(arg);
+ default_filename = save;
+}
+#endif
+
+/* ARGSUSED */
+void
+command_quit(char *arg)
+{
+
+ printf("Exiting...\n");
+ delay(1 * 1000 * 1000);
+ reboot();
+ /* Note: we shouldn't get to this point! */
+ panic("Could not reboot!");
+}
+
+void
+command_boot(char *arg)
+{
+ char *filename;
+ int howto;
+
+ if (!parseboot(arg, &filename, &howto))
+ return;
+
+ if (filename != NULL) {
+ bootit(filename, howto);
+ } else {
+ int i;
+
+ if (howto == 0)
+ bootdefault();
+ for (i = 0; i < NUMNAMES; i++) {
+ bootit(names[i][0], howto);
+ bootit(names[i][1], howto);
+ }
+ }
+}
+
+void
+command_dev(char *arg)
+{
+ static char savedevname[MAXDEVNAME + 1];
+ char *fsname, *devname;
+ const char *file; /* dummy */
+
+ if (*arg == '\0') {
+ biosdisk_probe();
+ printf("default %s%d%c\n", default_devname, default_unit,
+ 'a' + default_partition);
+ return;
+ }
+
+ if (strchr(arg, ':') == NULL ||
+ parsebootfile(arg, &fsname, &devname, &default_unit,
+ &default_partition, &file)) {
+ command_help(NULL);
+ return;
+ }
+
+ /* put to own static storage */
+ strncpy(savedevname, devname, MAXDEVNAME + 1);
+ default_devname = savedevname;
+}
+
+/* ARGSUSED */
+void
+command_consdev(char *arg)
+{
+
+ /* XXX not implemented yet */
+}
+
+#ifndef SMALL
+/* ARGSUSED */
+void
+command_menu(char *arg)
+{
+
+ if (bootcfg_info.nummenu > 0) {
+ /* Does not return */
+ doboottypemenu();
+ } else
+ printf("No menu defined in boot.cfg\n");
+}
+#endif /* !SMALL */
+
+void
+command_modules(char *arg)
+{
+
+ if (strcmp(arg, "enabled") == 0 ||
+ strcmp(arg, "on") == 0)
+ boot_modules_enabled = true;
+ else if (strcmp(arg, "disabled") == 0 ||
+ strcmp(arg, "off") == 0)
+ boot_modules_enabled = false;
+ else
+ printf("invalid flag, must be 'enabled' or 'disabled'.\n");
+}
+
+void
+command_multiboot(char *arg)
+{
+ char *filename;
+
+ filename = arg;
+ if (exec_multiboot(filename, gettrailer(arg)) < 0)
+ printf("multiboot: %s: %s\n", sprint_bootsel(filename),
+ strerror(errno));
+ else
+ printf("boot returned\n");
+}
+
+void
+command_version(char *arg)
+{
+
+ if (strcmp(arg, "full") == 0) {
+ printf("ImageBase: 0x%" PRIxPTR "\n",
+ (uintptr_t)efi_li->ImageBase);
+ printf("Stack: 0x%" PRIxPTR "\n", efi_main_sp);
+ printf("EFI version: %d.%02d\n",
+ ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff);
+ Print(L"EFI Firmware: %s (rev %d.%02d)\n", ST->FirmwareVendor,
+ ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff);
+ }
+
+ printf("\n"
+ ">> %s, Revision %s (from NetBSD %s)\n"
+ ">> Memory: %d/%d k\n",
+ bootprog_name, bootprog_rev, bootprog_kernrev,
+ getbasemem(), getextmem());
+}
+
+void
+command_memmap(char *arg)
+{
+ bool sorted = true;
+
+ if (*arg == '\0' || strcmp(arg, "sorted") == 0)
+ /* Already sorted is true. */;
+ else if (strcmp(arg, "unsorted") == 0)
+ sorted = false;
+ else {
+ printf("invalid flag, "
+ "must be 'sorted' or 'unsorted'.\n");
+ return;
+ }
+
+ efi_memory_show_map(sorted);
+}
+
+void
+command_devpath(char *arg)
+{
+ EFI_STATUS status;
+ UINTN i, nhandles;
+ EFI_HANDLE *handles;
+ EFI_DEVICE_PATH *dp0, *dp;
+ CHAR16 *path;
+ UINTN cols, rows, row = 0;
+
+ status = uefi_call_wrapper(ST->ConOut->QueryMode, 4, ST->ConOut,
+ ST->ConOut->Mode->Mode, &cols, &rows);
+ if (EFI_ERROR(status) || rows <= 2)
+ rows = 0;
+ else
+ rows -= 2;
+
+ /*
+ * all devices.
+ */
+ status = LibLocateHandle(ByProtocol, &DevicePathProtocol, NULL,
+ &nhandles, &handles);
+ if (EFI_ERROR(status))
+ return;
+
+ for (i = 0; i < nhandles; i++) {
+ status = uefi_call_wrapper(BS->HandleProtocol, 3, handles[i],
+ &DevicePathProtocol, (void **)&dp0);
+ if (EFI_ERROR(status))
+ break;
+
+ Print(L"DevicePathType %d\n", DevicePathType(dp0));
+ for (dp = dp0;
+ !IsDevicePathEnd(dp);
+ dp = NextDevicePathNode(dp)) {
+ path = DevicePathToStr(dp);
+ Print(L"%d:%d:%s\n", DevicePathType(dp), DevicePathSubType(dp), path);
+ FreePool(path);
+
+ if (rows >= 0 && ++row >= rows) {
+ row = 0;
+ Print(L"Press Any Key to continue :");
+ (void) awaitkey(-1, 0);
+ Print(L"\n");
+ }
+ }
+ }
+}
+
+void
+command_efivar(char *arg)
+{
+ static const CHAR16 header[] =
+ L"GUID Variable Name Value\n"
+ L"=================================== ==================== ========\n";
+ EFI_STATUS status;
+ UINTN sz = 64;
+ CHAR16 *name = NULL, *tmp, *val;
+ EFI_GUID vendor;
+ UINTN cols, rows, row = 0;
+
+ status = uefi_call_wrapper(ST->ConOut->QueryMode, 4, ST->ConOut,
+ ST->ConOut->Mode->Mode, &cols, &rows);
+ if (EFI_ERROR(status) || rows <= 2)
+ rows = 0;
+ else
+ rows -= 2;
+
+ name = AllocatePool(sz);
+ if (name == NULL) {
+ Print(L"memory allocation failed: %ld bytes\n",
+ (UINT64)sz);
+ return;
+ }
+
+ name[0] = 0;
+ vendor = NullGuid;
+
+ Print(L"%s", header);
+ for (;;) {
+ status = uefi_call_wrapper(RT->GetNextVariableName, 3,
+ &sz, name, &vendor);
+ if (EFI_ERROR(status)) {
+ if (status == EFI_NOT_FOUND)
+ break;
+ if (status != EFI_BUFFER_TOO_SMALL) {
+ Print(L"GetNextVariableName failed: %r\n",
+ status);
+ break;
+ }
+
+ tmp = AllocatePool(sz);
+ if (tmp == NULL) {
+ Print(L"memory allocation failed: %ld bytes\n",
+ (UINT64)sz);
+ break;
+ }
+ FreePool(name);
+ name = tmp;
+ }
+
+ val = LibGetVariable(name, &vendor);
+ Print(L"%.-35g %.-20s %s\n", &vendor, name,
+ val ? val : L"(null)");
+ FreePool(val);
+
+ if (rows >= 0 && ++row >= rows) {
+ row = 0;
+ Print(L"Press Any Key to continue :");
+ (void) awaitkey(-1, 0);
+ Print(L"\n");
+ }
+ }
+
+ FreePool(name);
+}
Index: src/sys/arch/i386/stand/efiboot/conf.c
diff -u /dev/null src/sys/arch/i386/stand/efiboot/conf.c:1.1
--- /dev/null Tue Jan 24 11:09:15 2017
+++ src/sys/arch/i386/stand/efiboot/conf.c Tue Jan 24 11:09:14 2017
@@ -0,0 +1,69 @@
+/* $NetBSD: conf.c,v 1.1 2017/01/24 11:09:14 nonaka Exp $ */
+
+/*
+ * Copyright (c) 1997
+ * Matthias Drochner. 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.
+ */
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+#include <lib/libsa/stand.h>
+#include <lib/libsa/ufs.h>
+#include <lib/libsa/lfs.h>
+#ifdef SUPPORT_EXT2FS
+#include <lib/libsa/ext2fs.h>
+#endif
+#ifdef SUPPORT_MINIXFS3
+#include <lib/libsa/minixfs3.h>
+#endif
+#ifdef SUPPORT_DOSFS
+#include <lib/libsa/dosfs.h>
+#endif
+#ifdef SUPPORT_CD9660
+#include <lib/libsa/cd9660.h>
+#endif
+#include <biosdisk.h>
+
+struct devsw devsw[] = {
+ { "disk", biosdisk_strategy, biosdisk_open, biosdisk_close, biosdisk_ioctl },
+};
+int ndevs = __arraycount(devsw);
+
+struct fs_ops file_system[] = {
+#ifdef SUPPORT_CD9660
+ FS_OPS(cd9660),
+#endif
+ FS_OPS(ffsv1), FS_OPS(ffsv2),
+ FS_OPS(lfsv1), FS_OPS(lfsv2),
+#ifdef SUPPORT_EXT2FS
+ FS_OPS(ext2fs),
+#endif
+#ifdef SUPPORT_MINIXFS3
+ FS_OPS(minixfs3),
+#endif
+#ifdef SUPPORT_DOSFS
+ FS_OPS(dosfs),
+#endif
+};
+int nfsys = __arraycount(file_system);
Index: src/sys/arch/i386/stand/efiboot/devopen.c
diff -u /dev/null src/sys/arch/i386/stand/efiboot/devopen.c:1.1
--- /dev/null Tue Jan 24 11:09:15 2017
+++ src/sys/arch/i386/stand/efiboot/devopen.c Tue Jan 24 11:09:14 2017
@@ -0,0 +1,110 @@
+/* $NetBSD: devopen.c,v 1.1 2017/01/24 11:09:14 nonaka Exp $ */
+
+/*-
+ * Copyright (c) 2005 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Bang Jun-Young.
+ *
+ * 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``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 FOUNDATION OR CONTRIBUTORS
+ * 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.
+ */
+
+/*
+ * Copyright (c) 1996, 1997
+ * Matthias Drochner. 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.
+ */
+
+#include "efiboot.h"
+
+#include <biosdisk.h>
+#include "devopen.h"
+#include <bootinfo.h>
+
+static int
+dev2bios(char *devname, int unit, int *biosdev)
+{
+
+ if (strcmp(devname, "hd") == 0)
+ *biosdev = 0x80 + unit;
+ else
+ return ENXIO;
+ return 0;
+}
+
+void
+bios2dev(int biosdev, daddr_t sector, char **devname, int *unit, int *partition)
+{
+
+ *unit = biosdev & 0x7f;
+ *devname = "hd";
+ *partition = biosdisk_findpartition(biosdev, sector);
+}
+
+struct btinfo_bootpath bibp;
+extern bool kernel_loaded;
+
+/*
+ * Open the EFI disk device
+ */
+int
+devopen(struct open_file *f, const char *fname, char **file)
+{
+ char *fsname, *devname;
+ int unit, partition;
+ int biosdev;
+ int error;
+
+ if ((error = parsebootfile(fname, &fsname, &devname,
+ &unit, &partition, (const char **) file))
+ || (error = dev2bios(devname, unit, &biosdev)))
+ return error;
+
+ f->f_dev = &devsw[0]; /* must be biosdisk */
+
+ if (!kernel_loaded) {
+ strncpy(bibp.bootpath, *file, sizeof(bibp.bootpath));
+ BI_ADD(&bibp, BTINFO_BOOTPATH, sizeof(bibp));
+ }
+
+ return biosdisk_open(f, biosdev, partition);
+}
Index: src/sys/arch/i386/stand/efiboot/devopen.h
diff -u /dev/null src/sys/arch/i386/stand/efiboot/devopen.h:1.1
--- /dev/null Tue Jan 24 11:09:15 2017
+++ src/sys/arch/i386/stand/efiboot/devopen.h Tue Jan 24 11:09:14 2017
@@ -0,0 +1,31 @@
+/* $NetBSD: devopen.h,v 1.1 2017/01/24 11:09:14 nonaka Exp $ */
+
+/*-
+ * Copyright (c) 2016 Kimihiro Nonaka <[email protected]>
+ * 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 REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ */
+
+extern int boot_biosdev;
+
+void bios2dev(int, daddr_t, char **, int *, int *);
Index: src/sys/arch/i386/stand/efiboot/efiboot.c
diff -u /dev/null src/sys/arch/i386/stand/efiboot/efiboot.c:1.1
--- /dev/null Tue Jan 24 11:09:15 2017
+++ src/sys/arch/i386/stand/efiboot/efiboot.c Tue Jan 24 11:09:14 2017
@@ -0,0 +1,137 @@
+/* $NetBSD: efiboot.c,v 1.1 2017/01/24 11:09:14 nonaka Exp $ */
+
+/*-
+ * Copyright (c) 2016 Kimihiro Nonaka <[email protected]>
+ * 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 REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ */
+
+#include "efiboot.h"
+
+#include "bootinfo.h"
+#include "devopen.h"
+
+EFI_HANDLE IH;
+EFI_DEVICE_PATH *efi_bootdp;
+EFI_LOADED_IMAGE *efi_li;
+uintptr_t efi_main_sp;
+
+static EFI_PHYSICAL_ADDRESS heap_start = EFI_ALLOCATE_MAX_ADDRESS;
+static UINTN heap_size = 1 * 1024 * 1024; /* 1MB */
+static struct btinfo_efi btinfo_efi;
+
+static void efi_heap_init(void);
+
+EFI_STATUS EFIAPI efi_main(EFI_HANDLE, EFI_SYSTEM_TABLE *);
+EFI_STATUS EFIAPI
+efi_main(EFI_HANDLE imageHandle, EFI_SYSTEM_TABLE *systemTable)
+{
+ EFI_STATUS status;
+ EFI_DEVICE_PATH *dp0, *dp;
+ extern char twiddle_toggle;
+
+ IH = imageHandle;
+ InitializeLib(IH, systemTable);
+
+ efi_main_sp = (uintptr_t)&status;
+ twiddle_toggle = 1; /* no twiddling until we're ready */
+
+ cninit();
+ efi_heap_init();
+ efi_md_init();
+
+ status = uefi_call_wrapper(BS->HandleProtocol, 3, IH,
+ &LoadedImageProtocol, (void **)&efi_li);
+ if (EFI_ERROR(status))
+ Panic(L"HandleProtocol(LoadedImageProtocol): %r", status);
+ status = uefi_call_wrapper(BS->HandleProtocol, 3, efi_li->DeviceHandle,
+ &DevicePathProtocol, (void **)&dp0);
+ if (EFI_ERROR(status))
+ Panic(L"HandleProtocol(DevicePathProtocol): %r", status);
+ for (dp = dp0; !IsDevicePathEnd(dp); dp = NextDevicePathNode(dp)) {
+ if (DevicePathType(dp) == MEDIA_DEVICE_PATH)
+ continue;
+ if (DevicePathSubType(dp) == MEDIA_HARDDRIVE_DP) {
+ boot_biosdev = 0x80;
+ efi_bootdp = dp;
+ break;
+ }
+ break;
+ }
+
+ efi_disk_probe();
+
+ status = uefi_call_wrapper(BS->SetWatchdogTimer, 4, 0, 0, 0, NULL);
+ if (EFI_ERROR(status))
+ Panic(L"SetWatchdogTimer: %r", status);
+
+ boot();
+
+ return EFI_SUCCESS;
+}
+
+void
+efi_cleanup(void)
+{
+ EFI_STATUS status;
+ EFI_MEMORY_DESCRIPTOR *desc;
+ UINTN NoEntries, MapKey, DescriptorSize;
+ UINT32 DescriptorVersion;
+
+ clearit();
+
+ memset(&btinfo_efi, 0, sizeof(btinfo_efi));
+ btinfo_efi.systblpa = (intptr_t)ST;
+#ifdef __i386__ /* bootia32.efi */
+ btinfo_efi.flags |= BI_EFI_32BIT;
+#endif
+ BI_ADD(&btinfo_efi, BTINFO_EFI, sizeof(btinfo_efi));
+
+ NoEntries = 0;
+ desc = LibMemoryMap(&NoEntries, &MapKey, &DescriptorSize,
+ &DescriptorVersion);
+ status = uefi_call_wrapper(BS->ExitBootServices, 2, IH, MapKey);
+ if (EFI_ERROR(status)) {
+ FreePool(desc);
+ desc = LibMemoryMap(&NoEntries, &MapKey, &DescriptorSize,
+ &DescriptorVersion);
+ status = uefi_call_wrapper(BS->ExitBootServices, 2, IH, MapKey);
+ if (EFI_ERROR(status))
+ Panic(L"ExitBootServices failed");
+ }
+}
+
+static void
+efi_heap_init(void)
+{
+ EFI_STATUS status;
+ u_int sz = EFI_SIZE_TO_PAGES(heap_size);
+
+ status = uefi_call_wrapper(BS->AllocatePages, 4, AllocateMaxAddress,
+ EfiLoaderData, sz, &heap_start);
+ if (EFI_ERROR(status))
+ Panic(L"%a: AllocatePages() failed: %d page(s): %r",
+ __func__, sz, status);
+ setheap((void *)(UINTN)heap_start,
+ (void *)(UINTN)(heap_start + heap_size));
+}
Index: src/sys/arch/i386/stand/efiboot/efiboot.h
diff -u /dev/null src/sys/arch/i386/stand/efiboot/efiboot.h:1.1
--- /dev/null Tue Jan 24 11:09:15 2017
+++ src/sys/arch/i386/stand/efiboot/efiboot.h Tue Jan 24 11:09:14 2017
@@ -0,0 +1,66 @@
+/* $NetBSD: efiboot.h,v 1.1 2017/01/24 11:09:14 nonaka Exp $ */
+
+/*-
+ * Copyright (c) 2016 Kimihiro Nonaka <[email protected]>
+ * 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 REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ */
+
+#include <efi.h>
+#include <efilib.h>
+
+#include <lib/libsa/stand.h>
+#include <lib/libkern/libkern.h>
+
+#include "libi386.h"
+
+#include "efiboot_machdep.h"
+
+extern EFI_GUID GraphicsOutputProtocol;
+
+/* boot.c */
+void boot(void);
+void clearit(void);
+void print_banner(void);
+
+/* efiboot.c */
+extern EFI_HANDLE IH;
+extern EFI_DEVICE_PATH *efi_bootdp;
+extern EFI_LOADED_IMAGE *efi_li;
+extern uintptr_t efi_main_sp;
+void efi_cleanup(void);
+
+/* eficons.c */
+int cninit(void);
+void command_text(char *);
+void command_gop(char *);
+
+/* efidisk.c */
+void efi_disk_probe(void);
+
+/* efimemory.c */
+void efi_memory_probe(void);
+void efi_memory_show_map(bool);
+
+/* panic.c */
+__dead VOID Panic(IN CHAR16 *, ...);
Index: src/sys/arch/i386/stand/efiboot/eficons.c
diff -u /dev/null src/sys/arch/i386/stand/efiboot/eficons.c:1.1
--- /dev/null Tue Jan 24 11:09:15 2017
+++ src/sys/arch/i386/stand/efiboot/eficons.c Tue Jan 24 11:09:14 2017
@@ -0,0 +1,557 @@
+/* $NetBSD: eficons.c,v 1.1 2017/01/24 11:09:14 nonaka Exp $ */
+
+/*-
+ * Copyright (c) 2016 Kimihiro Nonaka <[email protected]>
+ * 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 REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ */
+
+#include <sys/bitops.h>
+#include <sys/stdint.h>
+
+#include "efiboot.h"
+
+#include "bootinfo.h"
+#include "vbe.h"
+
+struct btinfo_console btinfo_console;
+
+static EFI_GRAPHICS_OUTPUT_PROTOCOL *efi_gop;
+static int efi_gop_mode = -1;
+
+static CHAR16 keybuf[16];
+static int keybuf_read = 0;
+static int keybuf_write = 0;
+
+static void eficons_init_video(void);
+static void efi_switch_video_to_text_mode(void);
+
+int
+cninit(void)
+{
+
+ efi_switch_video_to_text_mode();
+ eficons_init_video();
+
+ /* XXX serial console */
+ btinfo_console.devname[0] = 'p';
+ btinfo_console.devname[1] = 'c';
+ btinfo_console.devname[2] = 0;
+
+ return 0;
+}
+
+int
+getchar(void)
+{
+ EFI_STATUS status;
+ EFI_INPUT_KEY key;
+ int c;
+
+ if (keybuf_read != keybuf_write) {
+ c = keybuf[keybuf_read];
+ keybuf_read = (keybuf_read + 1) % __arraycount(keybuf);
+ return c;
+ }
+
+ status = uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn,
+ &key);
+ while (status == EFI_NOT_READY) {
+ WaitForSingleEvent(ST->ConIn->WaitForKey, 0);
+ status = uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2,
+ ST->ConIn, &key);
+ }
+ return key.UnicodeChar;
+}
+
+void
+putchar(int c)
+{
+ CHAR16 buf[2];
+
+ buf[1] = 0;
+ if (c == '\n') {
+ buf[0] = '\r';
+ Output(buf);
+ }
+ buf[0] = c;
+ Output(buf);
+}
+
+/*ARGSUSED*/
+int
+iskey(int intr)
+{
+ EFI_STATUS status;
+ EFI_INPUT_KEY key;
+
+ if (keybuf_read != keybuf_write)
+ return 1;
+
+ status = uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn,
+ &key);
+ if (EFI_ERROR(status))
+ return 0;
+
+ keybuf[keybuf_write] = key.UnicodeChar;
+ keybuf_write = (keybuf_write + 1) % __arraycount(keybuf);
+ return 1;
+}
+
+char
+awaitkey(int timeout, int tell)
+{
+ char c = 0;
+
+ for (;;) {
+ if (tell) {
+ char numbuf[32];
+ int len;
+
+ len = snprintf(numbuf, sizeof(numbuf), "%d seconds. ",
+ timeout);
+ if (len > 0 && len < sizeof(numbuf)) {
+ char *p = numbuf;
+
+ printf("%s", numbuf);
+ while (*p)
+ *p++ = '\b';
+ printf("%s", numbuf);
+ }
+ }
+ if (iskey(1)) {
+ /* flush input buffer */
+ while (iskey(0))
+ c = getchar();
+ if (c == 0)
+ c = -1;
+ goto out;
+ }
+ if (timeout--)
+ WaitForSingleEvent(ST->ConIn->WaitForKey, 10000000);
+ else
+ break;
+ }
+
+out:
+ if (tell)
+ printf("0 seconds. \n");
+
+ return c;
+}
+
+void
+clear_pc_screen(void)
+{
+
+ uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
+}
+
+static uint8_t
+getdepth(const EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info)
+{
+
+ switch (info->PixelFormat) {
+ case PixelBlueGreenRedReserved8BitPerColor:
+ case PixelRedGreenBlueReserved8BitPerColor:
+ return 32;
+
+ case PixelBitMask:
+ return fls32(info->PixelInformation.RedMask
+ | info->PixelInformation.GreenMask
+ | info->PixelInformation.BlueMask
+ | info->PixelInformation.ReservedMask);
+
+ case PixelBltOnly:
+ case PixelFormatMax:
+ return 0;
+ }
+ return 0;
+}
+
+static void
+setpixelformat(UINT32 mask, uint8_t *num, uint8_t *pos)
+{
+ uint8_t n, p;
+
+ n = popcount32(mask);
+ p = ffs32(mask);
+ if (p > 0)
+ p--;
+
+ *num = n;
+ *pos = p;
+}
+
+static void
+bi_framebuffer(void)
+{
+ EFI_STATUS status;
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info;
+ struct btinfo_framebuffer fb;
+ UINT64 res, bestres = 0;
+ UINTN sz;
+ UINT32 i;
+ INT32 bestmode = -1;
+
+ if (efi_gop == NULL) {
+ framebuffer_configure(NULL);
+ return;
+ }
+
+ if (efi_gop_mode >= 0) {
+ bestmode = efi_gop_mode;
+ } else {
+ /* XXX EDID? EFI_EDID_DISCOVERD_PROTOCOL */
+ for (i = 0; i < efi_gop->Mode->MaxMode; i++) {
+ status = uefi_call_wrapper(efi_gop->QueryMode, 4,
+ efi_gop, i, &sz, &info);
+ if (EFI_ERROR(status))
+ continue;
+
+ res = (UINT64)info->HorizontalResolution *
+ (UINT64)info->VerticalResolution *
+ (UINT64)getdepth(info);
+ if (res > bestres) {
+ bestmode = i;
+ bestres = res;
+ }
+ }
+ }
+ if (bestmode >= 0) {
+ status = uefi_call_wrapper(efi_gop->SetMode, 2, efi_gop,
+ bestmode);
+ if (EFI_ERROR(status) || efi_gop->Mode->Mode != bestmode)
+ Print(L"GOP setmode failed: %r\n", status);
+ }
+
+ info = efi_gop->Mode->Info;
+ memset(&fb, 0, sizeof(fb));
+ fb.physaddr = efi_gop->Mode->FrameBufferBase;
+ fb.flags = 0;
+ fb.width = info->HorizontalResolution;
+ fb.height = info->VerticalResolution;
+ fb.depth = getdepth(info);
+ fb.stride = info->PixelsPerScanLine * ((fb.depth + 7) / 8);
+ fb.vbemode = 0; /* XXX */
+
+ switch (info->PixelFormat) {
+ case PixelBlueGreenRedReserved8BitPerColor:
+ fb.rnum = 8;
+ fb.gnum = 8;
+ fb.bnum = 8;
+ fb.rpos = 16;
+ fb.gpos = 8;
+ fb.bpos = 0;
+ break;
+
+ case PixelRedGreenBlueReserved8BitPerColor:
+ fb.rnum = 8;
+ fb.gnum = 8;
+ fb.bnum = 8;
+ fb.rpos = 0;
+ fb.gpos = 8;
+ fb.bpos = 16;
+ break;
+
+ case PixelBitMask:
+ setpixelformat(info->PixelInformation.RedMask,
+ &fb.rnum, &fb.rpos);
+ setpixelformat(info->PixelInformation.GreenMask,
+ &fb.gnum, &fb.gpos);
+ setpixelformat(info->PixelInformation.BlueMask,
+ &fb.bnum, &fb.bpos);
+ break;
+
+ case PixelBltOnly:
+ case PixelFormatMax:
+ Panic(L"Error: invalid pixel format (%d)", info->PixelFormat);
+ break;
+ }
+
+ framebuffer_configure(&fb);
+}
+
+int
+vbe_commit(void)
+{
+
+ bi_framebuffer();
+ return 0;
+}
+
+static void
+print_text_modes(void)
+{
+ EFI_STATUS status;
+ UINTN cols, rows;
+ INT32 i, curmode;
+
+ curmode = ST->ConOut->Mode->Mode;
+ for (i = 0; i < ST->ConOut->Mode->MaxMode; i++) {
+ status = uefi_call_wrapper(ST->ConOut->QueryMode, 4,
+ ST->ConOut, i, &cols, &rows);
+ if (EFI_ERROR(status))
+ continue;
+ Print(L"%c%d: %dx%d\n", i == curmode ? '*' : ' ',
+ i, cols, rows);
+ }
+}
+
+static int
+efi_find_text_mode(char *arg)
+{
+ EFI_STATUS status;
+ UINTN cols, rows;
+ INT32 i;
+ char mode[32];
+
+ for (i = 0; i < ST->ConOut->Mode->MaxMode; i++) {
+ status = uefi_call_wrapper(ST->ConOut->QueryMode, 4,
+ ST->ConOut, i, &cols, &rows);
+ if (EFI_ERROR(status))
+ continue;
+ snprintf(mode, sizeof(mode), "%lux%lu", (long)cols, (long)rows);
+ if (strcmp(arg, mode) == 0)
+ return i;
+ }
+ return -1;
+}
+
+void
+command_text(char *arg)
+{
+ EFI_STATUS status;
+ INT32 modenum;
+
+ if (*arg == '\0' || strcmp(arg, "list") == 0) {
+ print_text_modes();
+ return;
+ }
+
+ if (strchr(arg, 'x') != NULL) {
+ modenum = efi_find_text_mode(arg);
+ if (modenum == -1) {
+ printf("mode %s not supported by firmware\n", arg);
+ return;
+ }
+ } else {
+ modenum = strtoul(arg, NULL, 0);
+ }
+
+ status = uefi_call_wrapper(ST->ConOut->SetMode, 2, ST->ConOut, modenum);
+ if (!EFI_ERROR(status))
+ return;
+
+ printf("invalid flag, must be 'list', a display mode, "
+ "or a mode number\n");
+}
+
+static int
+print_gop_modes(void)
+{
+ EFI_STATUS status;
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info;
+ UINTN sz;
+ UINT32 i;
+ uint8_t depth;
+
+ if (efi_gop == NULL)
+ return 1;
+
+ for (i = 0; i < efi_gop->Mode->MaxMode; i++) {
+ status = uefi_call_wrapper(efi_gop->QueryMode, 4, efi_gop, i,
+ &sz, &info);
+ if (EFI_ERROR(status) && status == EFI_NOT_STARTED) {
+ status = uefi_call_wrapper(efi_gop->SetMode, 2,
+ efi_gop, efi_gop->Mode->Mode);
+ status = uefi_call_wrapper(efi_gop->QueryMode, 4,
+ efi_gop, i, &sz, &info);
+ }
+ if (EFI_ERROR(status))
+ continue;
+
+ Print(L"%c%d: %dx%d ",
+ memcmp(info, efi_gop->Mode->Info, sizeof(*info)) == 0 ?
+ '*' : ' ',
+ i, info->HorizontalResolution, info->VerticalResolution);
+ switch (info->PixelFormat) {
+ case PixelRedGreenBlueReserved8BitPerColor:
+ Print(L"RGBR");
+ break;
+ case PixelBlueGreenRedReserved8BitPerColor:
+ Print(L"BGRR");
+ break;
+ case PixelBitMask:
+ Print(L"R:%08x G:%08x B:%08x X:%08x",
+ info->PixelInformation.RedMask,
+ info->PixelInformation.GreenMask,
+ info->PixelInformation.BlueMask,
+ info->PixelInformation.ReservedMask);
+ break;
+ case PixelBltOnly:
+ Print(L"(blt only)");
+ break;
+ default:
+ Print(L"(Invalid pixel format)");
+ break;
+ }
+ Print(L" pitch %d", info->PixelsPerScanLine);
+ depth = getdepth(info);
+ if (depth > 0)
+ Print(L" bpp %d", depth);
+ Print(L"\n");
+ }
+
+ return 0;
+}
+
+static int
+efi_find_gop_mode(char *arg)
+{
+ EFI_STATUS status;
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info;
+ UINTN sz;
+ UINT32 i;
+ char mode[32];
+ uint8_t depth;
+
+ for (i = 0; i < efi_gop->Mode->MaxMode; i++) {
+ status = uefi_call_wrapper(efi_gop->QueryMode, 4, efi_gop, i,
+ &sz, &info);
+ if (EFI_ERROR(status))
+ continue;
+
+ depth = getdepth(info);
+ if (depth == 0)
+ continue;
+
+ snprintf(mode, sizeof(mode), "%lux%lux%u",
+ (long)info->HorizontalResolution,
+ (long)info->HorizontalResolution,
+ depth);
+ if (strcmp(arg, mode) == 0)
+ return i;
+ }
+ return -1;
+}
+
+void
+command_gop(char *arg)
+{
+ EFI_STATUS status;
+ INT32 modenum;
+
+ if (efi_gop == NULL) {
+ printf("GOP not supported by firmware\n");
+ return;
+ }
+
+ if (*arg == '\0' || strcmp(arg, "list") == 0) {
+ print_gop_modes();
+ return;
+ }
+
+ if (strchr(arg, 'x') != NULL) {
+ modenum = efi_find_gop_mode(arg);
+ if (modenum == -1) {
+ printf("mode %s not supported by firmware\n", arg);
+ return;
+ }
+ } else {
+ modenum = strtoul(arg, NULL, 0);
+ }
+
+ status = uefi_call_wrapper(efi_gop->SetMode, 2, efi_gop, modenum);
+ if (!EFI_ERROR(status) && efi_gop->Mode->Mode == modenum) {
+ efi_gop_mode = modenum;
+ return;
+ }
+
+ printf("invalid flag, must be 'list', a display mode, "
+ "or a mode number\n");
+}
+
+static void
+eficons_init_video(void)
+{
+ EFI_STATUS status;
+ UINTN cols, rows, dim = 0;
+ INT32 i, best = -1;
+
+ /*
+ * Setup text mode
+ */
+ uefi_call_wrapper(ST->ConOut->Reset, 2, ST->ConOut, TRUE);
+
+ for (i = 0; i < ST->ConOut->Mode->MaxMode; i++) {
+ status = uefi_call_wrapper(ST->ConOut->QueryMode, 4,
+ ST->ConOut, i, &cols, &rows);
+ if (EFI_ERROR(status))
+ continue;
+ if (dim < cols * rows) {
+ dim = cols * rows;
+ best = i;
+ }
+ }
+ if (best >= 0)
+ uefi_call_wrapper(ST->ConOut->SetMode, 2, ST->ConOut, best);
+ uefi_call_wrapper(ST->ConOut->EnableCursor, 2, ST->ConOut, TRUE);
+ uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
+
+ LibLocateProtocol(&GraphicsOutputProtocol, (void **)&efi_gop);
+}
+
+/*
+ * for Apple EFI
+ */
+#define CONSOLE_CONTROL_PROTOCOL \
+ {0xf42f7782, 0x12e, 0x4c12, {0x99, 0x56, 0x49, 0xf9, 0x43, 0x4, 0xf7, 0x21}}
+static EFI_GUID ConsoleControlProtocol = CONSOLE_CONTROL_PROTOCOL;
+
+struct _EFI_CONSOLE_CONTROL_INTERFACE;
+typedef struct _EFI_CONSOLE_CONTROL_INTERFACE EFI_CONSOLE_CONTROL_INTERFACE;
+typedef enum { EfiConsoleControlScreenText } EFI_CONSOLE_CONTROL_SCREEN_MODE;
+typedef EFI_STATUS (EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_SET_MODE) (
+ IN EFI_CONSOLE_CONTROL_INTERFACE *This,
+ IN EFI_CONSOLE_CONTROL_SCREEN_MODE Mode
+);
+struct _EFI_CONSOLE_CONTROL_INTERFACE {
+ VOID *GetMode;
+ EFI_CONSOLE_CONTROL_PROTOCOL_SET_MODE SetMode;
+ VOID *LockStdIn;
+};
+
+static void
+efi_switch_video_to_text_mode(void)
+{
+ EFI_STATUS status;
+ EFI_CONSOLE_CONTROL_INTERFACE *cci;
+
+ /* Set up the console, so printf works. */
+ status = LibLocateProtocol(&ConsoleControlProtocol, (void **)&cci);
+ if (!EFI_ERROR(status)) {
+ uefi_call_wrapper(cci->SetMode, 2, cci,
+ EfiConsoleControlScreenText);
+ }
+}
Index: src/sys/arch/i386/stand/efiboot/efidelay.c
diff -u /dev/null src/sys/arch/i386/stand/efiboot/efidelay.c:1.1
--- /dev/null Tue Jan 24 11:09:15 2017
+++ src/sys/arch/i386/stand/efiboot/efidelay.c Tue Jan 24 11:09:14 2017
@@ -0,0 +1,46 @@
+/* $NetBSD: efidelay.c,v 1.1 2017/01/24 11:09:14 nonaka Exp $ */
+
+/*-
+ * Copyright (c) 2016 Kimihiro Nonaka <[email protected]>
+ * 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 REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ */
+
+#include "efiboot.h"
+
+void
+delay(int us)
+{
+ EFI_STATUS status;
+
+ status = uefi_call_wrapper(BS->Stall, 1, us);
+ if (EFI_ERROR(status))
+ Panic(L"%a: couldn't delay %d us: %r\n", __func__, us, status);
+}
+
+void
+wait_sec(int sec)
+{
+ while (sec-- > 0)
+ delay(1000 * 1000);
+}
Index: src/sys/arch/i386/stand/efiboot/efidisk.c
diff -u /dev/null src/sys/arch/i386/stand/efiboot/efidisk.c:1.1
--- /dev/null Tue Jan 24 11:09:15 2017
+++ src/sys/arch/i386/stand/efiboot/efidisk.c Tue Jan 24 11:09:14 2017
@@ -0,0 +1,127 @@
+/* $NetBSD: efidisk.c,v 1.1 2017/01/24 11:09:14 nonaka Exp $ */
+
+/*-
+ * Copyright (c) 2016 Kimihiro Nonaka <[email protected]>
+ * 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 REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ */
+
+#include "efiboot.h"
+
+#include "efidisk.h"
+
+static struct efidiskinfo_lh efi_disklist;
+static int nefidisks;
+
+void
+efi_disk_probe(void)
+{
+ EFI_STATUS status;
+ UINTN i, nhandles;
+ EFI_HANDLE *handles;
+ EFI_BLOCK_IO *bio;
+ EFI_BLOCK_IO_MEDIA *media;
+ struct efidiskinfo *edi;
+ EFI_DEVICE_PATH *dp, *bdp;
+ bool bootdev;
+ int dev;
+
+ TAILQ_INIT(&efi_disklist);
+
+ status = LibLocateHandle(ByProtocol, &BlockIoProtocol, NULL,
+ &nhandles, &handles);
+ if (EFI_ERROR(status))
+ Panic(L"LocateHandle(BlockIoProtocol): %r", status);
+
+ for (i = 0; i < nhandles; i++) {
+ status = uefi_call_wrapper(BS->HandleProtocol, 3, handles[i],
+ &BlockIoProtocol, (void **)&bio);
+ if (EFI_ERROR(status))
+ Panic(L"HandleProtocol(BlockIoProtocol): %r", status);
+
+ media = bio->Media;
+ if (media->LogicalPartition || !media->MediaPresent)
+ continue;
+
+ edi = alloc(sizeof(struct efidiskinfo));
+ memset(edi, 0, sizeof(*edi));
+ edi->bio = bio;
+ edi->media_id = media->MediaId;
+
+ bootdev = false;
+ if (efi_bootdp == NULL)
+ goto next;
+
+ status = uefi_call_wrapper(BS->HandleProtocol, 3, handles[i],
+ &DevicePathProtocol, (void **)&dp);
+ if (EFI_ERROR(status))
+ goto next;
+
+ bdp = efi_bootdp;
+ for (;;) {
+ if (IsDevicePathEnd(dp)) {
+ bootdev = true;
+ break;
+ }
+ if (memcmp(dp, bdp, sizeof(EFI_DEVICE_PATH)) != 0 ||
+ memcmp(dp, bdp, DevicePathNodeLength(dp)) != 0)
+ break;
+ dp = NextDevicePathNode(dp);
+ bdp = NextDevicePathNode(bdp);
+ }
+next:
+ if (bootdev)
+ TAILQ_INSERT_HEAD(&efi_disklist, edi, list);
+ else
+ TAILQ_INSERT_TAIL(&efi_disklist, edi, list);
+ }
+
+ FreePool(handles);
+
+ dev = 0x80;
+ TAILQ_FOREACH(edi, &efi_disklist, list) {
+ edi->dev = dev++;
+ nefidisks++;
+ }
+}
+
+const struct efidiskinfo *
+efidisk_getinfo(int dev)
+{
+ const struct efidiskinfo *edi;
+
+ TAILQ_FOREACH(edi, &efi_disklist, list) {
+ if (dev == edi->dev)
+ return edi;
+ }
+ return NULL;
+}
+
+/*
+ * Return the number of hard disk drives.
+ */
+int
+get_harddrives(void)
+{
+ return nefidisks;
+}
Index: src/sys/arch/i386/stand/efiboot/efidisk.h
diff -u /dev/null src/sys/arch/i386/stand/efiboot/efidisk.h:1.1
--- /dev/null Tue Jan 24 11:09:15 2017
+++ src/sys/arch/i386/stand/efiboot/efidisk.h Tue Jan 24 11:09:14 2017
@@ -0,0 +1,40 @@
+/* $NetBSD: efidisk.h,v 1.1 2017/01/24 11:09:14 nonaka Exp $ */
+
+/*-
+ * Copyright (c) 2016 Kimihiro Nonaka <[email protected]>
+ * 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 REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ */
+
+#include <sys/queue.h>
+
+struct efidiskinfo {
+ TAILQ_ENTRY(efidiskinfo) list;
+
+ int dev;
+ EFI_BLOCK_IO *bio;
+ UINT32 media_id;
+};
+TAILQ_HEAD(efidiskinfo_lh, efidiskinfo);
+
+const struct efidiskinfo *efidisk_getinfo(int);
Index: src/sys/arch/i386/stand/efiboot/efidisk_ll.c
diff -u /dev/null src/sys/arch/i386/stand/efiboot/efidisk_ll.c:1.1
--- /dev/null Tue Jan 24 11:09:15 2017
+++ src/sys/arch/i386/stand/efiboot/efidisk_ll.c Tue Jan 24 11:09:14 2017
@@ -0,0 +1,200 @@
+/* $NetBSD: efidisk_ll.c,v 1.1 2017/01/24 11:09:14 nonaka Exp $ */
+/* NetBSD: biosdisk_ll.c,v 1.31 2011/02/21 02:58:02 jakllsch Exp */
+
+/*-
+ * Copyright (c) 2005 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Bang Jun-Young.
+ *
+ * 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``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 FOUNDATION OR CONTRIBUTORS
+ * 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.
+ */
+
+/*
+ * Copyright (c) 1996
+ * Matthias Drochner. All rights reserved.
+ * Copyright (c) 1996
+ * Perry E. Metzger. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgements:
+ * This product includes software developed for the NetBSD Project
+ * by Matthias Drochner.
+ * This product includes software developed for the NetBSD Project
+ * by Perry E. Metzger.
+ * 4. The names of the authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * 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.
+ */
+
+/*
+ * shared by bootsector startup (bootsectmain) and biosdisk.c
+ * needs lowlevel parts from bios_disk.S
+ */
+
+#include "efiboot.h"
+
+#include "biosdisk_ll.h"
+#include "diskbuf.h"
+#include "efidisk.h"
+
+static int do_read(struct biosdisk_ll *, daddr_t, int, char *);
+
+#ifndef BIOSDISK_RETRIES
+#define BIOSDISK_RETRIES 5
+#endif
+
+int
+set_geometry(struct biosdisk_ll *d, struct biosdisk_extinfo *ed)
+{
+ const struct efidiskinfo *edi;
+ EFI_BLOCK_IO_MEDIA *media;
+
+ edi = efidisk_getinfo(d->dev);
+ if (edi == NULL)
+ return 1;
+
+ media = edi->bio->Media;
+
+ d->secsize = media->BlockSize;
+ d->type = BIOSDISK_TYPE_HD;
+ d->flags = BIOSDISK_INT13EXT;
+
+ ed->totsec = media->LastBlock + 1;
+ ed->sbytes = media->BlockSize;
+ ed->flags = 0;
+ if (media->RemovableMedia)
+ ed->flags |= EXTINFO_REMOVABLE;
+
+ return 0;
+}
+
+/*
+ * Global shared "diskbuf" is used as read ahead buffer. For reading from
+ * floppies, the bootstrap has to be loaded on a 64K boundary to ensure that
+ * this buffer doesn't cross a 64K DMA boundary.
+ */
+static int ra_dev;
+static daddr_t ra_end;
+static daddr_t ra_first;
+
+static int
+do_read(struct biosdisk_ll *d, daddr_t dblk, int num, char *buf)
+{
+ EFI_STATUS status;
+ const struct efidiskinfo *edi;
+
+ edi = efidisk_getinfo(d->dev);
+ if (edi == NULL)
+ return -1;
+
+ status = uefi_call_wrapper(edi->bio->ReadBlocks, 5, edi->bio,
+ edi->media_id, dblk, num * d->secsize, buf);
+ if (EFI_ERROR(status))
+ return -1;
+ return num;
+}
+
+/*
+ * NB if 'cold' is set below not all of the program is loaded, so
+ * mustn't use data segment, bss, call library functions or do read-ahead.
+ */
+int
+readsects(struct biosdisk_ll *d, daddr_t dblk, int num, char *buf, int cold)
+{
+ while (num) {
+ int nsec;
+
+ /* check for usable data in read-ahead buffer */
+ if (cold || diskbuf_user != &ra_dev || d->dev != ra_dev
+ || dblk < ra_first || dblk >= ra_end) {
+
+ /* no, read from disk */
+ char *trbuf;
+ int maxsecs;
+ int retries = BIOSDISK_RETRIES;
+
+ if (cold) {
+ /* transfer directly to buffer */
+ trbuf = buf;
+ maxsecs = num;
+ } else {
+ /* fill read-ahead buffer */
+ trbuf = alloc_diskbuf(0); /* no data yet */
+ maxsecs = DISKBUFSIZE / d->secsize;
+ }
+
+ while ((nsec = do_read(d, dblk, maxsecs, trbuf)) < 0) {
+#ifdef DISK_DEBUG
+ if (!cold)
+ printf("read error dblk %"PRId64"-%"PRId64"\n",
+ dblk, (dblk + maxsecs - 1));
+#endif
+ if (--retries >= 0)
+ continue;
+ return -1; /* XXX cannot output here if
+ * (cold) */
+ }
+ if (!cold) {
+ ra_dev = d->dev;
+ ra_first = dblk;
+ ra_end = dblk + nsec;
+ diskbuf_user = &ra_dev;
+ }
+ } else /* can take blocks from end of read-ahead
+ * buffer */
+ nsec = ra_end - dblk;
+
+ if (!cold) {
+ /* copy data from read-ahead to user buffer */
+ if (nsec > num)
+ nsec = num;
+ memcpy(buf,
+ diskbufp + (dblk - ra_first) * d->secsize,
+ nsec * d->secsize);
+ }
+ buf += nsec * d->secsize;
+ num -= nsec;
+ dblk += nsec;
+ }
+
+ return 0;
+}
Index: src/sys/arch/i386/stand/efiboot/efigetsecs.c
diff -u /dev/null src/sys/arch/i386/stand/efiboot/efigetsecs.c:1.1
--- /dev/null Tue Jan 24 11:09:15 2017
+++ src/sys/arch/i386/stand/efiboot/efigetsecs.c Tue Jan 24 11:09:14 2017
@@ -0,0 +1,52 @@
+/* $NetBSD: efigetsecs.c,v 1.1 2017/01/24 11:09:14 nonaka Exp $ */
+
+/*
+ * Copyright (c) 2015 YASUOKA Masahiko <[email protected]>
+ *
+ * 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 "efiboot.h"
+
+#include <lib/libsa/net.h>
+
+satime_t
+getsecs(void)
+{
+ static const int daytab[][14] = {
+ { 0, -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364 },
+ { 0, -1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
+ };
+ EFI_TIME t;
+ satime_t r;
+ int y;
+#define isleap(_y) (((_y) % 4) == 0 && (((_y) % 100) != 0 || ((_y) % 400) == 0))
+
+ uefi_call_wrapper(RT->GetTime, 2, &t, NULL);
+
+ /* Calc days from UNIX epoch */
+ r = (t.Year - 1970) * 365;
+ for (y = 1970; y < t.Year; y++) {
+ if (isleap(y))
+ r++;
+ }
+ r += daytab[isleap(t.Year) ? 1 : 0][t.Month] + t.Day;
+
+ /* Calc secs */
+ r *= 60 * 60 * 24;
+ r += ((t.Hour * 60) + t.Minute) * 60 + t.Second;
+ if (-24 * 60 < t.TimeZone && t.TimeZone < 24 * 60)
+ r += t.TimeZone * 60;
+
+ return r;
+}
Index: src/sys/arch/i386/stand/efiboot/efimemory.c
diff -u /dev/null src/sys/arch/i386/stand/efiboot/efimemory.c:1.1
--- /dev/null Tue Jan 24 11:09:15 2017
+++ src/sys/arch/i386/stand/efiboot/efimemory.c Tue Jan 24 11:09:14 2017
@@ -0,0 +1,350 @@
+/* $NetBSD: efimemory.c,v 1.1 2017/01/24 11:09:14 nonaka Exp $ */
+
+/*-
+ * Copyright (c) 2016 Kimihiro Nonaka <[email protected]>
+ * 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 REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ */
+
+#include "efiboot.h"
+
+#include <bootinfo.h>
+
+static const char *memtypes[] = {
+ "unknown",
+ "available",
+ "reserved",
+ "ACPI reclaimable",
+ "ACPI NVS"
+};
+
+static const char *efimemtypes[] = {
+ "Reserved",
+ "LoaderCode",
+ "LoaderData",
+ "BootServicesCode",
+ "BootServicesData",
+ "RuntimeServicesCode",
+ "RuntimeServicesData",
+ "ConventionalMemory",
+ "UnusableMemory",
+ "ACPIReclaimMemory",
+ "ACPIMemoryNVS",
+ "MemoryMappedIO",
+ "MemoryMappedIOPortSpace",
+ "PalCode",
+};
+
+static int
+getmemtype(EFI_MEMORY_DESCRIPTOR *md)
+{
+
+ switch (md->Type) {
+ case EfiLoaderCode:
+ case EfiLoaderData:
+ case EfiBootServicesCode:
+ case EfiBootServicesData:
+ case EfiConventionalMemory:
+ return (md->Attribute & EFI_MEMORY_WB) ?
+ BIM_Memory : BIM_Reserved;
+
+ case EfiACPIReclaimMemory:
+ return BIM_ACPI;
+
+ case EfiACPIMemoryNVS:
+ return BIM_NVS;
+
+ case EfiReservedMemoryType:
+ case EfiRuntimeServicesCode:
+ case EfiRuntimeServicesData:
+ case EfiUnusableMemory:
+ case EfiMemoryMappedIO:
+ case EfiMemoryMappedIOPortSpace:
+ case EfiPalCode:
+ case EfiMaxMemoryType:
+ return BIM_Reserved;
+ }
+ return BIM_Reserved;
+}
+
+static EFI_MEMORY_DESCRIPTOR *
+GetMemoryMap(OUT UINTN *NoEntries, OUT UINTN *MapKey, OUT UINTN *DescriptorSize,
+ OUT UINT32 *DescriptorVersion, bool sorted)
+{
+ EFI_MEMORY_DESCRIPTOR *desc, *md, *next, *target, tmp;
+ UINTN i, j;
+
+ *NoEntries = 0;
+ desc = LibMemoryMap(NoEntries, MapKey, DescriptorSize,
+ DescriptorVersion);
+ if (desc == NULL)
+ Panic(L"LibMemoryMap failed");
+
+ if (!sorted)
+ return desc;
+
+ for (i = 0, md = desc; i < *NoEntries - 1; i++, md = next) {
+ target = next = NextMemoryDescriptor(md, *DescriptorSize);
+ for (j = i + 1; j < *NoEntries; j++) {
+ if (md->PhysicalStart > target->PhysicalStart) {
+ CopyMem(&tmp, md, sizeof(*md));
+ CopyMem(md, target, sizeof(*md));
+ CopyMem(target, &tmp, sizeof(*md));
+ }
+ target = NextMemoryDescriptor(target, *DescriptorSize);
+ }
+ }
+ return desc;
+}
+
+/*
+ * get memory size below 1MB
+ */
+int
+getbasemem(void)
+{
+ EFI_MEMORY_DESCRIPTOR *mdtop, *md, *next;
+ UINTN i, NoEntries, MapKey, DescriptorSize, MappingSize;
+ UINT32 DescriptorVersion;
+ EFI_PHYSICAL_ADDRESS basemem = 0, epa;
+
+ mdtop = GetMemoryMap(&NoEntries, &MapKey, &DescriptorSize,
+ &DescriptorVersion, true);
+
+ for (i = 0, md = mdtop; i < NoEntries; i++, md = next) {
+ next = NextMemoryDescriptor(md, DescriptorSize);
+ if (getmemtype(md) != BIM_Memory)
+ continue;
+ if (md->PhysicalStart >= 1 * 1024 * 1024)
+ continue;
+ if (basemem != md->PhysicalStart)
+ continue;
+
+ MappingSize = md->NumberOfPages * EFI_PAGE_SIZE;
+ epa = md->PhysicalStart + MappingSize;
+ if (epa == 0 || epa > 1 * 1024 * 1024)
+ epa = 1 * 1024 * 1024;
+ basemem = epa;
+ }
+
+ FreePool(mdtop);
+
+ return basemem / 1024; /* KiB */
+}
+
+/*
+ * get memory size above 1MB below 4GB
+ */
+int
+getextmemx(void)
+{
+ EFI_MEMORY_DESCRIPTOR *mdtop, *md, *next;
+ UINTN i, NoEntries, MapKey, DescriptorSize, MappingSize;
+ UINT32 DescriptorVersion;
+ EFI_PHYSICAL_ADDRESS extmem16m = 0; /* 0-16MB */
+ EFI_PHYSICAL_ADDRESS extmem4g = 0; /* 16MB-4GB */
+ EFI_PHYSICAL_ADDRESS pa, epa;
+ bool first16m = true, first4g = true;
+ int extmem;
+
+ mdtop = GetMemoryMap(&NoEntries, &MapKey, &DescriptorSize,
+ &DescriptorVersion, true);
+
+ for (i = 0, md = mdtop; i < NoEntries; i++, md = next) {
+ next = NextMemoryDescriptor(md, DescriptorSize);
+ if (getmemtype(md) == BIM_Reserved)
+ continue;
+ if (md->PhysicalStart >= 4 * 1024 * 1024 * 1024ULL)
+ continue;
+
+ MappingSize = md->NumberOfPages * EFI_PAGE_SIZE;
+ epa = md->PhysicalStart + MappingSize;
+ if (epa == 0 || epa > 4 * 1024 * 1024 * 1024LL)
+ epa = 4 * 1024 * 1024 * 1024LL;
+
+ if (epa <= 1 * 1024 * 1024)
+ continue;
+
+ pa = md->PhysicalStart;
+ if (pa < 16 * 1024 * 1024) {
+ if (first16m || extmem16m == pa) {
+ first16m = false;
+ if (epa >= 16 * 1024 * 1024) {
+ extmem16m = 16 * 1024 * 1024;
+ pa = 16 * 1024 * 1024;
+ } else
+ extmem16m = epa;
+ }
+ }
+ if (pa >= 16 * 1024 * 1024) {
+ if (first4g || extmem4g == pa) {
+ first4g = false;
+ extmem4g = epa;
+ }
+ }
+ }
+
+ FreePool(mdtop);
+
+ if (extmem16m > 1 * 1024 * 1024)
+ extmem16m -= 1 * 1024 * 1024; /* below 1MB */
+
+ extmem = extmem16m / 1024;
+ if (extmem == 15 * 1024)
+ extmem += extmem4g / 1024;
+ return extmem;
+}
+
+void
+efi_memory_probe(void)
+{
+ EFI_MEMORY_DESCRIPTOR *mdtop, *md, *next;
+ UINTN i, n, NoEntries, MapKey, DescriptorSize, MappingSize;
+ UINT32 DescriptorVersion;
+ int memtype;
+
+ mdtop = GetMemoryMap(&NoEntries, &MapKey, &DescriptorSize,
+ &DescriptorVersion, false);
+
+ Print(L" mem[");
+ for (i = 0, n = 0, md = mdtop; i < NoEntries; i++, md = next) {
+ next = NextMemoryDescriptor(md, DescriptorSize);
+
+ memtype = getmemtype(md);
+ if (memtype != BIM_Memory)
+ continue;
+
+ MappingSize = md->NumberOfPages * EFI_PAGE_SIZE;
+ if (MappingSize < 12 * 1024) /* XXX Why? from OpenBSD */
+ continue;
+
+ if (n++ > 0)
+ Print(L" ");
+ Print(L"0x%lx-0x%lx", md->PhysicalStart,
+ md->PhysicalStart + MappingSize - 1);
+ }
+ Print(L"]");
+
+ FreePool(mdtop);
+}
+
+void
+efi_memory_show_map(bool sorted)
+{
+ EFI_STATUS status;
+ EFI_MEMORY_DESCRIPTOR *mdtop, *md, *next;
+ UINTN i, NoEntries, MapKey, DescriptorSize;
+ UINT32 DescriptorVersion;
+ char memstr[32], efimemstr[32];
+ int memtype;
+ UINTN cols, rows, row = 0;
+
+ status = uefi_call_wrapper(ST->ConOut->QueryMode, 4, ST->ConOut,
+ ST->ConOut->Mode->Mode, &cols, &rows);
+ if (EFI_ERROR(status) || rows <= 2)
+ rows = 0;
+ else
+ rows -= 2;
+
+ mdtop = GetMemoryMap(&NoEntries, &MapKey, &DescriptorSize,
+ &DescriptorVersion, sorted);
+
+ for (i = 0, md = mdtop; i < NoEntries; i++, md = next) {
+ next = NextMemoryDescriptor(md, DescriptorSize);
+
+ memtype = getmemtype(md);
+ if (memtype >= __arraycount(memtypes))
+ snprintf(memstr, sizeof(memstr), "unknown (%d)",
+ memtype);
+ if (md->Type >= __arraycount(efimemtypes))
+ snprintf(efimemstr, sizeof(efimemstr), "unknown (%d)",
+ md->Type);
+ printf("%016" PRIxMAX "/%016" PRIxMAX ": %s [%s]\n",
+ (uintmax_t)md->PhysicalStart,
+ (uintmax_t)md->PhysicalStart +
+ md->NumberOfPages * EFI_PAGE_SIZE - 1,
+ memtype >= __arraycount(memtypes) ?
+ memstr : memtypes[memtype],
+ md->Type >= __arraycount(efimemtypes) ?
+ efimemstr : efimemtypes[md->Type]);
+
+ if (rows >= 0 && ++row >= rows) {
+ row = 0;
+ Print(L"Press Any Key to continue :");
+ (void) awaitkey(-1, 0);
+ Print(L"\n");
+ }
+ }
+
+ FreePool(mdtop);
+}
+
+void
+bi_getmemmap(void)
+{
+ EFI_MEMORY_DESCRIPTOR *md;
+ UINTN NoEntries, MapKey, DescriptorSize;
+ UINT32 DescriptorVersion;
+ struct btinfo_efimemmap *bim;
+ size_t allocsz;
+
+ md = GetMemoryMap(&NoEntries, &MapKey, &DescriptorSize,
+ &DescriptorVersion, true);
+
+ allocsz = sizeof(struct btinfo_efimemmap) - 1
+ + NoEntries * DescriptorSize;
+ bim = alloc(allocsz);
+
+ bim->num = NoEntries;
+ bim->version = DescriptorVersion;
+ bim->size = DescriptorSize;
+ memcpy(bim->memmap, md, NoEntries * DescriptorSize);
+
+ FreePool(md);
+
+ BI_ADD(bim, BTINFO_EFIMEMMAP, allocsz);
+}
+
+void
+vpbcopy(const void *va, void *pa, size_t n)
+{
+ memmove(pa, va, n);
+}
+
+void
+pvbcopy(const void *pa, void *va, size_t n)
+{
+ memmove(va, pa, n);
+}
+
+void
+pbzero(void *pa, size_t n)
+{
+ memset(pa, 0, n);
+}
+
+physaddr_t
+vtophys(void *va)
+{
+ return (physaddr_t)va;
+}
Index: src/sys/arch/i386/stand/efiboot/panic.c
diff -u /dev/null src/sys/arch/i386/stand/efiboot/panic.c:1.1
--- /dev/null Tue Jan 24 11:09:15 2017
+++ src/sys/arch/i386/stand/efiboot/panic.c Tue Jan 24 11:09:14 2017
@@ -0,0 +1,69 @@
+/* $NetBSD: panic.c,v 1.1 2017/01/24 11:09:14 nonaka Exp $ */
+
+/*-
+ * Copyright (c) 2016 Kimihiro Nonaka <[email protected]>
+ * 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 REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ */
+
+#include "efiboot.h"
+
+#include <efistdarg.h>
+
+/* from sys/external/bsd/gnu-efi/dist/lib/print.c */
+UINTN VPrint (IN CHAR16 *, va_list);
+
+__dead VOID
+Panic(
+ IN CHAR16 *fmt,
+ ...
+ )
+{
+ va_list args;
+
+ va_start(args, fmt);
+ VPrint(fmt, args);
+ Print(L"\n");
+ va_end(args);
+ reboot();
+ /*NOTREACHED*/
+}
+
+void
+reboot(void)
+{
+
+ WaitForSingleEvent(ST->ConIn->WaitForKey, 0);
+
+ uefi_call_wrapper(RT->ResetSystem, 4, EfiResetCold, EFI_SUCCESS,
+ 0, NULL);
+ for (;;)
+ continue;
+}
+
+void
+_rtt(void)
+{
+
+ reboot();
+}
Index: src/sys/arch/i386/stand/efiboot/self_reloc.c
diff -u /dev/null src/sys/arch/i386/stand/efiboot/self_reloc.c:1.1
--- /dev/null Tue Jan 24 11:09:15 2017
+++ src/sys/arch/i386/stand/efiboot/self_reloc.c Tue Jan 24 11:09:14 2017
@@ -0,0 +1,99 @@
+/* $NetBSD: self_reloc.c,v 1.1 2017/01/24 11:09:14 nonaka Exp $ */
+
+/*-
+ * Copyright (c) 2008-2010 Rui Paulo <[email protected]>
+ * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+ */
+
+#include <sys/types.h>
+#include <sys/exec_elf.h>
+
+#include <efi.h>
+
+void self_reloc(Elf_Addr, Elf_Dyn *);
+
+#if defined(__aarch64__)
+#define USE_RELA
+#endif
+
+/*
+ * A simple elf relocator.
+ */
+void
+self_reloc(Elf_Addr baseaddr, Elf_Dyn *dynamic)
+{
+ Elf_Word relsz, relent;
+ Elf_Addr *newaddr;
+ Elf_Rel *rel = NULL;
+ Elf_Dyn *dynp;
+
+ /*
+ * Find the relocation address, its size and the relocation entry.
+ */
+ relsz = 0;
+ relent = 0;
+ for (dynp = dynamic; dynp->d_tag != DT_NULL; dynp++) {
+ switch (dynp->d_tag) {
+ case DT_REL:
+ case DT_RELA:
+ rel = (Elf_Rel *)(dynp->d_un.d_ptr + baseaddr);
+ break;
+ case DT_RELSZ:
+ case DT_RELASZ:
+ relsz = dynp->d_un.d_val;
+ break;
+ case DT_RELENT:
+ case DT_RELAENT:
+ relent = dynp->d_un.d_val;
+ break;
+ default:
+ break;
+ }
+ }
+
+ /*
+ * Perform the actual relocation.
+ */
+ for (; relsz > 0; relsz -= relent) {
+ switch (ELF_R_TYPE(rel->r_info)) {
+ case R_TYPE(NONE):
+ /* No relocation needs be performed. */
+ break;
+
+ case R_TYPE(RELATIVE):
+ /* Address relative to the base address. */
+ newaddr = (Elf_Addr *)(rel->r_offset + baseaddr);
+ *newaddr += baseaddr;
+#ifdef USE_RELA
+ /* Add the addend when the ABI uses them */
+ *newaddr += ((Elf_Rela *)rel)->r_addend;
+#endif
+ break;
+ default:
+ /* XXX: do we need other relocations ? */
+ break;
+ }
+ rel = (Elf_Rel *) ((char *) rel + relent);
+ }
+}
Index: src/sys/arch/i386/stand/efiboot/version
diff -u /dev/null src/sys/arch/i386/stand/efiboot/version:1.1
--- /dev/null Tue Jan 24 11:09:15 2017
+++ src/sys/arch/i386/stand/efiboot/version Tue Jan 24 11:09:14 2017
@@ -0,0 +1,7 @@
+$NetBSD: version,v 1.1 2017/01/24 11:09:14 nonaka Exp $
+
+NOTE ANY CHANGES YOU MAKE TO THE EFI BOOTLOADER HERE. The format of this
+file is important - make sure the entries are appended on end, last item
+is taken as the current.
+
+1.0: Initial version.
Index: src/sys/arch/i386/stand/efiboot/bootia32/Makefile
diff -u /dev/null src/sys/arch/i386/stand/efiboot/bootia32/Makefile:1.1
--- /dev/null Tue Jan 24 11:09:15 2017
+++ src/sys/arch/i386/stand/efiboot/bootia32/Makefile Tue Jan 24 11:09:14 2017
@@ -0,0 +1,17 @@
+# $NetBSD: Makefile,v 1.1 2017/01/24 11:09:14 nonaka Exp $
+
+PROG= bootia32.efi
+OBJFMT= pei-i386
+
+EXTRA_SOURCES= efibootia32.c
+
+CPUFLAGS= -march=i686 -mtune=i686
+GNUEFIARCH= ia32
+LIBKERN_ARCH= i386
+LIBGNUEFI_ARCH= i386
+KLINK_MACHINE= i386
+
+CFLAGS+= -m32
+AFLAGS+= -m32
+
+.include "${.CURDIR}/../Makefile.efiboot"
Index: src/sys/arch/i386/stand/efiboot/bootia32/efiboot_machdep.h
diff -u /dev/null src/sys/arch/i386/stand/efiboot/bootia32/efiboot_machdep.h:1.1
--- /dev/null Tue Jan 24 11:09:15 2017
+++ src/sys/arch/i386/stand/efiboot/bootia32/efiboot_machdep.h Tue Jan 24 11:09:14 2017
@@ -0,0 +1,29 @@
+/* $NetBSD: efiboot_machdep.h,v 1.1 2017/01/24 11:09:14 nonaka Exp $ */
+
+/*-
+ * Copyright (c) 2016 Kimihiro Nonaka <[email protected]>
+ * 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 REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ */
+
+void efi_md_init(void);
Index: src/sys/arch/i386/stand/efiboot/bootia32/efibootia32.c
diff -u /dev/null src/sys/arch/i386/stand/efiboot/bootia32/efibootia32.c:1.1
--- /dev/null Tue Jan 24 11:09:15 2017
+++ src/sys/arch/i386/stand/efiboot/bootia32/efibootia32.c Tue Jan 24 11:09:14 2017
@@ -0,0 +1,51 @@
+/* $NetBSD: efibootia32.c,v 1.1 2017/01/24 11:09:14 nonaka Exp $ */
+
+/*-
+ * Copyright (c) 2016 Kimihiro Nonaka <[email protected]>
+ * 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 REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ */
+
+#include "efiboot.h"
+
+#include <sys/bootblock.h>
+
+struct x86_boot_params boot_params;
+
+void
+efi_md_init(void)
+{
+ /* Nothing to do */
+}
+
+void
+startprog(physaddr_t entry, uint32_t argc, uint32_t *argv, physaddr_t sp)
+{
+ Panic(L"%a: not implemented", __func__);
+}
+
+void
+multiboot(physaddr_t entry, physaddr_t header, physaddr_t sp)
+{
+ Panic(L"%a: not implemented", __func__);
+}
Index: src/sys/arch/i386/stand/efiboot/bootia32/ldscript
diff -u /dev/null src/sys/arch/i386/stand/efiboot/bootia32/ldscript:1.1
--- /dev/null Tue Jan 24 11:09:15 2017
+++ src/sys/arch/i386/stand/efiboot/bootia32/ldscript Tue Jan 24 11:09:14 2017
@@ -0,0 +1,76 @@
+/* $NetBSD: ldscript,v 1.1 2017/01/24 11:09:14 nonaka Exp $ */
+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+OUTPUT_ARCH(i386)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0;
+ ImageBase = .;
+ .hash : { *(.hash) } /* this MUST come first! */
+ . = ALIGN(4096);
+ .text :
+ {
+ *(.text)
+ *(.text.*)
+ *(.gnu.linkonce.t.*)
+ }
+ . = ALIGN(4096);
+ .sdata :
+ {
+ *(.got.plt)
+ *(.got)
+ *(.srodata)
+ *(.sdata)
+ *(.sbss)
+ *(.scommon)
+ }
+ . = ALIGN(4096);
+ .data :
+ {
+ *(.rodata*)
+ *(.data)
+ *(.data1)
+ *(.data.*)
+ *(.sdata)
+ *(.got.plt)
+ *(.got)
+ /* the EFI loader doesn't seem to like a .bss section, so we stick
+ it all into .data: */
+ *(.sbss)
+ *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ . = ALIGN(4096);
+ .dynamic : { *(.dynamic) }
+ . = ALIGN(4096);
+ .rel :
+ {
+ *(.rel.data)
+ *(.rel.data.*)
+ *(.rel.got)
+ *(.rel.stab)
+ *(.data.rel.ro.local)
+ *(.data.rel.local)
+ *(.data.rel.ro)
+ *(.data.rel*)
+ }
+ . = ALIGN(4096);
+ .reloc : /* This is the PECOFF .reloc section! */
+ {
+ *(.reloc)
+ }
+ . = ALIGN(4096);
+ .dynsym : { *(.dynsym) }
+ . = ALIGN(4096);
+ .dynstr : { *(.dynstr) }
+ . = ALIGN(4096);
+ /DISCARD/ :
+ {
+ *(.rel.reloc)
+ *(.eh_frame)
+ *(.note.GNU-stack)
+ }
+ .comment 0 : { *(.comment) }
+}
Index: src/sys/arch/i386/stand/efiboot/bootia32/start.S
diff -u /dev/null src/sys/arch/i386/stand/efiboot/bootia32/start.S:1.1
--- /dev/null Tue Jan 24 11:09:15 2017
+++ src/sys/arch/i386/stand/efiboot/bootia32/start.S Tue Jan 24 11:09:14 2017
@@ -0,0 +1,74 @@
+/* $NetBSD: start.S,v 1.1 2017/01/24 11:09:14 nonaka Exp $ */
+
+/*-
+ * Copyright (c) 2008-2010 Rui Paulo <[email protected]>
+ * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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: head/sys/boot/efi/loader/arch/i386/start.S 282728 2015-05-10 13:30:21Z ian $
+ */
+
+#include <machine/asm.h>
+
+ .text
+ .align 16
+
+/*
+ * EFI entry point.
+ * _start(EFI_IMAGE image_handle, EFI_SYSTEM_TABLE *system_table);
+ *
+ * We calculate the base address along with _DYNAMIC, relocate us and finally
+ * pass control to efi_main.
+ */
+
+ENTRY(_start)
+ pushl %ebp
+ movl %esp, %ebp
+
+ pushl 12(%ebp) /* image_handle */
+ pushl 8(%ebp) /* system_table */
+ call 0f
+0: popl %eax
+ movl %eax, %ebx
+ addl $ImageBase-0b, %eax
+ addl $_DYNAMIC-0b, %ebx
+ pushl %ebx /* dynamic */
+ pushl %eax /* ImageBase */
+ call _C_LABEL(self_reloc)
+ popl %ebx /* remove ImageBase from the stack */
+ popl %ebx /* remove dynamic from the stack */
+ call _C_LABEL(efi_main)
+1: leave
+ ret
+END(_start)
+
+ /*
+ * hand-craft a dummy .reloc section so EFI knows it's a relocatable
+ * executable:
+ */
+
+ .data
+ .section .reloc, "a"
+ .long 0
+ .long 10
+ .word 0
Index: src/sys/arch/i386/stand/efiboot/bootx64/Makefile
diff -u /dev/null src/sys/arch/i386/stand/efiboot/bootx64/Makefile:1.1
--- /dev/null Tue Jan 24 11:09:15 2017
+++ src/sys/arch/i386/stand/efiboot/bootx64/Makefile Tue Jan 24 11:09:14 2017
@@ -0,0 +1,12 @@
+# $NetBSD: Makefile,v 1.1 2017/01/24 11:09:14 nonaka Exp $
+
+PROG= bootx64.efi
+OBJFMT= pei-x86-64
+NEWVERSWHAT= "EFI Boot (x64)"
+
+EXTRA_SOURCES= efibootx64.c startprog64.S
+
+COPTS+= -mno-red-zone
+CPPFLAGS+= -DEFI_FUNCTION_WRAPPER
+
+.include "${.CURDIR}/../Makefile.efiboot"
Index: src/sys/arch/i386/stand/efiboot/bootx64/efiboot_machdep.h
diff -u /dev/null src/sys/arch/i386/stand/efiboot/bootx64/efiboot_machdep.h:1.1
--- /dev/null Tue Jan 24 11:09:15 2017
+++ src/sys/arch/i386/stand/efiboot/bootx64/efiboot_machdep.h Tue Jan 24 11:09:14 2017
@@ -0,0 +1,29 @@
+/* $NetBSD: efiboot_machdep.h,v 1.1 2017/01/24 11:09:14 nonaka Exp $ */
+
+/*-
+ * Copyright (c) 2016 Kimihiro Nonaka <[email protected]>
+ * 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 REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ */
+
+void efi_md_init(void);
Index: src/sys/arch/i386/stand/efiboot/bootx64/efibootx64.c
diff -u /dev/null src/sys/arch/i386/stand/efiboot/bootx64/efibootx64.c:1.1
--- /dev/null Tue Jan 24 11:09:15 2017
+++ src/sys/arch/i386/stand/efiboot/bootx64/efibootx64.c Tue Jan 24 11:09:14 2017
@@ -0,0 +1,75 @@
+/* $NetBSD: efibootx64.c,v 1.1 2017/01/24 11:09:14 nonaka Exp $ */
+
+/*-
+ * Copyright (c) 2016 Kimihiro Nonaka <[email protected]>
+ * 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 REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ */
+
+#include "efiboot.h"
+
+#include <sys/bootblock.h>
+
+struct x86_boot_params boot_params;
+
+void startprog64_start(void *, physaddr_t, physaddr_t);
+extern void (*startprog64)(void *, physaddr_t, physaddr_t);
+extern u_int startprog64_size;
+
+void
+efi_md_init(void)
+{
+ EFI_STATUS status;
+ EFI_PHYSICAL_ADDRESS addr = EFI_ALLOCATE_MAX_ADDRESS;
+ u_int sz = EFI_SIZE_TO_PAGES(startprog64_size);
+
+ status = uefi_call_wrapper(BS->AllocatePages, 4, AllocateMaxAddress,
+ EfiLoaderData, sz, &addr);
+ if (EFI_ERROR(status))
+ Panic(L"%a: AllocatePages() failed: %d page(s): %r",
+ __func__, sz, status);
+ startprog64 = (void *)addr;
+ CopyMem(startprog64, startprog64_start, startprog64_size);
+}
+
+/* ARGSUSED */
+void
+startprog(physaddr_t entry, uint32_t argc, uint32_t *argv, physaddr_t sp)
+{
+ uint32_t *newsp = (void *)((char *)startprog64 + startprog64_size);
+
+ /* Copy argv to new stack pointer */
+ if (argc > 0) {
+ newsp -= argc;
+ memcpy(newsp, argv, sizeof(*argv) * argc);
+ }
+
+ (*startprog64)(startprog64, entry, (physaddr_t)newsp);
+}
+
+/* ARGSUSED */
+void
+multiboot(physaddr_t entry, physaddr_t header, physaddr_t sp)
+{
+ Panic(L"%a: not implemented", __func__);
+}
Index: src/sys/arch/i386/stand/efiboot/bootx64/ldscript
diff -u /dev/null src/sys/arch/i386/stand/efiboot/bootx64/ldscript:1.1
--- /dev/null Tue Jan 24 11:09:15 2017
+++ src/sys/arch/i386/stand/efiboot/bootx64/ldscript Tue Jan 24 11:09:14 2017
@@ -0,0 +1,66 @@
+/* $NetBSD: ldscript,v 1.1 2017/01/24 11:09:14 nonaka Exp $ */
+/* Same as elf_x86_64_fbsd_efi.lds, except for OUTPUT_FORMAT below - KEEP IN SYNC */
+OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
+OUTPUT_ARCH(i386:x86-64)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0;
+ ImageBase = .;
+ .hash : { *(.hash) } /* this MUST come first! */
+ . = ALIGN(4096);
+ .eh_frame :
+ {
+ *(.eh_frame)
+ }
+ . = ALIGN(4096);
+ .text :
+ {
+ *(.text)
+ *(.text.*)
+ *(.gnu.linkonce.t.*)
+ }
+ . = ALIGN(4096);
+ .reloc :
+ {
+ *(.reloc)
+ }
+ . = ALIGN(4096);
+ .data :
+ {
+ *(.rodata*)
+ *(.got.plt)
+ *(.got)
+ *(.data*)
+ *(.sdata)
+ /* the EFI loader doesn't seem to like a .bss section, so we stick
+ it all into .data: */
+ *(.sbss)
+ *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ *(.rel.local)
+ }
+ . = ALIGN(4096);
+ .dynamic : { *(.dynamic) }
+ . = ALIGN(4096);
+ .rela :
+ {
+ *(.rela.data*)
+ *(.rela.got)
+ *(.rela.stab)
+ }
+ . = ALIGN(4096);
+ .dynsym : { *(.dynsym) }
+ . = ALIGN(4096);
+ .dynstr : { *(.dynstr) }
+ . = ALIGN(4096);
+ .ignored.reloc :
+ {
+ *(.rela.reloc)
+ *(.eh_frame)
+ *(.note.GNU-stack)
+ }
+ .comment 0 : { *(.comment) }
+}
Index: src/sys/arch/i386/stand/efiboot/bootx64/start.S
diff -u /dev/null src/sys/arch/i386/stand/efiboot/bootx64/start.S:1.1
--- /dev/null Tue Jan 24 11:09:15 2017
+++ src/sys/arch/i386/stand/efiboot/bootx64/start.S Tue Jan 24 11:09:14 2017
@@ -0,0 +1,79 @@
+/* $NetBSD: start.S,v 1.1 2017/01/24 11:09:14 nonaka Exp $ */
+
+/*-
+ * Copyright (C) 1999 Hewlett-Packard Co.
+ * Contributed by David Mosberger <[email protected]>.
+ * Copyright (C) 2005 Intel Co.
+ * Contributed by Fenghua Yu <[email protected]>.
+ * 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.
+ * 3. Neither the name of Hewlett-Packard Co. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 COPYRIGHT
+ * OWNER OR CONTRIBUTORS 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.
+ */
+
+/*
+ * crt0-efi-x86_64.S - x86_64 EFI startup code.
+ * $FreeBSD: head/sys/boot/efi/loader/arch/amd64/start.S 282727 2015-05-10 13:24:26Z ian $
+ */
+
+#include <machine/asm.h>
+
+ .text
+ .align 16
+ .globl _start
+_start:
+ subq $8, %rsp
+ pushq %rcx
+ pushq %rdx
+
+0:
+ lea ImageBase(%rip), %rdi
+ lea _DYNAMIC(%rip), %rsi
+
+ popq %rcx
+ popq %rdx
+ pushq %rcx
+ pushq %rdx
+ call _C_LABEL(self_reloc)
+
+ popq %rdi
+ popq %rsi
+
+ call _C_LABEL(efi_main)
+ addq $8, %rsp
+
+.Lexit:
+ ret
+
+ /*
+ * hand-craft a dummy .reloc section so EFI knows it's a relocatable
+ * executable:
+ */
+
+ .data
+ .section .reloc, "a"
+ .long 0
+ .long 10
+ .word 0
Index: src/sys/arch/i386/stand/efiboot/bootx64/startprog64.S
diff -u /dev/null src/sys/arch/i386/stand/efiboot/bootx64/startprog64.S:1.1
--- /dev/null Tue Jan 24 11:09:15 2017
+++ src/sys/arch/i386/stand/efiboot/bootx64/startprog64.S Tue Jan 24 11:09:14 2017
@@ -0,0 +1,155 @@
+/* $NetBSD: startprog64.S,v 1.1 2017/01/24 11:09:14 nonaka Exp $ */
+/* NetBSD: startprog.S,v 1.3 2003/02/01 14:48:18 dsl Exp */
+
+/* starts program in protected mode / flat space
+ with given stackframe
+ needs global variables flatcodeseg and flatdataseg
+ (gdt offsets)
+ derived from: NetBSD:sys/arch/i386/boot/asm.S
+ */
+
+/*
+ * Ported to boot 386BSD by Julian Elischer ([email protected]) Sept 1992
+ *
+ * Mach Operating System
+ * Copyright (c) 1992, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or [email protected]
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+
+/*
+ Copyright 1988, 1989, 1990, 1991, 1992
+ by Intel Corporation, Santa Clara, California.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appears in all
+copies and that both the copyright notice and this permission notice
+appear in supporting documentation, and that the name of Intel
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+#include <machine/asm.h>
+#include <machine/specialreg.h>
+
+#define CODE_SEGMENT 0x08
+#define DATA_SEGMENT 0x10
+
+ .align 16
+ .globl _C_LABEL(startprog64)
+_C_LABEL(startprog64):
+ .quad 0
+
+ .globl _C_LABEL(startprog64_size)
+_C_LABEL(startprog64_size):
+ .long startprog64_end - _C_LABEL(startprog64_start)
+
+ .text
+ .p2align 4,,15
+
+/*
+ * startprog64(loadddr,entry,stack)
+ */
+ENTRY(startprog64_start)
+start:
+ /*
+ * This function is to call the loaded kernel's start() with
+ * 32bit segment mode from x64 mode.
+ * %rdi: loaded start address
+ * %rsi: kernel entry address
+ * %rdx: stack address
+ */
+
+ cld # LynxOS depends on it
+
+ /* Prepare jump address */
+ lea (start32a - start)(%rdi), %rax
+ movl %eax, (start32r - start)(%rdi)
+
+ cli
+
+ /* Setup GDT */
+ lea (gdt - start)(%rdi), %rax
+ mov %rax, (gdtrr - start)(%rdi)
+ lgdt (gdtr - start)(%rdi)
+
+ /* Jump to set %cs */
+ ljmp *(start32r - start)(%rdi)
+
+ .align 4
+ .code32
+start32a:
+ movl $DATA_SEGMENT, %eax
+ movw %eax, %ds
+ movw %eax, %es
+ movw %eax, %fs
+ movw %eax, %gs
+ movw %eax, %ss
+
+ movl %edx, %esp
+
+ /* Disable Paging in CR0 */
+ movl %cr0, %eax
+ andl $(~CR0_PG), %eax
+ movl %eax, %cr0
+
+ /* Disable PAE in CR4 */
+ movl %cr4, %eax
+ andl $(~CR4_PAE), %eax
+ movl %eax, %cr4
+
+ jmp start32b
+
+ .align 4
+start32b:
+ xor %eax, %eax
+ call *%esi
+
+ .align 16
+start32r:
+ .long 0
+ .long CODE_SEGMENT
+ .align 16
+gdt:
+ .long 0, 0
+ .byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x9f, 0xcf, 0x00
+ .byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x93, 0xcf, 0x00
+gdtr:
+ .word gdtr - gdt
+gdtrr:
+ .quad
+start32end:
+ /* Space for the stack */
+ .align 16
+ .space 8192
+startprog64_end:
Index: src/sys/lib/libgnuefi/arch/i386/Makefile.inc
diff -u /dev/null src/sys/lib/libgnuefi/arch/i386/Makefile.inc:1.1
--- /dev/null Tue Jan 24 11:09:15 2017
+++ src/sys/lib/libgnuefi/arch/i386/Makefile.inc Tue Jan 24 11:09:15 2017
@@ -0,0 +1,3 @@
+# $NetBSD: Makefile.inc,v 1.1 2017/01/24 11:09:15 nonaka Exp $
+
+SRCS+= efi_stub.S
Index: src/sys/lib/libgnuefi/arch/x86_64/Makefile.inc
diff -u /dev/null src/sys/lib/libgnuefi/arch/x86_64/Makefile.inc:1.1
--- /dev/null Tue Jan 24 11:09:15 2017
+++ src/sys/lib/libgnuefi/arch/x86_64/Makefile.inc Tue Jan 24 11:09:15 2017
@@ -0,0 +1,3 @@
+# $NetBSD: Makefile.inc,v 1.1 2017/01/24 11:09:15 nonaka Exp $
+
+SRCS+= callwrap.c efi_stub.S