summaryrefslogtreecommitdiffstats
path: root/sys/boot/efi/loader
diff options
context:
space:
mode:
Diffstat (limited to 'sys/boot/efi/loader')
-rw-r--r--sys/boot/efi/loader/Makefile123
-rw-r--r--sys/boot/efi/loader/conf.c95
-rw-r--r--sys/boot/efi/loader/main.c562
-rw-r--r--sys/boot/efi/loader/version16
4 files changed, 796 insertions, 0 deletions
diff --git a/sys/boot/efi/loader/Makefile b/sys/boot/efi/loader/Makefile
new file mode 100644
index 0000000..e2f9a84
--- /dev/null
+++ b/sys/boot/efi/loader/Makefile
@@ -0,0 +1,123 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../common
+
+BASE= loader
+PROG= ${BASE}.efi
+NOMAN=
+NEWVERSWHAT= "EFI boot" ${MACHINE_ARCH}
+BINDIR?= /boot
+STRIP= # We must not strip loader.efi at install time.
+
+SRCS+= main.c conf.c dev_net.c
+
+CFLAGS+= -ffreestanding
+
+.if !defined(NOFORTH)
+# Enable BootForth
+BOOT_FORTH= yes
+CFLAGS+= -DBOOT_FORTH
+CFLAGS+= -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/${MACHINE_ARCH}
+.if exists(${.OBJDIR}/../../ficl/libficl.a)
+LIBFICL= ${.OBJDIR}/../../ficl/libficl.a
+.else
+LIBFICL= ${.CURDIR}/../../ficl/libficl.a
+.endif
+.endif
+
+# where to get libstand from
+.if exists(${.OBJDIR}/../../../../lib/libstand/libstand.a)
+LIBSTAND= ${.OBJDIR}/../../../../lib/libstand/libstand.a
+.else
+LIBSTAND= ${.CURDIR}/../../../../lib/libstand/libstand.a
+.endif
+
+.if exists(${.OBJDIR}/../libefi/libefi.a)
+LIBEFI= ${.OBJDIR}/../libefi/libefi.a
+.else
+LIBEFI= ${.CURDIR}/../libefi/libefi.a
+.endif
+
+# Always add MI sources
+.PATH: ${.CURDIR}/../../common
+.include <${.CURDIR}/../../common/Makefile.inc>
+
+CFLAGS+= -I-
+CFLAGS+= -I${.CURDIR}/../include
+CFLAGS+= -I${.CURDIR}/../include/${MACHINE_ARCH}
+CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}
+CFLAGS+= -I${.CURDIR}/../../.. -I.
+CFLAGS+= -I${.CURDIR}/../libefi
+CFLAGS+= -I${.CURDIR}/../../../../lib/libstand
+CFLAGS+= -DLOADER
+
+LDSCRIPT= ${.CURDIR}/../libefi/arch/${MACHINE_ARCH}/ldscript.${MACHINE_ARCH}
+LDFLAGS= -nostdlib -T ${LDSCRIPT} -shared -Bsymbolic
+OBJCOPY?= objcopy
+
+CLEANFILES+= setdef0.c setdef0.o setdef1.c setdef1.o setdefs.h start.o \
+ vers.c vers.o ${BASE}.efi ${BASE}.sym ${BASE}.list
+CLEANFILES+= loader.help
+CLEANFILES+= machine
+
+CRT= start.o
+
+all: ${BASE}
+
+vers.o: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version
+ sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT}
+ ${CC} -c vers.c
+
+${BASE}: ${BASE}.efi ${BASE}.help
+
+${BASE}.efi: ${BASE}.sym
+ ${OBJCOPY} -j .text \
+ -j .hash \
+ -j .data \
+ -j .sdata \
+ -j .dynamic \
+ -j .rela \
+ -j .reloc \
+ -j .dynsym \
+ -j .dynstr \
+ --target=efi-app-${MACHINE_ARCH} \
+ ${BASE}.sym ${BASE}.efi
+
+${BASE}.help: help.common
+ cat ${.ALLSRC} | awk -f ${.CURDIR}/../../common/merge_help.awk \
+ > ${.TARGET}
+
+beforeinstall:
+.if exists(${.OBJDIR}/loader.help)
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
+ ${.OBJDIR}/${BASE}.help ${DESTDIR}/boot
+.else
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
+ ${.CURDIR}/${BASE}.help ${DESTDIR}/boot
+.endif
+.if !exists(${DESTDIR}/boot/loader.rc)
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
+ ${.CURDIR}/../../forth/loader.rc ${DESTDIR}/boot
+.endif
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
+ ${.CURDIR}/../../forth/loader.4th ${DESTDIR}/boot
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
+ ${.CURDIR}/../../forth/support.4th ${DESTDIR}/boot
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
+ ${.CURDIR}/../../forth/loader.conf ${DESTDIR}/boot/defaults
+
+
+# Other fragments still to be brought in from ../Makfile.booters?
+start.o: ${.CURDIR}/../libefi/arch/${MACHINE_ARCH}/start.S
+ ${CC} -c ${CFLAGS} ${.IMPSRC}
+
+machine:
+ ln -sf ${.CURDIR}/../../../${MACHINE_ARCH}/include machine
+
+.include <bsd.prog.mk>
+
+${BASE}.sym: ${OBJS} ${LIBFICL} ${LIBEFI} ${LIBSTAND} ${CRT} vers.o
+ ${LD} ${LDFLAGS} -o ${BASE}.sym -M ${CRT} ${OBJS} vers.o \
+ ${LIBFICL} ${LIBEFI} ${LIBSTAND} > ${.OBJDIR}/${BASE}.list
+
+beforedepend ${OBJS}: machine
diff --git a/sys/boot/efi/loader/conf.c b/sys/boot/efi/loader/conf.c
new file mode 100644
index 0000000..145b16b
--- /dev/null
+++ b/sys/boot/efi/loader/conf.c
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project
+ * by Matthias Drochner.
+ * 4. The name of the author 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.
+ *
+ * $NetBSD: conf.c,v 1.2 1997/03/22 09:03:29 thorpej Exp $
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <efi.h>
+#include <efilib.h>
+
+#include "efiboot.h"
+
+/*
+ * We could use linker sets for some or all of these, but
+ * then we would have to control what ended up linked into
+ * the bootstrap. So it's easier to conditionalise things
+ * here.
+ *
+ * XXX rename these arrays to be consistent and less namespace-hostile
+ */
+
+/* Exported for libstand */
+struct devsw *devsw[] = {
+ &efifs_dev,
+ &netdev,
+ NULL
+};
+
+struct fs_ops *file_system[] = {
+ &efi_fsops,
+/* &ufs_fsops, */
+ &nfs_fsops,
+ &gzipfs_fsops,
+ NULL
+};
+
+struct netif_driver *netif_drivers[] = {
+ &efi_net,
+ NULL,
+};
+
+/* Exported for ia64 only */
+/*
+ * Sort formats so that those that can detect based on arguments
+ * rather than reading the file go first.
+ */
+extern struct file_format ia64_elf;
+
+struct file_format *file_formats[] = {
+ &ia64_elf,
+ NULL
+};
+
+/*
+ * Consoles
+ *
+ * We don't prototype these in efiboot.h because they require
+ * data structures from bootstrap.h as well.
+ */
+extern struct console efi_console;
+
+struct console *consoles[] = {
+ &efi_console,
+ NULL
+};
diff --git a/sys/boot/efi/loader/main.c b/sys/boot/efi/loader/main.c
new file mode 100644
index 0000000..752c243
--- /dev/null
+++ b/sys/boot/efi/loader/main.c
@@ -0,0 +1,562 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * Copyright (c) 1998,2000 Doug Rabson <dfr@freebsd.org>
+ * 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 <stand.h>
+#include <string.h>
+#include <setjmp.h>
+#include <machine/sal.h>
+#include <machine/pal.h>
+#include <machine/pte.h>
+#include <machine/dig64.h>
+
+#include <efi.h>
+#include <efilib.h>
+
+#include "bootstrap.h"
+#include "efiboot.h"
+
+extern char bootprog_name[];
+extern char bootprog_rev[];
+extern char bootprog_date[];
+extern char bootprog_maker[];
+
+struct efi_devdesc currdev; /* our current device */
+struct arch_switch archsw; /* MI/MD interface boundary */
+
+extern u_int64_t ia64_pal_entry;
+
+EFI_GUID acpi = ACPI_TABLE_GUID;
+EFI_GUID acpi20 = ACPI_20_TABLE_GUID;
+EFI_GUID devid = DEVICE_PATH_PROTOCOL;
+EFI_GUID hcdp = HCDP_TABLE_GUID;
+EFI_GUID imgid = LOADED_IMAGE_PROTOCOL;
+EFI_GUID mps = MPS_TABLE_GUID;
+EFI_GUID netid = EFI_SIMPLE_NETWORK_PROTOCOL;
+EFI_GUID sal = SAL_SYSTEM_TABLE_GUID;
+EFI_GUID smbios = SMBIOS_TABLE_GUID;
+
+static void
+find_pal_proc(void)
+{
+ int i;
+ struct sal_system_table *saltab = 0;
+ static int sizes[6] = {
+ 48, 32, 16, 32, 16, 16
+ };
+ u_int8_t *p;
+
+ saltab = efi_get_table(&sal);
+ if (saltab == NULL) {
+ printf("Can't find SAL System Table\n");
+ return;
+ }
+
+ if (memcmp(saltab->sal_signature, "SST_", 4)) {
+ printf("Bad signature for SAL System Table\n");
+ return;
+ }
+
+ p = (u_int8_t *) (saltab + 1);
+ for (i = 0; i < saltab->sal_entry_count; i++) {
+ if (*p == 0) {
+ struct sal_entrypoint_descriptor *dp;
+ dp = (struct sal_entrypoint_descriptor *) p;
+ ia64_pal_entry = dp->sale_pal_proc;
+ return;
+ }
+ p += sizes[*p];
+ }
+
+ printf("Can't find PAL proc\n");
+ return;
+}
+
+EFI_STATUS
+main(int argc, CHAR16 *argv[])
+{
+ 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();
+
+ /*
+ * Initialise the block cache
+ */
+ bcache_init(32, 512); /* 16k XXX tune this */
+
+ find_pal_proc();
+
+ /*
+ * 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)();
+
+ efinet_init_driver();
+
+ /* Get our loaded image protocol interface structure. */
+ BS->HandleProtocol(IH, &imgid, (VOID**)&img);
+
+ printf("Image base: 0x%016lx\n", (u_long)img->ImageBase);
+
+ printf("\n");
+ printf("%s, Revision %s\n", bootprog_name, bootprog_rev);
+ printf("(%s, %s)\n", bootprog_maker, bootprog_date);
+
+ i = efifs_get_unit(img->DeviceHandle);
+ if (i >= 0) {
+ currdev.d_dev = devsw[0]; /* XXX disk */
+ currdev.d_kind.efidisk.unit = i;
+ /* XXX should be able to detect this, default to autoprobe */
+ currdev.d_kind.efidisk.slice = -1;
+ currdev.d_kind.efidisk.partition = 0;
+ } else {
+ currdev.d_dev = devsw[1]; /* XXX net */
+ currdev.d_kind.netif.unit = 0; /* XXX */
+ }
+ 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, efi_fmtdev(&currdev),
+ efi_setcurrdev, env_nounset);
+ env_setenv("loaddev", EV_VOLATILE, efi_fmtdev(&currdev), env_noset,
+ env_nounset);
+
+ setenv("LINES", "24", 1); /* optional */
+
+ archsw.arch_autoload = efi_autoload;
+ archsw.arch_getdev = efi_getdev;
+ archsw.arch_copyin = efi_copyin;
+ archsw.arch_copyout = efi_copyout;
+ archsw.arch_readin = efi_readin;
+
+ interact(); /* doesn't return */
+
+ return (EFI_SUCCESS); /* keep compiler happy */
+}
+
+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 ");
+ if (p->Attribute & EFI_MEMORY_RUNTIME)
+ printf("RUNTIME");
+ 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 if (!memcmp(guid, &sal, sizeof(EFI_GUID)))
+ printf("SAL System Table");
+ else if (!memcmp(guid, &hcdp, sizeof(EFI_GUID)))
+ printf("DIG64 HCDP Table");
+ else
+ printf("Unknown Table (%s)", guid_to_string(guid));
+ printf(" at %p\n", ST->ConfigurationTable[i].VendorTable);
+ }
+
+ return CMD_OK;
+}
+
+COMMAND_SET(sal, "sal", "print SAL System Table", command_sal);
+
+static int
+command_sal(int argc, char *argv[])
+{
+ int i;
+ struct sal_system_table *saltab = 0;
+ static int sizes[6] = {
+ 48, 32, 16, 32, 16, 16
+ };
+ u_int8_t *p;
+
+ saltab = efi_get_table(&sal);
+ if (saltab == NULL) {
+ printf("Can't find SAL System Table\n");
+ return CMD_ERROR;
+ }
+
+ if (memcmp(saltab->sal_signature, "SST_", 4)) {
+ printf("Bad signature for SAL System Table\n");
+ return CMD_ERROR;
+ }
+
+ printf("SAL Revision %x.%02x\n",
+ saltab->sal_rev[1],
+ saltab->sal_rev[0]);
+ printf("SAL A Version %x.%02x\n",
+ saltab->sal_a_version[1],
+ saltab->sal_a_version[0]);
+ printf("SAL B Version %x.%02x\n",
+ saltab->sal_b_version[1],
+ saltab->sal_b_version[0]);
+
+ p = (u_int8_t *) (saltab + 1);
+ for (i = 0; i < saltab->sal_entry_count; i++) {
+ printf(" Desc %d", *p);
+ if (*p == 0) {
+ struct sal_entrypoint_descriptor *dp;
+ dp = (struct sal_entrypoint_descriptor *) p;
+ printf("\n");
+ printf(" PAL Proc at 0x%lx\n",
+ dp->sale_pal_proc);
+ printf(" SAL Proc at 0x%lx\n",
+ dp->sale_sal_proc);
+ printf(" SAL GP at 0x%lx\n",
+ dp->sale_sal_gp);
+ } else if (*p == 1) {
+ struct sal_memory_descriptor *dp;
+ dp = (struct sal_memory_descriptor *) p;
+ printf(" Type %d.%d, ",
+ dp->sale_memory_type[0],
+ dp->sale_memory_type[1]);
+ printf("Address 0x%lx, ",
+ dp->sale_physical_address);
+ printf("Length 0x%x\n",
+ dp->sale_length);
+ } else if (*p == 5) {
+ struct sal_ap_wakeup_descriptor *dp;
+ dp = (struct sal_ap_wakeup_descriptor *) p;
+ printf("\n");
+ printf(" Mechanism %d\n", dp->sale_mechanism);
+ printf(" Vector 0x%lx\n", dp->sale_vector);
+ } else
+ printf("\n");
+
+ p += sizes[*p];
+ }
+
+ return CMD_OK;
+}
+
+int
+print_trs(int type)
+{
+ struct ia64_pal_result res;
+ int i, maxtr;
+ struct {
+ struct ia64_pte pte;
+ struct ia64_itir itir;
+ struct ia64_ifa ifa;
+ struct ia64_rr rr;
+ } buf;
+ static const char* psnames[] = {
+ "1B", "2B", "4B", "8B",
+ "16B", "32B", "64B", "128B",
+ "256B", "512B", "1K", "2K",
+ "4K", "8K", "16K", "32K",
+ "64K", "128K", "256K", "512K",
+ "1M", "2M", "4M", "8M",
+ "16M", "32M", "64M", "128M",
+ "256M", "512M", "1G", "2G"
+ };
+ static const char* manames[] = {
+ "WB", "bad", "bad", "bad",
+ "UC", "UCE", "WC", "NaT",
+
+ };
+
+ res = ia64_call_pal_static(PAL_VM_SUMMARY, 0, 0, 0);
+ if (res.pal_status != 0) {
+ printf("Can't get VM summary\n");
+ return CMD_ERROR;
+ }
+
+ if (type == 0)
+ maxtr = (res.pal_result[0] >> 40) & 0xff;
+ else
+ maxtr = (res.pal_result[0] >> 32) & 0xff;
+
+ printf("%d translation registers\n", maxtr);
+
+ pager_open();
+ pager_output("TR# RID Virtual Page Physical Page PgSz ED AR PL D A MA P KEY\n");
+ for (i = 0; i <= maxtr; i++) {
+ char lbuf[128];
+
+ bzero(&buf, sizeof(buf));
+ res = ia64_call_pal_stacked(PAL_VM_TR_READ, i, type,
+ (u_int64_t) &buf);
+ if (res.pal_status != 0)
+ break;
+
+ /* Only display valid translations */
+ if ((buf.ifa.ifa_ig & 1) == 0)
+ continue;
+
+ if (!(res.pal_result[0] & 1))
+ buf.pte.pte_ar = 0;
+ if (!(res.pal_result[0] & 2))
+ buf.pte.pte_pl = 0;
+ if (!(res.pal_result[0] & 4))
+ buf.pte.pte_d = 0;
+ if (!(res.pal_result[0] & 8))
+ buf.pte.pte_ma = 0;
+ sprintf(lbuf,
+ "%03d %06x %013lx %013lx %4s %d %d %d %d %d %-3s %d %06x\n",
+ i,
+ buf.rr.rr_rid,
+ buf.ifa.ifa_vpn,
+ buf.pte.pte_ppn,
+ psnames[buf.itir.itir_ps],
+ buf.pte.pte_ed,
+ buf.pte.pte_ar,
+ buf.pte.pte_pl,
+ buf.pte.pte_d,
+ buf.pte.pte_a,
+ manames[buf.pte.pte_ma],
+ buf.pte.pte_p,
+ buf.itir.itir_key);
+ pager_output(lbuf);
+ }
+ pager_close();
+
+ if (res.pal_status != 0) {
+ printf("Error while getting TR contents\n");
+ return CMD_ERROR;
+ }
+ return CMD_OK;
+}
+
+COMMAND_SET(itr, "itr", "print instruction TRs", command_itr);
+
+static int
+command_itr(int argc, char *argv[])
+{
+ return print_trs(0);
+}
+
+COMMAND_SET(dtr, "dtr", "print data TRs", command_dtr);
+
+static int
+command_dtr(int argc, char *argv[])
+{
+ return print_trs(1);
+}
+
+COMMAND_SET(hcdp, "hcdp", "Dump HCDP info", command_hcdp);
+
+static char *
+hcdp_string(char *s, u_int len)
+{
+ static char buffer[256];
+
+ memcpy(buffer, s, len);
+ buffer[len] = 0;
+ return (buffer);
+}
+
+static int
+command_hcdp(int argc, char *argv[])
+{
+ struct dig64_hcdp_table *tbl;
+ struct dig64_hcdp_entry *ent;
+ struct dig64_gas *gas;
+ int i;
+
+ tbl = efi_get_table(&hcdp);
+ if (tbl == NULL) {
+ printf("No HCDP table present\n");
+ return (CMD_OK);
+ }
+ if (memcmp(tbl->signature, HCDP_SIGNATURE, sizeof(tbl->signature))) {
+ printf("HCDP table has invalid signature\n");
+ return (CMD_OK);
+ }
+ if (tbl->length < sizeof(*tbl) - sizeof(*tbl->entry)) {
+ printf("HCDP table too short\n");
+ return (CMD_OK);
+ }
+ printf("HCDP table at 0x%016lx\n", (u_long)tbl);
+ printf("Signature = %s\n", hcdp_string(tbl->signature, 4));
+ printf("Length = %u\n", tbl->length);
+ printf("Revision = %u\n", tbl->revision);
+ printf("Checksum = %u\n", tbl->checksum);
+ printf("OEM Id = %s\n", hcdp_string(tbl->oem_id, 6));
+ printf("Table Id = %s\n", hcdp_string(tbl->oem_tbl_id, 8));
+ printf("OEM rev = %u\n", tbl->oem_rev);
+ printf("Creator Id = %s\n", hcdp_string(tbl->creator_id, 4));
+ printf("Creator rev= %u\n", tbl->creator_rev);
+ printf("Entries = %u\n", tbl->entries);
+ for (i = 0; i < tbl->entries; i++) {
+ ent = tbl->entry + i;
+ printf("Entry #%d:\n", i + 1);
+ printf(" Type = %u\n", ent->type);
+ printf(" Databits = %u\n", ent->databits);
+ printf(" Parity = %u\n", ent->parity);
+ printf(" Stopbits = %u\n", ent->stopbits);
+ printf(" PCI seg = %u\n", ent->pci_segment);
+ printf(" PCI bus = %u\n", ent->pci_bus);
+ printf(" PCI dev = %u\n", ent->pci_device);
+ printf(" PCI func = %u\n", ent->pci_function);
+ printf(" Interrupt = %u\n", ent->interrupt);
+ printf(" PCI flag = %u\n", ent->pci_flag);
+ printf(" Baudrate = %lu\n",
+ ((u_long)ent->baud_high << 32) + (u_long)ent->baud_low);
+ gas = &ent->address;
+ printf(" Addr space= %u\n", gas->addr_space);
+ printf(" Bit width = %u\n", gas->bit_width);
+ printf(" Bit offset= %u\n", gas->bit_offset);
+ printf(" Address = 0x%016lx\n",
+ ((u_long)gas->addr_high << 32) + (u_long)gas->addr_low);
+ printf(" PCI type = %u\n", ent->pci_devid);
+ printf(" PCI vndr = %u\n", ent->pci_vendor);
+ printf(" IRQ = %u\n", ent->irq);
+ printf(" PClock = %u\n", ent->pclock);
+ printf(" PCI iface = %u\n", ent->pci_interface);
+ }
+ printf("<EOT>\n");
+ return (CMD_OK);
+}
diff --git a/sys/boot/efi/loader/version b/sys/boot/efi/loader/version
new file mode 100644
index 0000000..71f9400
--- /dev/null
+++ b/sys/boot/efi/loader/version
@@ -0,0 +1,16 @@
+$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: Pass the HCDP table address to the kernel via bootinfo if one
+ is present in the EFI system table.
+1.0: Don't map the I/O port range. We expect the kernel to do it. It
+ was done in the loader as a debugging aid and not intended as a
+ service/feature.
+0.3: Pass the physical address of the bootinfo block in register r8
+ to the kernel. Continue to put it at the fixed address for now.
+0.2: Much improved version. Significant is the support for passing
+ the FPSWA interface pointer to the kernel.
+0.1: Initial EFI version, germinated from the NetBSD i386
+ standalone, but enormously modified.
OpenPOWER on IntegriCloud