Commit f652e6af11c670da4bbd738a1bca8b4b31ed97b4

Authored by aurel32
1 parent b7da58fd

Implement device tree support needed for Bamboo emulation

To implement the -kernel, -initrd, and -append options, 4xx board emulation
must load the guest kernel as if firmware had loaded it. Where u-boot would be
the firmware, we must load the flat device tree into memory and set key fields
such as /chosen/bootargs.

This patch introduces a dependency on libfdt for flat device tree support.

Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6064 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile.target
... ... @@ -655,6 +655,10 @@ OBJS+= heathrow_pic.o grackle_pci.o ppc_oldworld.o
655 655 OBJS+= unin_pci.o ppc_chrp.o
656 656 # PowerPC 4xx boards
657 657 OBJS+= pflash_cfi02.o ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o
  658 +ifdef FDT_LIBS
  659 +OBJS+= device_tree.o
  660 +LIBS+= $(FDT_LIBS)
  661 +endif
658 662 # virtio support
659 663 OBJS+= virtio.o virtio-blk.o virtio-balloon.o
660 664 endif
... ...
configure
... ... @@ -119,6 +119,7 @@ kvm=&quot;yes&quot;
119 119 kerneldir=""
120 120 aix="no"
121 121 blobs="yes"
  122 +fdt="yes"
122 123  
123 124 # OS specific
124 125 targetos=`uname -s`
... ... @@ -966,6 +967,18 @@ if $cc $ARCH_CFLAGS -o $TMPE $TMPC &gt; /dev/null 2&gt; /dev/null ; then
966 967 iovec=yes
967 968 fi
968 969  
  970 +##########################################
  971 +# fdt probe
  972 +if test "$fdt" = "yes" ; then
  973 + fdt=no
  974 + cat > $TMPC << EOF
  975 +int main(void) { return 0; }
  976 +EOF
  977 + if $cc $ARCH_CFLAGS -o $TMPE ${OS_CFLAGS} $TMPC -lfdt 2> /dev/null ; then
  978 + fdt=yes
  979 + fi
  980 +fi
  981 +
969 982 # Check if tools are available to build documentation.
970 983 if [ -x "`which texi2html 2>/dev/null`" ] && \
971 984 [ -x "`which pod2man 2>/dev/null`" ]; then
... ... @@ -1061,6 +1074,7 @@ echo &quot;vde support $vde&quot;
1061 1074 echo "AIO support $aio"
1062 1075 echo "Install blobs $blobs"
1063 1076 echo "KVM support $kvm"
  1077 +echo "fdt support $fdt"
1064 1078  
1065 1079 if test $sdl_too_old = "yes"; then
1066 1080 echo "-> Your SDL version is too old - please upgrade to have SDL support"
... ... @@ -1350,6 +1364,10 @@ fi
1350 1364 if test "$iovec" = "yes" ; then
1351 1365 echo "#define HAVE_IOVEC 1" >> $config_h
1352 1366 fi
  1367 +if test "$fdt" = "yes" ; then
  1368 + echo "#define HAVE_FDT 1" >> $config_h
  1369 + echo "FDT_LIBS=-lfdt" >> $config_mak
  1370 +fi
