|
|
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
#ifndef DTC_H
|
|
|
|
#define DTC_H
|
|
|
|
|
|
|
|
/*
|
|
|
|
* (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <assert.h>
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <inttypes.h>
|
|
|
|
|
|
|
|
#include <libfdt_env.h>
|
|
|
|
#include <fdt.h>
|
|
|
|
|
|
|
|
#include "util.h"
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
#define debug(...) printf(__VA_ARGS__)
|
|
|
|
#else
|
|
|
|
#define debug(...)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define DEFAULT_FDT_VERSION 17
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Command line options
|
|
|
|
*/
|
|
|
|
extern int quiet; /* Level of quietness */
|
|
|
|
extern unsigned int reservenum; /* Number of memory reservation slots */
|
|
|
|
extern int minsize; /* Minimum blob size */
|
|
|
|
extern int padsize; /* Additional padding to blob */
|
|
|
|
extern int alignsize; /* Additional padding to blob accroding to the alignsize */
|
Support ePAPR compliant phandle properties
Currently, the Linux kernel, libfdt and dtc, when using flattened
device trees encode a node's phandle into a property named
"linux,phandle". The ePAPR specification, however - aiming as it is
to not be a Linux specific spec - requires that phandles be encoded in
a property named simply "phandle".
This patch adds support for this newer approach to dtc and libfdt.
Specifically:
- fdt_get_phandle() will now return the correct phandle if it
is supplied in either of these properties
- fdt_node_offset_by_phandle() will correctly find a node with
the given phandle encoded in either property.
- By default, when auto-generating phandles, dtc will encode
it into both properties for maximum compatibility. A new -H
option allows either only old-style or only new-style
properties to be generated.
- If phandle properties are explicitly supplied in the dts
file, dtc will not auto-generate ones in the alternate format.
- If both properties are supplied, dtc will check that they
have the same value.
- Some existing testcases are updated to use a mix of old and
new-style phandles, partially testing the changes.
- A new phandle_format test further tests the libfdt support,
and the -H option.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
15 years ago
|
|
|
extern int phandle_format; /* Use linux,phandle or phandle properties */
|
|
|
|
extern int generate_symbols; /* generate symbols for nodes with labels */
|
|
|
|
extern int generate_fixups; /* generate fixups */
|
|
|
|
extern int auto_label_aliases; /* auto generate labels -> aliases */
|
annotations: add the annotation functionality
Provide the new command-line option:
--annotate (abbreviated -T)
--annotate provides one or more filenames and line numbers indicating
the origin of a given line. The filename is expressed relative the the
filename provided on the command line. Nothing is printed for overlays,
etc.
-T can be repeated giving more verbose annotations. These consist of
one or more tuples of: filename, starting line, starting column, ending
line ending column. The full path is given for the file name.
Overlays, etc are annotated with <no-file>:<no-line>.
The verbose annotations may be too verbose for normal use.
There are numerous changes in srcpos.c to provide the relative filenames
(variables initial_path, initial_pathlen and initial_cpp, new functions
set_initial_path and shorten_to_initial_path, and changes in
srcfile_push and srcpos_set_line). The change in srcpos_set_line takes
care of the case where cpp is used as a preprocessor. In that case the
initial file name is not the one provided on the command line but the
one found at the beginnning of the cpp output.
shorten_to_initial_path only returns a string if it has some shortening
to do. Otherwise it returns NULL and relies on the caller to use the
initial string. This simplifies memory management, by making clear to
the caller whether a new string is allocated.
The new functions srcpos_string_comment, srcpos_string_first, and
srcpos_string_last print the annotations. srcpos_string_comment is
recursive to print a list of source file positions.
Various changes are sprinkled throughout treesource.c to print the
annotations.
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
6 years ago
|
|
|
extern int annotate; /* annotate .dts with input source location */
|
Support ePAPR compliant phandle properties
Currently, the Linux kernel, libfdt and dtc, when using flattened
device trees encode a node's phandle into a property named
"linux,phandle". The ePAPR specification, however - aiming as it is
to not be a Linux specific spec - requires that phandles be encoded in
a property named simply "phandle".
This patch adds support for this newer approach to dtc and libfdt.
Specifically:
- fdt_get_phandle() will now return the correct phandle if it
is supplied in either of these properties
- fdt_node_offset_by_phandle() will correctly find a node with
the given phandle encoded in either property.
- By default, when auto-generating phandles, dtc will encode
it into both properties for maximum compatibility. A new -H
option allows either only old-style or only new-style
properties to be generated.
- If phandle properties are explicitly supplied in the dts
file, dtc will not auto-generate ones in the alternate format.
- If both properties are supplied, dtc will check that they
have the same value.
- Some existing testcases are updated to use a mix of old and
new-style phandles, partially testing the changes.
- A new phandle_format test further tests the libfdt support,
and the -H option.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
15 years ago
|
|
|
|
|
|
|
#define PHANDLE_LEGACY 0x1
|
|
|
|
#define PHANDLE_EPAPR 0x2
|
|
|
|
#define PHANDLE_BOTH 0x3
|
|
|
|
|
|
|
|
typedef uint32_t cell_t;
|
|
|
|
|
|
|
|
static inline bool phandle_is_valid(cell_t phandle)
|
|
|
|
{
|
|
|
|
return phandle != 0 && phandle != ~0U;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline uint16_t dtb_ld16(const void *p)
|
|
|
|
{
|
|
|
|
const uint8_t *bp = (const uint8_t *)p;
|
|
|
|
|
|
|
|
return ((uint16_t)bp[0] << 8)
|
|
|
|
| bp[1];
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline uint32_t dtb_ld32(const void *p)
|
|
|
|
{
|
|
|
|
const uint8_t *bp = (const uint8_t *)p;
|
|
|
|
|
|
|
|
return ((uint32_t)bp[0] << 24)
|
|
|
|
| ((uint32_t)bp[1] << 16)
|
|
|
|
| ((uint32_t)bp[2] << 8)
|
|
|
|
| bp[3];
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline uint64_t dtb_ld64(const void *p)
|
|
|
|
{
|
|
|
|
const uint8_t *bp = (const uint8_t *)p;
|
|
|
|
|
|
|
|
return ((uint64_t)bp[0] << 56)
|
|
|
|
| ((uint64_t)bp[1] << 48)
|
|
|
|
| ((uint64_t)bp[2] << 40)
|
|
|
|
| ((uint64_t)bp[3] << 32)
|
|
|
|
| ((uint64_t)bp[4] << 24)
|
|
|
|
| ((uint64_t)bp[5] << 16)
|
|
|
|
| ((uint64_t)bp[6] << 8)
|
|
|
|
| bp[7];
|
|
|
|
}
|
|
|
|
|
|
|
|
#define streq(a, b) (strcmp((a), (b)) == 0)
|
|
|
|
#define strstarts(s, prefix) (strncmp((s), (prefix), strlen(prefix)) == 0)
|
|
|
|
#define strprefixeq(a, n, b) (strlen(b) == (n) && (memcmp(a, b, n) == 0))
|
|
|
|
static inline bool strends(const char *str, const char *suffix)
|
|
|
|
{
|
|
|
|
unsigned int len, suffix_len;
|
|
|
|
|
|
|
|
len = strlen(str);
|
|
|
|
suffix_len = strlen(suffix);
|
|
|
|
if (len < suffix_len)
|
|
|
|
return false;
|
|
|
|
return streq(str + len - suffix_len, suffix);
|
|
|
|
}
|
|
|
|
|
|
|
|
#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
|
|
|
|
|
|
|
|
/* Data blobs */
|
|
|
|
enum markertype {
|
|
|
|
TYPE_NONE,
|
|
|
|
REF_PHANDLE,
|
|
|
|
REF_PATH,
|
|
|
|
LABEL,
|
|
|
|
TYPE_UINT8,
|
|
|
|
TYPE_UINT16,
|
|
|
|
TYPE_UINT32,
|
|
|
|
TYPE_UINT64,
|
|
|
|
TYPE_STRING,
|
|
|
|
};
|
|
|
|
|
|
|
|
static inline bool is_type_marker(enum markertype type)
|
|
|
|
{
|
|
|
|
return type >= TYPE_UINT8;
|
|
|
|
}
|
|
|
|
|
|
|
|
extern const char *markername(enum markertype markertype);
|
|
|
|
|
|
|
|
struct marker {
|
|
|
|
enum markertype type;
|
|
|
|
unsigned int offset;
|
|
|
|
char *ref;
|
|
|
|
struct marker *next;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct data {
|
|
|
|
unsigned int len;
|
|
|
|
char *val;
|
|
|
|
struct marker *markers;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#define empty_data ((struct data){ 0 /* all .members = 0 or NULL */ })
|
|
|
|
|
|
|
|
#define for_each_marker(m) \
|
|
|
|
for (; (m); (m) = (m)->next)
|
|
|
|
#define for_each_marker_of_type(m, t) \
|
|
|
|
for_each_marker(m) \
|
|
|
|
if ((m)->type == (t))
|
|
|
|
|
|
|
|
static inline struct marker *next_type_marker(struct marker *m)
|
|
|
|
{
|
|
|
|
for_each_marker(m)
|
|
|
|
if (is_type_marker(m->type))
|
|
|
|
break;
|
|
|
|
return m;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline size_t type_marker_length(struct marker *m)
|
|
|
|
{
|
|
|
|
struct marker *next = next_type_marker(m->next);
|
|
|
|
|
|
|
|
if (next)
|
|
|
|
return next->offset - m->offset;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void data_free(struct data d);
|
|
|
|
|
|
|
|
struct data data_grow_for(struct data d, unsigned int xlen);
|
|
|
|
|
|
|
|
struct data data_copy_mem(const char *mem, int len);
|
|
|
|
struct data data_copy_escape_string(const char *s, int len);
|
|
|
|
struct data data_copy_file(FILE *f, size_t len);
|
|
|
|
|
|
|
|
struct data data_append_data(struct data d, const void *p, int len);
|
|
|
|
struct data data_insert_at_marker(struct data d, struct marker *m,
|
|
|
|
const void *p, int len);
|
|
|
|
struct data data_merge(struct data d1, struct data d2);
|
|
|
|
struct data data_append_cell(struct data d, cell_t word);
|
|
|
|
struct data data_append_integer(struct data d, uint64_t word, int bits);
|
|
|
|
struct data data_append_re(struct data d, uint64_t address, uint64_t size);
|
|
|
|
struct data data_append_addr(struct data d, uint64_t addr);
|
|
|
|
struct data data_append_byte(struct data d, uint8_t byte);
|
|
|
|
struct data data_append_zeroes(struct data d, int len);
|
|
|
|
struct data data_append_align(struct data d, int align);
|
|
|
|
|
|
|
|
struct data data_add_marker(struct data d, enum markertype type, char *ref);
|
|
|
|
|
|
|
|
bool data_is_one_string(struct data d);
|
|
|
|
|
|
|
|
/* DT constraints */
|
|
|
|
|
|
|
|
#define MAX_PROPNAME_LEN 31
|
|
|
|
#define MAX_NODENAME_LEN 31
|
|
|
|
|
|
|
|
/* Live trees */
|
|
|
|
struct label {
|
|
|
|
bool deleted;
|
|
|
|
char *label;
|
|
|
|
struct label *next;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct bus_type {
|
|
|
|
const char *name;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct property {
|
|
|
|
bool deleted;
|
|
|
|
char *name;
|
|
|
|
struct data val;
|
|
|
|
|
|
|
|
struct property *next;
|
|
|
|
|
|
|
|
struct label *labels;
|
annotations: add positions
Extend the parser to record positions, in build_node,
build_node_delete, and build_property.
srcpos structures are added to the property and node types, and to the
parameter lists of the above functions that construct these types.
Nodes and properties that are created by the compiler rather than from
parsing source code have NULL as the srcpos value.
merge_nodes, defined in livetree.c, uses srcpos_extend to combine
multiple positions, resulting in a list of positions. srcpos_extend
is defined in srcpos.c. New elements are added at the end. This
requires the srcpos type, define in srcpos.h, to be a list structure
with a next field. This next field is initialized to NULL in
srcpos.h, in the macro YYLLOC_DEFAULT invoked implicitly by the
generated parser code.
Another change to srcpos.c is to make srcpos_copy always do a full
copy, including a copy of the file substructure. This is required
because when dtc is used on the output of cpp, the successive detected
file names overwrite the file name in the file structure. The next
field does not need to be deep copied, because it is always NULL when
srcpos_copy is called; an assert checks for this. File names are only
updated in uncopied position structures.
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
6 years ago
|
|
|
struct srcpos *srcpos;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct node {
|
|
|
|
bool deleted;
|
|
|
|
char *name;
|
|
|
|
struct property *proplist;
|
|
|
|
struct node *children;
|
|
|
|
|
|
|
|
struct node *parent;
|
|
|
|
struct node *next_sibling;
|
|
|
|
|
|
|
|
char *fullpath;
|
|
|
|
int basenamelen;
|
|
|
|
|
|
|
|
cell_t phandle;
|
|
|
|
int addr_cells, size_cells;
|
|
|
|
|
|
|
|
struct label *labels;
|
|
|
|
const struct bus_type *bus;
|
annotations: add positions
Extend the parser to record positions, in build_node,
build_node_delete, and build_property.
srcpos structures are added to the property and node types, and to the
parameter lists of the above functions that construct these types.
Nodes and properties that are created by the compiler rather than from
parsing source code have NULL as the srcpos value.
merge_nodes, defined in livetree.c, uses srcpos_extend to combine
multiple positions, resulting in a list of positions. srcpos_extend
is defined in srcpos.c. New elements are added at the end. This
requires the srcpos type, define in srcpos.h, to be a list structure
with a next field. This next field is initialized to NULL in
srcpos.h, in the macro YYLLOC_DEFAULT invoked implicitly by the
generated parser code.
Another change to srcpos.c is to make srcpos_copy always do a full
copy, including a copy of the file substructure. This is required
because when dtc is used on the output of cpp, the successive detected
file names overwrite the file name in the file structure. The next
field does not need to be deep copied, because it is always NULL when
srcpos_copy is called; an assert checks for this. File names are only
updated in uncopied position structures.
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
6 years ago
|
|
|
struct srcpos *srcpos;
|
dtc: add ability to make nodes conditional on them being referenced
A number of platforms have a need to reduce the number of DT nodes,
mostly because of two similar constraints: the size of the DT blob, and
the time it takes to parse it.
As the DT is used in more and more SoCs, and by more projects, some
constraints start to appear in bootloaders running from SRAM with an
order of magnitude of 10kB. A typical DT is in the same order of
magnitude, so any effort to reduce the blob size is welcome in such an
environment.
Some platforms also want to reach very fast boot time, and the time it
takes to parse a typical DT starts to be noticeable.
Both of these issues can be mitigated by reducing the number of nodes in
the DT. The biggest provider of nodes is usually the pin controller and
its subnodes, usually one for each valid pin configuration in a given
SoC.
Obviously, a single, fixed, set of these nodes will be used by a given
board, so we can introduce a node property that will tell the DT
compiler to drop the nodes when they are not referenced in the tree, and
as such wouldn't be useful in the targetted system.
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
7 years ago
|
|
|
|
|
|
|
bool omit_if_unused, is_referenced;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define for_each_label_withdel(l0, l) \
|
|
|
|
for ((l) = (l0); (l); (l) = (l)->next)
|
|
|
|
|
|
|
|
#define for_each_label(l0, l) \
|
|
|
|
for_each_label_withdel(l0, l) \
|
|
|
|
if (!(l)->deleted)
|
|
|
|
|
|
|
|
#define for_each_property_withdel(n, p) \
|
|
|
|
for ((p) = (n)->proplist; (p); (p) = (p)->next)
|
|
|
|
|
|
|
|
#define for_each_property(n, p) \
|
|
|
|
for_each_property_withdel(n, p) \
|
|
|
|
if (!(p)->deleted)
|
|
|
|
|
|
|
|
#define for_each_child_withdel(n, c) \
|
|
|
|
for ((c) = (n)->children; (c); (c) = (c)->next_sibling)
|
|
|
|
|
|
|
|
#define for_each_child(n, c) \
|
|
|
|
for_each_child_withdel(n, c) \
|
|
|
|
if (!(c)->deleted)
|
|
|
|
|
|
|
|
void add_label(struct label **labels, char *label);
|
|
|
|
void delete_labels(struct label **labels);
|
|
|
|
|
|
|
|
struct property *build_property(const char *name, struct data val,
|
annotations: add positions
Extend the parser to record positions, in build_node,
build_node_delete, and build_property.
srcpos structures are added to the property and node types, and to the
parameter lists of the above functions that construct these types.
Nodes and properties that are created by the compiler rather than from
parsing source code have NULL as the srcpos value.
merge_nodes, defined in livetree.c, uses srcpos_extend to combine
multiple positions, resulting in a list of positions. srcpos_extend
is defined in srcpos.c. New elements are added at the end. This
requires the srcpos type, define in srcpos.h, to be a list structure
with a next field. This next field is initialized to NULL in
srcpos.h, in the macro YYLLOC_DEFAULT invoked implicitly by the
generated parser code.
Another change to srcpos.c is to make srcpos_copy always do a full
copy, including a copy of the file substructure. This is required
because when dtc is used on the output of cpp, the successive detected
file names overwrite the file name in the file structure. The next
field does not need to be deep copied, because it is always NULL when
srcpos_copy is called; an assert checks for this. File names are only
updated in uncopied position structures.
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
6 years ago
|
|
|
struct srcpos *srcpos);
|
|
|
|
struct property *build_property_delete(const char *name);
|
|
|
|
struct property *chain_property(struct property *first, struct property *list);
|
|
|
|
struct property *reverse_properties(struct property *first);
|
|
|
|
|
annotations: add positions
Extend the parser to record positions, in build_node,
build_node_delete, and build_property.
srcpos structures are added to the property and node types, and to the
parameter lists of the above functions that construct these types.
Nodes and properties that are created by the compiler rather than from
parsing source code have NULL as the srcpos value.
merge_nodes, defined in livetree.c, uses srcpos_extend to combine
multiple positions, resulting in a list of positions. srcpos_extend
is defined in srcpos.c. New elements are added at the end. This
requires the srcpos type, define in srcpos.h, to be a list structure
with a next field. This next field is initialized to NULL in
srcpos.h, in the macro YYLLOC_DEFAULT invoked implicitly by the
generated parser code.
Another change to srcpos.c is to make srcpos_copy always do a full
copy, including a copy of the file substructure. This is required
because when dtc is used on the output of cpp, the successive detected
file names overwrite the file name in the file structure. The next
field does not need to be deep copied, because it is always NULL when
srcpos_copy is called; an assert checks for this. File names are only
updated in uncopied position structures.
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
6 years ago
|
|
|
struct node *build_node(struct property *proplist, struct node *children,
|
|
|
|
struct srcpos *srcpos);
|
|
|
|
struct node *build_node_delete(struct srcpos *srcpos);
|
|
|
|
struct node *name_node(struct node *node, const char *name);
|
dtc: add ability to make nodes conditional on them being referenced
A number of platforms have a need to reduce the number of DT nodes,
mostly because of two similar constraints: the size of the DT blob, and
the time it takes to parse it.
As the DT is used in more and more SoCs, and by more projects, some
constraints start to appear in bootloaders running from SRAM with an
order of magnitude of 10kB. A typical DT is in the same order of
magnitude, so any effort to reduce the blob size is welcome in such an
environment.
Some platforms also want to reach very fast boot time, and the time it
takes to parse a typical DT starts to be noticeable.
Both of these issues can be mitigated by reducing the number of nodes in
the DT. The biggest provider of nodes is usually the pin controller and
its subnodes, usually one for each valid pin configuration in a given
SoC.
Obviously, a single, fixed, set of these nodes will be used by a given
board, so we can introduce a node property that will tell the DT
compiler to drop the nodes when they are not referenced in the tree, and
as such wouldn't be useful in the targetted system.
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
7 years ago
|
|
|
struct node *omit_node_if_unused(struct node *node);
|
|
|
|
struct node *reference_node(struct node *node);
|
|
|
|
struct node *chain_node(struct node *first, struct node *list);
|
|
|
|
struct node *merge_nodes(struct node *old_node, struct node *new_node);
|
|
|
|
struct node *add_orphan_node(struct node *old_node, struct node *new_node, char *ref);
|
|
|
|
|
|
|
|
void add_property(struct node *node, struct property *prop);
|
|
|
|
void delete_property_by_name(struct node *node, char *name);
|
|
|
|
void delete_property(struct property *prop);
|
|
|
|
void add_child(struct node *parent, struct node *child);
|
|
|
|
void delete_node_by_name(struct node *parent, char *name);
|
|
|
|
void delete_node(struct node *node);
|
|
|
|
void append_to_property(struct node *node,
|
|
|
|
char *name, const void *data, int len,
|
|
|
|
enum markertype type);
|
|
|
|
|
|
|
|
const char *get_unitname(struct node *node);
|
|
|
|
struct property *get_property(struct node *node, const char *propname);
|
|
|
|
cell_t propval_cell(struct property *prop);
|
|
|
|
cell_t propval_cell_n(struct property *prop, unsigned int n);
|
|
|
|
struct property *get_property_by_label(struct node *tree, const char *label,
|
|
|
|
struct node **node);
|
|
|
|
struct marker *get_marker_label(struct node *tree, const char *label,
|
|
|
|
struct node **node, struct property **prop);
|
|
|
|
struct node *get_subnode(struct node *node, const char *nodename);
|
|
|
|
struct node *get_node_by_path(struct node *tree, const char *path);
|
dtc: Flexible tree checking infrastructure (v2)
dtc: Flexible tree checking infrastructure
Here, at last, is a substantial start on revising dtc's infrastructure
for checking the tree; this is the rework I've been saying was
necessary practically since dtc was first release.
In the new model, we have a table of "check" structures, each with a
name, references to checking functions, and status variables. Each
check can (in principle) be individually switched off or on (as either
a warning or error). Checks have a list of prerequisites, so if
checks need to rely on results from earlier checks to make sense (or
even to avoid crashing) they just need to list the relevant other
checks there.
For now, only the "structural" checks and the fixups for phandle
references are converted to the new mechanism. The rather more
involved semantic checks (which is where this new mechanism will
really be useful) will have to be converted in future patches.
At present, there's no user interface for turning on/off the checks -
the -f option now forces output even if "error" level checks fail.
Again, future patches will be needed to add the fine-grained control,
but that should be quite straightforward with the infrastructure
implemented here.
Also adds a testcase for the handling of bad references, which catches
a bug encountered while developing this patch.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
17 years ago
|
|
|
struct node *get_node_by_label(struct node *tree, const char *label);
|
|
|
|
struct node *get_node_by_phandle(struct node *tree, cell_t phandle);
|
|
|
|
struct node *get_node_by_ref(struct node *tree, const char *ref);
|
dtc: Flexible tree checking infrastructure (v2)
dtc: Flexible tree checking infrastructure
Here, at last, is a substantial start on revising dtc's infrastructure
for checking the tree; this is the rework I've been saying was
necessary practically since dtc was first release.
In the new model, we have a table of "check" structures, each with a
name, references to checking functions, and status variables. Each
check can (in principle) be individually switched off or on (as either
a warning or error). Checks have a list of prerequisites, so if
checks need to rely on results from earlier checks to make sense (or
even to avoid crashing) they just need to list the relevant other
checks there.
For now, only the "structural" checks and the fixups for phandle
references are converted to the new mechanism. The rather more
involved semantic checks (which is where this new mechanism will
really be useful) will have to be converted in future patches.
At present, there's no user interface for turning on/off the checks -
the -f option now forces output even if "error" level checks fail.
Again, future patches will be needed to add the fine-grained control,
but that should be quite straightforward with the infrastructure
implemented here.
Also adds a testcase for the handling of bad references, which catches
a bug encountered while developing this patch.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
17 years ago
|
|
|
cell_t get_node_phandle(struct node *root, struct node *node);
|
|
|
|
|
|
|
|
uint32_t guess_boot_cpuid(struct node *tree);
|
|
|
|
|
|
|
|
/* Boot info (tree plus memreserve information */
|
|
|
|
|
|
|
|
struct reserve_info {
|
|
|
|
uint64_t address, size;
|
|
|
|
|
|
|
|
struct reserve_info *next;
|
|
|
|
|
|
|
|
struct label *labels;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct reserve_info *build_reserve_entry(uint64_t start, uint64_t len);
|
|
|
|
struct reserve_info *chain_reserve_entry(struct reserve_info *first,
|
|
|
|
struct reserve_info *list);
|
|
|
|
struct reserve_info *add_reserve_entry(struct reserve_info *list,
|
|
|
|
struct reserve_info *new);
|
|
|
|
|
|
|
|
|
|
|
|
struct dt_info {
|
|
|
|
unsigned int dtsflags;
|
|
|
|
struct reserve_info *reservelist;
|
|
|
|
uint32_t boot_cpuid_phys;
|
|
|
|
struct node *dt; /* the device tree */
|
|
|
|
const char *outname; /* filename being written to, "-" for stdout */
|
|
|
|
};
|
|
|
|
|
|
|
|
/* DTS version flags definitions */
|
|
|
|
#define DTSF_V1 0x0001 /* /dts-v1/ */
|
|
|
|
#define DTSF_PLUGIN 0x0002 /* /plugin/ */
|
|
|
|
|
|
|
|
struct dt_info *build_dt_info(unsigned int dtsflags,
|
|
|
|
struct reserve_info *reservelist,
|
|
|
|
struct node *tree, uint32_t boot_cpuid_phys);
|
|
|
|
void sort_tree(struct dt_info *dti);
|
|
|
|
void generate_label_tree(struct dt_info *dti, const char *name, bool allocph);
|
|
|
|
void generate_fixups_tree(struct dt_info *dti, const char *name);
|
|
|
|
void generate_local_fixups_tree(struct dt_info *dti, const char *name);
|
|
|
|
|
|
|
|
/* Checks */
|
|
|
|
|
|
|
|
void parse_checks_option(bool warn, bool error, const char *arg);
|
|
|
|
void process_checks(bool force, struct dt_info *dti);
|
|
|
|
|
|
|
|
/* Flattened trees */
|
|
|
|
|
|
|
|
void dt_to_blob(FILE *f, struct dt_info *dti, int version);
|
|
|
|
void dt_to_asm(FILE *f, struct dt_info *dti, int version);
|
|
|
|
|
|
|
|
struct dt_info *dt_from_blob(const char *fname);
|
|
|
|
|
|
|
|
/* Tree source */
|
|
|
|
|
|
|
|
void dt_to_source(FILE *f, struct dt_info *dti);
|
|
|
|
struct dt_info *dt_from_source(const char *f);
|
|
|
|
|
|
|
|
/* YAML source */
|
|
|
|
|
|
|
|
void dt_to_yaml(FILE *f, struct dt_info *dti);
|
|
|
|
|
|
|
|
/* FS trees */
|
|
|
|
|
|
|
|
struct dt_info *dt_from_fs(const char *dirname);
|
|
|
|
|
|
|
|
#endif /* DTC_H */
|