Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 1 Apr 2015 08:30:41 +0000 (UTC)
From:      Andrew Turner <andrew@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r280950 - in head/sys/boot: amd64 efi efi/boot1 efi/loader efi/loader/arch efi/loader/arch/amd64
Message-ID:  <201504010830.t318Ufhn039066@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: andrew
Date: Wed Apr  1 08:30:40 2015
New Revision: 280950
URL: https://svnweb.freebsd.org/changeset/base/280950

Log:
  Move the efi loaders to be under sys/boot/efi. This will help us add
  support for booting arm and arm64 from UEFI.
  
  Differential Revision:	https://reviews.freebsd.org/D2164
  Reviewed by:	emaste, imp (previous version)
  Sponsored by:	The FreeBSD Foundation

Added:
  head/sys/boot/efi/boot1/
  head/sys/boot/efi/boot1/Makefile
     - copied, changed from r280949, head/sys/boot/amd64/boot1.efi/Makefile
  head/sys/boot/efi/boot1/Makefile.fat
     - copied unchanged from r280570, head/sys/boot/amd64/boot1.efi/Makefile.fat
  head/sys/boot/efi/boot1/boot1.c
     - copied unchanged from r280570, head/sys/boot/amd64/boot1.efi/boot1.c
  head/sys/boot/efi/boot1/fat.tmpl.bz2.uu
     - copied unchanged from r280570, head/sys/boot/amd64/boot1.efi/fat.tmpl.bz2.uu
  head/sys/boot/efi/boot1/generate-fat.sh
     - copied unchanged from r280570, head/sys/boot/amd64/boot1.efi/generate-fat.sh
  head/sys/boot/efi/loader/
  head/sys/boot/efi/loader/Makefile
     - copied, changed from r280570, head/sys/boot/amd64/efi/Makefile
  head/sys/boot/efi/loader/arch/
  head/sys/boot/efi/loader/arch/amd64/
  head/sys/boot/efi/loader/arch/amd64/Makefile.inc   (contents, props changed)
  head/sys/boot/efi/loader/arch/amd64/amd64_tramp.S
     - copied unchanged from r280570, head/sys/boot/amd64/efi/amd64_tramp.S
  head/sys/boot/efi/loader/arch/amd64/elf64_freebsd.c
     - copied, changed from r280570, head/sys/boot/amd64/efi/elf64_freebsd.c
  head/sys/boot/efi/loader/arch/amd64/framebuffer.c
     - copied unchanged from r280570, head/sys/boot/amd64/efi/framebuffer.c
  head/sys/boot/efi/loader/arch/amd64/framebuffer.h
     - copied unchanged from r280570, head/sys/boot/amd64/efi/framebuffer.h
  head/sys/boot/efi/loader/arch/amd64/ldscript.amd64
     - copied unchanged from r280570, head/sys/boot/amd64/efi/ldscript.amd64
  head/sys/boot/efi/loader/arch/amd64/reloc.c
     - copied unchanged from r280570, head/sys/boot/amd64/efi/reloc.c
  head/sys/boot/efi/loader/arch/amd64/start.S
     - copied unchanged from r280570, head/sys/boot/amd64/efi/start.S
  head/sys/boot/efi/loader/autoload.c
     - copied, changed from r280570, head/sys/boot/amd64/efi/autoload.c
  head/sys/boot/efi/loader/bootinfo.c
     - copied, changed from r280570, head/sys/boot/amd64/efi/bootinfo.c
  head/sys/boot/efi/loader/conf.c
     - copied, changed from r280570, head/sys/boot/amd64/efi/conf.c
  head/sys/boot/efi/loader/copy.c
     - copied, changed from r280570, head/sys/boot/amd64/efi/copy.c
  head/sys/boot/efi/loader/devicename.c
     - copied, changed from r280570, head/sys/boot/amd64/efi/devicename.c
  head/sys/boot/efi/loader/loader_efi.h
     - copied, changed from r280570, head/sys/boot/amd64/efi/x86_efi.h
  head/sys/boot/efi/loader/main.c
     - copied, changed from r280570, head/sys/boot/amd64/efi/main.c
  head/sys/boot/efi/loader/version
     - copied unchanged from r280570, head/sys/boot/amd64/efi/version
Deleted:
  head/sys/boot/amd64/
Modified:
  head/sys/boot/efi/Makefile
  head/sys/boot/efi/Makefile.inc

Modified: head/sys/boot/efi/Makefile
==============================================================================
--- head/sys/boot/efi/Makefile	Wed Apr  1 08:25:40 2015	(r280949)
+++ head/sys/boot/efi/Makefile	Wed Apr  1 08:30:40 2015	(r280950)
@@ -2,4 +2,8 @@
 
 SUBDIR=		libefi
 
+.if ${MACHINE_CPUARCH} == "amd64"
+SUBDIR+=	loader boot1
+.endif
+
 .include <bsd.subdir.mk>

Modified: head/sys/boot/efi/Makefile.inc
==============================================================================
--- head/sys/boot/efi/Makefile.inc	Wed Apr  1 08:25:40 2015	(r280949)
+++ head/sys/boot/efi/Makefile.inc	Wed Apr  1 08:30:40 2015	(r280950)
@@ -7,7 +7,10 @@ CFLAGS+=        -march=i386
 .endif
 
 # Options used when building app-specific efi components
+# See conf/kern.mk for the correct set of these
 CFLAGS+=	-ffreestanding -fshort-wchar -Wformat
