Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 31 Mar 2014 19:50:41 +0000 (UTC)
From:      Andrew Turner <andrew@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r263976 - in projects/arm64/sys: arm64/arm64 arm64/include boot/arm64/efi
Message-ID:  <201403311950.s2VJofup053910@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: andrew
Date: Mon Mar 31 19:50:40 2014
New Revision: 263976
URL: http://svnweb.freebsd.org/changeset/base/263976

Log:
  Pass module data to the kernel and have the memory map passed though it.

Added:
  projects/arm64/sys/arm64/include/metadata.h   (contents, props changed)
  projects/arm64/sys/boot/arm64/efi/bootinfo.c   (contents, props changed)
Modified:
  projects/arm64/sys/arm64/arm64/machdep.c
  projects/arm64/sys/boot/arm64/efi/Makefile
  projects/arm64/sys/boot/arm64/efi/exec.c

Modified: projects/arm64/sys/arm64/arm64/machdep.c
==============================================================================
--- projects/arm64/sys/arm64/arm64/machdep.c	Mon Mar 31 19:37:39 2014	(r263975)
+++ projects/arm64/sys/arm64/arm64/machdep.c	Mon Mar 31 19:50:40 2014	(r263976)
@@ -32,18 +32,22 @@ __FBSDID("$FreeBSD$");
 #include <sys/systm.h>
 #include <sys/bus.h>
 #include <sys/cpu.h>
+#include <sys/efi.h>
 #include <sys/imgact.h>
+#include <sys/linker.h>
 #include <sys/pcpu.h>
 #include <sys/proc.h>
 #include <sys/ptrace.h>
+#include <sys/reboot.h>
 #include <sys/signalvar.h>
 #include <sys/sysproto.h>
 #include <sys/ucontext.h>
 
-#include <machine/bootinfo.h>
 #include <machine/cpu.h>
+#include <machine/metadata.h>
 #include <machine/pcb.h>
 #include <machine/reg.h>
+#include <machine/vmparam.h>
 
 struct pcpu __pcpu[MAXCPU];
 struct pcpu *pcpup = &__pcpu[0];
@@ -53,6 +57,8 @@ vm_paddr_t phys_avail[10];
 int cold = 1;
 long realmem = 0;
 
+#define	PHYSMAP_SIZE	(2 * (VM_PHYSSEG_MAX - 1))
+
 void
 bzero(void *buf, size_t len)
 {
@@ -254,7 +260,7 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, 
 	panic("sendsig");
 }
 
-void initarm(struct bootinfo *);
+void initarm(vm_offset_t);
 
 #ifdef EARLY_PRINTF
 static void 
@@ -277,32 +283,195 @@ typedef struct {
 	uint64_t attr;
 } EFI_MEMORY_DESCRIPTOR;
 
