root/scripts/dtc/fdtdump.c

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

DEFINITIONS

This source file includes following definitions.
  1. print_data
  2. dump_blob
  3. main

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * fdtdump.c - Contributed by Pantelis Antoniou <pantelis.antoniou AT gmail.com>
   4  */
   5 
   6 #include <stdint.h>
   7 #include <stdio.h>
   8 #include <stdlib.h>
   9 #include <string.h>
  10 #include <ctype.h>
  11 
  12 #include <fdt.h>
  13 #include <libfdt_env.h>
  14 
  15 #include "util.h"
  16 
  17 #define ALIGN(x, a)     (((x) + ((a) - 1)) & ~((a) - 1))
  18 #define PALIGN(p, a)    ((void *)(ALIGN((unsigned long)(p), (a))))
  19 #define GET_CELL(p)     (p += 4, *((const uint32_t *)(p-4)))
  20 
  21 static void print_data(const char *data, int len)
  22 {
  23         int i;
  24         const char *p = data;
  25 
  26         /* no data, don't print */
  27         if (len == 0)
  28                 return;
  29 
  30         if (util_is_printable_string(data, len)) {
  31                 printf(" = \"%s\"", (const char *)data);
  32         } else if ((len % 4) == 0) {
  33                 printf(" = <");
  34                 for (i = 0; i < len; i += 4)
  35                         printf("0x%08x%s", fdt32_to_cpu(GET_CELL(p)),
  36                                i < (len - 4) ? " " : "");
  37                 printf(">");
  38         } else {
  39                 printf(" = [");
  40                 for (i = 0; i < len; i++)
  41                         printf("%02x%s", *p++, i < len - 1 ? " " : "");
  42                 printf("]");
  43         }
  44 }
  45 
  46 static void dump_blob(void *blob)
  47 {
  48         struct fdt_header *bph = blob;
  49         uint32_t off_mem_rsvmap = fdt32_to_cpu(bph->off_mem_rsvmap);
  50         uint32_t off_dt = fdt32_to_cpu(bph->off_dt_struct);
  51         uint32_t off_str = fdt32_to_cpu(bph->off_dt_strings);
  52         struct fdt_reserve_entry *p_rsvmap =
  53                 (struct fdt_reserve_entry *)((char *)blob + off_mem_rsvmap);
  54         const char *p_struct = (const char *)blob + off_dt;
  55         const char *p_strings = (const char *)blob + off_str;
  56         uint32_t version = fdt32_to_cpu(bph->version);
  57         uint32_t totalsize = fdt32_to_cpu(bph->totalsize);
  58         uint32_t tag;
  59         const char *p, *s, *t;
  60         int depth, sz, shift;
  61         int i;
  62         uint64_t addr, size;
  63 
  64         depth = 0;
  65         shift = 4;
  66 
  67         printf("/dts-v1/;\n");
  68         printf("// magic:\t\t0x%x\n", fdt32_to_cpu(bph->magic));
  69         printf("// totalsize:\t\t0x%x (%d)\n", totalsize, totalsize);
  70         printf("// off_dt_struct:\t0x%x\n", off_dt);
  71         printf("// off_dt_strings:\t0x%x\n", off_str);
  72         printf("// off_mem_rsvmap:\t0x%x\n", off_mem_rsvmap);
  73         printf("// version:\t\t%d\n", version);
  74         printf("// last_comp_version:\t%d\n",
  75                fdt32_to_cpu(bph->last_comp_version));
  76         if (version >= 2)
  77                 printf("// boot_cpuid_phys:\t0x%x\n",
  78                        fdt32_to_cpu(bph->boot_cpuid_phys));
  79 
  80         if (version >= 3)
  81                 printf("// size_dt_strings:\t0x%x\n",
  82                        fdt32_to_cpu(bph->size_dt_strings));
  83         if (version >= 17)
  84                 printf("// size_dt_struct:\t0x%x\n",
  85                        fdt32_to_cpu(bph->size_dt_struct));
  86         printf("\n");
  87 
  88         for (i = 0; ; i++) {
  89                 addr = fdt64_to_cpu(p_rsvmap[i].address);
  90                 size = fdt64_to_cpu(p_rsvmap[i].size);
  91                 if (addr == 0 && size == 0)
  92                         break;
  93 
  94                 printf("/memreserve/ %llx %llx;\n",
  95                        (unsigned long long)addr, (unsigned long long)size);
  96         }
  97 
  98         p = p_struct;
  99         while ((tag = fdt32_to_cpu(GET_CELL(p))) != FDT_END) {
 100 
 101                 /* printf("tag: 0x%08x (%d)\n", tag, p - p_struct); */
 102 
 103                 if (tag == FDT_BEGIN_NODE) {
 104                         s = p;
 105                         p = PALIGN(p + strlen(s) + 1, 4);
 106 
 107                         if (*s == '\0')
 108                                 s = "/";
 109 
 110                         printf("%*s%s {\n", depth * shift, "", s);
 111 
 112                         depth++;
 113                         continue;
 114                 }
 115 
 116                 if (tag == FDT_END_NODE) {
 117                         depth--;
 118 
 119                         printf("%*s};\n", depth * shift, "");
 120                         continue;
 121                 }
 122 
 123                 if (tag == FDT_NOP) {
 124                         printf("%*s// [NOP]\n", depth * shift, "");
 125                         continue;
 126                 }
 127 
 128                 if (tag != FDT_PROP) {
 129                         fprintf(stderr, "%*s ** Unknown tag 0x%08x\n", depth * shift, "", tag);
 130                         break;
 131                 }
 132                 sz = fdt32_to_cpu(GET_CELL(p));
 133                 s = p_strings + fdt32_to_cpu(GET_CELL(p));
 134                 if (version < 16 && sz >= 8)
 135                         p = PALIGN(p, 8);
 136                 t = p;
 137 
 138                 p = PALIGN(p + sz, 4);
 139 
 140                 printf("%*s%s", depth * shift, "", s);
 141                 print_data(t, sz);
 142                 printf(";\n");
 143         }
 144 }
 145 
 146 
 147 int main(int argc, char *argv[])
 148 {
 149         char *buf;
 150 
 151         if (argc < 2) {
 152                 fprintf(stderr, "supply input filename\n");
 153                 return 5;
 154         }
 155 
 156         buf = utilfdt_read(argv[1]);
 157         if (buf)
 158                 dump_blob(buf);
 159         else
 160                 return 10;
 161 
 162         return 0;
 163 }

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