+CFLAGS+=	-mno-red-zone
+CFLAGS+=	-mno-mmx -mno-sse -mno-aes -mno-avx -msoft-float
 LDFLAGS+=	-nostdlib
 
 .include "../Makefile.inc"

Copied and modified: head/sys/boot/efi/boot1/Makefile (from r280949, head/sys/boot/amd64/boot1.efi/Makefile)
==============================================================================
--- head/sys/boot/amd64/boot1.efi/Makefile	Wed Apr  1 08:25:40 2015	(r280949, copy source)
+++ head/sys/boot/efi/boot1/Makefile	Wed Apr  1 08:30:40 2015	(r280950)
@@ -17,19 +17,19 @@ SRCS=	boot1.c reloc.c start.S
 
 CFLAGS+=	-fPIC
 CFLAGS+=	-I.
-CFLAGS+=	-I${.CURDIR}/../../efi/include
-CFLAGS+=	-I${.CURDIR}/../../efi/include/${MACHINE_CPUARCH}
+CFLAGS+=	-I${.CURDIR}/../include
+CFLAGS+=	-I${.CURDIR}/../include/${MACHINE_CPUARCH}
 CFLAGS+=	-I${.CURDIR}/../../../contrib/dev/acpica/include
 CFLAGS+=	-I${.CURDIR}/../../..
 
 # Always add MI sources and REGULAR efi loader bits
-.PATH:		${.CURDIR}/../efi ${.CURDIR}/../../common
+.PATH:		${.CURDIR}/../loader/arch/amd64 ${.CURDIR}/../../common
 CFLAGS+=	-I${.CURDIR}/../../common
 
 FILES=	boot1.efi boot1.efifat
 FILESMODE_boot1.efi=	${BINMODE}
 
-LDSCRIPT=	${.CURDIR}/../efi/ldscript.${MACHINE_CPUARCH}
+LDSCRIPT=	${.CURDIR}/../loader/arch/${MACHINE_CPUARCH}/ldscript.${MACHINE_CPUARCH}
 LDFLAGS=	-Wl,-T${LDSCRIPT} -Wl,-Bsymbolic -shared -Wl,-znocombreloc
 
 ${PROG}:	${LDSCRIPT}
@@ -39,7 +39,7 @@ OBJDUMP?=	objdump
 
 .if ${MACHINE_CPUARCH} == "amd64"
 EFI_TARGET=	efi-app-x86_64
-.else
+.elif ${MACHINE_CPUARCH} == "i386"
 EFI_TARGET=	efi-app-ia32
 .endif
 

Copied: head/sys/boot/efi/boot1/Makefile.fat (from r280570, head/sys/boot/amd64/boot1.efi/Makefile.fat)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/boot/efi/boot1/Makefile.fat	Wed Apr  1 08:30:40 2015	(r280950, copy of r280570, head/sys/boot/amd64/boot1.efi/Makefile.fat)
@@ -0,0 +1,3 @@
+# This file autogenerated by generate-fat.sh - DO NOT EDIT
+# $FreeBSD$
+BOOT1_OFFSET=0x2d

