Home | History | Annotate | Download | only in qemu
      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 (at) us.ibm.com>
      8  *          Hollis Blanchard <hollisb (at) 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 "device_tree.h"
     24 #include "hw/loader.h"
     25 
     26 #include <libfdt.h>
     27 
     28 void *load_device_tree(const char *filename_path, int *sizep)
     29 {
     30     int dt_size;
     31     int dt_file_load_size;
     32     int ret;
     33     void *fdt = NULL;
     34 
     35     *sizep = 0;
     36     dt_size = get_image_size(filename_path);
     37     if (dt_size < 0) {
     38         printf("Unable to get size of device tree file '%s'\n",
     39             filename_path);
     40         goto fail;
     41     }
     42 
     43     /* Expand to 2x size to give enough room for manipulation.  */
     44     dt_size *= 2;
     45     /* First allocate space in qemu for device tree */
     46     fdt = qemu_mallocz(dt_size);
     47 
     48     dt_file_load_size = load_image(filename_path, fdt);
     49     if (dt_file_load_size < 0) {
     50         printf("Unable to open device tree file '%s'\n",
     51                filename_path);
     52         goto fail;
     53     }
     54 
     55     ret = fdt_open_into(fdt, fdt, dt_size);
     56     if (ret) {
     57         printf("Unable to copy device tree in memory\n");
     58         goto fail;
     59     }
     60 
     61     /* Check sanity of device tree */
     62     if (fdt_check_header(fdt)) {
     63         printf ("Device tree file loaded into memory is invalid: %s\n",
     64             filename_path);
     65         goto fail;
     66     }
     67     *sizep = dt_size;
     68     return fdt;
     69 
     70 fail:
     71     qemu_free(fdt);
     72     return NULL;
     73 }
     74 
     75 int qemu_devtree_setprop(void *fdt, const char *node_path,
     76                          const char *property, void *val_array, int size)
     77 {
     78     int offset;
     79 
     80     offset = fdt_path_offset(fdt, node_path);
     81     if (offset < 0)
     82         return offset;
     83 
     84     return fdt_setprop(fdt, offset, property, val_array, size);
     85 }
     86 
     87 int qemu_devtree_setprop_cell(void *fdt, const char *node_path,
     88                               const char *property, uint32_t val)
     89 {
     90     int offset;
     91 
     92     offset = fdt_path_offset(fdt, node_path);
     93     if (offset < 0)
     94         return offset;
     95 
     96     return fdt_setprop_cell(fdt, offset, property, val);
     97 }
     98 
     99 int qemu_devtree_setprop_string(void *fdt, const char *node_path,
    100                                 const char *property, const char *string)
    101 {
    102     int offset;
    103 
    104     offset = fdt_path_offset(fdt, node_path);
    105     if (offset < 0)
    106         return offset;
    107 
    108     return fdt_setprop_string(fdt, offset, property, string);
    109 }
    110