Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F150027109
D50587.id156265.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
13 KB
Referenced Files
None
Subscribers
None
D50587.id156265.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D50587: stand: Retire arch_loadaddr, pending its replacement
Attached
Detach File
Event Timeline
Log In to Comment