Copied: head/sys/boot/efi/boot1/boot1.c (from r280570, head/sys/boot/amd64/boot1.efi/boot1.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/boot/efi/boot1/boot1.c	Wed Apr  1 08:30:40 2015	(r280950, copy of r280570, head/sys/boot/amd64/boot1.efi/boot1.c)
@@ -0,0 +1,552 @@
+/*-
+ * Copyright (c) 1998 Robert Nordier
+ * All rights reserved.
+ * Copyright (c) 2001 Robert Drehmel
+ * All rights reserved.
+ * Copyright (c) 2014 Nathan Whitehorn
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are freely
+ * permitted provided that the above copyright notice and this
+ * paragraph and the following disclaimer are duplicated in all
+ * such forms.
+ *
+ * This software is provided "AS IS" and without any express or
+ * implied warranties, including, without limitation, the implied
+ * warranties of merchantability and fitness for a particular
+ * purpose.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/dirent.h>
+#include <machine/elf.h>
+#include <machine/stdarg.h>
+
+#include <efi.h>
+#include <eficonsctl.h>
+
+#define _PATH_LOADER	"/boot/loader.efi"
+#define _PATH_KERNEL	"/boot/kernel/kernel"
+ 
+#define BSIZEMAX	16384
+
+typedef int putc_func_t(char c, void *arg);
+
+struct sp_data {
+	char	*sp_buf;
+	u_int	sp_len;
+	u_int	sp_size;
+};
+        
+static const char digits[] = "0123456789abcdef";
+
+static void panic(const char *fmt, ...) __dead2;
+static int printf(const char *fmt, ...);
+static int putchar(char c, void *arg);
+static int vprintf(const char *fmt, va_list ap);
+static int vsnprintf(char *str, size_t sz, const char *fmt, va_list ap);
+
+static int __printf(const char *fmt, putc_func_t *putc, void *arg, va_list ap);
+static int __putc(char c, void *arg);
+static int __puts(const char *s, putc_func_t *putc, void *arg);
+static int __sputc(char c, void *arg);
+static char *__uitoa(char *buf, u_int val, int base);
+static char *__ultoa(char *buf, u_long val, int base);
+
+static int domount(EFI_DEVICE_PATH *device, EFI_BLOCK_IO *blkio, int quiet);
+static void load(const char *fname);
+
+EFI_SYSTEM_TABLE *systab;
+EFI_HANDLE *image;
+
+static void     
+bcopy(const void *src, void *dst, size_t len)
+{
+	const char *s = src;
+	char *d = dst;
+
+	while (len-- != 0)
+		*d++ = *s++;
+}
+   
+static void
+memcpy(void *dst, const void *src, size_t len)
+{
+	bcopy(src, dst, len);
+}               
+
+static void
+bzero(void *b, size_t len)
+{
+	char *p = b;
+
+	while (len-- != 0)
+		*p++ = 0;
+}
+        
+static int
+strcmp(const char *s1, const char *s2)
+{
+	for (; *s1 == *s2 && *s1; s1++, s2++)
+		;
+	return ((u_char)*s1 - (u_char)*s2);
+}
+
+static EFI_GUID BlockIoProtocolGUID = BLOCK_IO_PROTOCOL;
+static EFI_GUID DevicePathGUID = DEVICE_PATH_PROTOCOL;
+static EFI_GUID LoadedImageGUID = LOADED_IMAGE_PROTOCOL;
+static EFI_GUID ConsoleControlGUID = EFI_CONSOLE_CONTROL_PROTOCOL_GUID;
+
+static EFI_BLOCK_IO *bootdev;
+static EFI_DEVICE_PATH *bootdevpath;
+static EFI_HANDLE *bootdevhandle;
+
+EFI_STATUS efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE* Xsystab)
+{
+	EFI_HANDLE handles[128];
+	EFI_BLOCK_IO *blkio;
+	UINTN i, nparts = sizeof(handles);
+	EFI_STATUS status;
+	EFI_DEVICE_PATH *devpath;
+	EFI_BOOT_SERVICES *BS;
+	EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL;
+	char *path = _PATH_LOADER;
+
+	systab = Xsystab;
+	image = Ximage;
+
+	BS = systab->BootServices;
+	status = BS->LocateProtocol(&ConsoleControlGUID, NULL,
+	    (VOID **)&ConsoleControl);
+	if (status == EFI_SUCCESS)
+		(void)ConsoleControl->SetMode(ConsoleControl,
+		    EfiConsoleControlScreenText);
+
+	printf(" \n>> FreeBSD EFI boot block\n");
+	printf("   Loader path: %s\n", path);
+
+	status = systab->BootServices->LocateHandle(ByProtocol,
+	    &BlockIoProtocolGUID, NULL, &nparts, handles);
+	nparts /= sizeof(handles[0]);
+
+	for (i = 0; i < nparts; i++) {
+		status = systab->BootServices->HandleProtocol(handles[i],
+		    &DevicePathGUID, (void **)&devpath); 
+		if (EFI_ERROR(status))
+			continue;
+
+		while (!IsDevicePathEnd(NextDevicePathNode(devpath)))
+			devpath = NextDevicePathNode(devpath);
+
+		status = systab->BootServices->HandleProtocol(handles[i],
+		    &BlockIoProtocolGUID, (void **)&blkio); 
+		if (EFI_ERROR(status))
+			continue;
+
+		if (!blkio->Media->LogicalPartition)
+			continue;
+
+		if (domount(devpath, blkio, 1) >= 0)
+			break;
+	}
+
+	if (i == nparts)
+		panic("No bootable partition found");
+
+	bootdevhandle = handles[i];
+	load(path);
+		
+	panic("Load failed");
+
+	return EFI_SUCCESS;
+}
+
+static int
+dskread(void *buf, u_int64_t lba, int nblk)
+{
+	EFI_STATUS status;
+	int size;
+
+	lba = lba / (bootdev->Media->BlockSize / DEV_BSIZE);
+	size = nblk * DEV_BSIZE;
+	status = bootdev->ReadBlocks(bootdev, bootdev->Media->MediaId, lba,
+	    size, buf);
+
+	if (EFI_ERROR(status))
+		return (-1);
+
+	return (0);
+}
+
+#include "ufsread.c"
+
+static ssize_t
+fsstat(ufs_ino_t inode)
+{
+#ifndef UFS2_ONLY
+	static struct ufs1_dinode dp1;
+	ufs1_daddr_t addr1;
+#endif
+#ifndef UFS1_ONLY
+	static struct ufs2_dinode dp2;
+#endif
+	static struct fs fs;
+	static ufs_ino_t inomap;
+	char *blkbuf;
+	void *indbuf;
+	size_t n, nb, size, off, vboff;
+	ufs_lbn_t lbn;
+	ufs2_daddr_t addr2, vbaddr;
+	static ufs2_daddr_t blkmap, indmap;
+	u_int u;
+
+	blkbuf = dmadat->blkbuf;
+	indbuf = dmadat->indbuf;
+	if (!dsk_meta) {
+		inomap = 0;
+		for (n = 0; sblock_try[n] != -1; n++) {
+			if (dskread(dmadat->sbbuf, sblock_try[n] / DEV_BSIZE,
+			    SBLOCKSIZE / DEV_BSIZE))
+				return -1;
+			memcpy(&fs, dmadat->sbbuf, sizeof(struct fs));
+			if ((
+#if defined(UFS1_ONLY)
+			    fs.fs_magic == FS_UFS1_MAGIC
+#elif defined(UFS2_ONLY)
+			    (fs.fs_magic == FS_UFS2_MAGIC &&
+			    fs.fs_sblockloc == sblock_try[n])
+#else
+			    fs.fs_magic == FS_UFS1_MAGIC ||
+			    (fs.fs_magic == FS_UFS2_MAGIC &&
+			    fs.fs_sblockloc == sblock_try[n])
+#endif
+			    ) &&
+			    fs.fs_bsize <= MAXBSIZE &&
+			    fs.fs_bsize >= sizeof(struct fs))
+				break;
+		}
+		if (sblock_try[n] == -1) {
+			printf("Not ufs\n");
+			return -1;
+		}
+		dsk_meta++;
+	} else
+		memcpy(&fs, dmadat->sbbuf, sizeof(struct fs));
+	if (!inode)
+		return 0;
+	if (inomap != inode) {
+		n = IPERVBLK(&fs);
+		if (dskread(blkbuf, INO_TO_VBA(&fs, n, inode), DBPERVBLK))
+			return -1;
+		n = INO_TO_VBO(n, inode);
+#if defined(UFS1_ONLY)
+		memcpy(&dp1, (struct ufs1_dinode *)blkbuf + n,
+		    sizeof(struct ufs1_dinode));
+#elif defined(UFS2_ONLY)
+		memcpy(&dp2, (struct ufs2_dinode *)blkbuf + n,
+		    sizeof(struct ufs2_dinode));
+#else
+		if (fs.fs_magic == FS_UFS1_MAGIC)
+			memcpy(&dp1, (struct ufs1_dinode *)blkbuf + n,
+			    sizeof(struct ufs1_dinode));
+		else
+			memcpy(&dp2, (struct ufs2_dinode *)blkbuf + n,
+			    sizeof(struct ufs2_dinode));
+#endif
+		inomap = inode;
+		fs_off = 0;
+		blkmap = indmap = 0;
+	}
+	size = DIP(di_size);
+	n = size - fs_off;
+	return (n);
+}
+
+static struct dmadat __dmadat;
+                
+static int
+domount(EFI_DEVICE_PATH *device, EFI_BLOCK_IO *blkio, int quiet)
+{
+
+	dmadat = &__dmadat;
+	bootdev = blkio;
+	bootdevpath = device;
+	if (fsread(0, NULL, 0)) {
+		if (!quiet)
+			printf("domount: can't read superblock\n");
+		return (-1);
+	} 
+	if (!quiet)
+		printf("Succesfully mounted UFS filesystem\n");
+	return (0);
+}
+
+static void
+load(const char *fname)
+{
+	ufs_ino_t ino;
+	EFI_STATUS status;
+	EFI_HANDLE loaderhandle;
+	EFI_LOADED_IMAGE *loaded_image;
+	void *buffer;
+	size_t bufsize;
+
+	if ((ino = lookup(fname)) == 0) {
+		printf("File %s not found\n", fname);
+		return;
+	}
+
+	bufsize = fsstat(ino);
+	status = systab->BootServices->AllocatePool(EfiLoaderData,
+	    bufsize, &buffer);
+	fsread(ino, buffer, bufsize);
+	
+	/* XXX: For secure boot, we need our own loader here */
+	status = systab->BootServices->LoadImage(TRUE, image, bootdevpath,
+	    buffer, bufsize, &loaderhandle);
+	if (EFI_ERROR(status))
+		printf("LoadImage failed with error %d\n", status);
+
+	status = systab->BootServices->HandleProtocol(loaderhandle,
+	    &LoadedImageGUID, (VOID**)&loaded_image);
+	if (EFI_ERROR(status))
+		printf("HandleProtocol failed with error %d\n", status);
+
+	loaded_image->DeviceHandle = bootdevhandle;
+
+	status = systab->BootServices->StartImage(loaderhandle, NULL, NULL);
+	if (EFI_ERROR(status))
+		printf("StartImage failed with error %d\n", status);
+}
+
+static void
+panic(const char *fmt, ...)
+{
+	char buf[128];
+	va_list ap;
+
+	va_start(ap, fmt);
+	vsnprintf(buf, sizeof buf, fmt, ap);
+	printf("panic: %s\n", buf);
+	va_end(ap);
+
+	while (1) {}
+}
+
+static int
+printf(const char *fmt, ...)
+{
+	va_list ap;
+	int ret;
+
+	/* Don't annoy the user as we probe for partitions */
+	if (strcmp(fmt,"Not ufs\n") == 0)
+		return 0;
+
+	va_start(ap, fmt);
+	ret = vprintf(fmt, ap);
+	va_end(ap);
+	return (ret);
+}
+
+static int
+putchar(char c, void *arg)
+{
+	CHAR16 buf[2];
+
+	if (c == '\n') {
+		buf[0] = '\r';
+		buf[1] = 0;
+		systab->ConOut->OutputString(systab->ConOut, buf);
+	}
+	buf[0] = c;
+	buf[1] = 0;
+	systab->ConOut->OutputString(systab->ConOut, buf);
+	return (1);
+}
+
+static int
+vprintf(const char *fmt, va_list ap)
+{
+	int ret;
+
+	ret = __printf(fmt, putchar, 0, ap);
+	return (ret);
+}
+
+static int
+vsnprintf(char *str, size_t sz, const char *fmt, va_list ap)
+{
+	struct sp_data sp;
+	int ret;
+
+	sp.sp_buf = str;
+	sp.sp_len = 0;
+	sp.sp_size = sz;
+	ret = __printf(fmt, __sputc, &sp, ap);
+	return (ret);
+}
+
+static int
+__printf(const char *fmt, putc_func_t *putc, void *arg, va_list ap)
+{
+	char buf[(sizeof(long) * 8) + 1];
+	char *nbuf;
+	u_long ul;
+	u_int ui;
+	int lflag;
+	int sflag;
+	char *s;
+	int pad;
+	int ret;
+	int c;
+
+	nbuf = &buf[sizeof buf - 1];
+	ret = 0;
+	while ((c = *fmt++) != 0) {
+		if (c != '%') {
+			ret += putc(c, arg);
+			continue;
+		}
+		lflag = 0;
+		sflag = 0;
+		pad = 0;
+reswitch:	c = *fmt++;
+		switch (c) {
+		case '#':
+			sflag = 1;
+			goto reswitch;
+		case '%':
+			ret += putc('%', arg);
+			break;
+		case 'c':
+			c = va_arg(ap, int);
+			ret += putc(c, arg);
+			break;
+		case 'd':
+			if (lflag == 0) {
+				ui = (u_int)va_arg(ap, int);
+				if (ui < (int)ui) {
+					ui = -ui;
+					ret += putc('-', arg);
+				}
+				s = __uitoa(nbuf, ui, 10);
+			} else {
+				ul = (u_long)va_arg(ap, long);
+				if (ul < (long)ul) {
+					ul = -ul;
+					ret += putc('-', arg);
+				}
+				s = __ultoa(nbuf, ul, 10);
+			}
+			ret += __puts(s, putc, arg);
+			break;
+		case 'l':
+			lflag = 1;
+			goto reswitch;
+		case 'o':
+			if (lflag == 0) {
+				ui = (u_int)va_arg(ap, u_int);
+				s = __uitoa(nbuf, ui, 8);
+			} else {
+				ul = (u_long)va_arg(ap, u_long);
+				s = __ultoa(nbuf, ul, 8);
+			}
+			ret += __puts(s, putc, arg);
+			break;
+		case 'p':
+			ul = (u_long)va_arg(ap, void *);
+			s = __ultoa(nbuf, ul, 16);
+			ret += __puts("0x", putc, arg);
+			ret += __puts(s, putc, arg);
+			break;
+		case 's':
+			s = va_arg(ap, char *);
+			ret += __puts(s, putc, arg);
+			break;
+		case 'u':
+			if (lflag == 0) {
+				ui = va_arg(ap, u_int);
+				s = __uitoa(nbuf, ui, 10);
+			} else {
+				ul = va_arg(ap, u_long);
+				s = __ultoa(nbuf, ul, 10);
+			}
+			ret += __puts(s, putc, arg);
+			break;
+		case 'x':
+			if (lflag == 0) {
+				ui = va_arg(ap, u_int);
+				s = __uitoa(nbuf, ui, 16);
+			} else {
+				ul = va_arg(ap, u_long);
+				s = __ultoa(nbuf, ul, 16);
+			}
+			if (sflag)
+				ret += __puts("0x", putc, arg);
+			ret += __puts(s, putc, arg);
+			break;
+		case '0': case '1': case '2': case '3': case '4':
+		case '5': case '6': case '7': case '8': case '9':
+			pad = pad * 10 + c - '0';
+			goto reswitch;
+		default:
+			break;
+		}
+	}
+	return (ret);
+}
+
+static int
+__sputc(char c, void *arg)
+{
+	struct sp_data *sp;
+
+	sp = arg;
+	if (sp->sp_len < sp->sp_size)
+		sp->sp_buf[sp->sp_len++] = c;
+	sp->sp_buf[sp->sp_len] = '\0';
+	return (1);
+}
+
+static int
+__puts(const char *s, putc_func_t *putc, void *arg)
+{
+	const char *p;
+	int ret;
+
+	ret = 0;
+	for (p = s; *p != '\0'; p++)
+		ret += putc(*p, arg);
+	return (ret);
+}
+
+static char *
+__uitoa(char *buf, u_int ui, int base)
+{
+	char *p;
+
+	p = buf;
+	*p = '\0';
+	do
+		*--p = digits[ui % base];
+	while ((ui /= base) != 0);
+	return (p);
+}
+
+static char *
+__ultoa(char *buf, u_long ul, int base)
+{
+	char *p;
+
+	p = buf;
+	*p = '\0';
+	do
+		*--p = digits[ul % base];
+	while ((ul /= base) != 0);
+	return (p);
+}
+