+static int
+add_physmap_entry(uint64_t base, uint64_t length, vm_paddr_t *physmap,
+    int *physmap_idxp)
+{
+	int i, insert_idx, physmap_idx;
+
+	physmap_idx = *physmap_idxp;
+
+	if (length == 0)
+		return (1);
+
+	/*
+	 * Find insertion point while checking for overlap.  Start off by
+	 * assuming the new entry will be added to the end.
+	 */
+	insert_idx = physmap_idx + 2;
+	for (i = 0; i <= physmap_idx; i += 2) {
+		if (base < physmap[i + 1]) {
+			if (base + length <= physmap[i]) {
+				insert_idx = i;
+				break;
+			}
+			if (boothowto & RB_VERBOSE)
+				printf(
+		    "Overlapping memory regions, ignoring second region\n");
+			return (1);
+		}
+	}
+
+	/* See if we can prepend to the next entry. */
+	if (insert_idx <= physmap_idx && base + length == physmap[insert_idx]) {
+		physmap[insert_idx] = base;
+		return (1);
+	}
+
+	/* See if we can append to the previous entry. */
+	if (insert_idx > 0 && base == physmap[insert_idx - 1]) {
+		physmap[insert_idx - 1] += length;
+		return (1);
+	}
+
+	physmap_idx += 2;
+	*physmap_idxp = physmap_idx;
+	if (physmap_idx == PHYSMAP_SIZE) {
+		printf(
+		"Too many segments in the physical address map, giving up\n");
+		return (0);
+	}
+
+	/*
+	 * Move the last 'N' entries down to make room for the new
+	 * entry if needed.
+	 */
+	for (i = physmap_idx; i > insert_idx; i -= 2) {
+		physmap[i] = physmap[i - 2];
+		physmap[i + 1] = physmap[i - 1];
+	}
+
+	/* Insert the new entry. */
+	physmap[insert_idx] = base;
+	physmap[insert_idx + 1] = base + length;
+	return (1);
+}
+
+#define efi_next_descriptor(ptr, size) \
+	((struct efi_md *)(((uint8_t *) ptr) + size))
+
+static void
+add_efi_map_entries(struct efi_map_header *efihdr, vm_paddr_t *physmap,
+    int *physmap_idx)
+{
+	struct efi_md *map, *p;
+	const char *type;
+	size_t efisz;
+	int ndesc, i;
+
+	static const char *types[] = {
+		"Reserved",
+		"LoaderCode",
+		"LoaderData",
+		"BootServicesCode",
+		"BootServicesData",
+		"RuntimeServicesCode",
+		"RuntimeServicesData",
+		"ConventionalMemory",
+		"UnusableMemory",
+		"ACPIReclaimMemory",
+		"ACPIMemoryNVS",
+		"MemoryMappedIO",
+		"MemoryMappedIOPortSpace",
+		"PalCode"
+	};
+
+	/*
+	 * Memory map data provided by UEFI via the GetMemoryMap
+	 * Boot Services API.
+	 */
+	efisz = (sizeof(struct efi_map_header) + 0xf) & ~0xf;
+	map = (struct efi_md *)((uint8_t *)efihdr + efisz); 
+
+	if (efihdr->descriptor_size == 0)
+		return;
+	ndesc = efihdr->memory_size / efihdr->descriptor_size;
+
+	if (boothowto & RB_VERBOSE)
+		printf("%23s %12s %12s %8s %4s\n",
+		    "Type", "Physical", "Virtual", "#Pages", "Attr");
+
+	for (i = 0, p = map; i < ndesc; i++,
+	    p = efi_next_descriptor(p, efihdr->descriptor_size)) {
+		if (boothowto & RB_VERBOSE) {
+			if (p->md_type <= EFI_MD_TYPE_PALCODE)
+				type = types[p->md_type];
+			else
+				type = "<INVALID>";
+			printf("%23s %012llx %12p %08llx ", type, p->md_phys,
+			    p->md_virt, p->md_pages);
+			if (p->md_attr & EFI_MD_ATTR_UC)
+				printf("UC ");
+			if (p->md_attr & EFI_MD_ATTR_WC)
+				printf("WC ");
+			if (p->md_attr & EFI_MD_ATTR_WT)
+				printf("WT ");
+			if (p->md_attr & EFI_MD_ATTR_WB)
+				printf("WB ");
+			if (p->md_attr & EFI_MD_ATTR_UCE)
+				printf("UCE ");
+			if (p->md_attr & EFI_MD_ATTR_WP)
+				printf("WP ");
+			if (p->md_attr & EFI_MD_ATTR_RP)
+				printf("RP ");
+			if (p->md_attr & EFI_MD_ATTR_XP)
+				printf("XP ");
+			if (p->md_attr & EFI_MD_ATTR_RT)
+				printf("RUNTIME");
+			printf("\n");
+		}
+
+		switch (p->md_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:
+			/*
+			 * We're allowed to use any entry with these types.
+			 */
+			break;
+		default:
+			continue;
+		}
+
+		if (!add_physmap_entry(p->md_phys, (p->md_pages * PAGE_SIZE),
+		    physmap, physmap_idx))
+			break;
+	}
+}
 void
