[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH 05/10] xen: arm: move boot time fdt parsing into separate file.



On Mon, 16 Jun 2014, Ian Campbell wrote:
> Move the early code for walking the flattended device tree out of
> device_tree.c. The intention is that eventually only only the proper (i.e.
                                                    ^  ^ 
> unflattened) device tree support will live in device_tree.c.
> 
> The new home is bootfdt.c to try and better reflect the purpose of the code.
> Although in theory this early code could be generic in reality it is pretty 
> ARM
> specific, so place it under xen/arch/arm until a second user wants it.
> 
> As part of the move rename device_tree_early_init to boot_fdt_info. Drop
> device_tree_dump, it is unused.
> 
> Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>

Acked-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>


>  xen/arch/arm/Makefile         |    1 +
>  xen/arch/arm/bootfdt.c        |  343 +++++++++++++++++++++++++++++++++++++++
>  xen/arch/arm/setup.c          |    2 +-
>  xen/common/device_tree.c      |  356 
> -----------------------------------------
>  xen/include/asm-arm/setup.h   |    2 +
>  xen/include/xen/device_tree.h |    3 -
>  6 files changed, 347 insertions(+), 360 deletions(-)
>  create mode 100644 xen/arch/arm/bootfdt.c
> 
> diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile
> index 63e0460..58a6714 100644
> --- a/xen/arch/arm/Makefile
> +++ b/xen/arch/arm/Makefile
> @@ -21,6 +21,7 @@ obj-y += guestcopy.o
>  obj-y += physdev.o
>  obj-y += platform.o
>  obj-y += setup.o
> +obj-y += bootfdt.o
>  obj-y += time.o
>  obj-y += smpboot.o
>  obj-y += smp.o
> diff --git a/xen/arch/arm/bootfdt.c b/xen/arch/arm/bootfdt.c
> new file mode 100644
> index 0000000..11182cd
> --- /dev/null
> +++ b/xen/arch/arm/bootfdt.c
> @@ -0,0 +1,343 @@
> +/*
> + * Early Device Tree
> + *
> + * Copyright (C) 2012-2014 Citrix Systems, Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +#include <xen/config.h>
> +#include <xen/types.h>
> +#include <xen/lib.h>
> +#include <xen/kernel.h>
> +#include <xen/init.h>
> +#include <xen/device_tree.h>
> +#include <xen/libfdt/libfdt.h>
> +#include <asm/setup.h>
> +
> +static bool_t __init device_tree_node_matches(const void *fdt, int node,
> +                                              const char *match)
> +{
> +    const char *name;
> +    size_t match_len;
> +
> +    name = fdt_get_name(fdt, node, NULL);
> +    match_len = strlen(match);
> +
> +    /* Match both "match" and "match@..." patterns but not
> +       "match-foo". */
> +    return strncmp(name, match, match_len) == 0
> +        && (name[match_len] == '@' || name[match_len] == '\0');
> +}
> +
> +static bool_t __init device_tree_node_compatible(const void *fdt, int node,
> +                                                 const char *match)
> +{
> +    int len, l;
> +    int mlen;
> +    const void *prop;
> +
> +    mlen = strlen(match);
> +
> +    prop = fdt_getprop(fdt, node, "compatible", &len);
> +    if ( prop == NULL )
> +        return 0;
> +
> +    while ( len > 0 ) {
> +        if ( !dt_compat_cmp(prop, match) )
> +            return 1;
> +        l = strlen(prop) + 1;
> +        prop += l;
> +        len -= l;
> +    }
> +
> +    return 0;
> +}
> +
> +static void __init device_tree_get_reg(const __be32 **cell, u32 
> address_cells,
> +                                       u32 size_cells, u64 *start, u64 *size)
> +{
> +    *start = dt_next_cell(address_cells, cell);
> +    *size = dt_next_cell(size_cells, cell);
> +}
> +
> +static u32 __init device_tree_get_u32(const void *fdt, int node,
> +                                      const char *prop_name, u32 dflt)
> +{
> +    const struct fdt_property *prop;
> +
> +    prop = fdt_get_property(fdt, node, prop_name, NULL);
> +    if ( !prop || prop->len < sizeof(u32) )
> +        return dflt;
> +
> +    return fdt32_to_cpu(*(uint32_t*)prop->data);
> +}
> +
> +/**
> + * device_tree_for_each_node - iterate over all device tree nodes
> + * @fdt: flat device tree.
> + * @func: function to call for each node.
> + * @data: data to pass to @func.
> + *
> + * Any nodes nested at DEVICE_TREE_MAX_DEPTH or deeper are ignored.
> + *
> + * Returns 0 if all nodes were iterated over successfully.  If @func
> + * returns a value different from 0, that value is returned immediately.
> + */
> +static int __init device_tree_for_each_node(const void *fdt,
> +                                            device_tree_node_func func,
> +                                            void *data)
> +{
> +    int node;
> +    int depth;
> +    u32 address_cells[DEVICE_TREE_MAX_DEPTH];
> +    u32 size_cells[DEVICE_TREE_MAX_DEPTH];
> +    int ret;
> +
> +    for ( node = 0, depth = 0;
> +          node >=0 && depth >= 0;
> +          node = fdt_next_node(fdt, node, &depth) )
> +    {
> +        const char *name = fdt_get_name(fdt, node, NULL);
> +
> +        if ( depth >= DEVICE_TREE_MAX_DEPTH )
> +        {
> +            printk("Warning: device tree node `%s' is nested too deep\n",
> +                   name);
> +            continue;
> +        }
> +
> +        address_cells[depth] = device_tree_get_u32(fdt, node, 
> "#address-cells",
> +                                depth > 0 ? address_cells[depth-1] : 0);
> +        size_cells[depth] = device_tree_get_u32(fdt, node, "#size-cells",
> +                                depth > 0 ? size_cells[depth-1] : 0);
> +
> +
> +        ret = func(fdt, node, name, depth,
> +                   address_cells[depth-1], size_cells[depth-1], data);
> +        if ( ret != 0 )
> +            return ret;
> +    }
> +    return 0;
> +}
> +
> +static void __init process_memory_node(const void *fdt, int node,
> +                                       const char *name,
> +                                       u32 address_cells, u32 size_cells)
> +{
> +    const struct fdt_property *prop;
> +    int i;
> +    int banks;
> +    const __be32 *cell;
> +    paddr_t start, size;
> +    u32 reg_cells = address_cells + size_cells;
> +
> +    if ( address_cells < 1 || size_cells < 1 )
> +    {
> +        printk("fdt: node `%s': invalid #address-cells or #size-cells",
> +               name);
> +        return;
> +    }
> +
> +    prop = fdt_get_property(fdt, node, "reg", NULL);
> +    if ( !prop )
> +    {
> +        printk("fdt: node `%s': missing `reg' property\n", name);
> +        return;
> +    }
> +
> +    cell = (const __be32 *)prop->data;
> +    banks = fdt32_to_cpu(prop->len) / (reg_cells * sizeof (u32));
> +
> +    for ( i = 0; i < banks && bootinfo.mem.nr_banks < NR_MEM_BANKS; i++ )
> +    {
> +        device_tree_get_reg(&cell, address_cells, size_cells, &start, &size);
> +        bootinfo.mem.bank[bootinfo.mem.nr_banks].start = start;
> +        bootinfo.mem.bank[bootinfo.mem.nr_banks].size = size;
> +        bootinfo.mem.nr_banks++;
> +    }
> +}
> +
> +static void __init process_multiboot_node(const void *fdt, int node,
> +                                          const char *name,
> +                                          u32 address_cells, u32 size_cells)
> +{
> +    const struct fdt_property *prop;
> +    const __be32 *cell;
> +    int nr;
> +    struct bootmodule *mod;
> +    int len;
> +
> +    if ( fdt_node_check_compatible(fdt, node, "xen,linux-zimage") == 0 ||
> +         fdt_node_check_compatible(fdt, node, "multiboot,kernel") == 0 )
> +        nr = MOD_KERNEL;
> +    else if ( fdt_node_check_compatible(fdt, node, "xen,linux-initrd") == 0 
> ||
> +              fdt_node_check_compatible(fdt, node, "multiboot,ramdisk") == 0 
> )
> +        nr = MOD_INITRD;
> +    else if ( fdt_node_check_compatible(fdt, node, "xen,xsm-policy") == 0 )
> +        nr = MOD_XSM;
> +    else
> +        panic("%s not a known xen multiboot type\n", name);
> +
> +    mod = &bootinfo.modules.module[nr];
> +
> +    prop = fdt_get_property(fdt, node, "reg", &len);
> +    if ( !prop )
> +        panic("node %s missing `reg' property\n", name);
> +
> +    if ( len < dt_cells_to_size(address_cells + size_cells) )
> +        panic("fdt: node `%s': `reg` property length is too short\n",
> +                    name);
> +
> +    cell = (const __be32 *)prop->data;
> +    device_tree_get_reg(&cell, address_cells, size_cells,
> +                        &mod->start, &mod->size);
> +
> +    prop = fdt_get_property(fdt, node, "bootargs", &len);
> +    if ( prop )
> +    {
> +        if ( len > sizeof(mod->cmdline) )
> +            panic("module %d command line too long\n", nr);
> +
> +        safe_strcpy(mod->cmdline, prop->data);
> +    }
> +    else
> +        mod->cmdline[0] = 0;
> +
> +    if ( nr > bootinfo.modules.nr_mods )
> +        bootinfo.modules.nr_mods = nr;
> +}
> +
> +static void __init process_chosen_node(const void *fdt, int node,
> +                                       const char *name,
> +                                       u32 address_cells, u32 size_cells)
> +{
> +    const struct fdt_property *prop;
> +    struct bootmodule *mod = &bootinfo.modules.module[MOD_INITRD];
> +    paddr_t start, end;
> +    int len;
> +
> +    printk("Checking for initrd in /chosen\n");
> +
> +    prop = fdt_get_property(fdt, node, "linux,initrd-start", &len);
> +    if ( !prop )
> +        /* No initrd present. */
> +        return;
> +    if ( len != sizeof(u32) && len != sizeof(u64) )
> +    {
> +        printk("linux,initrd-start property has invalid length %d\n", len);
> +        return;
> +    }
> +    start = dt_read_number((void *)&prop->data, dt_size_to_cells(len));
> +
> +    prop = fdt_get_property(fdt, node, "linux,initrd-end", &len);
> +    if ( !prop )
> +    {
> +        printk("linux,initrd-end not present but -start was\n");
> +        return;
> +    }
> +    if ( len != sizeof(u32) && len != sizeof(u64) )
> +    {
> +        printk("linux,initrd-end property has invalid length %d\n", len);
> +        return;
> +    }
> +    end = dt_read_number((void *)&prop->data, dt_size_to_cells(len));
> +
> +    if ( start >= end )
> +    {
> +        printk("linux,initrd limits invalid: %"PRIpaddr" >= %"PRIpaddr"\n",
> +                  start, end);
> +        return;
> +    }
> +
> +    printk("Initrd %"PRIpaddr"-%"PRIpaddr"\n", start, end);
> +
> +    mod->start = start;
> +    mod->size = end - start;
> +
> +    bootinfo.modules.nr_mods = max(MOD_INITRD, bootinfo.modules.nr_mods);
> +}
> +
> +static int __init early_scan_node(const void *fdt,
> +                                  int node, const char *name, int depth,
> +                                  u32 address_cells, u32 size_cells,
> +                                  void *data)
> +{
> +    if ( device_tree_node_matches(fdt, node, "memory") )
> +        process_memory_node(fdt, node, name, address_cells, size_cells);
> +    else if ( device_tree_node_compatible(fdt, node, "xen,multiboot-module" 
> ) ||
> +              device_tree_node_compatible(fdt, node, "multiboot,module" ))
> +        process_multiboot_node(fdt, node, name, address_cells, size_cells);
> +    else if ( depth == 1 && device_tree_node_matches(fdt, node, "chosen") )
> +        process_chosen_node(fdt, node, name, address_cells, size_cells);
> +
> +    return 0;
> +}
> +
> +static void __init early_print_info(void)
> +{
> +    struct meminfo *mi = &bootinfo.mem;
> +    struct bootmodules *mods = &bootinfo.modules;
> +    int i, nr_rsvd;
> +
> +    for ( i = 0; i < mi->nr_banks; i++ )
> +        printk("RAM: %"PRIpaddr" - %"PRIpaddr"\n",
> +                     mi->bank[i].start,
> +                     mi->bank[i].start + mi->bank[i].size - 1);
> +    printk("\n");
> +    for ( i = 1 ; i < mods->nr_mods + 1; i++ )
> +        printk("MODULE[%d]: %"PRIpaddr" - %"PRIpaddr" %s\n",
> +                     i,
> +                     mods->module[i].start,
> +                     mods->module[i].start + mods->module[i].size,
> +                     mods->module[i].cmdline);
> +    nr_rsvd = fdt_num_mem_rsv(device_tree_flattened);
> +    for ( i = 0; i < nr_rsvd; i++ )
> +    {
> +        paddr_t s, e;
> +        if ( fdt_get_mem_rsv(device_tree_flattened, i, &s, &e) < 0 )
> +            continue;
> +        /* fdt_get_mem_rsv returns length */
> +        e += s;
> +        printk(" RESVD[%d]: %"PRIpaddr" - %"PRIpaddr"\n",
> +                     i, s, e);
> +    }
> +    printk("\n");
> +}
> +
> +/**
> + * boot_fdt_info - initialize bootinfo from a DTB
> + * @fdt: flattened device tree binary
> + *
> + * Returns the size of the DTB.
> + */
> +size_t __init boot_fdt_info(const void *fdt, paddr_t paddr)
> +{
> +    struct bootmodule *mod;
> +    int ret;
> +
> +    ret = fdt_check_header(fdt);
> +    if ( ret < 0 )
> +        panic("No valid device tree\n");
> +
> +    mod = &bootinfo.modules.module[MOD_FDT];
> +    mod->start = paddr;
> +    mod->size = fdt_totalsize(fdt);
> +
> +    bootinfo.modules.nr_mods = max(MOD_FDT, bootinfo.modules.nr_mods);
> +
> +    device_tree_for_each_node((void *)fdt, early_scan_node, NULL);
> +    early_print_info();
> +
> +    return fdt_totalsize(fdt);
> +}
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
> index 63f6b8e..4a84a32 100644
> --- a/xen/arch/arm/setup.c
> +++ b/xen/arch/arm/setup.c
> @@ -678,7 +678,7 @@ void __init start_xen(unsigned long boot_phys_offset,
>      /* This is mapped by head.S */
>      device_tree_flattened = (void *)BOOT_FDT_VIRT_START
>          + (fdt_paddr & ((1 << SECOND_SHIFT) - 1));
> -    fdt_size = device_tree_early_init(device_tree_flattened, fdt_paddr);
> +    fdt_size = boot_fdt_info(device_tree_flattened, fdt_paddr);
>  
>      cmdline = device_tree_bootargs(device_tree_flattened);
>      printk("Command line: %s\n", cmdline);
> diff --git a/xen/common/device_tree.c b/xen/common/device_tree.c
> index a1896d3..89de269 100644
> --- a/xen/common/device_tree.c
> +++ b/xen/common/device_tree.c
> @@ -22,7 +22,6 @@
>  #include <xen/string.h>
>  #include <xen/cpumask.h>
>  #include <xen/ctype.h>
> -#include <xen/lib.h>
>  #include <asm/setup.h>
>  
>  const void *device_tree_flattened;
> @@ -89,52 +88,6 @@ struct dt_bus
>      unsigned int (*get_flags)(const __be32 *addr);
>  };
>  
> -static bool_t __init device_tree_node_matches(const void *fdt, int node,
> -                                              const char *match)
> -{
> -    const char *name;
> -    size_t match_len;
> -
> -    name = fdt_get_name(fdt, node, NULL);
> -    match_len = strlen(match);
> -
> -    /* Match both "match" and "match@..." patterns but not
> -       "match-foo". */
> -    return strncmp(name, match, match_len) == 0
> -        && (name[match_len] == '@' || name[match_len] == '\0');
> -}
> -
> -static bool_t __init device_tree_node_compatible(const void *fdt, int node,
> -                                                 const char *match)
> -{
> -    int len, l;
> -    int mlen;
> -    const void *prop;
> -
> -    mlen = strlen(match);
> -
> -    prop = fdt_getprop(fdt, node, "compatible", &len);
> -    if ( prop == NULL )
> -        return 0;
> -
> -    while ( len > 0 ) {
> -        if ( !dt_compat_cmp(prop, match) )
> -            return 1;
> -        l = strlen(prop) + 1;
> -        prop += l;
> -        len -= l;
> -    }
> -
> -    return 0;
> -}
> -
> -static void __init device_tree_get_reg(const __be32 **cell, u32 
> address_cells,
> -                                       u32 size_cells, u64 *start, u64 *size)
> -{
> -    *start = dt_next_cell(address_cells, cell);
> -    *size = dt_next_cell(size_cells, cell);
> -}
> -
>  void dt_get_range(const __be32 **cell, const struct dt_device_node *np,
>                    u64 *address, u64 *size)
>  {
> @@ -162,66 +115,6 @@ void dt_set_range(__be32 **cellp, const struct 
> dt_device_node *np,
>      dt_set_cell(cellp, dt_n_size_cells(np), size);
>  }
>  
> -static u32 __init device_tree_get_u32(const void *fdt, int node,
> -                                      const char *prop_name, u32 dflt)
> -{
> -    const struct fdt_property *prop;
> -
> -    prop = fdt_get_property(fdt, node, prop_name, NULL);
> -    if ( !prop || prop->len < sizeof(u32) )
> -        return dflt;
> -
> -    return fdt32_to_cpu(*(uint32_t*)prop->data);
> -}
> -
> -/**
> - * device_tree_for_each_node - iterate over all device tree nodes
> - * @fdt: flat device tree.
> - * @func: function to call for each node.
> - * @data: data to pass to @func.
> - *
> - * Any nodes nested at DEVICE_TREE_MAX_DEPTH or deeper are ignored.
> - *
> - * Returns 0 if all nodes were iterated over successfully.  If @func
> - * returns a value different from 0, that value is returned immediately.
> - */
> -static int __init device_tree_for_each_node(const void *fdt,
> -                                            device_tree_node_func func,
> -                                            void *data)
> -{
> -    int node;
> -    int depth;
> -    u32 address_cells[DEVICE_TREE_MAX_DEPTH];
> -    u32 size_cells[DEVICE_TREE_MAX_DEPTH];
> -    int ret;
> -
> -    for ( node = 0, depth = 0;
> -          node >=0 && depth >= 0;
> -          node = fdt_next_node(fdt, node, &depth) )
> -    {
> -        const char *name = fdt_get_name(fdt, node, NULL);
> -
> -        if ( depth >= DEVICE_TREE_MAX_DEPTH )
> -        {
> -            printk("Warning: device tree node `%s' is nested too deep\n",
> -                   name);
> -            continue;
> -        }
> -
> -        address_cells[depth] = device_tree_get_u32(fdt, node, 
> "#address-cells",
> -                                depth > 0 ? address_cells[depth-1] : 0);
> -        size_cells[depth] = device_tree_get_u32(fdt, node, "#size-cells",
> -                                depth > 0 ? size_cells[depth-1] : 0);
> -
> -
> -        ret = func(fdt, node, name, depth,
> -                   address_cells[depth-1], size_cells[depth-1], data);
> -        if ( ret != 0 )
> -            return ret;
> -    }
> -    return 0;
> -}
> -
>  /**
>   * device_tree_bootargs - return the bootargs (the Xen command line)
>   * @fdt flat device tree.
> @@ -253,255 +146,6 @@ const char *device_tree_bootargs(const void *fdt)
>      return prop->data;
>  }
>  
> -static int dump_node(const void *fdt, int node, const char *name, int depth,
> -                     u32 address_cells, u32 size_cells, void *data)
> -{
> -    char prefix[2*DEVICE_TREE_MAX_DEPTH + 1] = "";
> -    int i;
> -    int prop;
> -
> -    for ( i = 0; i < depth; i++ )
> -        safe_strcat(prefix, "  ");
> -
> -    if ( name[0] == '\0' )
> -        name = "/";
> -    printk("%s%s:\n", prefix, name);
> -
> -    for ( prop = fdt_first_property_offset(fdt, node);
> -          prop >= 0;
> -          prop = fdt_next_property_offset(fdt, prop) )
> -    {
> -        const struct fdt_property *p;
> -
> -        p = fdt_get_property_by_offset(fdt, prop, NULL);
> -
> -        printk("%s  %s\n", prefix, fdt_string(fdt, 
> fdt32_to_cpu(p->nameoff)));
> -    }
> -
> -    return 0;
> -}
> -
> -/**
> - * device_tree_dump - print a text representation of a device tree
> - * @fdt: flat device tree to print
> - */
> -void __init device_tree_dump(const void *fdt)
> -{
> -    device_tree_for_each_node(fdt, dump_node, NULL);
> -}
> -
> -
> -static void __init process_memory_node(const void *fdt, int node,
> -                                       const char *name,
> -                                       u32 address_cells, u32 size_cells)
> -{
> -    const struct fdt_property *prop;
> -    int i;
> -    int banks;
> -    const __be32 *cell;
> -    paddr_t start, size;
> -    u32 reg_cells = address_cells + size_cells;
> -
> -    if ( address_cells < 1 || size_cells < 1 )
> -    {
> -        printk("fdt: node `%s': invalid #address-cells or #size-cells",
> -               name);
> -        return;
> -    }
> -
> -    prop = fdt_get_property(fdt, node, "reg", NULL);
> -    if ( !prop )
> -    {
> -        printk("fdt: node `%s': missing `reg' property\n", name);
> -        return;
> -    }
> -
> -    cell = (const __be32 *)prop->data;
> -    banks = fdt32_to_cpu(prop->len) / (reg_cells * sizeof (u32));
> -
> -    for ( i = 0; i < banks && bootinfo.mem.nr_banks < NR_MEM_BANKS; i++ )
> -    {
> -        device_tree_get_reg(&cell, address_cells, size_cells, &start, &size);
> -        bootinfo.mem.bank[bootinfo.mem.nr_banks].start = start;
> -        bootinfo.mem.bank[bootinfo.mem.nr_banks].size = size;
> -        bootinfo.mem.nr_banks++;
> -    }
> -}
> -
> -static void __init process_multiboot_node(const void *fdt, int node,
> -                                          const char *name,
> -                                          u32 address_cells, u32 size_cells)
> -{
> -    const struct fdt_property *prop;
> -    const __be32 *cell;
> -    int nr;
> -    struct bootmodule *mod;
> -    int len;
> -
> -    if ( fdt_node_check_compatible(fdt, node, "xen,linux-zimage") == 0 ||
> -         fdt_node_check_compatible(fdt, node, "multiboot,kernel") == 0 )
> -        nr = MOD_KERNEL;
> -    else if ( fdt_node_check_compatible(fdt, node, "xen,linux-initrd") == 0 
> ||
> -              fdt_node_check_compatible(fdt, node, "multiboot,ramdisk") == 0 
> )
> -        nr = MOD_INITRD;
> -    else if ( fdt_node_check_compatible(fdt, node, "xen,xsm-policy") == 0 )
> -        nr = MOD_XSM;
> -    else
> -        panic("%s not a known xen multiboot type\n", name);
> -
> -    mod = &bootinfo.modules.module[nr];
> -
> -    prop = fdt_get_property(fdt, node, "reg", &len);
> -    if ( !prop )
> -        panic("node %s missing `reg' property\n", name);
> -
> -    if ( len < dt_cells_to_size(address_cells + size_cells) )
> -        panic("fdt: node `%s': `reg` property length is too short\n",
> -                    name);
> -
> -    cell = (const __be32 *)prop->data;
> -    device_tree_get_reg(&cell, address_cells, size_cells,
> -                        &mod->start, &mod->size);
> -
> -    prop = fdt_get_property(fdt, node, "bootargs", &len);
> -    if ( prop )
> -    {
> -        if ( len > sizeof(mod->cmdline) )
> -            panic("module %d command line too long\n", nr);
> -
> -        safe_strcpy(mod->cmdline, prop->data);
> -    }
> -    else
> -        mod->cmdline[0] = 0;
> -
> -    if ( nr > bootinfo.modules.nr_mods )
> -        bootinfo.modules.nr_mods = nr;
> -}
> -
> -static void __init process_chosen_node(const void *fdt, int node,
> -                                       const char *name,
> -                                       u32 address_cells, u32 size_cells)
> -{
> -    const struct fdt_property *prop;
> -    struct bootmodule *mod = &bootinfo.modules.module[MOD_INITRD];
> -    paddr_t start, end;
> -    int len;
> -
> -    printk("Checking for initrd in /chosen\n");
> -
> -    prop = fdt_get_property(fdt, node, "linux,initrd-start", &len);
> -    if ( !prop )
> -        /* No initrd present. */
> -        return;
> -    if ( len != sizeof(u32) && len != sizeof(u64) )
> -    {
> -        printk("linux,initrd-start property has invalid length %d\n", len);
> -        return;
> -    }
> -    start = dt_read_number((void *)&prop->data, dt_size_to_cells(len));
> -
> -    prop = fdt_get_property(fdt, node, "linux,initrd-end", &len);
> -    if ( !prop )
> -    {
> -        printk("linux,initrd-end not present but -start was\n");
> -        return;
> -    }
> -    if ( len != sizeof(u32) && len != sizeof(u64) )
> -    {
> -        printk("linux,initrd-end property has invalid length %d\n", len);
> -        return;
> -    }
> -    end = dt_read_number((void *)&prop->data, dt_size_to_cells(len));
> -
> -    if ( start >= end )
> -    {
> -        printk("linux,initrd limits invalid: %"PRIpaddr" >= %"PRIpaddr"\n",
> -                  start, end);
> -        return;
> -    }
> -
> -    printk("Initrd %"PRIpaddr"-%"PRIpaddr"\n", start, end);
> -
> -    mod->start = start;
> -    mod->size = end - start;
> -
> -    bootinfo.modules.nr_mods = max(MOD_INITRD, bootinfo.modules.nr_mods);
> -}
> -
> -static int __init early_scan_node(const void *fdt,
> -                                  int node, const char *name, int depth,
> -                                  u32 address_cells, u32 size_cells,
> -                                  void *data)
> -{
> -    if ( device_tree_node_matches(fdt, node, "memory") )
> -        process_memory_node(fdt, node, name, address_cells, size_cells);
> -    else if ( device_tree_node_compatible(fdt, node, "xen,multiboot-module" 
> ) ||
> -              device_tree_node_compatible(fdt, node, "multiboot,module" ))
> -        process_multiboot_node(fdt, node, name, address_cells, size_cells);
> -    else if ( depth == 1 && device_tree_node_matches(fdt, node, "chosen") )
> -        process_chosen_node(fdt, node, name, address_cells, size_cells);
> -
> -    return 0;
> -}
> -
> -static void __init early_print_info(void)
> -{
> -    struct meminfo *mi = &bootinfo.mem;
> -    struct bootmodules *mods = &bootinfo.modules;
> -    int i, nr_rsvd;
> -
> -    for ( i = 0; i < mi->nr_banks; i++ )
> -        printk("RAM: %"PRIpaddr" - %"PRIpaddr"\n",
> -                     mi->bank[i].start,
> -                     mi->bank[i].start + mi->bank[i].size - 1);
> -    printk("\n");
> -    for ( i = 1 ; i < mods->nr_mods + 1; i++ )
> -        printk("MODULE[%d]: %"PRIpaddr" - %"PRIpaddr" %s\n",
> -                     i,
> -                     mods->module[i].start,
> -                     mods->module[i].start + mods->module[i].size,
> -                     mods->module[i].cmdline);
> -    nr_rsvd = fdt_num_mem_rsv(device_tree_flattened);
> -    for ( i = 0; i < nr_rsvd; i++ )
> -    {
> -        paddr_t s, e;
> -        if ( fdt_get_mem_rsv(device_tree_flattened, i, &s, &e) < 0 )
> -            continue;
> -        /* fdt_get_mem_rsv returns length */
> -        e += s;
> -        printk(" RESVD[%d]: %"PRIpaddr" - %"PRIpaddr"\n",
> -                     i, s, e);
> -    }
> -    printk("\n");
> -}
> -
> -/**
> - * device_tree_early_init - initialize early info from a DTB
> - * @fdt: flattened device tree binary
> - *
> - * Returns the size of the DTB.
> - */
> -size_t __init device_tree_early_init(const void *fdt, paddr_t paddr)
> -{
> -    struct bootmodule *mod;
> -    int ret;
> -
> -    ret = fdt_check_header(fdt);
> -    if ( ret < 0 )
> -        panic("No valid device tree\n");
> -
> -    mod = &bootinfo.modules.module[MOD_FDT];
> -    mod->start = paddr;
> -    mod->size = fdt_totalsize(fdt);
> -
> -    bootinfo.modules.nr_mods = max(MOD_FDT, bootinfo.modules.nr_mods);
> -
> -    device_tree_for_each_node((void *)fdt, early_scan_node, NULL);
> -    early_print_info();
> -
> -    return fdt_totalsize(fdt);
> -}
> -
>  static void __init *unflatten_dt_alloc(unsigned long *mem, unsigned long 
> size,
>                                         unsigned long align)
>  {
> diff --git a/xen/include/asm-arm/setup.h b/xen/include/asm-arm/setup.h
> index ea0dc46..21dbcd4 100644
> --- a/xen/include/asm-arm/setup.h
> +++ b/xen/include/asm-arm/setup.h
> @@ -53,6 +53,8 @@ int construct_dom0(struct domain *d);
>  
>  void discard_initial_modules(void);
>  
> +size_t __init boot_fdt_info(const void *fdt, paddr_t paddr);
> +
>  #endif
>  /*
>   * Local variables:
> diff --git a/xen/include/xen/device_tree.h b/xen/include/xen/device_tree.h
> index 74e98f5..0edec85 100644
> --- a/xen/include/xen/device_tree.h
> +++ b/xen/include/xen/device_tree.h
> @@ -157,10 +157,7 @@ typedef int (*device_tree_node_func)(const void *fdt,
>  
>  extern const void *device_tree_flattened;
>  
> -size_t __init device_tree_early_init(const void *fdt, paddr_t paddr);
> -
>  const char __init *device_tree_bootargs(const void *fdt);
> -void __init device_tree_dump(const void *fdt);
>  
>  /**
>   * dt_unflatten_host_device_tree - Unflatten the host device tree
> -- 
> 1.7.10.4
> 

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.