svn commit: r189937 - projects/efi/sys/boot/i386/efi

Rui Paulo rpaulo at FreeBSD.org
Tue Mar 17 12:57:13 PDT 2009


Author: rpaulo
Date: Tue Mar 17 19:57:11 2009
New Revision: 189937
URL: http://svn.freebsd.org/changeset/base/189937

Log:
  loader.efi support for i386.
  
  Obtained from:	//depot/projects/efi/

Added:
  projects/efi/sys/boot/i386/efi/
  projects/efi/sys/boot/i386/efi/Makefile
  projects/efi/sys/boot/i386/efi/conf.c
  projects/efi/sys/boot/i386/efi/exec.c
  projects/efi/sys/boot/i386/efi/ldscript.amd64
  projects/efi/sys/boot/i386/efi/ldscript.i386
  projects/efi/sys/boot/i386/efi/main.c
  projects/efi/sys/boot/i386/efi/reloc.c
  projects/efi/sys/boot/i386/efi/start.S
  projects/efi/sys/boot/i386/efi/version

Added: projects/efi/sys/boot/i386/efi/Makefile
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/efi/sys/boot/i386/efi/Makefile	Tue Mar 17 19:57:11 2009	(r189937)
@@ -0,0 +1,67 @@
+# $FreeBSD$
+
+NO_MAN=
+WITHOUT_SSP=
+BUILDING_EFI=
+
+.include <bsd.own.mk>
+
+PROG=		loader.sym
+INTERNALPROG=
+
+# architecture-specific loader code
+SRCS=		main.c exec.c conf.c vers.c reloc.c start.S
+
+CFLAGS+=	-I${.CURDIR}/../../efi/include
+CFLAGS+=	-I${.CURDIR}/../../efi/include/i386
+
+.if ${MK_FORTH} != "no"
+BOOT_FORTH=	yes
+CFLAGS+=	-DBOOT_FORTH
+CFLAGS+=	-I${.CURDIR}/../../ficl
+CFLAGS+=	-I${.CURDIR}/../../ficl/i386
+LIBFICL=	${.OBJDIR}/../../ficl/libficl.a
+.endif
+
+# Include bcache code.
+HAVE_BCACHE=    yes
+
+# Always add MI sources 
+.PATH:		${.CURDIR}/../../common
+.include	"${.CURDIR}/../../common/Makefile.inc"
+CFLAGS+=	-I${.CURDIR}/../../common
+
+FILES=	loader.efi
+FILESMODE_loader.efi=	${BINMODE}
+
+LDSCRIPT=	${.CURDIR}/ldscript.${MACHINE_ARCH}
+LDFLAGS=	-Wl,-T${LDSCRIPT} -shared -symbolic
+
+${PROG}:	${LDSCRIPT}
+
+CLEANFILES=	vers.c loader.efi
+
+NEWVERSWHAT=	"EFI loader" ${MACHINE_ARCH}
+
+vers.c:	${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version
+	sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT}
+
+OBJCOPY?=	objcopy
+OBJDUMP?=	objdump
+
+loader.efi: loader.sym
+	if [ `${OBJDUMP} -t ${.ALLSRC} | fgrep '*UND*' | wc -l` != 0 ]; then \
+		${OBJDUMP} -t ${.ALLSRC} | fgrep '*UND*'; \
+		exit 1; \
+	fi
+	${OBJCOPY} -j .data -j .dynamic -j .dynstr -j .dynsym -j .hash \
+	    -j .rel.dyn -j .reloc -j .sdata -j .text -j set_Xcommand_set \
+	    --target=efi-app-ia32 ${.ALLSRC} ${.TARGET}
+
+LIBEFI=		${.OBJDIR}/../../efi/libefi/libefi.a
+LIBI386=	${.OBJDIR}/../libi386/libi386.a
+
+DPADD=		${LIBFICL} ${LIBEFI} ${LIBI386} ${LIBSTAND}
+LDADD=		${LIBFICL} ${LIBEFI} ${LIBI386} -lstand
+
+.include <bsd.prog.mk>