Copied: head/sys/boot/efi/boot1/fat.tmpl.bz2.uu (from r280570, head/sys/boot/amd64/boot1.efi/fat.tmpl.bz2.uu)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/boot/efi/boot1/fat.tmpl.bz2.uu	Wed Apr  1 08:30:40 2015	(r280950, copy of r280570, head/sys/boot/amd64/boot1.efi/fat.tmpl.bz2.uu)
@@ -0,0 +1,20 @@
+FAT template boot filesystem created by generate-fat.sh
+DO NOT EDIT
+$FreeBSD$
+begin 644 fat.tmpl.bz2
+M0EIH.3%!629362AK*D(`&I+____[ZZKJZ_^N_ZO^Z_Z_OJ[L`4`!7I0$#&$"
+M0$!$3&(<P`(;J*C:0E0E#30&AH`T````9#0```9````#)ZF0:,-3U/409,`)
+M@`"8`C3",````$R:8F@P`C`````"24U,D>I-DTU,)ZAZ0VA-!M0T'J`>H#"9
+M'I#0-H&HQI&0&3&FH>H>*`JHHU3V]1%/4/2``T#0`!H``#0`````#1H,@``6
+M'1&G'&@?$6[T#A)?X8$A160"20BO#")0J4TB1*4GXF$B4I,&>43+=_?K=#3*
+M6]<E0HE`UBF?(J%8BRF#?8OQ2'D)`)(EL2;F4.'R>R"ZNKJZI,9*68E8*E2Q
+M4J5*E3'(1830A"$(12A-"<(0A#]VD)H0A"$,>I0FA"$(0I\>P^=F5:M6K5JU
+M:DI3:64UN;[7%5B]Y-^\]@_K@B:N\/,5F%&H<\G#IXQXAEFC&D?![6%0'6MR
+MX1@@%FC"FD`M7,/SXFNG:2`'-0<-C$8^+$N.7M1B,^6)9,DV9,0A\OL<:C"L
+ML1V&,<\9YRB>XV#BG")'6NKRK^("UF2XO?_L!#29">MGDF$R3).!PX&%E,4C
+M''=(FL1.`_3?CN@-IB2PI3!FF\<8X.X@D,>CA90I)#M$XRPNDFJELL<3=1?8
+M2B7\5Z64,!7Z;EEBW-MXN-4IJ@W$462]-*\YCR,-B,5[W?=3&L/U>SX,WV#\
+M\B`:I"'0Z)5"$1B.E)(K[5I4RS`%R$>Y\D0NR*,;<9CZ:^V3P(I?D<D#!UC)
+D^M-HEE3SAN-8O0FQ$(`$(DF`?ZQ]'U2F_XNY(IPH2!0UE2$`
+`
+end

Copied: head/sys/boot/efi/boot1/generate-fat.sh (from r280570, head/sys/boot/amd64/boot1.efi/generate-fat.sh)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/boot/efi/boot1/generate-fat.sh	Wed Apr  1 08:30:40 2015	(r280950, copy of r280570, head/sys/boot/amd64/boot1.efi/generate-fat.sh)
@@ -0,0 +1,66 @@
+#!/bin/sh
+
+# This script generates the dummy FAT filesystem used for the EFI boot
+# blocks. It uses newfs_msdos to generate a template filesystem with the
+# relevant interesting files. These are then found by grep, and the offsets
+# written to a Makefile snippet.
+#
+# Because it requires root, and because it is overkill, we do not
+# do this as part of the normal build. If makefs(8) grows workable FAT
+# support, this should be revisited.
+
+# $FreeBSD$
+
+FAT_SIZE=1600 			#Size in 512-byte blocks of the produced image
+
+BOOT1_SIZE=128k
+
+#
+# Known filenames
+# amd64: BOOTx64.efi
+# arm64: BOOTaa64.efi
+#
+if [ -z "$1" ]; then
+	echo "Usage: $0 filename"
+	exit 1
+fi
+
+FILENAME=$1
+
+# Generate 800K FAT image
+OUTPUT_FILE=fat.tmpl
+
+dd if=/dev/zero of=$OUTPUT_FILE bs=512 count=$FAT_SIZE
+DEVICE=`mdconfig -a -f $OUTPUT_FILE`
+newfs_msdos -F 12 -L EFI $DEVICE
+mkdir stub
+mount -t msdosfs /dev/$DEVICE stub
+
+# Create and bless a directory for the boot loader
+mkdir -p stub/efi/boot
+
+# Make a dummy file for boot1
+echo 'Boot1 START' | dd of=stub/efi/boot/$FILENAME cbs=$BOOT1_SIZE count=1 conv=block
+
+umount stub
+mdconfig -d -u $DEVICE
+rmdir stub
+
+# Locate the offset of the fake file
+BOOT1_OFFSET=$(hd $OUTPUT_FILE | grep 'Boot1 START' | cut -f 1 -d ' ')
+
+# Convert to number of blocks
+BOOT1_OFFSET=$(echo 0x$BOOT1_OFFSET | awk '{printf("%x\n",$1/512);}')
+
+echo '# This file autogenerated by generate-fat.sh - DO NOT EDIT' > Makefile.fat
+echo '# $FreeBSD$' >> Makefile.fat
+echo "BOOT1_OFFSET=0x$BOOT1_OFFSET" >> Makefile.fat
+
+bzip2 $OUTPUT_FILE
+echo 'FAT template boot filesystem created by generate-fat.sh' > $OUTPUT_FILE.bz2.uu
+echo 'DO NOT EDIT' >> $OUTPUT_FILE.bz2.uu
+echo '$FreeBSD$' >> $OUTPUT_FILE.bz2.uu
+
+uuencode $OUTPUT_FILE.bz2 $OUTPUT_FILE.bz2 >> $OUTPUT_FILE.bz2.uu
+rm $OUTPUT_FILE.bz2
+

Copied and modified: head/sys/boot/efi/loader/Makefile (from r280570, head/sys/boot/amd64/efi/Makefile)
==============================================================================
--- head/sys/boot/amd64/efi/Makefile	Wed Mar 25 11:14:17 2015	(r280570, copy source)
+++ head/sys/boot/efi/loader/Makefile	Wed Apr  1 08:30:40 2015	(r280950)
@@ -12,27 +12,24 @@ MK_SSP=		no
 PROG=		loader.sym
 INTERNALPROG=
 
+.PATH: ${.CURDIR}/../../efi/loader
 # architecture-specific loader code
 SRCS=	autoload.c \
 	bootinfo.c \
 	conf.c \
 	copy.c \
 	devicename.c \
-	elf64_freebsd.c \
-	framebuffer.c \
 	main.c \
-	reloc.c \
 	vers.c
-SRCS+=	amd64_tramp.S \
-	start.S
-.PATH:	${.CURDIR}/../../i386/libi386
-SRCS+=	nullconsole.c \
-	comconsole.c
+
+.PATH: ${.CURDIR}/arch/${MACHINE_CPUARCH}
+.include "${.CURDIR}/arch/${MACHINE_CPUARCH}/Makefile.inc"
 
 CFLAGS+=	-fPIC
-CFLAGS+=	-I.
-CFLAGS+=	-I${.CURDIR}/../../efi/include
-CFLAGS+=	-I${.CURDIR}/../../efi/include/${MACHINE_CPUARCH}
+CFLAGS+=	-I${.CURDIR}
+CFLAGS+=	-I${.CURDIR}/arch/${MACHINE_CPUARCH}
+CFLAGS+=	-I${.CURDIR}/../include
+CFLAGS+=	-I${.CURDIR}/../include/${MACHINE_CPUARCH}
 CFLAGS+=	-I${.CURDIR}/../../../contrib/dev/acpica/include
 CFLAGS+=	-I${.CURDIR}/../../..
 CFLAGS+=	-DNO_PCI
@@ -60,14 +57,14 @@ CFLAGS+=	-I${.CURDIR}/../../common
 FILES=	loader.efi
 FILESMODE_loader.efi=	${BINMODE}
 
-LDSCRIPT=	${.CURDIR}/ldscript.${MACHINE_CPUARCH}
+LDSCRIPT=	${.CURDIR}/arch/${MACHINE_CPUARCH}/ldscript.${MACHINE_CPUARCH}
 LDFLAGS=	-Wl,-T${LDSCRIPT} -Wl,-Bsymbolic -shared -Wl,-znocombreloc
 
 CLEANFILES=	vers.c loader.efi
 
 NEWVERSWHAT=	"EFI loader" ${MACHINE_CPUARCH}
 
-vers.c:	${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version
+vers.c:	${.CURDIR}/../../common/newvers.sh ${.CURDIR}/../../efi/loader/version
 	sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT}
 
 OBJCOPY?=	objcopy
@@ -75,7 +72,7 @@ OBJDUMP?=	objdump
 
 .if ${MACHINE_CPUARCH} == "amd64"
 EFI_TARGET=	efi-app-x86_64
-.else
+.elif ${MACHINE_CPUARCH} == "i386"
 EFI_TARGET=	efi-app-ia32
 .endif
 
@@ -89,7 +86,7 @@ loader.efi: loader.sym
 		-j .rela.dyn -j .reloc -j .eh_frame -j set_Xcommand_set \
 		--output-target=${EFI_TARGET} ${.ALLSRC} ${.TARGET}
 
-LIBEFI=		${.OBJDIR}/../../efi/libefi/libefi.a
+LIBEFI=		${.OBJDIR}/../libefi/libefi.a
 
 DPADD=		${LIBFICL} ${LIBEFI} ${LIBSTAND} ${LDSCRIPT}
 LDADD=		${LIBFICL} ${LIBEFI} ${LIBSTAND}

Added: head/sys/boot/efi/loader/arch/amd64/Makefile.inc
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/boot/efi/loader/arch/amd64/Makefile.inc	Wed Apr  1 08:30:40 2015	(r280950)
@@ -0,0 +1,11 @@
+# $FreeBSD$
+
+SRCS+=	amd64_tramp.S \
+	start.S \
+	framebuffer.c \
+	elf64_freebsd.c \
+	reloc.c
+
+.PATH:	${.CURDIR}/../../i386/libi386
+SRCS+=	nullconsole.c \
+	comconsole.c

Copied: head/sys/boot/efi/loader/arch/amd64/amd64_tramp.S (from r280570, head/sys/boot/amd64/efi/amd64_tramp.S)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/boot/efi/loader/arch/amd64/amd64_tramp.S	Wed Apr  1 08:30:40 2015	(r280950, copy of r280570, head/sys/boot/amd64/efi/amd64_tramp.S)
@@ -0,0 +1,64 @@
+/*-
+ * Copyright (c) 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Benno Rice under sponsorship from
+ * the FreeBSD Foundation.
+ * 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$
+ */
+
+#include <machine/asmacros.h>
+
+	.text
+	.globl	amd64_tramp
+
+/*
+ * void amd64_tramp(uint64_t stack, void *copy_finish, uint64_t kernend,
+ *		    uint64_t modulep, uint64_t pagetable, uint64_t entry)
+ */
+amd64_tramp:
+	cli			/* Make sure we don't get interrupted. */
+	movq	%rdi,%rsp	/* Switch to our temporary stack. */
+
+	movq	%rdx,%r12	/* Stash the kernel values for later. */
+	movq	%rcx,%r13
+	movq	%r8,%r14
+	movq	%r9,%r15
+
+	callq	*%rsi		/* Call copy_finish so we're all ready to go. */
+
+	pushq	%r12		/* Push kernend. */
+	salq	$32,%r13	/* Shift modulep and push it. */
+	pushq	%r13
+	pushq	%r15		/* Push the entry address. */
+	movq	%r14,%cr3	/* Switch page tables. */
+	ret			/* "Return" to kernel entry. */
+
+	ALIGN_TEXT
+amd64_tramp_end:
+
+	.data
+	.globl	amd64_tramp_size
+amd64_tramp_size:
+	.long	amd64_tramp_end-amd64_tramp

Copied and modified: head/sys/boot/efi/loader/arch/amd64/elf64_freebsd.c (from r280570, head/sys/boot/amd64/efi/elf64_freebsd.c)
==============================================================================
--- head/sys/boot/amd64/efi/elf64_freebsd.c	Wed Mar 25 11:14:17 2015	(r280570, copy source)
+++ head/sys/boot/efi/loader/arch/amd64/elf64_freebsd.c	Wed Apr  1 08:30:40 2015	(r280950)
@@ -47,7 +47,7 @@ __FBSDID("$FreeBSD$");
 #include "actypes.h"
 #include "actbl.h"
 
-#include "x86_efi.h"
+#include "loader_efi.h"
 
 static EFI_GUID acpi_guid = ACPI_TABLE_GUID;
 static EFI_GUID acpi20_guid = ACPI_20_TABLE_GUID;
@@ -57,8 +57,14 @@ extern int bi_load(char *args, vm_offset
 static int	elf64_exec(struct preloaded_file *amp);
 static int	elf64_obj_exec(struct preloaded_file *amp);
 
-struct file_format amd64_elf = { elf64_loadfile, elf64_exec };
-struct file_format amd64_elf_obj = { elf64_obj_loadfile, elf64_obj_exec };
+static struct file_format amd64_elf = { elf64_loadfile, elf64_exec };
+static struct file_format amd64_elf_obj = { elf64_obj_loadfile, elf64_obj_exec };
+
+struct file_format *file_formats[] = {
+	&amd64_elf,
+	&amd64_elf_obj,
+	NULL
+};
 
 #define PG_V    0x001
 #define PG_RW   0x002
@@ -168,7 +174,7 @@ elf64_exec(struct preloaded_file *fp)
 	if (err != 0)
 		return(err);
 
-	status = BS->ExitBootServices(IH, x86_efi_mapkey);
+	status = BS->ExitBootServices(IH, efi_mapkey);
 	if (EFI_ERROR(status)) {
 		printf("%s: ExitBootServices() returned 0x%lx\n", __func__,
 		    (long)status);
@@ -177,7 +183,7 @@ elf64_exec(struct preloaded_file *fp)
 
 	dev_cleanup();
 
-	trampoline(trampstack, x86_efi_copy_finish, kernend, modulep, PT4,
+	trampoline(trampstack, efi_copy_finish, kernend, modulep, PT4,
 	    ehdr->e_entry);
 
 	panic("exec returned");

Copied: head/sys/boot/efi/loader/arch/amd64/framebuffer.c (from r280570, head/sys/boot/amd64/efi/framebuffer.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/boot/efi/loader/arch/amd64/framebuffer.c	Wed Apr  1 08:30:40 2015	(r280950, copy of r280570, head/sys/boot/amd64/efi/framebuffer.c)
@@ -0,0 +1,85 @@
+/*-
+ * Copyright (c) 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Benno Rice under sponsorship from
+ * the FreeBSD Foundation.
+ * 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/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+
+#include <efi.h>
+#include <efilib.h>
+#include <machine/metadata.h>
+
+static EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
+
+int
+efi_find_framebuffer(struct efi_fb *efifb)
+{
+	EFI_GRAPHICS_OUTPUT			*gop;
+	EFI_STATUS				status;
+	EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE	*mode;
+	EFI_GRAPHICS_OUTPUT_MODE_INFORMATION	*info;
+
+	status = BS->LocateProtocol(&gop_guid, NULL, (VOID **)&gop);
+	if (EFI_ERROR(status))
+		return (1);
+
+	mode = gop->Mode;
+	info = gop->Mode->Info;
+
+	efifb->fb_addr = mode->FrameBufferBase;
+	efifb->fb_size = mode->FrameBufferSize;
+	efifb->fb_height = info->VerticalResolution;
+	efifb->fb_width = info->HorizontalResolution;
+	efifb->fb_stride = info->PixelsPerScanLine;
+
+	switch (info->PixelFormat) {
+	case PixelRedGreenBlueReserved8BitPerColor:
+		efifb->fb_mask_red = 0x000000ff;
+		efifb->fb_mask_green = 0x0000ff00;
+		efifb->fb_mask_blue = 0x00ff0000;
+		efifb->fb_mask_reserved = 0xff000000;
+		break;
+	case PixelBlueGreenRedReserved8BitPerColor:
+		efifb->fb_mask_red = 0x00ff0000;
+		efifb->fb_mask_green = 0x0000ff00;
+		efifb->fb_mask_blue = 0x000000ff;
+		efifb->fb_mask_reserved = 0xff000000;
+		break;
+	case PixelBitMask:
+		efifb->fb_mask_red = info->PixelInformation.RedMask;
+		efifb->fb_mask_green = info->PixelInformation.GreenMask;
+		efifb->fb_mask_blue = info->PixelInformation.BlueMask;
+		efifb->fb_mask_reserved =
+		    info->PixelInformation.ReservedMask;
+		break;
+	default:
+		return (1);
+	}
+	return (0);
+}

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201504010830.t318Ufhn039066>