svn commit: r197113 - in projects/ppc64/sys/boot: ofw/libofw
powerpc/ofw
Nathan Whitehorn
nwhitehorn at FreeBSD.org
Sat Sep 12 05:39:52 UTC 2009
Author: nwhitehorn
Date: Sat Sep 12 05:39:51 2009
New Revision: 197113
URL: http://svn.freebsd.org/changeset/base/197113
Log:
Teach the PowerPC loader how to emit metadata for 64-bit kernels, as well.
Hopefully I don't have to muck around with the loader any more.
Modified:
projects/ppc64/sys/boot/ofw/libofw/ppc64_elf_freebsd.c
projects/ppc64/sys/boot/powerpc/ofw/metadata.c
Modified: projects/ppc64/sys/boot/ofw/libofw/ppc64_elf_freebsd.c
==============================================================================
--- projects/ppc64/sys/boot/ofw/libofw/ppc64_elf_freebsd.c Sat Sep 12 04:49:33 2009 (r197112)
+++ projects/ppc64/sys/boot/ofw/libofw/ppc64_elf_freebsd.c Sat Sep 12 05:39:51 2009 (r197113)
@@ -80,7 +80,7 @@ ppc64_ofw_elf_exec(struct preloaded_file
/* Handle function descriptor */
entry = *(uint64_t *)e->e_entry;
- if ((error = md_load(fp->f_args, &mdp)) != 0)
+ if ((error = md_load64(fp->f_args, &mdp)) != 0)
return (error);
printf("Kernel entry at 0x%lx ...\n", entry);
Modified: projects/ppc64/sys/boot/powerpc/ofw/metadata.c
==============================================================================
--- projects/ppc64/sys/boot/powerpc/ofw/metadata.c Sat Sep 12 04:49:33 2009 (r197112)
+++ projects/ppc64/sys/boot/powerpc/ofw/metadata.c Sat Sep 12 05:39:51 2009 (r197113)
@@ -175,6 +175,9 @@ md_copyenv(vm_offset_t addr)
* MOD_SIZE sizeof(size_t) module size
* MOD_METADATA (variable) type-specific metadata
*/
+
+static int align;
+
#define COPY32(v, a, c) { \
u_int32_t x = (v); \
if (c) \
@@ -187,7 +190,7 @@ md_copyenv(vm_offset_t addr)
COPY32(strlen(s) + 1, a, c) \
if (c) \
archsw.arch_copyin(s, a, strlen(s) + 1);\
- a += roundup(strlen(s) + 1, sizeof(u_long));\
+ a += roundup(strlen(s) + 1, align); \
}
#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c)
@@ -199,7 +202,7 @@ md_copyenv(vm_offset_t addr)
COPY32(sizeof(s), a, c); \
if (c) \
archsw.arch_copyin(&s, a, sizeof(s)); \
- a += roundup(sizeof(s), sizeof(u_long)); \
+ a += roundup(sizeof(s), align); \
}
#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c)
@@ -210,7 +213,7 @@ md_copyenv(vm_offset_t addr)
COPY32(mm->md_size, a, c); \
if (c) \
archsw.arch_copyin(mm->md_data, a, mm->md_size);\
- a += roundup(mm->md_size, sizeof(u_long)); \
+ a += roundup(mm->md_size, align); \
}
#define MOD_END(a, c) { \
@@ -219,10 +222,11 @@ md_copyenv(vm_offset_t addr)
}
vm_offset_t
-md_copymodules(vm_offset_t addr)
+md_copymodules(vm_offset_t addr, int kern64)
{
struct preloaded_file *fp;
struct file_metadata *md;
+ uint64_t scratch64;
int c;
c = addr != 0;
@@ -233,8 +237,15 @@ md_copymodules(vm_offset_t addr)
MOD_TYPE(addr, fp->f_type, c);
if (fp->f_args)
MOD_ARGS(addr, fp->f_args, c);
- MOD_ADDR(addr, fp->f_addr, c);
- MOD_SIZE(addr, fp->f_size, c);
+ if (kern64) {
+ scratch64 = fp->f_addr;
+ MOD_ADDR(addr, scratch64, c);
+ scratch64 = fp->f_size;
+ MOD_SIZE(addr, scratch64, c);
+ } else {
+ MOD_ADDR(addr, fp->f_addr, c);
+ MOD_SIZE(addr, fp->f_size, c);
+ }
for (md = fp->f_metadata; md != NULL; md = md->md_next) {
if (!(md->md_type & MODINFOMD_NOCOPY)) {
MOD_METADATA(addr, md, c);
@@ -254,7 +265,7 @@ md_copymodules(vm_offset_t addr)
* - Module metadata are formatted and placed in kernel space.
*/
int
-md_load(char *args, vm_offset_t *modulep)
+md_load_dual(char *args, vm_offset_t *modulep, int kern64)
{
struct preloaded_file *kfp;
struct preloaded_file *xp;
@@ -263,11 +274,11 @@ md_load(char *args, vm_offset_t *modulep
vm_offset_t addr;
vm_offset_t envp;
vm_offset_t size;
+ uint64_t scratch64;
char *rootdevname;
int howto;
- int dtlb_slots;
- int itlb_slots;
+ align = kern64 ? 8 : 4;
howto = md_getboothowto(args);
/*
@@ -298,23 +309,48 @@ md_load(char *args, vm_offset_t *modulep
addr = roundup(addr, PAGE_SIZE);
kernend = 0;
- kfp = file_findfile(NULL, "elf32 kernel");
+ kfp = file_findfile(NULL, kern64 ? "elf64 kernel" : "elf32 kernel");
if (kfp == NULL)
kfp = file_findfile(NULL, "elf kernel");
if (kfp == NULL)
panic("can't find kernel file");
file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof howto, &howto);
- file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp);
- file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend);
+ if (kern64) {
+ scratch64 = envp;
+ file_addmetadata(kfp, MODINFOMD_ENVP, sizeof scratch64, &scratch64);
+ scratch64 = kernend;
+ file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof scratch64, &scratch64);
+ } else {
+ file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp);
+ file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend);
+ }
*modulep = addr;
- size = md_copymodules(0);
+ size = md_copymodules(0, kern64);
kernend = roundup(addr + size, PAGE_SIZE);
md = file_findmetadata(kfp, MODINFOMD_KERNEND);
- bcopy(&kernend, md->md_data, sizeof kernend);
-
- (void)md_copymodules(addr);
+ if (kern64) {
+ scratch64 = kernend;
+ bcopy(&scratch64, md->md_data, sizeof scratch64);
+ } else {
+ bcopy(&kernend, md->md_data, sizeof kernend);
+ }
+
+ (void)md_copymodules(addr, kern64);
return(0);
}
+
+int
+md_load(char *args, vm_offset_t *modulep)
+{
+ return (md_load_dual(args, modulep, 0));
+}
+
+int
+md_load64(char *args, vm_offset_t *modulep)
+{
+ return (md_load_dual(args, modulep, 1));
+}
+
More information about the svn-src-projects
mailing list