Added: projects/efi/sys/boot/i386/efi/conf.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/efi/sys/boot/i386/efi/conf.c	Tue Mar 17 19:57:11 2009	(r189937)
@@ -0,0 +1,72 @@
+/*-
+ * Copyright (c) 2006 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <bootstrap.h>
+#include <efi.h>
+#include <efilib.h>
+
+struct devsw *devsw[] = {
+	&efifs_dev,
+	&efinet_dev,
+	NULL
+};
+
+struct fs_ops *file_system[] = {
+	&efifs_fsops,
+	&ufs_fsops,
+	&dosfs_fsops,
+	&nfs_fsops,
+	NULL
+};
+
+struct netif_driver *netif_drivers[] = {
+	&efinetif,
+	NULL
+};
+
+extern struct file_format amd64_elf;
+extern struct file_format amd64_elf_obj;
+extern struct file_format i386_elf;
+extern struct file_format i386_elf_obj;
+
+struct file_format *file_formats[] = {
+	&amd64_elf,
+	&amd64_elf_obj,
+	&i386_elf,
+	&i386_elf_obj,
+	NULL
+};
+
+extern struct console efi_console;
+
+struct console *consoles[] = {
+	&efi_console,
+	NULL
+};

Added: projects/efi/sys/boot/i386/efi/exec.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/efi/sys/boot/i386/efi/exec.c	Tue Mar 17 19:57:11 2009	(r189937)
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 2006 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include "../btx/lib/btxv86.h"
+
+uint32_t __base;
+struct __v86 __v86;
+
+void
+__v86int()
+{
+	printf("%s\n", __func__);
+	exit(1);
+}
+
+void
+__exec(caddr_t addr, ...)
+{
+	printf("%s(%p, ...)\n", __func__, addr);
+	exit (0);
+}

Added: projects/efi/sys/boot/i386/efi/ldscript.amd64
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/efi/sys/boot/i386/efi/ldscript.amd64	Tue Mar 17 19:57:11 2009	(r189937)
@@ -0,0 +1,72 @@
+/* $FreeBSD$ */
+OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
+OUTPUT_ARCH(i386:x86-64)
+ENTRY(_start)
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  . = 0;
+  ImageBase = .;
+  . = SIZEOF_HEADERS;
+  . = ALIGN(4096);
+  .text		: {
+    *(.text .stub .text.* .gnu.linkonce.t.*)
+    /* .gnu.warning sections are handled specially by elf32.em. */
+    *(.gnu.warning)
+    *(.plt)
+  } =0x00300000010070000002000001000400
+  . = ALIGN(4096);
+  .data		: {
+    *(.rodata .rodata.* .gnu.linkonce.r.*)
+    *(.rodata1)
+    *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+    *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)
+    *(.opd)
+    *(.data .data.* .gnu.linkonce.d.*)
+    *(.data1)
+    *(.plabel)
+    *(.dynbss)
+    *(.bss .bss.* .gnu.linkonce.b.*)
+    *(COMMON)
+  }
+  . = ALIGN(4096);
+  set_Xcommand_set	: {
+    __start_set_Xcommand_set = .;
+    *(set_Xcommand_set)
+    __stop_set_Xcommand_set = .;
+  }
+  . = ALIGN(4096);
+  __gp = .;
+  .sdata	: {
+    *(.got.plt .got)
+    *(.sdata .sdata.* .gnu.linkonce.s.*)
+    *(dynsbss)
+    *(.sbss .sbss.* .gnu.linkonce.sb.*)
+    *(.scommon)
+  }
+  . = ALIGN(4096);
+  .dynamic	: { *(.dynamic) }
+  . = ALIGN(4096);
+  .rel.dyn	: {
+    *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
+    *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
+    *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
+    *(.rel.got)
+    *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*)
+    *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*)
+    *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*)
+    *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*)
+    *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
+    *(.rel.plt)
+    *(.relset_*)
+    *(.rel.dyn .rel.dyn.*)
+  }
+  . = ALIGN(4096);
+  .reloc	: { *(.reloc) }
+  . = ALIGN(4096);
+  .hash		: { *(.hash) }
+  . = ALIGN(4096);
+  .dynsym	: { *(.dynsym) }
+  . = ALIGN(4096);
+  .dynstr	: { *(.dynstr) }
+}