-initarm(struct bootinfo *bi)
+initarm(vm_offset_t modulep)
 {
-	EFI_MEMORY_DESCRIPTOR *desc;
-	const char str[] = "FreeBSD\r\n";
-	volatile uint32_t *uart;
+	vm_paddr_t physmap[PHYSMAP_SIZE];
+	struct efi_map_header *efihdr;
+	int physmap_idx;
+	caddr_t kmdp;
+	vm_paddr_t mem_len;
 	int i;
 
-	uart = (uint32_t*)0x1c090000;
-	for (i = 0; i < sizeof(str); i++) {
-		*uart = str[i];
-	}
-
-	printf("In initarm on arm64 %p\n", bi);
-	printf("%llx\n", bi->bi_memmap);
-	printf("%llx\n", bi->bi_memmap_size);
-	printf("%llx\n", bi->bi_memdesc_size);
-	printf("%llx\n", bi->bi_memdesc_version);
-
-	desc = (void *)bi->bi_memmap;
-	for (i = 0; i < bi->bi_memmap_size / bi->bi_memdesc_size; i++) {
-		printf("%x %llx %llx %llx %llx\n", desc->type,
-		    desc->phys_start, desc->virt_start, desc->num_pages,
-		    desc->attr);
+	printf("In initarm on arm64 %llx\n", modulep);
 
-		desc = (void *)((uint8_t *)desc + bi->bi_memdesc_size);
+	/* Find the kernel address */
+	preload_metadata = (caddr_t)(uintptr_t)(modulep);
+	kmdp = preload_search_by_type("elf kernel");
+	if (kmdp == NULL)
+		kmdp = preload_search_by_type("elf64 kernel");
+
+	/* Load the physical memory ranges */
+	physmap_idx = 0;
+	efihdr = (struct efi_map_header *)preload_search_info(kmdp,
+	    MODINFO_METADATA | MODINFOMD_EFI_MAP);
+	add_efi_map_entries(efihdr, physmap, &physmap_idx);
+
+	/* Print the memory map */
+	mem_len = 0;
+	for (i = 0; i <= physmap_idx; i += 2) {
+		mem_len += physmap[i + 1] - physmap[i];
+		printf("%llx - %llx\n", physmap[i], physmap[i + 1]);
 	}
+	printf("Total = %llx\n", mem_len);
+
+	printf("End initarm\n");
 }
 

Added: projects/arm64/sys/arm64/include/metadata.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/arm64/sys/arm64/include/metadata.h	Mon Mar 31 19:50:40 2014	(r263976)
@@ -0,0 +1,40 @@
+/*-
+ * Copyright (c) 2014 Andrew Turner <andrew@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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _MACHINE_METADATA_H_
+#define	_MACHINE_METADATA_H_
+
+#define	MODINFOMD_EFI_MAP	0x1001
+
+struct efi_map_header {
+	size_t		memory_size;
+	size_t		descriptor_size;
+	uint32_t	descriptor_version;
+};
+
+#endif /* !_MACHINE_METADATA_H_ */

Modified: projects/arm64/sys/boot/arm64/efi/Makefile
==============================================================================
--- projects/arm64/sys/boot/arm64/efi/Makefile	Mon Mar 31 19:37:39 2014	(r263975)
+++ projects/arm64/sys/boot/arm64/efi/Makefile	Mon Mar 31 19:50:40 2014	(r263976)
@@ -11,7 +11,7 @@ INTERNALPROG=
 
 # architecture-specific loader code
 SRCS=	start.S main.c conf.c vers.c reloc.c autoload.c
-SRCS+=	copy.c devicename.c exec.c
+SRCS+=	copy.c devicename.c exec.c bootinfo.c
 
 CFLAGS+=	-fno-builtin
 CFLAGS+=	-I${.CURDIR}

Added: projects/arm64/sys/boot/arm64/efi/bootinfo.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/arm64/sys/boot/arm64/efi/bootinfo.c	Mon Mar 31 19:50:40 2014	(r263976)
@@ -0,0 +1,235 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * Copyright (c) 2004, 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 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/param.h>
+#include <sys/linker.h>
+
+#include <machine/metadata.h>
+
+#include <efi.h>
+#include <efilib.h>
+
+#include "bootstrap.h"
+#include "libarm64.h"
+
+UINTN arm64_efi_mapkey;
+
+/*
+ * Copy module-related data into the load area, where it can be
+ * used as a directory for loaded modules.
+ *
+ * Module data is presented in a self-describing format.  Each datum
+ * is preceded by a 32-bit identifier and a 32-bit size field.
+ *
+ * Currently, the following data are saved:
+ *
+ * MOD_NAME	(variable)		module name (string)
+ * MOD_TYPE	(variable)		module type (string)
+ * MOD_ARGS	(variable)		module parameters (string)
+ * MOD_ADDR	sizeof(vm_offset_t)	module load address
+ * MOD_SIZE	sizeof(size_t)		module size
+ * MOD_METADATA	(variable)		type-specific metadata
+ */
+#define COPY32(v, a, c) {				\
+	uint32_t x = (v);				\
+	if (c)						\
+		arm64_efi_copyin(&x, a, sizeof(x));	\
+	a += sizeof(x);					\
+}
+
+#define MOD_STR(t, a, s, c) {				\
+	COPY32(t, a, c);				\
+	COPY32(strlen(s) + 1, a, c);			\
+	if (c)						\
+		arm64_efi_copyin(s, a, strlen(s) + 1);	\
+	a += roundup(strlen(s) + 1, sizeof(u_int64_t));	\
+}
+
+#define MOD_NAME(a, s, c)	MOD_STR(MODINFO_NAME, a, s, c)
+#define MOD_TYPE(a, s, c)	MOD_STR(MODINFO_TYPE, a, s, c)
+#define MOD_ARGS(a, s, c)	MOD_STR(MODINFO_ARGS, a, s, c)
+
+#define MOD_VAR(t, a, s, c) {				\
+	COPY32(t, a, c);				\
+	COPY32(sizeof(s), a, c);			\
+	if (c)						\
+		arm64_efi_copyin(&s, a, sizeof(s));	\
+	a += roundup(sizeof(s), sizeof(u_int64_t));	\
+}
+
+#define MOD_ADDR(a, s, c)	MOD_VAR(MODINFO_ADDR, a, s, c)
+#define MOD_SIZE(a, s, c)	MOD_VAR(MODINFO_SIZE, a, s, c)
+
+#define MOD_METADATA(a, mm, c) {			\
+	COPY32(MODINFO_METADATA | mm->md_type, a, c);	\
+	COPY32(mm->md_size, a, c);			\
+	if (c)						\
+		arm64_efi_copyin(mm->md_data, a, mm->md_size);	\
+	a += roundup(mm->md_size, sizeof(u_int64_t));	\
+}
+
+#define MOD_END(a, c) {					\
+	COPY32(MODINFO_END, a, c);			\
+	COPY32(0, a, c);				\
+}
+
+static vm_offset_t
+bi_copymodules(vm_offset_t addr)
+{
+	struct preloaded_file	*fp;
+	struct file_metadata	*md;
+	int			c;
+	u_int64_t		v;
+
+	c = addr != 0;
+	/* start with the first module on the list, should be the kernel */
+	for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) {
+		MOD_NAME(addr, fp->f_name, c);	/* this field must come first */
+		MOD_TYPE(addr, fp->f_type, c);
+		if (fp->f_args)
+			MOD_ARGS(addr, fp->f_args, c);
+		v = fp->f_addr;
+		MOD_ADDR(addr, v, c);
+		v = fp->f_size;
+		MOD_SIZE(addr, v, c);
+		for (md = fp->f_metadata; md != NULL; md = md->md_next)
+			if (!(md->md_type & MODINFOMD_NOCOPY))
+				MOD_METADATA(addr, md, c);
+	}
+	MOD_END(addr, c);
+	return(addr);
+}
+
+static int
+bi_load_efi_data(struct preloaded_file *kfp)
+{
+	EFI_MEMORY_DESCRIPTOR *mm;
+	EFI_PHYSICAL_ADDRESS addr;
+	EFI_STATUS status;
+	size_t efisz;
+	UINTN mmsz, pages, sz;
+	UINT32 mmver;
+	struct efi_map_header *efihdr;
+
+        efisz = (sizeof(struct efi_map_header) + 0xf) & ~0xf;
+
+	/*
+	 * Allocate enough pages to hold the bootinfo block and the memory
+	 * map EFI will return to us. The memory map has an unknown size,
+	 * so we have to determine that first. Note that the AllocatePages
+	 * call can itself modify the memory map, so we have to take that
+	 * into account as well. The changes to the memory map are caused
+	 * by splitting a range of free memory into two (AFAICT), so that
+	 * one is marked as being loader data.
+	 */
+	sz = 0;
+	BS->GetMemoryMap(&sz, NULL, &arm64_efi_mapkey, &mmsz, &mmver);
+	sz += mmsz;
+	sz = (sz + 0xf) & ~0xf;
+	pages = EFI_SIZE_TO_PAGES(sz + efisz);
+	status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData, pages,
+	    &addr);
+	if (EFI_ERROR(status)) {
+		printf("%s: AllocatePages() returned 0x%lx\n", __func__,
+		    (long)status);
+		return (ENOMEM);
+	}
+
+	/*
+	 * Read the memory map and stash it after bootinfo. Align the
+	 * memory map on a 16-byte boundary (the bootinfo block is page
+	 * aligned).
+	 */
+	efihdr = (struct efi_map_header *)addr;
+	mm = (void *)((uint8_t *)efihdr + efisz);
+	sz = (EFI_PAGE_SIZE * pages) - efisz;
+	status = BS->GetMemoryMap(&sz, mm, &arm64_efi_mapkey, &mmsz, &mmver);
+	if (EFI_ERROR(status)) {
+		printf("%s: GetMemoryMap() returned 0x%lx\n", __func__,
+		    (long)status);
+		return (EINVAL);
+	}
+
+	efihdr->memory_size = sz;
+	efihdr->descriptor_size = mmsz;
+	efihdr->descriptor_version = mmver;
+
+	file_addmetadata(kfp, MODINFOMD_EFI_MAP, efisz + sz, efihdr);
+
+	return (0);
+}
+
+/*
+ * Load the information expected by an arm64 kernel.
+ *
+ * - The 'boothowto' argument is constructed
+ * - The 'bootdev' argument is constructed
+ * - The 'bootinfo' struct is constructed, and copied into the kernel space.
+ * - The kernel environment is copied into kernel space.
+ * - Module metadata are formatted and placed in kernel space.
+ */
+int
+bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp)
+{
+	struct preloaded_file *xp, *kfp;
+	uint64_t kernend;
+	vm_offset_t addr, size;
+
+	/* find the last module in the chain */
+	addr = 0;
+	for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) {
+	if (addr < (xp->f_addr + xp->f_size))
+		addr = xp->f_addr + xp->f_size;
+	}
+	/* pad to a page boundary */
+	addr = roundup(addr, PAGE_SIZE);
+
+	kfp = file_findfile(NULL, "elf kernel");
+	if (kfp == NULL)
+		kfp = file_findfile(NULL, "elf64 kernel");
+	if (kfp == NULL)
+		panic("can't find kernel file");
+	kernend = 0;	/* fill it in later */
+	file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend);
+
+	bi_load_efi_data(kfp);
+
+	/* Figure out the size and location of the metadata */
+	*modulep = addr;
+	size = bi_copymodules(0);
+	kernend = roundup(addr + size, PAGE_SIZE);
+	*kernendp = kernend;
+
+	/* copy module list and metadata */
+	(void)bi_copymodules(addr);
+
+	return (0);
+}
+

