Page MenuHomeFreeBSD

D50587.id156265.diff
No OneTemporary

D50587.id156265.diff

diff --git a/stand/common/bootstrap.h b/stand/common/bootstrap.h
--- a/stand/common/bootstrap.h
+++ b/stand/common/bootstrap.h
@@ -351,14 +351,6 @@
int (*arch_isainb)(int port);
void (*arch_isaoutb)(int port, int value);
- /*
- * Interface to adjust the load address according to the "object"
- * being loaded.
- */
- uint64_t (*arch_loadaddr)(u_int type, void *data, uint64_t addr);
-#define LOAD_ELF 1 /* data points to the ELF header. */
-#define LOAD_RAW 2 /* data points to the file name. */
-
/*
* Interface to inform MD code about a loaded (ELF) segment. This
* can be used to flush caches and/or set up translations.
diff --git a/stand/common/load_elf.c b/stand/common/load_elf.c
--- a/stand/common/load_elf.c
+++ b/stand/common/load_elf.c
@@ -403,6 +403,7 @@
* in the elf header (an ARM kernel can be loaded at any 2MB
* boundary), so we leave dest set to the value calculated by
* archsw.arch_loadaddr() and passed in to this function.
+ * XXX This comment is obsolete, but it still seems to work
*/
#ifndef __arm__
if (ehdr->e_type == ET_EXEC)
@@ -445,10 +446,7 @@
goto oerr;
}
- if (archsw.arch_loadaddr != NULL)
- dest = archsw.arch_loadaddr(LOAD_ELF, ehdr, dest);
- else
- dest = roundup(dest, PAGE_SIZE);
+ dest = md_align(dest);
/*
* Ok, we think we should handle this.
diff --git a/stand/common/load_elf_obj.c b/stand/common/load_elf_obj.c
--- a/stand/common/load_elf_obj.c
+++ b/stand/common/load_elf_obj.c
@@ -157,10 +157,7 @@
goto oerr;
}
- if (archsw.arch_loadaddr != NULL)
- dest = archsw.arch_loadaddr(LOAD_ELF, hdr, dest);
- else
- dest = roundup(dest, PAGE_SIZE);
+ dest = md_align(dest);
/*
* Ok, we think we should handle this.
diff --git a/stand/common/modinfo.c b/stand/common/modinfo.c
--- a/stand/common/modinfo.c
+++ b/stand/common/modinfo.c
@@ -202,7 +202,7 @@
* platform.
*
* XXX For the moment, it's just PAGE_SIZE to make the refactoring go faster,
- * but needs to hook-in arch_loadaddr (or its replacement) functionality.
+ * but needs to hook-in the replacement of arch_loadaddr.
*
* Also, we may need other logical things when dealing with different types of
* page sizes and/or masking or sizes. This works well for addr and sizes, but
diff --git a/stand/common/module.c b/stand/common/module.c
--- a/stand/common/module.c
+++ b/stand/common/module.c
@@ -43,6 +43,7 @@
#endif
#include "bootstrap.h"
+#include "modinfo.h"
#define MDIR_REMOVED 0x0001
#define MDIR_NOHINTS 0x0002
@@ -562,8 +563,7 @@
int i;
TSENTER2(filename);
- if (archsw.arch_loadaddr != NULL)
- dest = archsw.arch_loadaddr(LOAD_RAW, filename, dest);
+ dest = md_align(dest);
error = EFTYPE;
for (i = last_file_format, fp = NULL;
@@ -713,8 +713,7 @@
#endif
#endif
- if (archsw.arch_loadaddr != NULL)
- loadaddr = archsw.arch_loadaddr(LOAD_RAW, name, loadaddr);
+ loadaddr = md_align(loadaddr);
if (module_verbose > MODULE_VERBOSE_SILENT)
printf("%s ", name);
@@ -1015,9 +1014,7 @@
}
/* Figure out where to load the data. */
- dest = loadaddr;
- if (archsw.arch_loadaddr != NULL)
- dest = archsw.arch_loadaddr(LOAD_RAW, (void *)name, dest);
+ dest = md_align(loadaddr);
/* Create & populate control structure */
fp = file_alloc();
diff --git a/stand/kboot/kboot/arch/aarch64/exec.c b/stand/kboot/kboot/arch/aarch64/exec.c
--- a/stand/kboot/kboot/arch/aarch64/exec.c
+++ b/stand/kboot/kboot/arch/aarch64/exec.c
@@ -188,9 +188,9 @@
/*
* Figure out where to put it.
*
- * Linux does not allow us to kexec_load into any part of memory. Ask
- * arch_loadaddr to resolve the first available chunk of physical memory
- * where loading is possible (load_addr).
+ * Linux does not allow us to kexec_load into any part of memory. Find
+ * the first available chunk of physical memory where loading is
+ * possible (staging).
*
* The kernel is loaded at the 'base' address in continguous physical
* memory. We use the 2MB in front of the kernel as a place to put our
diff --git a/stand/kboot/kboot/arch/amd64/elf64_freebsd.c b/stand/kboot/kboot/arch/amd64/elf64_freebsd.c
--- a/stand/kboot/kboot/arch/amd64/elf64_freebsd.c
+++ b/stand/kboot/kboot/arch/amd64/elf64_freebsd.c
@@ -178,9 +178,9 @@
/*
* Figure out where to put it.
*
- * Linux does not allow to do kexec_load into any part of memory. Ask
- * arch_loadaddr to resolve the first available chunk of physical memory
- * where loading is possible (load_addr).
+ * Linux does not allow us to do kexec_load into any part of memory. Ask
+ * kboot_get_phys_load_segment to resolve the first available chunk of
+ * physical memory where loading is possible (staging).
*
* The kernel is loaded at the 'base' address in continguous physical
* pages (using 2MB super pages). The first such page is unused by the
diff --git a/stand/kboot/kboot/arch/powerpc64/ppc64_elf_freebsd.c b/stand/kboot/kboot/arch/powerpc64/ppc64_elf_freebsd.c
--- a/stand/kboot/kboot/arch/powerpc64/ppc64_elf_freebsd.c
+++ b/stand/kboot/kboot/arch/powerpc64/ppc64_elf_freebsd.c
@@ -89,21 +89,18 @@
/*
* Figure out where to put it.
*
- * Linux does not allow to do kexec_load into
- * any part of memory. Ask arch_loadaddr to
- * resolve the first available chunk of physical
- * memory where loading is possible (load_addr).
+ * Linux does not allow us to do kexec_load into any part of memory. Ask
+ * kboot_get_phys_load_segment to resolve the first available chunk of
+ * physical memory where loading is possible (load_addr).
*
- * Memory organization is shown below.
- * It is assumed, that text segment offset of
- * kernel ELF (KERNPHYSADDR) is non-zero,
- * which is true for PPC/PPC64 architectures,
- * where default is 0x100000.
+ * Memory organization is shown below. It is assumed, that text segment
+ * offset of kernel ELF (KERNPHYSADDR) is non-zero, which is true for
+ * PPC/PPC64 architectures, where default is 0x100000.
*
* load_addr: trampoline code
* load_addr + KERNPHYSADDR: kernel text segment
*/
- trampolinebase = archsw.arch_loadaddr(LOAD_RAW, NULL, 0);
+ trampolinebase = kboot_get_phys_load_segment();
printf("Load address at %#jx\n", (uintmax_t)trampolinebase);
printf("Relocation offset is %#jx\n", (uintmax_t)elf64_relocation_offset);
diff --git a/stand/uboot/copy.c b/stand/uboot/copy.c
--- a/stand/uboot/copy.c
+++ b/stand/uboot/copy.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
- * Copyright (c) 2007 Semihalf, Rafal Jaworowski <raj@semihalf.com>
+ * Copyright (c) 2007 Semihalf, Rafal Jaworowski <raj@semihalf.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -35,7 +35,7 @@
#include "libuboot.h"
/*
- * MD primitives supporting placement of module data
+ * MD primitives supporting placement of module data
*/
#ifdef __arm__
@@ -51,20 +51,17 @@
extern void _start(void); /* ubldr entry point address. */
+uint64_t loadbase;
+bool loadbase_set = false;
+
/*
* This is called for every object loaded (kernel, module, dtb file, etc). The
* expected return value is the next address at or after the given addr which is
* appropriate for loading the given object described by type and data. On each
* call the addr is the next address following the previously loaded object.
- *
- * The first call is for loading the kernel, and the addr argument will be zero,
- * and we search for a big block of ram to load the kernel and modules.
- *
- * On subsequent calls the addr will be non-zero, and we just round it up so
- * that each object begins on a page boundary.
*/
-uint64_t
-uboot_loadaddr(u_int type, void *data, uint64_t addr)
+static uint64_t
+uboot_loadaddr()
{
struct sys_info *si;
uint64_t sblock, eblock, subldr, eubldr;
@@ -73,87 +70,89 @@
int i;
char *envstr;
- if (addr == 0) {
- /*
- * If the loader_kernaddr environment variable is set, blindly
- * honor it. It had better be right. We force interpretation
- * of the value in base-16 regardless of any leading 0x prefix,
- * because that's the U-Boot convention.
- */
- envstr = ub_env_get("loader_kernaddr");
- if (envstr != NULL)
- return (strtoul(envstr, NULL, 16));
-
- /*
- * Find addr/size of largest DRAM block. Carve our own address
- * range out of the block, because loading the kernel over the
- * top ourself is a poor memory-conservation strategy. Avoid
- * memory at beginning of the first block of physical ram,
- * since u-boot likes to pass args and data there. Assume that
- * u-boot has moved itself to the very top of ram and
- * optimistically assume that we won't run into it up there.
- */
- if ((si = ub_get_sys_info()) == NULL)
- panic("could not retrieve system info");
-
- biggest_block = 0;
- biggest_size = 0;
- subldr = rounddown2((uintptr_t)_start, KERN_ALIGN);
- eubldr = roundup2((uint64_t)uboot_heap_end, KERN_ALIGN);
- for (i = 0; i < si->mr_no; i++) {
- if (si->mr[i].flags != MR_ATTR_DRAM)
- continue;
- sblock = roundup2((uint64_t)si->mr[i].start,
- KERN_ALIGN);
- eblock = rounddown2((uint64_t)si->mr[i].start +
- si->mr[i].size, KERN_ALIGN);
- if (biggest_size == 0)
- sblock += KERN_MINADDR;
- if (subldr >= sblock && subldr < eblock) {
- if (subldr - sblock > eblock - eubldr) {
- this_block = sblock;
- this_size = subldr - sblock;
- } else {
- this_block = eubldr;
- this_size = eblock - eubldr;
- }
- } else if (subldr < sblock && eubldr < eblock) {
- /* Loader is below or engulfs the sblock */
- this_block = (eubldr < sblock) ? sblock : eubldr;
- this_size = eblock - this_block;
+ /*
+ * If the loader_kernaddr environment variable is set, blindly
+ * honor it. It had better be right. We force interpretation
+ * of the value in base-16 regardless of any leading 0x prefix,
+ * because that's the U-Boot convention.
+ */
+ envstr = ub_env_get("loader_kernaddr");
+ if (envstr != NULL)
+ return (strtoul(envstr, NULL, 16));
+
+ /*
+ * Find addr/size of largest DRAM block. Carve our own address
+ * range out of the block, because loading the kernel over the
+ * top ourself is a poor memory-conservation strategy. Avoid
+ * memory at beginning of the first block of physical ram,
+ * since u-boot likes to pass args and data there. Assume that
+ * u-boot has moved itself to the very top of ram and
+ * optimistically assume that we won't run into it up there.
+ */
+ if ((si = ub_get_sys_info()) == NULL)
+ panic("could not retrieve system info");
+
+ biggest_block = 0;
+ biggest_size = 0;
+ subldr = rounddown2((uintptr_t)_start, KERN_ALIGN);
+ eubldr = roundup2((uint64_t)uboot_heap_end, KERN_ALIGN);
+ for (i = 0; i < si->mr_no; i++) {
+ if (si->mr[i].flags != MR_ATTR_DRAM)
+ continue;
+ sblock = roundup2((uint64_t)si->mr[i].start,
+ KERN_ALIGN);
+ eblock = rounddown2((uint64_t)si->mr[i].start +
+ si->mr[i].size, KERN_ALIGN);
+ if (biggest_size == 0)
+ sblock += KERN_MINADDR;
+ if (subldr >= sblock && subldr < eblock) {
+ if (subldr - sblock > eblock - eubldr) {
+ this_block = sblock;
+ this_size = subldr - sblock;
} else {
- this_block = 0;
- this_size = 0;
- }
- if (biggest_size < this_size) {
- biggest_block = this_block;
- biggest_size = this_size;
+ this_block = eubldr;
+ this_size = eblock - eubldr;
}
+ } else if (subldr < sblock && eubldr < eblock) {
+ /* Loader is below or engulfs the sblock */
+ this_block = (eubldr < sblock) ? sblock : eubldr;
+ this_size = eblock - this_block;
+ } else {
+ this_block = 0;
+ this_size = 0;
}
- if (biggest_size == 0)
- panic("Not enough DRAM to load kernel");
+ if (biggest_size < this_size) {
+ biggest_block = this_block;
+ biggest_size = this_size;
+ }
+ }
+ if (biggest_size == 0)
+ panic("Not enough DRAM to load kernel");
#if 0
- printf("Loading kernel into region 0x%08jx-0x%08jx (%ju MiB)\n",
- (uintmax_t)biggest_block,
- (uintmax_t)biggest_block + biggest_size - 1,
- (uintmax_t)biggest_size / 1024 / 1024);
+ printf("Loading kernel into region 0x%08jx-0x%08jx (%ju MiB)\n",
+ (uintmax_t)biggest_block,
+ (uintmax_t)biggest_block + biggest_size - 1,
+ (uintmax_t)biggest_size / 1024 / 1024);
#endif
- return (biggest_block);
- }
- return roundup2(addr, PAGE_SIZE);
+ return (biggest_block);
}
ssize_t
uboot_copyin(const void *src, vm_offset_t dest, const size_t len)
{
- bcopy(src, (void *)dest, len);
+ if (!loadbase_set) {
+ loadbase = uboot_loadaddr();
+ loadbase_set = true;
+ }
+
+ bcopy(src, (void *)(dest + loadbase), len);
return (len);
}
ssize_t
uboot_copyout(const vm_offset_t src, void *dest, const size_t len)
{
- bcopy((void *)src, dest, len);
+ bcopy((void *)(src + loadbase), dest, len);
return (len);
}
diff --git a/stand/uboot/libuboot.h b/stand/uboot/libuboot.h
--- a/stand/uboot/libuboot.h
+++ b/stand/uboot/libuboot.h
@@ -57,7 +57,6 @@
extern uintptr_t uboot_heap_start;
extern uintptr_t uboot_heap_end;
-uint64_t uboot_loadaddr(u_int type, void *data, uint64_t addr);
ssize_t uboot_copyin(const void *src, vm_offset_t dest, const size_t len);
ssize_t uboot_copyout(const vm_offset_t src, void *dest, const size_t len);
ssize_t uboot_readin(readin_handle_t fd, vm_offset_t dest, const size_t len);
diff --git a/stand/uboot/main.c b/stand/uboot/main.c
--- a/stand/uboot/main.c
+++ b/stand/uboot/main.c
@@ -41,7 +41,6 @@
struct uboot_devdesc currdev;
struct arch_switch archsw = { /* MI/MD interface boundary */
- .arch_loadaddr = uboot_loadaddr,
.arch_getdev = uboot_getdev,
.arch_copyin = uboot_copyin,
.arch_copyout = uboot_copyout,

File Metadata

Mime Type
text/plain
Expires
Sun, Mar 29, 8:27 PM (11 m, 24 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30553053
Default Alt Text
D50587.id156265.diff (13 KB)

Event Timeline