Index: stand/Makefile =================================================================== --- stand/Makefile +++ stand/Makefile @@ -39,6 +39,9 @@ .include S.${MK_EFI}+= efi +.if ${MK_FDT} != "no" +S.${MK_LOADER_KBOOT}+= kboot +.endif S.${MK_LOADER_UBOOT}+= uboot .if defined(LIB32LIST) Index: stand/powerpc/Makefile =================================================================== --- stand/powerpc/Makefile +++ stand/powerpc/Makefile @@ -6,8 +6,4 @@ SUBDIR.yes= boot1.chrp ofw -.if "${MACHINE_ARCH}" == "powerpc64" -SUBDIR.${MK_FDT}+= kboot -.endif - .include Index: stand/powerpc/kboot/Makefile =================================================================== --- /dev/null +++ stand/powerpc/kboot/Makefile @@ -1,46 +0,0 @@ -# $FreeBSD$ - -LOADER_CD9660_SUPPORT?= yes -LOADER_MSDOS_SUPPORT?= no -LOADER_EXT2FS_SUPPORT?= yes -LOADER_UFS_SUPPORT?= yes -LOADER_NET_SUPPORT?= yes -LOADER_NFS_SUPPORT?= yes -LOADER_TFTP_SUPPORT?= no -LOADER_GZIP_SUPPORT?= yes -LOADER_BZIP2_SUPPORT?= no - -.include - -PROG= loader.kboot -NEWVERSWHAT= "kboot loader" ${MACHINE_ARCH} -INSTALLFLAGS= -b - -# Architecture-specific loader code -SRCS= conf.c vers.c main.c ppc64_elf_freebsd.c -SRCS+= host_syscall.S hostcons.c hostdisk.c kerneltramp.S kbootfdt.c -SRCS+= ucmpdi2.c gfx_fb_stub.c - -CFLAGS.gfx_fb_stub.c += -I${SRCTOP}/contrib/pnglite -I${SRCTOP}/sys/teken - -.include "${BOOTSRC}/fdt.mk" - -CFLAGS+= -mcpu=powerpc64 - -# Always add MI sources -.include "${BOOTSRC}/loader.mk" -.PATH: ${SYSDIR}/libkern - -CFLAGS+= -Wall -DAIM -# load address. set in linker script -RELOC?= 0x0 -CFLAGS+= -DRELOC=${RELOC} - -LDFLAGS= -nostdlib -static -T ${.CURDIR}/ldscript.powerpc - -DPADD= ${LDR_INTERP} ${LIBOFW} ${LIBFDT} ${LIBSA} -LDADD= ${LDR_INTERP} ${LIBOFW} ${LIBFDT} ${LIBSA} - -MK_PIE= no - -.include Index: stand/powerpc/kboot/conf.c =================================================================== --- /dev/null +++ stand/powerpc/kboot/conf.c @@ -1,118 +0,0 @@ -/*- - * Copyright (C) 1999 Michael Smith - * 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 -__FBSDID("$FreeBSD$"); - -#include -#include "bootstrap.h" - -#if defined(LOADER_NET_SUPPORT) -#include "dev_net.h" -#endif - -extern struct devsw hostdisk; - -/* - * We could use linker sets for some or all of these, but - * then we would have to control what ended up linked into - * the bootstrap. So it's easier to conditionalise things - * here. - * - * XXX rename these arrays to be consistent and less namespace-hostile - */ - -/* Exported for libstand */ -struct devsw *devsw[] = { -#if defined(LOADER_DISK_SUPPORT) || defined(LOADER_CD9660_SUPPORT) - &hostdisk, -#endif -#if defined(LOADER_NET_SUPPORT) - &netdev, -#endif - NULL -}; - -struct fs_ops *file_system[] = { -#if defined(LOADER_UFS_SUPPORT) - &ufs_fsops, -#endif -#if defined(LOADER_CD9660_SUPPORT) - &cd9660_fsops, -#endif -#if defined(LOADER_EXT2FS_SUPPORT) - &ext2fs_fsops, -#endif -#if defined(LOADER_NFS_SUPPORT) - &nfs_fsops, -#endif -#if defined(LOADER_TFTP_SUPPORT) - &tftp_fsops, -#endif -#if defined(LOADER_GZIP_SUPPORT) - &gzipfs_fsops, -#endif -#if defined(LOADER_BZIP2_SUPPORT) - &bzipfs_fsops, -#endif - &dosfs_fsops, - NULL -}; - -extern struct netif_driver kbootnet; - -struct netif_driver *netif_drivers[] = { -#if 0 /* XXX */ -#if defined(LOADER_NET_SUPPORT) - &kbootnet, -#endif -#endif - NULL, -}; - -/* Exported for PowerPC only */ -/* - * Sort formats so that those that can detect based on arguments - * rather than reading the file go first. - */ - -extern struct file_format ppc_elf64; - -struct file_format *file_formats[] = { - &ppc_elf64, - NULL -}; - -/* - * Consoles - */ -extern struct console hostconsole; - -struct console *consoles[] = { - &hostconsole, - NULL -}; - Index: stand/powerpc/kboot/host_syscall.h =================================================================== --- /dev/null +++ stand/powerpc/kboot/host_syscall.h @@ -1,59 +0,0 @@ -/*- - * Copyright (C) 2014 Nathan Whitehorn - * 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 ``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 TOOLS GMBH 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 _HOST_SYSCALL_H -#define _HOST_SYSCALL_H - -#include - -ssize_t host_read(int fd, void *buf, size_t nbyte); -ssize_t host_write(int fd, const void *buf, size_t nbyte); -int host_open(const char *path, int flags, int mode); -ssize_t host_llseek(int fd, int32_t offset_high, int32_t offset_lo, uint64_t *result, int whence); -int host_close(int fd); -void *host_mmap(void *addr, size_t len, int prot, int flags, int fd, int); -#define host_getmem(size) host_mmap(0, size, 3 /* RW */, 0x22 /* ANON */, -1, 0); -struct old_utsname { - char sysname[65]; - char nodename[65]; - char release[65]; - char version[65]; - char machine[65]; -}; -int host_uname(struct old_utsname *); -struct host_timeval { - int tv_sec; - int tv_usec; -}; -int host_gettimeofday(struct host_timeval *a, void *b); -int host_select(int nfds, long *readfds, long *writefds, long *exceptfds, - struct host_timeval *timeout); -int kexec_load(uint32_t start, int nsegs, uint32_t segs); -int host_reboot(int, int, int, uint32_t); -int host_getdents(int fd, void *dirp, int count); - -#endif Index: stand/powerpc/kboot/host_syscall.S =================================================================== --- /dev/null +++ stand/powerpc/kboot/host_syscall.S @@ -1,88 +0,0 @@ -/* - * - * $FreeBSD$ - */ - -#include - -ENTRY(host_read) - li %r0, 3 # SYS_read - sc - bso 1f - blr -1: - li %r3, 0 - blr -END(host_read) - -ENTRY(host_write) - li %r0, 4 # SYS_write - sc - blr -END(host_write) - -ENTRY(host_llseek) - li %r0, 140 # SYS_llseek - sc - blr -END(host_llseek) - -ENTRY(host_open) - li %r0, 5 # SYS_open - sc - bso 1f - blr -1: - li %r3, 0 - blr -END(host_open) - -ENTRY(host_close) - li %r0, 6 # SYS_close - sc - blr -END(host_close) - -ENTRY(host_mmap) - li %r0, 90 # SYS_mmap - sc - blr -END(host_mmap) - -ENTRY(host_uname) - li %r0, 122 # SYS_uname - sc - blr -END(host_uname) - -ENTRY(host_gettimeofday) - li %r0, 78 # SYS_gettimeofday - sc - blr -END(host_gettimeofday) - -ENTRY(host_select) - li %r0, 142 # SYS_select - sc - blr -END(host_select) - -ENTRY(kexec_load) - lis %r6,21 # KEXEC_ARCH_PPC64 - li %r0,268 # __NR_kexec_load - sc - blr -END(kexec_load) - -ENTRY(host_reboot) - li %r0,88 # SYS_reboot - sc - blr -END(host_reboot) - -ENTRY(host_getdents) - li %r0,141 # SYS_getdents - sc - blr -END(host_getdents) - Index: stand/powerpc/kboot/hostcons.c =================================================================== --- /dev/null +++ stand/powerpc/kboot/hostcons.c @@ -1,97 +0,0 @@ -/*- - * Copyright (C) 2014 Nathan Whitehorn - * 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 ``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 TOOLS GMBH 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 -__FBSDID("$FreeBSD$"); - -#include -#include "bootstrap.h" -#include "host_syscall.h" - -static void hostcons_probe(struct console *cp); -static int hostcons_init(int arg); -static void hostcons_putchar(int c); -static int hostcons_getchar(); -static int hostcons_poll(); - -struct console hostconsole = { - "host", - "Host Console", - 0, - hostcons_probe, - hostcons_init, - hostcons_putchar, - hostcons_getchar, - hostcons_poll, -}; - -static void -hostcons_probe(struct console *cp) -{ - - cp->c_flags |= C_PRESENTIN|C_PRESENTOUT; -} - -static int -hostcons_init(int arg) -{ - - /* XXX: set nonblocking */ - /* tcsetattr(~(ICANON | ECHO)) */ - - return (0); -} - -static void -hostcons_putchar(int c) -{ - uint8_t ch = c; - - host_write(1, &ch, 1); -} - -static int -hostcons_getchar() -{ - uint8_t ch; - int rv; - - rv = host_read(0, &ch, 1); - if (rv == 1) - return (ch); - return (-1); -} - -static int -hostcons_poll() -{ - struct host_timeval tv = {0,0}; - long fds = 1 << 0; - int ret; - - ret = host_select(32, &fds, NULL, NULL, &tv); - return (ret > 0); -} - Index: stand/powerpc/kboot/hostdisk.c =================================================================== --- /dev/null +++ stand/powerpc/kboot/hostdisk.c @@ -1,129 +0,0 @@ -/*- - * Copyright (C) 2014 Nathan Whitehorn - * 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 ``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 TOOLS GMBH 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 -__FBSDID("$FreeBSD$"); - -#include -#include -#include "bootstrap.h" -#include "host_syscall.h" - -static int hostdisk_init(void); -static int hostdisk_strategy(void *devdata, int flag, daddr_t dblk, - size_t size, char *buf, size_t *rsize); -static int hostdisk_open(struct open_file *f, ...); -static int hostdisk_close(struct open_file *f); -static int hostdisk_ioctl(struct open_file *f, u_long cmd, void *data); -static int hostdisk_print(int verbose); - -struct devsw hostdisk = { - "/dev", - DEVT_DISK, - hostdisk_init, - hostdisk_strategy, - hostdisk_open, - hostdisk_close, - hostdisk_ioctl, - hostdisk_print, -}; - -static int -hostdisk_init(void) -{ - - return (0); -} - -static int -hostdisk_strategy(void *devdata, int flag, daddr_t dblk, size_t size, - char *buf, size_t *rsize) -{ - struct devdesc *desc = devdata; - daddr_t pos; - int n; - uint64_t res; - uint32_t posl, posh; - - pos = dblk * 512; - - posl = pos & 0xffffffff; - posh = (pos >> 32) & 0xffffffff; - if (host_llseek(desc->d_unit, posh, posl, &res, 0) < 0) { - printf("Seek error\n"); - return (EIO); - } - n = host_read(desc->d_unit, buf, size); - - if (n < 0) - return (EIO); - - *rsize = n; - return (0); -} - -static int -hostdisk_open(struct open_file *f, ...) -{ - struct devdesc *desc; - va_list vl; - - va_start(vl, f); - desc = va_arg(vl, struct devdesc *); - va_end(vl); - - desc->d_unit = host_open(desc->d_opendata, O_RDONLY, 0); - - if (desc->d_unit <= 0) { - printf("hostdisk_open: couldn't open %s: %d\n", - (char *)desc->d_opendata, desc->d_unit); - return (ENOENT); - } - - return (0); -} - -static int -hostdisk_close(struct open_file *f) -{ - struct devdesc *desc = f->f_devdata; - - host_close(desc->d_unit); - return (0); -} - -static int -hostdisk_ioctl(struct open_file *f, u_long cmd, void *data) -{ - - return (EINVAL); -} - -static int -hostdisk_print(int verbose) -{ - return (0); -} - Index: stand/powerpc/kboot/kbootfdt.c =================================================================== --- /dev/null +++ stand/powerpc/kboot/kbootfdt.c @@ -1,190 +0,0 @@ -/*- - * Copyright (C) 2014 Nathan Whitehorn - * 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 ``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 TOOLS GMBH 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 -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include "bootstrap.h" -#include "host_syscall.h" - -static void -add_node_to_fdt(void *buffer, const char *path, int fdt_offset) -{ - int child_offset, fd, pfd, error, dentsize; - char subpath[512]; - void *propbuf; - ssize_t proplen; - - struct host_dent { - unsigned long d_fileno; - unsigned long d_off; - unsigned short d_reclen; - char d_name[]; - /* uint8_t d_type; */ - }; - char dents[2048]; - struct host_dent *dent; - int d_type; - - fd = host_open(path, O_RDONLY, 0); - while (1) { - dentsize = host_getdents(fd, dents, sizeof(dents)); - if (dentsize <= 0) - break; - for (dent = (struct host_dent *)dents; - (char *)dent < dents + dentsize; - dent = (struct host_dent *)((void *)dent + dent->d_reclen)) { - sprintf(subpath, "%s/%s", path, dent->d_name); - if (strcmp(dent->d_name, ".") == 0 || - strcmp(dent->d_name, "..") == 0) - continue; - d_type = *((char *)(dent) + dent->d_reclen - 1); - if (d_type == 4 /* DT_DIR */) { - child_offset = fdt_add_subnode(buffer, fdt_offset, - dent->d_name); - if (child_offset < 0) { - printf("Error %d adding node %s/%s, skipping\n", - child_offset, path, dent->d_name); - continue; - } - - add_node_to_fdt(buffer, subpath, child_offset); - } else { - propbuf = malloc(1024); - proplen = 0; - pfd = host_open(subpath, O_RDONLY, 0); - if (pfd > 0) { - proplen = host_read(pfd, propbuf, 1024); - host_close(pfd); - } - error = fdt_setprop(buffer, fdt_offset, dent->d_name, - propbuf, proplen); - free(propbuf); - if (error) - printf("Error %d adding property %s to " - "node %d\n", error, dent->d_name, - fdt_offset); - } - } - } - - host_close(fd); -} - -/* Fix up wrong values added to the device tree by prom_init() in Linux */ - -static void -fdt_linux_fixups(void *fdtp) -{ - int offset, len; - const void *prop; - - /* - * Remove /memory/available properties, which reflect long-gone OF - * state - */ - - offset = fdt_path_offset(fdtp, "/memory@0"); - if (offset > 0) - fdt_delprop(fdtp, offset, "available"); - - /* - * Add reservations for OPAL and RTAS state if present - */ - - offset = fdt_path_offset(fdtp, "/ibm,opal"); - if (offset > 0) { - const uint64_t *base, *size; - base = fdt_getprop(fdtp, offset, "opal-base-address", - &len); - size = fdt_getprop(fdtp, offset, "opal-runtime-size", - &len); - if (base != NULL && size != NULL) - fdt_add_mem_rsv(fdtp, fdt64_to_cpu(*base), - fdt64_to_cpu(*size)); - } - offset = fdt_path_offset(fdtp, "/rtas"); - if (offset > 0) { - const uint32_t *base, *size; - base = fdt_getprop(fdtp, offset, "linux,rtas-base", &len); - size = fdt_getprop(fdtp, offset, "rtas-size", &len); - if (base != NULL && size != NULL) - fdt_add_mem_rsv(fdtp, fdt32_to_cpu(*base), - fdt32_to_cpu(*size)); - } - - /* - * Patch up /chosen nodes so that the stored handles mean something, - * where possible. - */ - offset = fdt_path_offset(fdtp, "/chosen"); - if (offset > 0) { - fdt_delprop(fdtp, offset, "cpu"); /* This node not meaningful */ - - offset = fdt_path_offset(fdtp, "/chosen"); - prop = fdt_getprop(fdtp, offset, "linux,stdout-package", &len); - if (prop != NULL) { - fdt_setprop(fdtp, offset, "stdout", prop, len); - offset = fdt_path_offset(fdtp, "/chosen"); - fdt_setprop(fdtp, offset, "stdin", prop, len); - } - } -} - -int -fdt_platform_load_dtb(void) -{ - void *buffer; - size_t buflen = 409600; - - buffer = malloc(buflen); - fdt_create_empty_tree(buffer, buflen); - add_node_to_fdt(buffer, "/proc/device-tree", - fdt_path_offset(buffer, "/")); - fdt_linux_fixups(buffer); - - fdt_pack(buffer); - - fdt_load_dtb_addr(buffer); - free(buffer); - - return (0); -} - -void -fdt_platform_load_overlays(void) -{ - -} - -void -fdt_platform_fixups(void) -{ - -} - Index: stand/powerpc/kboot/kerneltramp.S =================================================================== --- /dev/null +++ stand/powerpc/kboot/kerneltramp.S @@ -1,102 +0,0 @@ -/* - * This is the analog to the kexec "purgatory" code - * - * The goal here is to call the actual kernel entry point with the arguments it - * expects when kexec calls into it with no arguments. The value of the kernel - * entry point and arguments r3-r7 are copied into the trampoline text (which - * can be executed from any address) at bytes 8-32. kexec begins execution - * of APs at 0x60 bytes past the entry point, executing in a copy relocated - * to the absolute address 0x60. Here we implement a loop waiting on the release - * of a lock by the kernel at 0x40. - * - * $FreeBSD$ - */ - -#include - - .globl CNAME(kerneltramp),CNAME(szkerneltramp) -CNAME(kerneltramp): - mflr %r9 - bl 2f - .space 24 /* branch address, r3-r7 */ - -/* - * MUST BE IN SYNC WITH: - * struct trampoline_data { - * uint32_t kernel_entry; - * uint32_t dtb; - * uint32_t phys_mem_offset; - * uint32_t of_entry; - * uint32_t mdp; - * uint32_t mdp_size; - * }; - */ - -. = kerneltramp + 0x40 /* AP spinlock */ - .long 0 - -. = kerneltramp + 0x60 /* AP entry point */ - li %r3,0x40 -1: lwz %r1,0(%r3) - cmpwi %r1,0 - beq 1b - - /* Jump into CPU reset */ - li %r0,0x100 - icbi 0,%r0 - isync - sync - ba 0x100 - -2: /* Continuation of kerneltramp */ - mflr %r8 - mtlr %r9 - - mfmsr %r10 - andi. %r10, %r10, 1 /* test MSR_LE */ - bne little_endian - -/* We're starting in BE */ -big_endian: - lwz %r3,4(%r8) - lwz %r4,8(%r8) - lwz %r5,12(%r8) - lwz %r6,16(%r8) - lwz %r7,20(%r8) - - lwz %r10, 0(%r8) - mtctr %r10 - bctr - -/* We're starting in LE */ -little_endian: - - /* Entries are BE, swap them during load. */ - li %r10, 4 - lwbrx %r3, %r8, %r10 - li %r10, 8 - lwbrx %r4, %r8, %r10 - li %r10, 12 - lwbrx %r5, %r8, %r10 - li %r10, 16 - lwbrx %r6, %r8, %r10 - li %r10, 20 - lwbrx %r7, %r8, %r10 - - /* Clear MSR_LE flag to enter the BE world */ - mfmsr %r10 - clrrdi %r10, %r10, 1 - mtsrr1 %r10 - - /* Entry is at 0(%r8) */ - li %r10, 0 - lwbrx %r10, %r8, %r10 - mtsrr0 %r10 - - rfid - -endkerneltramp: - - .data -CNAME(szkerneltramp): - .long endkerneltramp - CNAME(kerneltramp) Index: stand/powerpc/kboot/ldscript.powerpc =================================================================== --- /dev/null +++ stand/powerpc/kboot/ldscript.powerpc @@ -1,111 +0,0 @@ -/* $FreeBSD: user/nwhitehorn/kboot/powerpc/kboot/ldscript.powerpc 272888 2014-10-10 06:24:09Z bapt $ */ - -OUTPUT_FORMAT("elf32-powerpc-freebsd", "elf32-powerpc-freebsd", - "elf32-powerpc-freebsd") -OUTPUT_ARCH(powerpc:common) -ENTRY(_start) -SEARCH_DIR(/usr/lib); -PROVIDE (__stack = 0); -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - . = 0x100000; - .text : - { - *(.text) - /* .gnu.warning sections are handled specially by elf32.em. */ - *(.gnu.warning) - *(.gnu.linkonce.t*) - } =0 - _etext = .; - .interp : { *(.interp) } - .hash : { *(.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .gnu.version : { *(.gnu.version) } - .gnu.version_d : { *(.gnu.version_d) } - .gnu.version_r : { *(.gnu.version_r) } - .rela.text : - { *(.rela.text) *(.rela.gnu.linkonce.t*) } - .rela.data : - { *(.rela.data) *(.rela.gnu.linkonce.d*) } - .rela.rodata : - { *(.rela.rodata) *(.rela.gnu.linkonce.r*) } - .rela.got : { *(.rela.got) } - .rela.got1 : { *(.rela.got1) } - .rela.got2 : { *(.rela.got2) } - .rela.ctors : { *(.rela.ctors) } - .rela.dtors : { *(.rela.dtors) } - .rela.init : { *(.rela.init) } - .rela.fini : { *(.rela.fini) } - .rela.bss : { *(.rela.bss) } - .rela.plt : { *(.rela.plt) } - .rela.sbss : { *(.rela.sbss) } - .rela.sbss2 : { *(.rela.sbss2) } - .text : - { - *(.text) - /* .gnu.warning sections are handled specially by elf32.em. */ - *(.gnu.warning) - *(.gnu.linkonce.t*) - } =0 - _etext = .; - PROVIDE (etext = .); - .init : { *(.init) } =0 - .fini : { *(.fini) } =0 - .rodata : { *(.rodata) *(.gnu.linkonce.r*) } - .rodata1 : { *(.rodata1) } - .sbss2 : { *(.sbss2) } - /* Adjust the address for the data segment to the next page up. */ - . = ((. + 0x1000) & ~(0x1000 - 1)); - .data : - { - *(.data) - *(.gnu.linkonce.d*) - CONSTRUCTORS - } - .data1 : { *(.data1) } - .got1 : { *(.got1) } - .dynamic : { *(.dynamic) } - /* Put .ctors and .dtors next to the .got2 section, so that the pointers - get relocated with -mrelocatable. Also put in the .fixup pointers. - The current compiler no longer needs this, but keep it around for 2.7.2 */ - PROVIDE (_GOT2_START_ = .); - .got2 : { *(.got2) } - PROVIDE (__CTOR_LIST__ = .); - .ctors : { *(.ctors) } - PROVIDE (__CTOR_END__ = .); - PROVIDE (__DTOR_LIST__ = .); - .dtors : { *(.dtors) } - PROVIDE (__DTOR_END__ = .); - PROVIDE (_FIXUP_START_ = .); - .fixup : { *(.fixup) } - PROVIDE (_FIXUP_END_ = .); - PROVIDE (_GOT2_END_ = .); - PROVIDE (_GOT_START_ = .); - .got : { *(.got) } - .got.plt : { *(.got.plt) } - PROVIDE (_GOT_END_ = .); - _edata = .; - PROVIDE (edata = .); - .sbss : - { - PROVIDE (__sbss_start = .); - *(.sbss) - *(.scommon) - *(.dynsbss) - PROVIDE (__sbss_end = .); - } - .plt : { *(.plt) } - .bss : - { - PROVIDE (__bss_start = .); - *(.dynbss) - *(.bss) - *(COMMON) - } - . = ALIGN(4096); - _end = . ; - PROVIDE (end = .); -} - Index: stand/powerpc/kboot/main.c =================================================================== --- /dev/null +++ stand/powerpc/kboot/main.c @@ -1,501 +0,0 @@ -/*- - * Copyright (C) 2010-2014 Nathan Whitehorn - * 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 ``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 TOOLS GMBH 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 -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include - -#include -#include -#include "host_syscall.h" - - -struct arch_switch archsw; -extern void *_end; - -int kboot_getdev(void **vdev, const char *devspec, const char **path); -ssize_t kboot_copyin(const void *src, vm_offset_t dest, const size_t len); -ssize_t kboot_copyout(vm_offset_t src, void *dest, const size_t len); -ssize_t kboot_readin(readin_handle_t fd, vm_offset_t dest, const size_t len); -int kboot_autoload(void); -uint64_t kboot_loadaddr(u_int type, void *data, uint64_t addr); -static void kboot_kseg_get(int *nseg, void **ptr); - -extern int command_fdt_internal(int argc, char *argv[]); - -struct region_desc { - uint64_t start; - uint64_t end; -}; - -static uint64_t -kboot_get_phys_load_segment(void) -{ - int fd; - uint64_t entry[2]; - static uint64_t load_segment = ~(0UL); - uint64_t val_64; - uint32_t val_32; - struct region_desc rsvd_reg[32]; - int rsvd_reg_cnt = 0; - int ret, a, b; - uint64_t start, end; - - if (load_segment == ~(0UL)) { - - /* Default load address is 0x00000000 */ - load_segment = 0UL; - - /* Read reserved regions */ - fd = host_open("/proc/device-tree/reserved-ranges", O_RDONLY, 0); - if (fd >= 0) { - while (host_read(fd, &entry[0], sizeof(entry)) == sizeof(entry)) { - rsvd_reg[rsvd_reg_cnt].start = be64toh(entry[0]); - rsvd_reg[rsvd_reg_cnt].end = - be64toh(entry[1]) + rsvd_reg[rsvd_reg_cnt].start - 1; - rsvd_reg_cnt++; - } - host_close(fd); - } - /* Read where the kernel ends */ - fd = host_open("/proc/device-tree/chosen/linux,kernel-end", O_RDONLY, 0); - if (fd >= 0) { - ret = host_read(fd, &val_64, sizeof(val_64)); - - if (ret == sizeof(uint64_t)) { - rsvd_reg[rsvd_reg_cnt].start = 0; - rsvd_reg[rsvd_reg_cnt].end = be64toh(val_64) - 1; - } else { - memcpy(&val_32, &val_64, sizeof(val_32)); - rsvd_reg[rsvd_reg_cnt].start = 0; - rsvd_reg[rsvd_reg_cnt].end = be32toh(val_32) - 1; - } - rsvd_reg_cnt++; - - host_close(fd); - } - /* Read memory size (SOCKET0 only) */ - fd = host_open("/proc/device-tree/memory@0/reg", O_RDONLY, 0); - if (fd < 0) - fd = host_open("/proc/device-tree/memory/reg", O_RDONLY, 0); - if (fd >= 0) { - ret = host_read(fd, &entry, sizeof(entry)); - - /* Memory range in start:length format */ - entry[0] = be64toh(entry[0]); - entry[1] = be64toh(entry[1]); - - /* Reserve everything what is before start */ - if (entry[0] != 0) { - rsvd_reg[rsvd_reg_cnt].start = 0; - rsvd_reg[rsvd_reg_cnt].end = entry[0] - 1; - rsvd_reg_cnt++; - } - /* Reserve everything what is after end */ - if (entry[1] != 0xffffffffffffffffUL) { - rsvd_reg[rsvd_reg_cnt].start = entry[0] + entry[1]; - rsvd_reg[rsvd_reg_cnt].end = 0xffffffffffffffffUL; - rsvd_reg_cnt++; - } - - host_close(fd); - } - - /* Sort entries in ascending order (bubble) */ - for (a = rsvd_reg_cnt - 1; a > 0; a--) { - for (b = 0; b < a; b++) { - if (rsvd_reg[b].start > rsvd_reg[b + 1].start) { - struct region_desc tmp; - tmp = rsvd_reg[b]; - rsvd_reg[b] = rsvd_reg[b + 1]; - rsvd_reg[b + 1] = tmp; - } - } - } - - /* Join overlapping/adjacent regions */ - for (a = 0; a < rsvd_reg_cnt - 1; ) { - - if ((rsvd_reg[a + 1].start >= rsvd_reg[a].start) && - ((rsvd_reg[a + 1].start - 1) <= rsvd_reg[a].end)) { - /* We have overlapping/adjacent regions! */ - rsvd_reg[a].end = - MAX(rsvd_reg[a].end, rsvd_reg[a + a].end); - - for (b = a + 1; b < rsvd_reg_cnt - 1; b++) - rsvd_reg[b] = rsvd_reg[b + 1]; - rsvd_reg_cnt--; - } else - a++; - } - - /* Find the first free region */ - if (rsvd_reg_cnt > 0) { - start = 0; - end = rsvd_reg[0].start; - for (a = 0; a < rsvd_reg_cnt - 1; a++) { - if ((start >= rsvd_reg[a].start) && - (start <= rsvd_reg[a].end)) { - start = rsvd_reg[a].end + 1; - end = rsvd_reg[a + 1].start; - } else - break; - } - - if (start != end) { - uint64_t align = 64UL*1024UL*1024UL; - - /* Align both to 64MB boundary */ - start = (start + align - 1UL) & ~(align - 1UL); - end = ((end + 1UL) & ~(align - 1UL)) - 1UL; - - if (start < end) - load_segment = start; - } - } - } - - return (load_segment); -} - -uint8_t -kboot_get_kernel_machine_bits(void) -{ - static uint8_t bits = 0; - struct old_utsname utsname; - int ret; - - if (bits == 0) { - /* Default is 32-bit kernel */ - bits = 32; - - /* Try to get system type */ - memset(&utsname, 0, sizeof(utsname)); - ret = host_uname(&utsname); - if (ret == 0) { - if (strcmp(utsname.machine, "ppc64") == 0) - bits = 64; - else if (strcmp(utsname.machine, "ppc64le") == 0) - bits = 64; - } - } - - return (bits); -} - -int -kboot_getdev(void **vdev, const char *devspec, const char **path) -{ - int i; - const char *devpath, *filepath; - struct devsw *dv; - struct devdesc *desc; - - if (strchr(devspec, ':') != NULL) { - devpath = devspec; - filepath = strchr(devspec, ':') + 1; - } else { - devpath = getenv("currdev"); - filepath = devspec; - } - - for (i = 0; (dv = devsw[i]) != NULL; i++) { - if (strncmp(dv->dv_name, devpath, strlen(dv->dv_name)) == 0) - goto found; - } - return (ENOENT); - -found: - if (path != NULL && filepath != NULL) - *path = filepath; - else if (path != NULL) - *path = strchr(devspec, ':') + 1; - - if (vdev != NULL) { - desc = malloc(sizeof(*desc)); - desc->d_dev = dv; - desc->d_unit = 0; - desc->d_opendata = strdup(devpath); - *vdev = desc; - } - - return (0); -} - -int -main(int argc, const char **argv) -{ - void *heapbase; - const size_t heapsize = 15*1024*1024; - const char *bootdev; - - /* - * Set the heap to one page after the end of the loader. - */ - heapbase = host_getmem(heapsize); - setheap(heapbase, heapbase + heapsize); - - /* - * Set up console. - */ - cons_probe(); - - /* Choose bootdev if provided */ - if (argc > 1) - bootdev = argv[1]; - else - bootdev = ""; - - printf("Boot device: %s\n", bootdev); - - archsw.arch_getdev = kboot_getdev; - archsw.arch_copyin = kboot_copyin; - archsw.arch_copyout = kboot_copyout; - archsw.arch_readin = kboot_readin; - archsw.arch_autoload = kboot_autoload; - archsw.arch_loadaddr = kboot_loadaddr; - archsw.arch_kexec_kseg_get = kboot_kseg_get; - - printf("\n%s", bootprog_info); - - setenv("currdev", bootdev, 1); - setenv("loaddev", bootdev, 1); - setenv("LINES", "24", 1); - setenv("usefdt", "1", 1); - - interact(); /* doesn't return */ - - return (0); -} - -void -exit(int code) -{ - while (1); /* XXX: host_exit */ - __unreachable(); -} - -void -delay(int usecs) -{ - struct host_timeval tvi, tv; - uint64_t ti, t; - host_gettimeofday(&tvi, NULL); - ti = tvi.tv_sec*1000000 + tvi.tv_usec; - do { - host_gettimeofday(&tv, NULL); - t = tv.tv_sec*1000000 + tv.tv_usec; - } while (t < ti + usecs); -} - -time_t -getsecs(void) -{ - struct host_timeval tv; - host_gettimeofday(&tv, NULL); - return (tv.tv_sec); -} - -time_t -time(time_t *tloc) -{ - time_t rv; - - rv = getsecs(); - if (tloc != NULL) - *tloc = rv; - - return (rv); -} - -struct kexec_segment { - void *buf; - int bufsz; - void *mem; - int memsz; -}; - -struct kexec_segment loaded_segments[128]; -int nkexec_segments = 0; - -static ssize_t -get_phys_buffer(vm_offset_t dest, const size_t len, void **buf) -{ - int i = 0; - const size_t segsize = 4*1024*1024; - - for (i = 0; i < nkexec_segments; i++) { - if (dest >= (vm_offset_t)loaded_segments[i].mem && - dest < (vm_offset_t)loaded_segments[i].mem + - loaded_segments[i].memsz) - goto out; - } - - loaded_segments[nkexec_segments].buf = host_getmem(segsize); - loaded_segments[nkexec_segments].bufsz = segsize; - loaded_segments[nkexec_segments].mem = (void *)rounddown2(dest,segsize); - loaded_segments[nkexec_segments].memsz = segsize; - - i = nkexec_segments; - nkexec_segments++; - -out: - *buf = loaded_segments[i].buf + (dest - - (vm_offset_t)loaded_segments[i].mem); - return (min(len,loaded_segments[i].bufsz - (dest - - (vm_offset_t)loaded_segments[i].mem))); -} - -ssize_t -kboot_copyin(const void *src, vm_offset_t dest, const size_t len) -{ - ssize_t segsize, remainder; - void *destbuf; - - remainder = len; - do { - segsize = get_phys_buffer(dest, remainder, &destbuf); - bcopy(src, destbuf, segsize); - remainder -= segsize; - src += segsize; - dest += segsize; - } while (remainder > 0); - - return (len); -} - -ssize_t -kboot_copyout(vm_offset_t src, void *dest, const size_t len) -{ - ssize_t segsize, remainder; - void *srcbuf; - - remainder = len; - do { - segsize = get_phys_buffer(src, remainder, &srcbuf); - bcopy(srcbuf, dest, segsize); - remainder -= segsize; - src += segsize; - dest += segsize; - } while (remainder > 0); - - return (len); -} - -ssize_t -kboot_readin(readin_handle_t fd, vm_offset_t dest, const size_t len) -{ - void *buf; - size_t resid, chunk, get; - ssize_t got; - vm_offset_t p; - - p = dest; - - chunk = min(PAGE_SIZE, len); - buf = malloc(chunk); - if (buf == NULL) { - printf("kboot_readin: buf malloc failed\n"); - return (0); - } - - for (resid = len; resid > 0; resid -= got, p += got) { - get = min(chunk, resid); - got = VECTX_READ(fd, buf, get); - if (got <= 0) { - if (got < 0) - printf("kboot_readin: read failed\n"); - break; - } - - kboot_copyin(buf, p, got); - } - - free (buf); - return (len - resid); -} - -int -kboot_autoload(void) -{ - - return (0); -} - -uint64_t -kboot_loadaddr(u_int type, void *data, uint64_t addr) -{ - - if (type == LOAD_ELF) - addr = roundup(addr, PAGE_SIZE); - else - addr += kboot_get_phys_load_segment(); - - return (addr); -} - -static void -kboot_kseg_get(int *nseg, void **ptr) -{ -#if 0 - int a; - - for (a = 0; a < nkexec_segments; a++) { - printf("kseg_get: %jx %jx %jx %jx\n", - (uintmax_t)loaded_segments[a].buf, - (uintmax_t)loaded_segments[a].bufsz, - (uintmax_t)loaded_segments[a].mem, - (uintmax_t)loaded_segments[a].memsz); - } -#endif - - *nseg = nkexec_segments; - *ptr = &loaded_segments[0]; -} - -void -_start(int argc, const char **argv, char **env) -{ - main(argc, argv); -} - -/* - * Since proper fdt command handling function is defined in fdt_loader_cmd.c, - * and declaring it as extern is in contradiction with COMMAND_SET() macro - * (which uses static pointer), we're defining wrapper function, which - * calls the proper fdt handling routine. - */ -static int -command_fdt(int argc, char *argv[]) -{ - - return (command_fdt_internal(argc, argv)); -} - -COMMAND_SET(fdt, "fdt", "flattened device tree handling", command_fdt); Index: stand/powerpc/kboot/ppc64_elf_freebsd.c =================================================================== --- /dev/null +++ stand/powerpc/kboot/ppc64_elf_freebsd.c @@ -1,171 +0,0 @@ -/*- - * Copyright (c) 2001 Benno Rice - * 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 -__FBSDID("$FreeBSD$"); - -#define __ELF_WORD_SIZE 64 - -#include -#include -#include - -#include -#include - -#include - -#include "bootstrap.h" -#include "host_syscall.h" - -extern char end[]; -extern void *kerneltramp; -extern size_t szkerneltramp; - -struct trampoline_data { - uint32_t kernel_entry; - uint32_t dtb; - uint32_t phys_mem_offset; - uint32_t of_entry; - uint32_t mdp; - uint32_t mdp_size; -}; - -vm_offset_t md_load64(char *args, vm_offset_t *modulep, vm_offset_t *dtb); - -int -ppc64_elf_loadfile(char *filename, uint64_t dest, - struct preloaded_file **result) -{ - int r; - - r = __elfN(loadfile)(filename, dest, result); - if (r != 0) - return (r); - - return (0); -} - -int -ppc64_elf_exec(struct preloaded_file *fp) -{ - struct file_metadata *fmp; - vm_offset_t mdp, dtb; - Elf_Ehdr *e; - int error; - uint32_t *trampoline; - uint64_t entry; - uint64_t trampolinebase; - struct trampoline_data *trampoline_data; - int nseg; - void *kseg; - - if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) { - return(EFTYPE); - } - e = (Elf_Ehdr *)&fmp->md_data; - - /* - * 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). - * - * 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); - printf("Load address at %#jx\n", (uintmax_t)trampolinebase); - printf("Relocation offset is %#jx\n", (uintmax_t)elf64_relocation_offset); - - /* Set up loader trampoline */ - trampoline = malloc(szkerneltramp); - memcpy(trampoline, &kerneltramp, szkerneltramp); - - /* Parse function descriptor for ELFv1 kernels */ - if ((e->e_flags & 3) == 2) - entry = e->e_entry; - else { - archsw.arch_copyout(e->e_entry + elf64_relocation_offset, - &entry, 8); - entry = be64toh(entry); - } - - /* - * Placeholder for trampoline data is at trampolinebase + 0x08 - * CAUTION: all data must be Big Endian - */ - trampoline_data = (void*)&trampoline[2]; - trampoline_data->kernel_entry = htobe32(entry + elf64_relocation_offset); - trampoline_data->phys_mem_offset = htobe32(0); - trampoline_data->of_entry = htobe32(0); - - if ((error = md_load64(fp->f_args, &mdp, &dtb)) != 0) - return (error); - - trampoline_data->dtb = htobe32(dtb); - trampoline_data->mdp = htobe32(mdp); - trampoline_data->mdp_size = htobe32(0xfb5d104d); - - printf("Kernel entry at %#jx (%#x) ...\n", - entry, be32toh(trampoline_data->kernel_entry)); - printf("DTB at %#x, mdp at %#x\n", - be32toh(trampoline_data->dtb), be32toh(trampoline_data->mdp)); - - dev_cleanup(); - - archsw.arch_copyin(trampoline, trampolinebase, szkerneltramp); - free(trampoline); - - if (archsw.arch_kexec_kseg_get == NULL) - panic("architecture did not provide kexec segment mapping"); - archsw.arch_kexec_kseg_get(&nseg, &kseg); - - error = kexec_load(trampolinebase, nseg, (uintptr_t)kseg); - if (error != 0) - panic("kexec_load returned error: %d", error); - - error = host_reboot(0xfee1dead, 672274793, - 0x45584543 /* LINUX_REBOOT_CMD_KEXEC */, (uintptr_t)NULL); - if (error != 0) - panic("reboot returned error: %d", error); - - while (1) {} -} - -struct file_format ppc_elf64 = -{ - ppc64_elf_loadfile, - ppc64_elf_exec -}; Index: stand/powerpc/kboot/version =================================================================== --- /dev/null +++ stand/powerpc/kboot/version @@ -1,6 +0,0 @@ -$FreeBSD: user/nwhitehorn/kboot/powerpc/kboot/version 224106 2011-07-16 19:01:09Z nwhitehorn $ - -NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this -file is important. Make sure the current version number is on line 6. - -0.1: Initial kboot/PowerPC version.