summaryrefslogtreecommitdiffstats
path: root/sys/boot/powerpc
diff options
context:
space:
mode:
authornwhitehorn <nwhitehorn@FreeBSD.org>2010-07-12 00:49:22 +0000
committernwhitehorn <nwhitehorn@FreeBSD.org>2010-07-12 00:49:22 +0000
commit88c6aef3299b7697de9a97ece63bc1b19b7c35c1 (patch)
treed99dc307dc7218f4c94faf9da092277a7c8ca452 /sys/boot/powerpc
parent33836b0d5c1da9a4b3bd4f8eb8ba8496b77ce2b0 (diff)
downloadFreeBSD-src-88c6aef3299b7697de9a97ece63bc1b19b7c35c1.zip
FreeBSD-src-88c6aef3299b7697de9a97ece63bc1b19b7c35c1.tar.gz
Provide support in loader for booting 64-bit PowerPC kernels. Like amd64,
64-bit PowerPC kernels are loaded by a 32-bit loader, since nearly all powerpc64 firmwares execute in 32-bit mode.
Diffstat (limited to 'sys/boot/powerpc')
-rw-r--r--sys/boot/powerpc/Makefile.inc5
-rw-r--r--sys/boot/powerpc/boot1.chrp/Makefile2
-rw-r--r--sys/boot/powerpc/ofw/Makefile5
-rw-r--r--sys/boot/powerpc/ofw/conf.c1
-rw-r--r--sys/boot/powerpc/ofw/ldscript.powerpc2
-rw-r--r--sys/boot/powerpc/ofw/metadata.c68
-rw-r--r--sys/boot/powerpc/uboot/Makefile5
-rw-r--r--sys/boot/powerpc/uboot/ldscript.powerpc2
8 files changed, 67 insertions, 23 deletions
diff --git a/sys/boot/powerpc/Makefile.inc b/sys/boot/powerpc/Makefile.inc
index 265f86d..dab65e5 100644
--- a/sys/boot/powerpc/Makefile.inc
+++ b/sys/boot/powerpc/Makefile.inc
@@ -1,3 +1,8 @@
# $FreeBSD$
+.if ${MACHINE_ARCH} == "powerpc64"
+CFLAGS+= -m32 -mcpu=powerpc
+LDFLAGS+= -m elf32ppc
+.endif
+
.include "../Makefile.inc"
diff --git a/sys/boot/powerpc/boot1.chrp/Makefile b/sys/boot/powerpc/boot1.chrp/Makefile
index 621b973..f3f7e4d 100644
--- a/sys/boot/powerpc/boot1.chrp/Makefile
+++ b/sys/boot/powerpc/boot1.chrp/Makefile
@@ -13,7 +13,7 @@ SRCS= boot1.c ashldi3.c
INTERNALPROG=
NO_MAN=
-CFLAGS= -ffreestanding -msoft-float -Os -D_KERNEL \
+CFLAGS= -ffreestanding -msoft-float -Os \
-I${.CURDIR}/../../common -I${.CURDIR}/../../../
LDFLAGS=-nostdlib -static -N
diff --git a/sys/boot/powerpc/ofw/Makefile b/sys/boot/powerpc/ofw/Makefile
index d42fa92..776f98e 100644
--- a/sys/boot/powerpc/ofw/Makefile
+++ b/sys/boot/powerpc/ofw/Makefile
@@ -10,6 +10,7 @@ INSTALLFLAGS= -b
# Architecture-specific loader code
SRCS= conf.c metadata.c vers.c start.c
+SRCS+= ucmpdi2.c
LOADER_DISK_SUPPORT?= yes
LOADER_UFS_SUPPORT?= yes
@@ -62,9 +63,9 @@ LIBFICL= ${.OBJDIR}/../../ficl/libficl.a
CFLAGS+= -DNETIF_OPEN_CLOSE_ONCE
# Always add MI sources
-.PATH: ${.CURDIR}/../../common
+.PATH: ${.CURDIR}/../../common ${.CURDIR}/../../../libkern
.include "${.CURDIR}/../../common/Makefile.inc"
-CFLAGS+= -I${.CURDIR}/../../common
+CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../../..
CFLAGS+= -I.
CLEANFILES+= vers.c loader.help
diff --git a/sys/boot/powerpc/ofw/conf.c b/sys/boot/powerpc/ofw/conf.c
index 4ab3e23..5666f4a 100644
--- a/sys/boot/powerpc/ofw/conf.c
+++ b/sys/boot/powerpc/ofw/conf.c
@@ -96,6 +96,7 @@ struct netif_driver *netif_drivers[] = {
struct file_format *file_formats[] = {
&ofw_elf,
+ &ofw_elf64,
NULL
};
diff --git a/sys/boot/powerpc/ofw/ldscript.powerpc b/sys/boot/powerpc/ofw/ldscript.powerpc
index ecf8129..e3b7b2c 100644
--- a/sys/boot/powerpc/ofw/ldscript.powerpc
+++ b/sys/boot/powerpc/ofw/ldscript.powerpc
@@ -1,7 +1,7 @@
/* $FreeBSD$ */
OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc")
-OUTPUT_ARCH(powerpc)
+OUTPUT_ARCH(powerpc:common)
ENTRY(_start)
SEARCH_DIR(/usr/lib);
/* Do we need any of these for elf?
diff --git a/sys/boot/powerpc/ofw/metadata.c b/sys/boot/powerpc/ofw/metadata.c
index 37c2bb7..caed9cd 100644
--- a/sys/boot/powerpc/ofw/metadata.c
+++ b/sys/boot/powerpc/ofw/metadata.c
@@ -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));
+}
+
diff --git a/sys/boot/powerpc/uboot/Makefile b/sys/boot/powerpc/uboot/Makefile
index afd1b97..6ba738f 100644
--- a/sys/boot/powerpc/uboot/Makefile
+++ b/sys/boot/powerpc/uboot/Makefile
@@ -10,6 +10,7 @@ NO_MAN=
# Architecture-specific loader code
SRCS= start.S conf.c vers.c
+SRCS+= ucmpdi2.c
LOADER_DISK_SUPPORT?= yes
LOADER_UFS_SUPPORT?= yes
@@ -68,9 +69,9 @@ LIBFICL= ${.OBJDIR}/../../ficl/libficl.a
.endif
# Always add MI sources
-.PATH: ${.CURDIR}/../../common
+.PATH: ${.CURDIR}/../../common ${.CURDIR}/../../../libkern
.include "${.CURDIR}/../../common/Makefile.inc"
-CFLAGS+= -I${.CURDIR}/../../common
+CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../../..
CFLAGS+= -I.
CLEANFILES+= vers.c ${PROG}.help
diff --git a/sys/boot/powerpc/uboot/ldscript.powerpc b/sys/boot/powerpc/uboot/ldscript.powerpc
index 43ef422..fdba57c 100644
--- a/sys/boot/powerpc/uboot/ldscript.powerpc
+++ b/sys/boot/powerpc/uboot/ldscript.powerpc
@@ -1,7 +1,7 @@
/* $FreeBSD$ */
OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc")
-OUTPUT_ARCH(powerpc)
+OUTPUT_ARCH(powerpc:common)
ENTRY(_start)
SEARCH_DIR(/usr/lib);
PROVIDE (__stack = 0);
OpenPOWER on IntegriCloud