1353 1371  
1354 1372 # XXX: suppress that
1355 1373 if [ "$bsd" = "yes" ] ; then
... ...
device_tree.c 0 โ†’ 100644
  1 +/*
  2 + * Functions to help device tree manipulation using libfdt.
  3 + * It also provides functions to read entries from device tree proc
  4 + * interface.
  5 + *
  6 + * Copyright 2008 IBM Corporation.
  7 + * Authors: Jerone Young <jyoung5@us.ibm.com>
  8 + * Hollis Blanchard <hollisb@us.ibm.com>
  9 + *
  10 + * This work is licensed under the GNU GPL license version 2 or later.
  11 + *
  12 + */
  13 +
  14 +#include <stdio.h>
  15 +#include <sys/types.h>
  16 +#include <sys/stat.h>
  17 +#include <fcntl.h>
  18 +#include <unistd.h>
  19 +#include <stdlib.h>
  20 +
  21 +#include "config.h"
  22 +#include "qemu-common.h"
  23 +#include "sysemu.h"
  24 +#include "device_tree.h"
  25 +
  26 +#include <libfdt.h>
  27 +
  28 +void *load_device_tree(const char *filename_path, void *load_addr)
  29 +{
  30 + int dt_file_size;
  31 + int dt_file_load_size;
  32 + int new_dt_size;
  33 + int ret;
  34 + void *dt_file = NULL;
  35 + void *fdt;
  36 +
  37 + dt_file_size = get_image_size(filename_path);
  38 + if (dt_file_size < 0) {
  39 + printf("Unable to get size of device tree file '%s'\n",
  40 + filename_path);
  41 + goto fail;
  42 + }
  43 +
  44 + /* First allocate space in qemu for device tree */
  45 + dt_file = qemu_mallocz(dt_file_size);
  46 + if (dt_file == NULL) {
  47 + printf("Unable to allocate memory in qemu for device tree\n");
  48 + goto fail;
  49 + }
  50 +
  51 + dt_file_load_size = load_image(filename_path, dt_file);
  52 +
  53 + /* Second we place new copy of 2x size in guest memory
  54 + * This give us enough room for manipulation.
  55 + */
  56 + new_dt_size = dt_file_size * 2;
  57 +
  58 + fdt = load_addr;
  59 + ret = fdt_open_into(dt_file, fdt, new_dt_size);
  60 + if (ret) {
  61 + printf("Unable to copy device tree in memory\n");
  62 + goto fail;
  63 + }
  64 +
  65 + /* Check sanity of device tree */
  66 + if (fdt_check_header(fdt)) {
  67 + printf ("Device tree file loaded into memory is invalid: %s\n",
  68 + filename_path);
  69 + goto fail;
  70 + }
  71 + /* free qemu memory with old device tree */
  72 + qemu_free(dt_file);
  73 + return fdt;
  74 +
  75 +fail:
  76 + qemu_free(dt_file);
  77 + return NULL;
  78 +}
  79 +
  80 +int qemu_devtree_setprop(void *fdt, const char *node_path,
  81 + const char *property, uint32_t *val_array, int size)
  82 +{
  83 + int offset;
  84 +
  85 + offset = fdt_path_offset(fdt, node_path);
  86 + if (offset < 0)
  87 + return offset;
  88 +
  89 + return fdt_setprop(fdt, offset, property, val_array, size);
  90 +}
  91 +
  92 +int qemu_devtree_setprop_cell(void *fdt, const char *node_path,
  93 + const char *property, uint32_t val)
  94 +{
  95 + int offset;
  96 +
  97 + offset = fdt_path_offset(fdt, node_path);
  98 + if (offset < 0)
  99 + return offset;
  100 +
  101 + return fdt_setprop_cell(fdt, offset, property, val);
  102 +}
  103 +
  104 +int qemu_devtree_setprop_string(void *fdt, const char *node_path,
  105 + const char *property, const char *string)
  106 +{
  107 + int offset;
  108 +
  109 + offset = fdt_path_offset(fdt, node_path);
  110 + if (offset < 0)
  111 + return offset;
  112 +
  113 + return fdt_setprop_string(fdt, offset, property, string);
  114 +}
... ...
device_tree.h 0 โ†’ 100644
  1 +/*
  2 + * Header with function prototypes to help device tree manipulation using
  3 + * libfdt. It also provides functions to read entries from device tree proc
  4 + * interface.
  5 + *
  6 + * Copyright 2008 IBM Corporation.
  7 + * Authors: Jerone Young <jyoung5@us.ibm.com>
  8 + * Hollis Blanchard <hollisb@us.ibm.com>
  9 + *
  10 + * This work is licensed under the GNU GPL license version 2 or later.
  11 + *
  12 + */
  13 +
  14 +#ifndef __DEVICE_TREE_H__
  15 +#define __DEVICE_TREE_H__
  16 +
  17 +void *load_device_tree(const char *filename_path, void *load_addr);
  18 +
  19 +int qemu_devtree_setprop(void *fdt, const char *node_path,
  20 + const char *property, uint32_t *val_array, int size);
  21 +int qemu_devtree_setprop_cell(void *fdt, const char *node_path,
  22 + const char *property, uint32_t val);
  23 +int qemu_devtree_setprop_string(void *fdt, const char *node_path,
  24 + const char *property, const char *string);
  25 +
  26 +#endif /* __DEVICE_TREE_H__ */
... ...
libfdt_env.h 0 โ†’ 100644
  1 +/*
  2 + * This program is free software; you can redistribute it and/or modify
  3 + * it under the terms of the GNU General Public License, version 2, as
  4 + * published by the Free Software Foundation.
  5 + *
  6 + * This program is distributed in the hope that it will be useful,
  7 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  8 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9 + * GNU General Public License for more details.
  10 + *
  11 + * You should have received a copy of the GNU General Public License
  12 + * along with this program; if not, write to the Free Software
  13 + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  14 + *
  15 + * Copyright IBM Corp. 2008
  16 + * Authors: Hollis Blanchard <hollisb@us.ibm.com>
  17 + *
  18 + */
  19 +
  20 +#ifndef _LIBFDT_ENV_H
  21 +#define _LIBFDT_ENV_H
  22 +
  23 +#include <stddef.h>
  24 +#include <stdint.h>
  25 +#include <string.h>
  26 +#include <endian.h>
  27 +#include <byteswap.h>
  28 +
  29 +#if __BYTE_ORDER == __BIG_ENDIAN
  30 +#define fdt32_to_cpu(x) (x)
  31 +#define cpu_to_fdt32(x) (x)
  32 +#define fdt64_to_cpu(x) (x)
  33 +#define cpu_to_fdt64(x) (x)
  34 +#else
  35 +#define fdt32_to_cpu(x) (bswap_32((x)))
  36 +#define cpu_to_fdt32(x) (bswap_32((x)))
  37 +#define fdt64_to_cpu(x) (bswap_64((x)))
  38 +#define cpu_to_fdt64(x) (bswap_64((x)))
  39 +#endif
  40 +
  41 +#endif /* _LIBFDT_ENV_H */
... ...