Added: projects/efi/sys/boot/i386/efi/ldscript.i386
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/efi/sys/boot/i386/efi/ldscript.i386	Tue Mar 17 19:57:11 2009	(r189937)
@@ -0,0 +1,72 @@
+/* $FreeBSD$ */
+OUTPUT_FORMAT("elf32-i386-freebsd", "elf32-i386-freebsd", "elf32-i386-freebsd")
+OUTPUT_ARCH(i386)
+ENTRY(_start)
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  . = 0;
+  ImageBase = .;
+  . = SIZEOF_HEADERS;
+  . = ALIGN(4096);
+  .text		: {
+    *(.text .stub .text.* .gnu.linkonce.t.*)
+    /* .gnu.warning sections are handled specially by elf32.em. */
+    *(.gnu.warning)
+    *(.plt)
+  } =0x00300000010070000002000001000400
+  . = ALIGN(4096);
+  .data		: {
+    *(.rodata .rodata.* .gnu.linkonce.r.*)
+    *(.rodata1)
+    *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+    *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)
+    *(.opd)
+    *(.data .data.* .gnu.linkonce.d.*)
+    *(.data1)
+    *(.plabel)
+    *(.dynbss)
+    *(.bss .bss.* .gnu.linkonce.b.*)
+    *(COMMON)
+  }
+  . = ALIGN(4096);
+  set_Xcommand_set	: {
+    __start_set_Xcommand_set = .;
+    *(set_Xcommand_set)
+    __stop_set_Xcommand_set = .;
+  }
+  . = ALIGN(4096);
+  __gp = .;
+  .sdata	: {
+    *(.got.plt .got)
+    *(.sdata .sdata.* .gnu.linkonce.s.*)
+    *(dynsbss)
+    *(.sbss .sbss.* .gnu.linkonce.sb.*)
+    *(.scommon)
+  }
+  . = ALIGN(4096);
+  .dynamic	: { *(.dynamic) }
+  . = ALIGN(4096);
+  .rel.dyn	: {
+    *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
+    *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
+    *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
+    *(.rel.got)
+    *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*)
+    *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*)
+    *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*)
+    *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*)
+    *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
+    *(.rel.plt)
+    *(.relset_*)
+    *(.rel.dyn .rel.dyn.*)
+  }
+  . = ALIGN(4096);
+  .reloc	: { *(.reloc) }
+  . = ALIGN(4096);
+  .hash		: { *(.hash) }
+  . = ALIGN(4096);
+  .dynsym	: { *(.dynsym) }
+  . = ALIGN(4096);
+  .dynstr	: { *(.dynstr) }
+}

