root/arch/powerpc/boot/libfdt-wrapper.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. expand_buf
  2. fdt_wrapper_finddevice
  3. fdt_wrapper_getprop
  4. fdt_wrapper_setprop
  5. fdt_wrapper_del_node
  6. fdt_wrapper_get_parent
  7. fdt_wrapper_create_node
  8. fdt_wrapper_find_node_by_prop_value
  9. fdt_wrapper_find_node_by_compatible
  10. fdt_wrapper_get_path
  11. fdt_wrapper_finalize
  12. fdt_init

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * This file does the necessary interface mapping between the bootwrapper
   4  * device tree operations and the interface provided by shared source
   5  * files flatdevicetree.[ch].
   6  *
   7  * Copyright 2007 David Gibson, IBM Corporation.
   8  */
   9 
  10 #include <stddef.h>
  11 #include <stdio.h>
  12 #include <page.h>
  13 #include <libfdt.h>
  14 #include "ops.h"
  15 
  16 #define DEBUG   0
  17 #define BAD_ERROR(err)  (((err) < 0) \
  18                          && ((err) != -FDT_ERR_NOTFOUND) \
  19                          && ((err) != -FDT_ERR_EXISTS))
  20 
  21 #define check_err(err) \
  22         ({ \
  23                 if (BAD_ERROR(err) || ((err < 0) && DEBUG)) \
  24                         printf("%s():%d  %s\n\r", __func__, __LINE__, \
  25                                fdt_strerror(err)); \
  26                 if (BAD_ERROR(err)) \
  27                         exit(); \
  28                 (err < 0) ? -1 : 0; \
  29         })
  30 
  31 #define offset_devp(off)        \
  32         ({ \
  33                 unsigned long _offset = (off); \
  34                 check_err(_offset) ? NULL : (void *)(_offset+1); \
  35         })
  36 
  37 #define devp_offset_find(devp)  (((unsigned long)(devp))-1)
  38 #define devp_offset(devp)       (devp ? ((unsigned long)(devp))-1 : 0)
  39 
  40 static void *fdt;
  41 static void *buf; /* = NULL */
  42 
  43 #define EXPAND_GRANULARITY      1024
  44 
  45 static void expand_buf(int minexpand)
  46 {
  47         int size = fdt_totalsize(fdt);
  48         int rc;
  49 
  50         size = _ALIGN(size + minexpand, EXPAND_GRANULARITY);
  51         buf = platform_ops.realloc(buf, size);
  52         if (!buf)
  53                 fatal("Couldn't find %d bytes to expand device tree\n\r", size);
  54         rc = fdt_open_into(fdt, buf, size);
  55         if (rc != 0)
  56                 fatal("Couldn't expand fdt into new buffer: %s\n\r",
  57                       fdt_strerror(rc));
  58 
  59         fdt = buf;
  60 }
  61 
  62 static void *fdt_wrapper_finddevice(const char *path)
  63 {
  64         return offset_devp(fdt_path_offset(fdt, path));
  65 }
  66 
  67 static int fdt_wrapper_getprop(const void *devp, const char *name,
  68                                void *buf, const int buflen)
  69 {
  70         const void *p;
  71         int len;
  72 
  73         p = fdt_getprop(fdt, devp_offset(devp), name, &len);
  74         if (!p)
  75                 return check_err(len);
  76         memcpy(buf, p, min(len, buflen));
  77         return len;
  78 }
  79 
  80 static int fdt_wrapper_setprop(const void *devp, const char *name,
  81                                const void *buf, const int len)
  82 {
  83         int rc;
  84 
  85         rc = fdt_setprop(fdt, devp_offset(devp), name, buf, len);
  86         if (rc == -FDT_ERR_NOSPACE) {
  87                 expand_buf(len + 16);
  88                 rc = fdt_setprop(fdt, devp_offset(devp), name, buf, len);
  89         }
  90 
  91         return check_err(rc);
  92 }
  93 
  94 static int fdt_wrapper_del_node(const void *devp)
  95 {
  96         return fdt_del_node(fdt, devp_offset(devp));
  97 }
  98 
  99 static void *fdt_wrapper_get_parent(const void *devp)
 100 {
 101         return offset_devp(fdt_parent_offset(fdt, devp_offset(devp)));
 102 }
 103 
 104 static void *fdt_wrapper_create_node(const void *devp, const char *name)
 105 {
 106         int offset;
 107 
 108         offset = fdt_add_subnode(fdt, devp_offset(devp), name);
 109         if (offset == -FDT_ERR_NOSPACE) {
 110                 expand_buf(strlen(name) + 16);
 111                 offset = fdt_add_subnode(fdt, devp_offset(devp), name);
 112         }
 113 
 114         return offset_devp(offset);
 115 }
 116 
 117 static void *fdt_wrapper_find_node_by_prop_value(const void *prev,
 118                                                  const char *name,
 119                                                  const char *val,
 120                                                  int len)
 121 {
 122         int offset = fdt_node_offset_by_prop_value(fdt, devp_offset_find(prev),
 123                                                    name, val, len);
 124         return offset_devp(offset);
 125 }
 126 
 127 static void *fdt_wrapper_find_node_by_compatible(const void *prev,
 128                                                  const char *val)
 129 {
 130         int offset = fdt_node_offset_by_compatible(fdt, devp_offset_find(prev),
 131                                                    val);
 132         return offset_devp(offset);
 133 }
 134 
 135 static char *fdt_wrapper_get_path(const void *devp, char *buf, int len)
 136 {
 137         int rc;
 138 
 139         rc = fdt_get_path(fdt, devp_offset(devp), buf, len);
 140         if (check_err(rc))
 141                 return NULL;
 142         return buf;
 143 }
 144 
 145 static unsigned long fdt_wrapper_finalize(void)
 146 {
 147         int rc;
 148 
 149         rc = fdt_pack(fdt);
 150         if (rc != 0)
 151                 fatal("Couldn't pack flat tree: %s\n\r",
 152                       fdt_strerror(rc));
 153         return (unsigned long)fdt;
 154 }
 155 
 156 void fdt_init(void *blob)
 157 {
 158         int err;
 159         int bufsize;
 160 
 161         dt_ops.finddevice = fdt_wrapper_finddevice;
 162         dt_ops.getprop = fdt_wrapper_getprop;
 163         dt_ops.setprop = fdt_wrapper_setprop;
 164         dt_ops.get_parent = fdt_wrapper_get_parent;
 165         dt_ops.create_node = fdt_wrapper_create_node;
 166         dt_ops.find_node_by_prop_value = fdt_wrapper_find_node_by_prop_value;
 167         dt_ops.find_node_by_compatible = fdt_wrapper_find_node_by_compatible;
 168         dt_ops.del_node = fdt_wrapper_del_node;
 169         dt_ops.get_path = fdt_wrapper_get_path;
 170         dt_ops.finalize = fdt_wrapper_finalize;
 171 
 172         /* Make sure the dt blob is the right version and so forth */
 173         fdt = blob;
 174         bufsize = fdt_totalsize(fdt) + EXPAND_GRANULARITY;
 175         buf = malloc(bufsize);
 176         if(!buf)
 177                 fatal("malloc failed. can't relocate the device tree\n\r");
 178 
 179         err = fdt_open_into(fdt, buf, bufsize);
 180 
 181         if (err != 0)
 182                 fatal("fdt_init(): %s\n\r", fdt_strerror(err));
 183 
 184         fdt = buf;
 185 }

/* [<][>][^][v][top][bottom][index][help] */