root/scripts/dtc/yamltree.c

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

DEFINITIONS

This source file includes following definitions.
  1. yaml_propval_int
  2. yaml_propval_string
  3. yaml_propval
  4. yaml_tree
  5. dt_to_yaml

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * (C) Copyright Linaro, Ltd. 2018
   4  * (C) Copyright Arm Holdings.  2017
   5  * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
   6  */
   7 
   8 #include <stdlib.h>
   9 #include <yaml.h>
  10 #include "dtc.h"
  11 #include "srcpos.h"
  12 
  13 char *yaml_error_name[] = {
  14         [YAML_NO_ERROR] = "no error",
  15         [YAML_MEMORY_ERROR] = "memory error",
  16         [YAML_READER_ERROR] = "reader error",
  17         [YAML_SCANNER_ERROR] = "scanner error",
  18         [YAML_PARSER_ERROR] = "parser error",
  19         [YAML_COMPOSER_ERROR] = "composer error",
  20         [YAML_WRITER_ERROR] = "writer error",
  21         [YAML_EMITTER_ERROR] = "emitter error",
  22 };
  23 
  24 #define yaml_emitter_emit_or_die(emitter, event) (                      \
  25 {                                                                       \
  26         if (!yaml_emitter_emit(emitter, event))                         \
  27                 die("yaml '%s': %s in %s, line %i\n",                   \
  28                     yaml_error_name[(emitter)->error],                  \
  29                     (emitter)->problem, __func__, __LINE__);            \
  30 })
  31 
  32 static void yaml_propval_int(yaml_emitter_t *emitter, struct marker *markers, char *data, int len, int width)
  33 {
  34         yaml_event_t event;
  35         void *tag;
  36         int off, start_offset = markers->offset;
  37 
  38         switch(width) {
  39                 case 1: tag = "!u8"; break;
  40                 case 2: tag = "!u16"; break;
  41                 case 4: tag = "!u32"; break;
  42                 case 8: tag = "!u64"; break;
  43                 default:
  44                         die("Invalid width %i", width);
  45         }
  46         assert(len % width == 0);
  47 
  48         yaml_sequence_start_event_initialize(&event, NULL,
  49                 (yaml_char_t *)tag, width == 4, YAML_FLOW_SEQUENCE_STYLE);
  50         yaml_emitter_emit_or_die(emitter, &event);
  51 
  52         for (off = 0; off < len; off += width) {
  53                 char buf[32];
  54                 struct marker *m;
  55                 bool is_phandle = false;
  56 
  57                 switch(width) {
  58                 case 1:
  59                         sprintf(buf, "0x%"PRIx8, *(uint8_t*)(data + off));
  60                         break;
  61                 case 2:
  62                         sprintf(buf, "0x%"PRIx16, fdt16_to_cpu(*(fdt16_t*)(data + off)));
  63                         break;
  64                 case 4:
  65                         sprintf(buf, "0x%"PRIx32, fdt32_to_cpu(*(fdt32_t*)(data + off)));
  66                         m = markers;
  67                         is_phandle = false;
  68                         for_each_marker_of_type(m, REF_PHANDLE) {
  69                                 if (m->offset == (start_offset + off)) {
  70                                         is_phandle = true;
  71                                         break;
  72                                 }
  73                         }
  74                         break;
  75                 case 8:
  76                         sprintf(buf, "0x%"PRIx64, fdt64_to_cpu(*(fdt64_t*)(data + off)));
  77                         break;
  78                 }
  79 
  80                 if (is_phandle)
  81                         yaml_scalar_event_initialize(&event, NULL,
  82                                 (yaml_char_t*)"!phandle", (yaml_char_t *)buf,
  83                                 strlen(buf), 0, 0, YAML_PLAIN_SCALAR_STYLE);
  84                 else
  85                         yaml_scalar_event_initialize(&event, NULL,
  86                                 (yaml_char_t*)YAML_INT_TAG, (yaml_char_t *)buf,
  87                                 strlen(buf), 1, 1, YAML_PLAIN_SCALAR_STYLE);
  88                 yaml_emitter_emit_or_die(emitter, &event);
  89         }
  90 
  91         yaml_sequence_end_event_initialize(&event);
  92         yaml_emitter_emit_or_die(emitter, &event);
  93 }
  94 
  95 static void yaml_propval_string(yaml_emitter_t *emitter, char *str, int len)
  96 {
  97         yaml_event_t event;
  98         int i;
  99 
 100         assert(str[len-1] == '\0');
 101 
 102         /* Make sure the entire string is in the lower 7-bit ascii range */
 103         for (i = 0; i < len; i++)
 104                 assert(isascii(str[i]));
 105 
 106         yaml_scalar_event_initialize(&event, NULL,
 107                 (yaml_char_t *)YAML_STR_TAG, (yaml_char_t*)str,
 108                 len-1, 0, 1, YAML_DOUBLE_QUOTED_SCALAR_STYLE);
 109         yaml_emitter_emit_or_die(emitter, &event);
 110 }
 111 
 112 static void yaml_propval(yaml_emitter_t *emitter, struct property *prop)
 113 {
 114         yaml_event_t event;
 115         int len = prop->val.len;
 116         struct marker *m = prop->val.markers;
 117 
 118         /* Emit the property name */
 119         yaml_scalar_event_initialize(&event, NULL,
 120                 (yaml_char_t *)YAML_STR_TAG, (yaml_char_t*)prop->name,
 121                 strlen(prop->name), 1, 1, YAML_PLAIN_SCALAR_STYLE);
 122         yaml_emitter_emit_or_die(emitter, &event);
 123 
 124         /* Boolean properties are easiest to deal with. Length is zero, so just emit 'true' */
 125         if (len == 0) {
 126                 yaml_scalar_event_initialize(&event, NULL,
 127                         (yaml_char_t *)YAML_BOOL_TAG,
 128                         (yaml_char_t*)"true",
 129                         strlen("true"), 1, 0, YAML_PLAIN_SCALAR_STYLE);
 130                 yaml_emitter_emit_or_die(emitter, &event);
 131                 return;
 132         }
 133 
 134         if (!m)
 135                 die("No markers present in property '%s' value\n", prop->name);
 136 
 137         yaml_sequence_start_event_initialize(&event, NULL,
 138                 (yaml_char_t *)YAML_SEQ_TAG, 1, YAML_FLOW_SEQUENCE_STYLE);
 139         yaml_emitter_emit_or_die(emitter, &event);
 140 
 141         for_each_marker(m) {
 142                 int chunk_len;
 143                 char *data = &prop->val.val[m->offset];
 144 
 145                 if (m->type < TYPE_UINT8)
 146                         continue;
 147 
 148                 chunk_len = type_marker_length(m) ? : len;
 149                 assert(chunk_len > 0);
 150                 len -= chunk_len;
 151 
 152                 switch(m->type) {
 153                 case TYPE_UINT16:
 154                         yaml_propval_int(emitter, m, data, chunk_len, 2);
 155                         break;
 156                 case TYPE_UINT32:
 157                         yaml_propval_int(emitter, m, data, chunk_len, 4);
 158                         break;
 159                 case TYPE_UINT64:
 160                         yaml_propval_int(emitter, m, data, chunk_len, 8);
 161                         break;
 162                 case TYPE_STRING:
 163                         yaml_propval_string(emitter, data, chunk_len);
 164                         break;
 165                 default:
 166                         yaml_propval_int(emitter, m, data, chunk_len, 1);
 167                         break;
 168                 }
 169         }
 170 
 171         yaml_sequence_end_event_initialize(&event);
 172         yaml_emitter_emit_or_die(emitter, &event);
 173 }
 174 
 175 
 176 static void yaml_tree(struct node *tree, yaml_emitter_t *emitter)
 177 {
 178         struct property *prop;
 179         struct node *child;
 180         yaml_event_t event;
 181 
 182         if (tree->deleted)
 183                 return;
 184 
 185         yaml_mapping_start_event_initialize(&event, NULL,
 186                 (yaml_char_t *)YAML_MAP_TAG, 1, YAML_ANY_MAPPING_STYLE);
 187         yaml_emitter_emit_or_die(emitter, &event);
 188 
 189         for_each_property(tree, prop)
 190                 yaml_propval(emitter, prop);
 191 
 192         /* Loop over all the children, emitting them into the map */
 193         for_each_child(tree, child) {
 194                 yaml_scalar_event_initialize(&event, NULL,
 195                         (yaml_char_t *)YAML_STR_TAG, (yaml_char_t*)child->name,
 196                         strlen(child->name), 1, 0, YAML_PLAIN_SCALAR_STYLE);
 197                 yaml_emitter_emit_or_die(emitter, &event);
 198                 yaml_tree(child, emitter);
 199         }
 200 
 201         yaml_mapping_end_event_initialize(&event);
 202         yaml_emitter_emit_or_die(emitter, &event);
 203 }
 204 
 205 void dt_to_yaml(FILE *f, struct dt_info *dti)
 206 {
 207         yaml_emitter_t emitter;
 208         yaml_event_t event;
 209 
 210         yaml_emitter_initialize(&emitter);
 211         yaml_emitter_set_output_file(&emitter, f);
 212         yaml_stream_start_event_initialize(&event, YAML_UTF8_ENCODING);
 213         yaml_emitter_emit_or_die(&emitter, &event);
 214 
 215         yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
 216         yaml_emitter_emit_or_die(&emitter, &event);
 217 
 218         yaml_sequence_start_event_initialize(&event, NULL, (yaml_char_t *)YAML_SEQ_TAG, 1, YAML_ANY_SEQUENCE_STYLE);
 219         yaml_emitter_emit_or_die(&emitter, &event);
 220 
 221         yaml_tree(dti->dt, &emitter);
 222 
 223         yaml_sequence_end_event_initialize(&event);
 224         yaml_emitter_emit_or_die(&emitter, &event);
 225 
 226         yaml_document_end_event_initialize(&event, 0);
 227         yaml_emitter_emit_or_die(&emitter, &event);
 228 
 229         yaml_stream_end_event_initialize(&event);
 230         yaml_emitter_emit_or_die(&emitter, &event);
 231 
 232         yaml_emitter_delete(&emitter);
 233 }

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