Added: projects/efi/sys/boot/i386/efi/main.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/efi/sys/boot/i386/efi/main.c	Tue Mar 17 19:57:11 2009	(r189937)
@@ -0,0 +1,371 @@
+/*-
+ * Copyright (c) 2008 Rui Paulo
+ * Copyright (c) 2006 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <string.h>
+#include <setjmp.h>
+
+#include <efi.h>
+#include <efilib.h>
+
+#include <bootstrap.h>
+#include "../libi386/libi386.h"
+
+extern char bootprog_name[];
+extern char bootprog_rev[];
+extern char bootprog_date[];
+extern char bootprog_maker[];
+
+struct devdesc currdev;		/* our current device */
+struct arch_switch archsw;	/* MI/MD interface boundary */
+
+EFI_GUID acpi = ACPI_TABLE_GUID;
+EFI_GUID acpi20 = ACPI_20_TABLE_GUID;
+EFI_GUID devid = DEVICE_PATH_PROTOCOL;
+EFI_GUID imgid = LOADED_IMAGE_PROTOCOL;
+EFI_GUID mps = MPS_TABLE_GUID;
+EFI_GUID netid = EFI_SIMPLE_NETWORK_PROTOCOL;
+EFI_GUID smbios = SMBIOS_TABLE_GUID;
+
+EFI_STATUS
+main(int argc, CHAR16 *argv[])
+{
+	char vendor[128];
+	EFI_LOADED_IMAGE *img;
+	int i;
+
+	/* 
+	 * XXX Chicken-and-egg problem; we want to have console output
+	 * early, but some console attributes may depend on reading from
+	 * eg. the boot device, which we can't do yet.  We can use
+	 * printf() etc. once this is done.
+	 */
+	cons_probe();
+
+	/*
+	 * March through the device switch probing for things.
+	 */
+	for (i = 0; devsw[i] != NULL; i++)
+		if (devsw[i]->dv_init != NULL)
+			(devsw[i]->dv_init)();
+
+	/* Get our loaded image protocol interface structure. */
+	BS->HandleProtocol(IH, &imgid, (VOID**)&img);
+
+	printf("Image base: 0x%lx\n", (u_long)img->ImageBase);
+	printf("EFI version: %d.%02d\n", ST->Hdr.Revision >> 16,
+	    ST->Hdr.Revision & 0xffff);
+	printf("EFI Firmware: ");
+	/* printf doesn't understand EFI Unicode */
+	ST->ConOut->OutputString(ST->ConOut, ST->FirmwareVendor);
+	printf(" (rev %d.%02d)\n", ST->FirmwareRevision >> 16,
+	    ST->FirmwareRevision & 0xffff);
+
+	printf("\n");
+	printf("%s, Revision %s\n", bootprog_name, bootprog_rev);
+	printf("(%s, %s)\n", bootprog_maker, bootprog_date);
+
+	efi_handle_lookup(img->DeviceHandle, &currdev.d_dev, &currdev.d_unit);
+	currdev.d_type = currdev.d_dev->dv_type;
+
+	/*
+	 * Disable the watchdog timer. By default the boot manager sets
+	 * the timer to 5 minutes before invoking a boot option. If we
+	 * want to return to the boot manager, we have to disable the
+	 * watchdog timer and since we're an interactive program, we don't
+	 * want to wait until the user types "quit". The timer may have
+	 * fired by then. We don't care if this fails. It does not prevent
+	 * normal functioning in any way...
+	 */
+	BS->SetWatchdogTimer(0, 0, 0, NULL);
+
+	env_setenv("currdev", EV_VOLATILE, i386_fmtdev(&currdev),
+	    i386_setcurrdev, env_nounset);
+	env_setenv("loaddev", EV_VOLATILE, i386_fmtdev(&currdev), env_noset,
+	    env_nounset);
+
+	setenv("LINES", "24", 1);	/* optional */
+    
+	archsw.arch_autoload = i386_autoload;
+	archsw.arch_getdev = i386_getdev;
+	archsw.arch_copyin = i386_copyin;
+	archsw.arch_copyout = i386_copyout;
+	archsw.arch_readin = i386_readin;
+
+	interact();			/* doesn't return */
+
+	return (EFI_SUCCESS);		/* keep compiler happy */
+}
+
+COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
+
+static int
+command_reboot(int argc, char *argv[])
+{
+	int i;
+
+	for (i = 0; devsw[i] != NULL; ++i)
+		if (devsw[i]->dv_cleanup != NULL)
+			(devsw[i]->dv_cleanup)();
+
+	RS->ResetSystem(EfiResetCold, EFI_SUCCESS, 23,
+	    (CHAR16 *)"Reboot from the loader");
+
+	/* NOTREACHED */
+	return (CMD_ERROR);
+}
+
+COMMAND_SET(quit, "quit", "exit the loader", command_quit);
+
+static int
+command_quit(int argc, char *argv[])
+{
+	exit(0);
+	return (CMD_OK);
+}
+
+COMMAND_SET(memmap, "memmap", "print memory map", command_memmap);
+
+static int
+command_memmap(int argc, char *argv[])
+{
+	UINTN sz;
+	EFI_MEMORY_DESCRIPTOR *map, *p;
+	UINTN key, dsz;
+	UINT32 dver;
+	EFI_STATUS status;
+	int i, ndesc;
+	static char *types[] = {
+	    "Reserved",
+	    "LoaderCode",
+	    "LoaderData",
+	    "BootServicesCode",
+	    "BootServicesData",
+	    "RuntimeServicesCode",
+	    "RuntimeServicesData",
+	    "ConventionalMemory",
+	    "UnusableMemory",
+	    "ACPIReclaimMemory",
+	    "ACPIMemoryNVS",
+	    "MemoryMappedIO",
+	    "MemoryMappedIOPortSpace",
+	    "PalCode"
+	};
+
+	sz = 0;
+	status = BS->GetMemoryMap(&sz, 0, &key, &dsz, &dver);
+	if (status != EFI_BUFFER_TOO_SMALL) {
+		printf("Can't determine memory map size\n");
+		return CMD_ERROR;
+	}
+	map = malloc(sz);
+	status = BS->GetMemoryMap(&sz, map, &key, &dsz, &dver);
+	if (EFI_ERROR(status)) {
+		printf("Can't read memory map\n");
+		return CMD_ERROR;
+	}
+
+	ndesc = sz / dsz;
+	printf("%23s %12s %12s %8s %4s\n",
+	       "Type", "Physical", "Virtual", "#Pages", "Attr");
+	       
+	for (i = 0, p = map; i < ndesc;
+	     i++, p = NextMemoryDescriptor(p, dsz)) {
+	    printf("%23s %012lx %012lx %08lx ",
+		   types[p->Type],
+		   p->PhysicalStart,
+		   p->VirtualStart,
+		   p->NumberOfPages);
+	    if (p->Attribute & EFI_MEMORY_UC)
+		printf("UC ");
+	    if (p->Attribute & EFI_MEMORY_WC)
+		printf("WC ");
+	    if (p->Attribute & EFI_MEMORY_WT)
+		printf("WT ");
+	    if (p->Attribute & EFI_MEMORY_WB)
+		printf("WB ");
+	    if (p->Attribute & EFI_MEMORY_UCE)
+		printf("UCE ");
+	    if (p->Attribute & EFI_MEMORY_WP)
+		printf("WP ");
+	    if (p->Attribute & EFI_MEMORY_RP)
+		printf("RP ");
+	    if (p->Attribute & EFI_MEMORY_XP)
+		printf("XP ");
+	    printf("\n");
+	}
+
+	return CMD_OK;
+}
+
+COMMAND_SET(configuration, "configuration",
+	    "print configuration tables", command_configuration);
+
+static const char *
+guid_to_string(EFI_GUID *guid)
+{
+	static char buf[40];
+
+	sprintf(buf, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+	    guid->Data1, guid->Data2, guid->Data3, guid->Data4[0],
+	    guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4],
+	    guid->Data4[5], guid->Data4[6], guid->Data4[7]);
+	return (buf);
+}
+
+static int
+command_configuration(int argc, char *argv[])
+{
+	int i;
+
+	printf("NumberOfTableEntries=%ld\n", ST->NumberOfTableEntries);
+	for (i = 0; i < ST->NumberOfTableEntries; i++) {
+		EFI_GUID *guid;
+
+		printf("  ");
+		guid = &ST->ConfigurationTable[i].VendorGuid;
+		if (!memcmp(guid, &mps, sizeof(EFI_GUID)))
+			printf("MPS Table");
+		else if (!memcmp(guid, &acpi, sizeof(EFI_GUID)))
+			printf("ACPI Table");
+		else if (!memcmp(guid, &acpi20, sizeof(EFI_GUID)))
+			printf("ACPI 2.0 Table");
+		else if (!memcmp(guid, &smbios, sizeof(EFI_GUID)))
+			printf("SMBIOS Table");
+		else
+			printf("Unknown Table (%s)", guid_to_string(guid));
+		printf(" at %p\n", ST->ConfigurationTable[i].VendorTable);
+	}
+
+	return CMD_OK;
+}    
+
+
+COMMAND_SET(mode, "mode", "change or display text modes", command_mode);
+
+static int
+command_mode(int argc, char *argv[])
+{
+	unsigned int cols, rows, mode;
+	int i;
+	char *cp;
+	char rowenv[8];
+	EFI_STATUS status;
+	SIMPLE_TEXT_OUTPUT_INTERFACE *conout;
+
+	conout = ST->ConOut;
+
+	if (argc > 1) {
+		mode = strtol(argv[1], &cp, 0);
+		if (cp[0] != '\0') {
+			printf("Invalid mode\n");
+			return (CMD_ERROR);
+		}
+		status = conout->QueryMode(conout, mode, &cols, &rows);
+		if (EFI_ERROR(status)) {
+			printf("invalid mode %d\n", mode);
+			return (CMD_ERROR);
+		}
+		status = conout->SetMode(conout, mode);
+		if (EFI_ERROR(status)) {
+			printf("couldn't set mode %d\n", mode);
+			return (CMD_ERROR);
+		}
+		sprintf(rowenv, "%d", rows);
+		setenv("LINES", rowenv, 1);
+
+		return (CMD_OK);
+	}
+
+	for (i = 0; ; i++) {
+		status = conout->QueryMode(conout, i, &cols, &rows);
+		if (EFI_ERROR(status))
+			break;
+		printf("Mode %d: %d columns, %d rows\n", i, cols, rows);
+	}
+
+	if (i != 0)
+		printf("Choose the mode with \"col <mode number>\"\n");	
+
+	return (CMD_OK);
+}
+
+
+COMMAND_SET(nvram, "nvram", "get or set NVRAM variables", command_nvram);
+
+static int
+command_nvram(int argc, char *argv[])
+{
+	CHAR16 var[128];
+	CHAR16 *data;
+	EFI_STATUS status;
+	EFI_GUID varguid = { 0,0,0,{0,0,0,0,0,0,0,0} };
+	unsigned int varsz;
+	unsigned int datasz;
+	SIMPLE_TEXT_OUTPUT_INTERFACE *conout;
+	int i;
+
+	conout = ST->ConOut;
+
+	/* Initiate the search */
+	status = RS->GetNextVariableName(&varsz, NULL, NULL);
+
+	for (; status != EFI_NOT_FOUND; ) {
+		status = RS->GetNextVariableName(&varsz, var,
+		    &varguid);
+		//if (EFI_ERROR(status))
+			//break;
+
+		conout->OutputString(conout, var);
+		printf("=");
+		datasz = 0;
+		status = RS->GetVariable(var, &varguid, NULL, &datasz,
+		    NULL);
+		/* XXX: check status */
+		data = malloc(datasz);
+		status = RS->GetVariable(var, &varguid, NULL, &datasz,
+		    data);
+		if (EFI_ERROR(status))
+			printf("<error retrieving variable>");
+		else {
+			for (i = 0; i < datasz; i++) {
+				if (isalnum(data[i]) || isspace(data[i]))
+					printf("%c", data[i]);
+				else
+					printf("\\x%02x", data[i]);
+			}
+		}
+		/* XXX */
+		pager_output("\n");
+		free(data);
+	}
+
+	return (CMD_OK);
+}