Modified: projects/arm64/sys/boot/arm64/efi/exec.c
==============================================================================
--- projects/arm64/sys/boot/arm64/efi/exec.c	Mon Mar 31 19:37:39 2014	(r263975)
+++ projects/arm64/sys/boot/arm64/efi/exec.c	Mon Mar 31 19:50:40 2014	(r263976)
@@ -40,11 +40,14 @@ __FBSDID("$FreeBSD$");
 #include <efilib.h>
 
 #include "libarm64.h"
-#include <machine/bootinfo.h>
+
+extern UINTN arm64_efi_mapkey;
 
 static int elf64_exec(struct preloaded_file *amp);
 static int elf64_obj_exec(struct preloaded_file *amp);
 
+int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp);
+
 static struct file_format arm64_elf = {
 	elf64_loadfile,
 	elf64_exec
@@ -58,74 +61,27 @@ struct file_format *file_formats[] = {
 static int
 elf64_exec(struct preloaded_file *fp)
 {
+	vm_offset_t modulep, kernendp;
 	struct file_metadata *md;
-	struct bootinfo *bi;
 	EFI_STATUS status;
-	EFI_MEMORY_DESCRIPTOR *memmap;
 	EFI_PHYSICAL_ADDRESS addr;
-	UINTN descsz, memmapsz, mapkey, pages;
-	UINT32 descver;
 	Elf_Ehdr *ehdr;
-	void (*entry)(void *);
+	int err;
+	void (*entry)(vm_offset_t);
 
 	if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
         	return(EFTYPE);
 
 	ehdr = (Elf_Ehdr *)&(md->md_data);
-
 	entry = arm64_efi_translate(ehdr->e_entry);
 
-	memmapsz = 0;
-	status = BS->GetMemoryMap(&memmapsz, NULL, &mapkey, &descsz, &descver);
-        if (EFI_ERROR(status) && status != EFI_BUFFER_TOO_SMALL) {
-		printf("%s: GetMemoryMap() returned 0x%lx\n", __func__,
-		    (long)status);
-		return (EINVAL);
-	}
-
-	memmapsz = roundup2(memmapsz, 16);
-	pages = EFI_SIZE_TO_PAGES(memmapsz + sizeof(*bi));
-	status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData, pages,
-	    &addr);
-        if (EFI_ERROR(status)) {
-		free(memmap);
-		printf("%s: AllocatePages() returned 0x%lx\n", __func__,
-		    (long)status);
-		return (ENOMEM);
-	}
-
-	memmap = (void *)(addr + sizeof(*bi));
-	status = BS->GetMemoryMap(&memmapsz, memmap, &mapkey, &descsz,
-		&descver);
-        if (EFI_ERROR(status)) {
-		free(memmap);
-		printf("%s: GetMemoryMap() returned 0x%lx\n", __func__,
-		    (long)status);
-		return (EINVAL);
-	}
-
-	bi = (void *)addr;
+	err = bi_load(fp->f_args, &modulep, &kernendp);
+	if (err != 0)
+		return (err);
 
-	bi->bi_magic = BOOTINFO_MAGIC;
-	bi->bi_version = BOOTINFO_VERSION;
-
-	bi->bi_memmap = (uint64_t)memmap;
-	bi->bi_memmap_size = memmapsz;
-	bi->bi_memdesc_size = descsz;
-	bi->bi_memdesc_version = descver;
-
-#if 0
-	/* Find a location for the bootinfo after the last module */
-	addr = 0;
-	for (md = file_findfile(NULL, NULL); md != NULL; md = md->f_next) {
-		if (addr < (md->f_addr + md->f_size))
-			addr = md->f_addr + md->f_size;
-	}
-	addr = roundup2(addr, 16);
-	arm64_copyin(&bi, addr, sizeof(bi));
-#endif
+	printf("%llx %llx\n", modulep, kernendp);
 
-	status = BS->ExitBootServices(IH, mapkey);
+	status = BS->ExitBootServices(IH, arm64_efi_mapkey);
         if (EFI_ERROR(status)) {
 		printf("%s: ExitBootServices() returned 0x%lx\n", __func__,
 		    (long)status);
@@ -133,7 +89,7 @@ elf64_exec(struct preloaded_file *fp)
 	}
 
 	/* TODO: Pass the required metadata to the kernel */
-	(*entry)(bi);
+	(*entry)(modulep);
 	panic("exec returned");
 }
 



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