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