Added: projects/efi/sys/boot/i386/efi/reloc.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/efi/sys/boot/i386/efi/reloc.c	Tue Mar 17 19:57:11 2009	(r189937)
@@ -0,0 +1,103 @@
+/*-
+ * Copyright (c) 2008 Rui Paulo
+ * 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/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/elf32.h>
+#include <efi.h>
+
+/*
+ * XXX: we can't include sys/systm.h.
+ */
+#ifndef CTASSERT                /* Allow lint to override */
+#define CTASSERT(x)             _CTASSERT(x, __LINE__)
+#define _CTASSERT(x, y)         __CTASSERT(x, y)
+#define __CTASSERT(x, y)        typedef char __assert ## y[(x) ? 1 : -1]
+#endif
+
+
+/*
+ * A simple relocator for IA32 EFI binaries.
+ */
+EFI_STATUS
+_reloc(unsigned long ImageBase, Elf32_Dyn *dynamic, EFI_HANDLE image_handle,
+    EFI_SYSTEM_TABLE *system_table)
+{
+	unsigned long relsz, relent;
+	unsigned long *newaddr;
+	Elf32_Rel *rel;
+	Elf32_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:
+			rel = (Elf32_Rel *) ((unsigned long) dynp->d_un.d_ptr +
+			    ImageBase);
+			break;
+		case DT_RELSZ:
+			relsz = dynp->d_un.d_val;
+			break;
+		case DT_RELENT:
+			relent = dynp->d_un.d_val;
+			break;
+		default:
+			break;
+		}
+	}
+
+	/*
+	 * Perform the actual relocation.
+	 * XXX: We are reusing code for the amd64 version of this, but
+	 * we must make sure the relocation types are the same.
+	 */
+	CTASSERT(R_386_NONE == R_X86_64_NONE);
+	CTASSERT(R_386_RELATIVE == R_X86_64_RELATIVE);
+	for (; relsz > 0; relsz -= relent) {
+		switch (ELF32_R_TYPE(rel->r_info)) {
+		case R_386_NONE:
+			/* No relocation needs be performed. */
+			break;
+		case R_386_RELATIVE:
+			/* Address relative to the base address. */
+			newaddr = (unsigned long *)(ImageBase + rel->r_offset);
+			*newaddr += ImageBase;
+			break;
+		default:
+			/* XXX: do we need other relocations ? */
+			return (EFI_LOAD_ERROR);
+		}
+		rel = (Elf32_Rel *) ((caddr_t) rel + relent);
+	}
+
+	return (EFI_SUCCESS);
+}

