coreboot-v3/util/dtc/ftdump.c
<<
>>
Prefs
   1/*
   2 * ftdump.c - Contributed by Pantelis Antoniou <pantelis.antoniou AT gmail.com>
   3 */
   4
   5#include <stdint.h>
   6#include <stdio.h>
   7#include <string.h>
   8#include <ctype.h>
   9#include <netinet/in.h>
  10#include <byteswap.h>
  11
  12#include "flat_dt.h"
  13
  14#define cpu_to_be16(x)  htons(x)
  15#define be16_to_cpu(x)  ntohs(x)
  16
  17#define cpu_to_be32(x)  htonl(x)
  18#define be32_to_cpu(x)  ntohl(x)
  19
  20#if __BYTE_ORDER == __BIG_ENDIAN
  21#define cpu_to_be64(x)  (x)
  22#define be64_to_cpu(x)  (x)
  23#else
  24#define cpu_to_be64(x)  bswap_64(x)
  25#define be64_to_cpu(x)  bswap_64(x)
  26#endif
  27
  28#define DALIGN(x, a)    (((x) + ((a) - 1)) & ~((a) - 1))
  29#define PALIGN(p, a)    ((void *)(DALIGN((unsigned long)(p), (a))))
  30#define GET_CELL(p)     (p += 4, *((uint32_t *)(p-4)))
  31
  32static int is_printable_string(const void *data, int len)
  33{
  34        const char *s = data;
  35        const char *ss;
  36
  37        /* zero length is not */
  38        if (len == 0)
  39                return 0;
  40
  41        /* must terminate with zero */
  42        if (s[len - 1] != '\0')
  43                return 0;
  44
  45        ss = s;
  46        while (*s && isprint(*s))
  47                s++;
  48
  49        /* not zero, or not done yet */
  50        if (*s != '\0' || (s + 1 - ss) < len)
  51                return 0;
  52
  53        return 1;
  54}
  55
  56static void print_data(const void *data, int len)
  57{
  58        int i;
  59        const uint8_t *s;
  60
  61        /* no data, don't print */
  62        if (len == 0)
  63                return;
  64
  65        if (is_printable_string(data, len)) {
  66                printf(" = \"%s\"", (char *)data);
  67        } else if ((len % 4) == 0) {
  68                printf(" = <");
  69                for (i = 0; i < len; i += 4)
  70                        printf("%08x%s", *((uint32_t *)data + i),
  71                               i < (len - 4) ? " " : "");
  72                printf(">");
  73        } else {
  74                printf(" = [");
  75                for (i = 0, s = data; i < len; i++)
  76                        printf("%02x%s", s[i], i < len - 1 ? " " : "");
  77                printf("]");
  78        }
  79}
  80
  81static void dump_blob(void *blob)
  82{
  83        struct boot_param_header *bph = blob;
  84        struct reserve_entry *p_rsvmap = 
  85                (struct reserve_entry *)(blob
  86                                         + be32_to_cpu(bph->off_mem_rsvmap));
  87        char *p_struct = blob + be32_to_cpu(bph->off_dt_struct);
  88        char *p_strings = blob + be32_to_cpu(bph->off_dt_strings);
  89        uint32_t version = be32_to_cpu(bph->version);
  90        uint32_t tag;
  91        char *p;
  92        char *s, *t;
  93        int depth, sz, shift;
  94        int i;
  95        uint64_t addr, size;
  96
  97        depth = 0;
  98        shift = 4;
  99
 100        printf("// Version 0x%x tree\n", version);
 101        for (i = 0; ; i++) {
 102                addr = be64_to_cpu(p_rsvmap[i].address);
 103                size = be64_to_cpu(p_rsvmap[i].size);
 104                if (addr == 0 && size == 0)
 105                        break;
 106
 107                printf("/memreserve/ %llx %llx;\n",
 108                       (unsigned long long)addr, (unsigned long long)size);
 109        }
 110
 111        p = p_struct;
 112        while ((tag = be32_to_cpu(GET_CELL(p))) != OF_DT_END) {
 113
 114                /* printf("tag: 0x%08x (%d)\n", tag, p - p_struct); */
 115
 116                if (tag == OF_DT_BEGIN_NODE) {
 117                        s = p;
 118                        p = PALIGN(p + strlen(s) + 1, 4);
 119
 120                        if (*s == '\0')
 121                                s = "/";
 122
 123                        printf("%*s%s {\n", depth * shift, "", s);
 124
 125                        depth++;
 126                        continue;
 127                }
 128
 129                if (tag == OF_DT_END_NODE) {
 130                        depth--;
 131
 132                        printf("%*s};\n", depth * shift, "");
 133                        continue;
 134                }
 135
 136                if (tag == OF_DT_NOP) {
 137                        printf("%*s// [NOP]\n", depth * shift, "");
 138                        continue;
 139                }
 140
 141                if (tag != OF_DT_PROP) {
 142                        fprintf(stderr, "%*s ** Unknown tag 0x%08x\n", depth * shift, "", tag);
 143                        break;
 144                }
 145                sz = GET_CELL(p);
 146                s = p_strings + be32_to_cpu(GET_CELL(p));
 147                if (version < 0x10 && sz >= 8)
 148                        p = PALIGN(p, 8);
 149                t = p;
 150
 151                p = PALIGN(p + sz, 4);
 152
 153                printf("%*s%s", depth * shift, "", s);
 154                print_data(t, sz);
 155                printf(";\n");
 156        }
 157}
 158
 159
 160int main(int argc, char *argv[])
 161{
 162        FILE *fp;
 163        char buf[16384];        /* 16k max */
 164        int size;
 165
 166        if (argc < 2) {
 167                fprintf(stderr, "supply input filename\n");
 168                return 5;
 169        }
 170
 171        fp = fopen(argv[1], "rb");
 172        if (fp == NULL) {
 173                fprintf(stderr, "unable to open %s\n", argv[1]);
 174                return 10;
 175        }
 176
 177        size = fread(buf, 1, sizeof(buf), fp);
 178        if (size == sizeof(buf)) {      /* too large */
 179                fprintf(stderr, "file too large\n");
 180                return 10;
 181        }
 182
 183        dump_blob(buf);
 184
 185        fclose(fp);
 186
 187        return 0;
 188}
 189
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.