From owner-svn-src-user@FreeBSD.ORG Thu Jan 1 18:07:59 2015 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 846FA507; Thu, 1 Jan 2015 18:07:59 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 655ED6636B; Thu, 1 Jan 2015 18:07:59 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t01I7xoc066922; Thu, 1 Jan 2015 18:07:59 GMT (envelope-from nwhitehorn@FreeBSD.org) Received: (from nwhitehorn@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t01I7vB5066912; Thu, 1 Jan 2015 18:07:57 GMT (envelope-from nwhitehorn@FreeBSD.org) Message-Id: <201501011807.t01I7vB5066912@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: nwhitehorn set sender to nwhitehorn@FreeBSD.org using -f From: Nathan Whitehorn Date: Thu, 1 Jan 2015 18:07:57 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r276506 - user/nwhitehorn/kboot/powerpc/kboot X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 01 Jan 2015 18:07:59 -0000 Author: nwhitehorn Date: Thu Jan 1 18:07:56 2015 New Revision: 276506 URL: https://svnweb.freebsd.org/changeset/base/276506 Log: Create FDT from /proc/device-tree on Linux host. This is enough to get into KDB. Added: user/nwhitehorn/kboot/powerpc/kboot/kbootfdt.c (contents, props changed) Modified: user/nwhitehorn/kboot/powerpc/kboot/Makefile user/nwhitehorn/kboot/powerpc/kboot/host_syscall.S user/nwhitehorn/kboot/powerpc/kboot/host_syscall.h user/nwhitehorn/kboot/powerpc/kboot/metadata.c user/nwhitehorn/kboot/powerpc/kboot/ppc64_elf_freebsd.c Modified: user/nwhitehorn/kboot/powerpc/kboot/Makefile ============================================================================== --- user/nwhitehorn/kboot/powerpc/kboot/Makefile Thu Jan 1 16:56:15 2015 (r276505) +++ user/nwhitehorn/kboot/powerpc/kboot/Makefile Thu Jan 1 18:07:56 2015 (r276506) @@ -10,7 +10,7 @@ INSTALLFLAGS= -b # Architecture-specific loader code SRCS= conf.c metadata.c vers.c main.c ppc64_elf_freebsd.c -SRCS+= host_syscall.S hostcons.c hostdisk.c kerneltramp.S +SRCS+= host_syscall.S hostcons.c hostdisk.c kerneltramp.S kbootfdt.c SRCS+= ucmpdi2.c LOADER_DISK_SUPPORT?= yes @@ -21,7 +21,7 @@ LOADER_NET_SUPPORT?= yes LOADER_NFS_SUPPORT?= yes LOADER_TFTP_SUPPORT?= no LOADER_GZIP_SUPPORT?= yes -LOADER_FDT_SUPPORT?= no +LOADER_FDT_SUPPORT?= yes LOADER_BZIP2_SUPPORT?= no .if ${LOADER_DISK_SUPPORT} == "yes" @@ -54,6 +54,7 @@ CFLAGS+= -DLOADER_TFTP_SUPPORT .if ${LOADER_FDT_SUPPORT} == "yes" CFLAGS+= -I${.CURDIR}/../../fdt CFLAGS+= -I${.OBJDIR}/../../fdt +CFLAGS+= -I${.CURDIR}/../../../contrib/libfdt CFLAGS+= -DLOADER_FDT_SUPPORT LIBFDT= ${.OBJDIR}/../../fdt/libfdt.a .endif Modified: user/nwhitehorn/kboot/powerpc/kboot/host_syscall.S ============================================================================== --- user/nwhitehorn/kboot/powerpc/kboot/host_syscall.S Thu Jan 1 16:56:15 2015 (r276505) +++ user/nwhitehorn/kboot/powerpc/kboot/host_syscall.S Thu Jan 1 18:07:56 2015 (r276506) @@ -3,6 +3,10 @@ ENTRY(host_read) li %r0, 3 # SYS_read sc + bso 1f + blr +1: + li %r3, -1 blr ENTRY(host_write) @@ -60,3 +64,8 @@ ENTRY(host_reboot) sc blr +ENTRY(host_getdents) + li %r0,141 # SYS_getdents + sc + blr + Modified: user/nwhitehorn/kboot/powerpc/kboot/host_syscall.h ============================================================================== --- user/nwhitehorn/kboot/powerpc/kboot/host_syscall.h Thu Jan 1 16:56:15 2015 (r276505) +++ user/nwhitehorn/kboot/powerpc/kboot/host_syscall.h Thu Jan 1 18:07:56 2015 (r276506) @@ -46,5 +46,6 @@ int host_select(int nfds, long *readfds, struct host_timeval *timeout); int kexec_load(vm_offset_t start); int host_reboot(int, int, int, void *); +int host_getdents(int fd, void *dirp, int count); #endif Added: user/nwhitehorn/kboot/powerpc/kboot/kbootfdt.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ user/nwhitehorn/kboot/powerpc/kboot/kbootfdt.c Thu Jan 1 18:07:56 2015 (r276506) @@ -0,0 +1,140 @@ +/*- + * 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 +print_fdt(void *fdtp) +{ + int offset, depth, i; + const char *compat; + + offset = fdt_path_offset(fdtp, "/"); + + for (depth = 0, offset = fdt_next_node(fdtp, offset, &depth); + offset >= 0; offset = fdt_next_node(fdtp, offset, &depth)) { + for (i = 1; i < depth; i++) printf("\t"); + printf("%d: %s",offset, fdt_get_name(fdtp, offset, NULL)); + compat = fdt_getprop(fdtp, offset, "compatible", NULL); + if (compat != NULL) + printf(" (%s)", compat); + printf("\n"); + } +} + +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 = open(path, O_RDONLY); + 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 { + pfd = open(subpath, O_RDONLY); + propbuf = malloc(1024); + proplen = read(pfd, propbuf, 1024); + if (proplen < 0) + proplen = 0; + error = fdt_setprop(buffer, fdt_offset, dent->d_name, + propbuf, proplen); + free(propbuf); + close(pfd); + if (error) + printf("Error %d adding property %s to " + "node %d\n", error, dent->d_name, + fdt_offset); + } + } + } + + close(fd); +} + +int +fdt_platform_load_dtb(void) +{ + void *buffer; + size_t buflen = 409600; + char path[255] = "/proc/device-tree"; + + buffer = malloc(buflen); + fdt_create_empty_tree(buffer, buflen); + add_node_to_fdt(buffer, path, fdt_path_offset(buffer, "/")); + fdt_pack(buffer); +printf("Device tree is %d total bytes\n", fdt_totalsize(buffer)); + + fdt_load_dtb_addr(buffer); + + return (0); +} + +void +fdt_platform_fixups(void) +{ + +} + Modified: user/nwhitehorn/kboot/powerpc/kboot/metadata.c ============================================================================== --- user/nwhitehorn/kboot/powerpc/kboot/metadata.c Thu Jan 1 16:56:15 2015 (r276505) +++ user/nwhitehorn/kboot/powerpc/kboot/metadata.c Thu Jan 1 18:07:56 2015 (r276506) @@ -242,7 +242,7 @@ md_copymodules(vm_offset_t addr, int ker * - Module metadata are formatted and placed in kernel space. */ int -md_load_dual(char *args, vm_offset_t *modulep, int kern64) +md_load_dual(char *args, vm_offset_t *modulep, vm_offset_t *dtb, int kern64) { struct preloaded_file *kfp; struct preloaded_file *xp; @@ -250,6 +250,7 @@ md_load_dual(char *args, vm_offset_t *mo vm_offset_t kernend; vm_offset_t addr; vm_offset_t envp; + vm_offset_t fdtp; vm_offset_t size; uint64_t scratch64; char *rootdevname; @@ -285,6 +286,11 @@ md_load_dual(char *args, vm_offset_t *mo /* pad to a page boundary */ addr = roundup(addr, PAGE_SIZE); + /* Copy out FDT */ + size = fdt_copy(addr); + *dtb = fdtp = addr; + addr = roundup(addr + size, PAGE_SIZE); + kernend = 0; kfp = file_findfile(NULL, kern64 ? "elf64 kernel" : "elf32 kernel"); if (kfp == NULL) @@ -295,10 +301,13 @@ md_load_dual(char *args, vm_offset_t *mo if (kern64) { scratch64 = envp; file_addmetadata(kfp, MODINFOMD_ENVP, sizeof scratch64, &scratch64); + scratch64 = fdtp; + file_addmetadata(kfp, MODINFOMD_DTBP, 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_DTBP, sizeof fdtp, &fdtp); file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend); } @@ -320,14 +329,14 @@ md_load_dual(char *args, vm_offset_t *mo } int -md_load(char *args, vm_offset_t *modulep) +md_load(char *args, vm_offset_t *modulep, vm_offset_t *dtb) { - return (md_load_dual(args, modulep, 0)); + return (md_load_dual(args, modulep, dtb, 0)); } int -md_load64(char *args, vm_offset_t *modulep) +md_load64(char *args, vm_offset_t *modulep, vm_offset_t *dtb) { - return (md_load_dual(args, modulep, 1)); + return (md_load_dual(args, modulep, dtb, 1)); } Modified: user/nwhitehorn/kboot/powerpc/kboot/ppc64_elf_freebsd.c ============================================================================== --- user/nwhitehorn/kboot/powerpc/kboot/ppc64_elf_freebsd.c Thu Jan 1 16:56:15 2015 (r276505) +++ user/nwhitehorn/kboot/powerpc/kboot/ppc64_elf_freebsd.c Thu Jan 1 18:07:56 2015 (r276506) @@ -62,7 +62,7 @@ int ppc64_elf_exec(struct preloaded_file *fp) { struct file_metadata *fmp; - vm_offset_t mdp; + vm_offset_t mdp, dtb; Elf_Ehdr *e; int error; uint32_t *trampoline; @@ -77,13 +77,13 @@ ppc64_elf_exec(struct preloaded_file *fp trampoline = malloc(szkerneltramp); memcpy(trampoline, &kerneltramp, szkerneltramp); trampoline[2] = e->e_entry; - trampoline[3] = 0; /* FDT */ trampoline[4] = 0; /* Phys. mem offset */ trampoline[5] = 0; /* OF entry point */ - if ((error = md_load64(fp->f_args, &mdp)) != 0) + if ((error = md_load64(fp->f_args, &mdp, &dtb)) != 0) return (error); + trampoline[3] = dtb; trampoline[6] = mdp; trampoline[7] = sizeof(mdp); printf("Kernel entry at %#jx ...\n", e->e_entry);