Added: projects/efi/sys/boot/i386/efi/start.S
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/efi/sys/boot/i386/efi/start.S	Tue Mar 17 19:57:11 2009	(r189937)
@@ -0,0 +1,70 @@
+/*-
+ * Copyright (c) 2008 Rui Paulo
+ * 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$
+ */
+
+	.text
+
+#include <machine/asm.h>
+
+#define EFI_SUCCESS		0
+
+/*
+ * 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	_reloc
+	cmpl	$EFI_SUCCESS, %eax
+	jne	1f
+	popl	%ebx		/* remove ImageBase from the stack */
+	popl	%ebx		/* remove dynamic from the stack */
+	call	efi_main
+1:	leave
+	ret
+END(_start)
+
+	.data
+	.section .reloc, "a"
+	.long	0
+	.long	10
+	.word	0

Added: projects/efi/sys/boot/i386/efi/version
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/efi/sys/boot/i386/efi/version	Tue Mar 17 19:57:11 2009	(r189937)
@@ -0,0 +1,7 @@
+$FreeBSD$
+
+NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE.  The format of this
+file is important.  Make sure the current version number is on line 6.
+
+1.1:	Keep in sync with i386 version.
+0.1:	Initial i386 version. Derived from ia64.


More information about the svn-src-projects mailing list