DeviceTree updates for 4.6:
- New tool dtx_diff to diff DT files. - Sync kernel's dtc/libfdt to current dtc repo master. - Fix for reserved memory regions located in highmem. - Document standard unit suffixes for DT properties. - Various DT binding doc updates. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJW7B34AAoJEPr7XbWNvGHDI4QP/0W0s3dvJ4l/TNeu/n1ZN8i7 H4FYNcNGVEPJMaI4gIV+GOnxJ4hTnEX2ftG9MEZCywVHWNCg4IAaIW1wQ52Sufnc Uncc9qO0MMR5Y1Siu/DuLi+ARyPQrke3M/o5xU9XJjSdz9QpnYw1MpMnpAJANomk /8Wjn2jEBHDJrxmJ73nE/CAVu8iFyWHTmt5pDQBoQub2NVuAX6rNcVmpmr0PhDMd 0CKokB+wmLHZEA2R4BBefjLwwKU1WrF/5ytXpsJ01NeZsExagJZz1fQdy3Z6o1Xx PRTukmmNhknatNTJOD8XmLr/SWN2CKNuJK5EOoV2opAvN/fc+mrk95DGKzjh5n64 aCRHzZgKAOYOqdVJKHfJ9hfzgG/zdt4mt1RKhLD+6qZNoSeQSrtikN3DWibPMZQR uHRC9fqalx+W4cBH4jakGYrpsbQOaQFjb6vHY8V/auSB2cx97YVuKCawnSerjWZv 1tu8dqNG0qwt9g0hgA+ycwitulUNSLSvLGp3mxBJXN2ULPHygCw53JUWFQEZhoAa JQqZ7lrUSE+AEp6Cwc0sNn07UMoCAoZKbTaurm2rn2RrKMfnirbf/sdZkc9Hq2pg TIJOJlmJmvheoCl7894iV1l18ooPqldk6h8d9fc6rngaQYkNaV0c9nlaMLTa2Rwi bVztrJItiymIhjIB86Iw =hz7v -----END PGP SIGNATURE----- Merge tag 'devicetree-for-4.6' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux Pull DeviceTree updates from Rob Herring: - new tool 'dtx_diff' to diff DT files - sync kernel's dtc/libfdt to current dtc repo master - fix for reserved memory regions located in highmem - document standard unit suffixes for DT properties - various DT binding doc updates * tag 'devicetree-for-4.6' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux: of: Add vendor prefix for eGalax_eMPIA Technology Inc Input: ads7846: Add description how to use internal reference (ADS7846) ARM: realview: add EB syscon variants to bindings devicetree: bindings: ARM: Use "uV" for micro-volt serial: fsl-imx-uart: Fix typo in fsl,dte-mode description of: add 'const' for of_property_*_string*() parameter '*np' of/unittest: fix infinite loop in of_unittest_destroy_tracked_overlays() of: alloc anywhere from memblock if range not specified kbuild: Allow using host dtc instead of kernel's copy of: resolver: Add missing of_node_get and of_node_put of: Add United Radiant Technology Corporation vendor prefix dt/bindings: add documentation on standard property unit suffixes scripts/dtc: Update to upstream commit b06e55c88b9b ARM: boot: Add an implementation of strnlen for libfdt scripts/dtc: dtx_diff - add info to error message dtc: create tool to diff device trees
This commit is contained in:
commit
31e182363b
|
@ -123,7 +123,9 @@ Required nodes:
|
||||||
|
|
||||||
- syscon: some subnode of the RealView SoC node must be a
|
- syscon: some subnode of the RealView SoC node must be a
|
||||||
system controller node pointing to the control registers,
|
system controller node pointing to the control registers,
|
||||||
with the compatible string set to one of these tuples:
|
with the compatible string set to one of these:
|
||||||
|
"arm,realview-eb11mp-revb-syscon", "arm,realview-eb-syscon", "syscon"
|
||||||
|
"arm,realview-eb11mp-revc-syscon", "arm,realview-eb-syscon", "syscon"
|
||||||
"arm,realview-eb-syscon", "syscon"
|
"arm,realview-eb-syscon", "syscon"
|
||||||
"arm,realview-pb1176-syscon", "syscon"
|
"arm,realview-pb1176-syscon", "syscon"
|
||||||
"arm,realview-pb11mp-syscon", "syscon"
|
"arm,realview-pb11mp-syscon", "syscon"
|
||||||
|
|
|
@ -250,7 +250,7 @@ nodes to be present and contain the properties described below.
|
||||||
Usage: optional
|
Usage: optional
|
||||||
Value type: <prop-encoded-array>
|
Value type: <prop-encoded-array>
|
||||||
Definition: A u32 value that represents the running time dynamic
|
Definition: A u32 value that represents the running time dynamic
|
||||||
power coefficient in units of mW/MHz/uVolt^2. The
|
power coefficient in units of mW/MHz/uV^2. The
|
||||||
coefficient can either be calculated from power
|
coefficient can either be calculated from power
|
||||||
measurements or derived by analysis.
|
measurements or derived by analysis.
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,8 @@ Optional properties:
|
||||||
ti,vref-delay-usecs vref supply delay in usecs, 0 for
|
ti,vref-delay-usecs vref supply delay in usecs, 0 for
|
||||||
external vref (u16).
|
external vref (u16).
|
||||||
ti,vref-mv The VREF voltage, in millivolts (u16).
|
ti,vref-mv The VREF voltage, in millivolts (u16).
|
||||||
|
Set to 0 to use internal refernce
|
||||||
|
(ADS7846).
|
||||||
ti,keep-vref-on set to keep vref on for differential
|
ti,keep-vref-on set to keep vref on for differential
|
||||||
measurements as well
|
measurements as well
|
||||||
ti,swap-xy swap x and y axis
|
ti,swap-xy swap x and y axis
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
Standard Unit Suffixes for Property names
|
||||||
|
|
||||||
|
Properties which have a unit of measure are recommended to have a unit
|
||||||
|
suffix appended to the property name. The list below contains the
|
||||||
|
recommended suffixes. Other variations exist in bindings, but should not
|
||||||
|
be used in new bindings or added here. The inconsistency in the unit
|
||||||
|
prefixes is due to selecting the most commonly used variants.
|
||||||
|
|
||||||
|
It is also recommended to use the units listed here and not add additional
|
||||||
|
unit prefixes.
|
||||||
|
|
||||||
|
Time/Frequency
|
||||||
|
----------------------------------------
|
||||||
|
-mhz : megahertz
|
||||||
|
-hz : Hertz (preferred)
|
||||||
|
-sec : seconds
|
||||||
|
-ms : milliseconds
|
||||||
|
-us : microseconds
|
||||||
|
-ns : nanoseconds
|
||||||
|
|
||||||
|
Distance
|
||||||
|
----------------------------------------
|
||||||
|
-mm : millimeters
|
||||||
|
|
||||||
|
Electricity
|
||||||
|
----------------------------------------
|
||||||
|
-microamp : micro amps
|
||||||
|
-ohms : Ohms
|
||||||
|
-micro-ohms : micro Ohms
|
||||||
|
-microvolt : micro volts
|
||||||
|
|
||||||
|
Temperature
|
||||||
|
----------------------------------------
|
||||||
|
-celsius : Degrees Celsius
|
||||||
|
-millicelsius : Degreee milli-Celsius
|
||||||
|
|
||||||
|
Pressure
|
||||||
|
----------------------------------------
|
||||||
|
-kpascal : kiloPascal
|
|
@ -72,6 +72,7 @@ dmo Data Modul AG
|
||||||
ea Embedded Artists AB
|
ea Embedded Artists AB
|
||||||
ebv EBV Elektronik
|
ebv EBV Elektronik
|
||||||
edt Emerging Display Technologies
|
edt Emerging Display Technologies
|
||||||
|
eeti eGalax_eMPIA Technology Inc
|
||||||
elan Elan Microelectronic Corp.
|
elan Elan Microelectronic Corp.
|
||||||
emmicro EM Microelectronic
|
emmicro EM Microelectronic
|
||||||
energymicro Silicon Laboratories (formerly Energy Micro AS)
|
energymicro Silicon Laboratories (formerly Energy Micro AS)
|
||||||
|
@ -247,6 +248,7 @@ tplink TP-LINK Technologies Co., Ltd.
|
||||||
tronfy Tronfy
|
tronfy Tronfy
|
||||||
truly Truly Semiconductors Limited
|
truly Truly Semiconductors Limited
|
||||||
upisemi uPI Semiconductor Corp.
|
upisemi uPI Semiconductor Corp.
|
||||||
|
urt United Radiant Technology Corporation
|
||||||
usi Universal Scientific Industrial Co., Ltd.
|
usi Universal Scientific Industrial Co., Ltd.
|
||||||
v3 V3 Semiconductor
|
v3 V3 Semiconductor
|
||||||
variscite Variscite Ltd.
|
variscite Variscite Ltd.
|
||||||
|
|
|
@ -65,6 +65,15 @@ size_t strlen(const char *s)
|
||||||
return sc - s;
|
return sc - s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t strnlen(const char *s, size_t count)
|
||||||
|
{
|
||||||
|
const char *sc;
|
||||||
|
|
||||||
|
for (sc = s; count-- && *sc != '\0'; ++sc)
|
||||||
|
/* nothing */;
|
||||||
|
return sc - s;
|
||||||
|
}
|
||||||
|
|
||||||
int memcmp(const void *cs, const void *ct, size_t count)
|
int memcmp(const void *cs, const void *ct, size_t count)
|
||||||
{
|
{
|
||||||
const unsigned char *su1 = cs, *su2 = ct, *end = su1 + count;
|
const unsigned char *su1 = cs, *su2 = ct, *end = su1 + count;
|
||||||
|
|
|
@ -1341,10 +1341,10 @@ EXPORT_SYMBOL_GPL(of_property_read_u64_array);
|
||||||
*
|
*
|
||||||
* The out_string pointer is modified only if a valid string can be decoded.
|
* The out_string pointer is modified only if a valid string can be decoded.
|
||||||
*/
|
*/
|
||||||
int of_property_read_string(struct device_node *np, const char *propname,
|
int of_property_read_string(const struct device_node *np, const char *propname,
|
||||||
const char **out_string)
|
const char **out_string)
|
||||||
{
|
{
|
||||||
struct property *prop = of_find_property(np, propname, NULL);
|
const struct property *prop = of_find_property(np, propname, NULL);
|
||||||
if (!prop)
|
if (!prop)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!prop->value)
|
if (!prop->value)
|
||||||
|
@ -1365,10 +1365,10 @@ EXPORT_SYMBOL_GPL(of_property_read_string);
|
||||||
* This function searches a string list property and returns the index
|
* This function searches a string list property and returns the index
|
||||||
* of a specific string value.
|
* of a specific string value.
|
||||||
*/
|
*/
|
||||||
int of_property_match_string(struct device_node *np, const char *propname,
|
int of_property_match_string(const struct device_node *np, const char *propname,
|
||||||
const char *string)
|
const char *string)
|
||||||
{
|
{
|
||||||
struct property *prop = of_find_property(np, propname, NULL);
|
const struct property *prop = of_find_property(np, propname, NULL);
|
||||||
size_t l;
|
size_t l;
|
||||||
int i;
|
int i;
|
||||||
const char *p, *end;
|
const char *p, *end;
|
||||||
|
@ -1404,10 +1404,11 @@ EXPORT_SYMBOL_GPL(of_property_match_string);
|
||||||
* Don't call this function directly. It is a utility helper for the
|
* Don't call this function directly. It is a utility helper for the
|
||||||
* of_property_read_string*() family of functions.
|
* of_property_read_string*() family of functions.
|
||||||
*/
|
*/
|
||||||
int of_property_read_string_helper(struct device_node *np, const char *propname,
|
int of_property_read_string_helper(const struct device_node *np,
|
||||||
const char **out_strs, size_t sz, int skip)
|
const char *propname, const char **out_strs,
|
||||||
|
size_t sz, int skip)
|
||||||
{
|
{
|
||||||
struct property *prop = of_find_property(np, propname, NULL);
|
const struct property *prop = of_find_property(np, propname, NULL);
|
||||||
int l = 0, i = 0;
|
int l = 0, i = 0;
|
||||||
const char *p, *end;
|
const char *p, *end;
|
||||||
|
|
||||||
|
|
|
@ -32,11 +32,13 @@ int __init __weak early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
|
||||||
phys_addr_t align, phys_addr_t start, phys_addr_t end, bool nomap,
|
phys_addr_t align, phys_addr_t start, phys_addr_t end, bool nomap,
|
||||||
phys_addr_t *res_base)
|
phys_addr_t *res_base)
|
||||||
{
|
{
|
||||||
|
phys_addr_t base;
|
||||||
/*
|
/*
|
||||||
* We use __memblock_alloc_base() because memblock_alloc_base()
|
* We use __memblock_alloc_base() because memblock_alloc_base()
|
||||||
* panic()s on allocation failure.
|
* panic()s on allocation failure.
|
||||||
*/
|
*/
|
||||||
phys_addr_t base = __memblock_alloc_base(size, align, end);
|
end = !end ? MEMBLOCK_ALLOC_ANYWHERE : end;
|
||||||
|
base = __memblock_alloc_base(size, align, end);
|
||||||
if (!base)
|
if (!base)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
|
|
@ -36,12 +36,14 @@ static struct device_node *__of_find_node_by_full_name(struct device_node *node,
|
||||||
|
|
||||||
/* check */
|
/* check */
|
||||||
if (of_node_cmp(node->full_name, full_name) == 0)
|
if (of_node_cmp(node->full_name, full_name) == 0)
|
||||||
return node;
|
return of_node_get(node);
|
||||||
|
|
||||||
for_each_child_of_node(node, child) {
|
for_each_child_of_node(node, child) {
|
||||||
found = __of_find_node_by_full_name(child, full_name);
|
found = __of_find_node_by_full_name(child, full_name);
|
||||||
if (found != NULL)
|
if (found != NULL) {
|
||||||
|
of_node_put(child);
|
||||||
return found;
|
return found;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -174,6 +176,7 @@ static int __of_adjust_phandle_ref(struct device_node *node,
|
||||||
if (of_prop_cmp(sprop->name, propstr) == 0)
|
if (of_prop_cmp(sprop->name, propstr) == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
of_node_put(refnode);
|
||||||
|
|
||||||
if (!sprop) {
|
if (!sprop) {
|
||||||
pr_err("%s: Could not find property '%s'\n",
|
pr_err("%s: Could not find property '%s'\n",
|
||||||
|
|
|
@ -1165,6 +1165,11 @@ static void of_unittest_destroy_tracked_overlays(void)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ret = of_overlay_destroy(id + overlay_first_id);
|
ret = of_overlay_destroy(id + overlay_first_id);
|
||||||
|
if (ret == -ENODEV) {
|
||||||
|
pr_warn("%s: no overlay to destroy for #%d\n",
|
||||||
|
__func__, id + overlay_first_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
defers++;
|
defers++;
|
||||||
pr_warn("%s: overlay destroy failed for #%d\n",
|
pr_warn("%s: overlay destroy failed for #%d\n",
|
||||||
|
|
|
@ -296,13 +296,13 @@ extern int of_property_read_u64_array(const struct device_node *np,
|
||||||
u64 *out_values,
|
u64 *out_values,
|
||||||
size_t sz);
|
size_t sz);
|
||||||
|
|
||||||
extern int of_property_read_string(struct device_node *np,
|
extern int of_property_read_string(const struct device_node *np,
|
||||||
const char *propname,
|
const char *propname,
|
||||||
const char **out_string);
|
const char **out_string);
|
||||||
extern int of_property_match_string(struct device_node *np,
|
extern int of_property_match_string(const struct device_node *np,
|
||||||
const char *propname,
|
const char *propname,
|
||||||
const char *string);
|
const char *string);
|
||||||
extern int of_property_read_string_helper(struct device_node *np,
|
extern int of_property_read_string_helper(const struct device_node *np,
|
||||||
const char *propname,
|
const char *propname,
|
||||||
const char **out_strs, size_t sz, int index);
|
const char **out_strs, size_t sz, int index);
|
||||||
extern int of_device_is_compatible(const struct device_node *device,
|
extern int of_device_is_compatible(const struct device_node *device,
|
||||||
|
@ -538,14 +538,14 @@ static inline int of_property_read_u64_array(const struct device_node *np,
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int of_property_read_string(struct device_node *np,
|
static inline int of_property_read_string(const struct device_node *np,
|
||||||
const char *propname,
|
const char *propname,
|
||||||
const char **out_string)
|
const char **out_string)
|
||||||
{
|
{
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int of_property_read_string_helper(struct device_node *np,
|
static inline int of_property_read_string_helper(const struct device_node *np,
|
||||||
const char *propname,
|
const char *propname,
|
||||||
const char **out_strs, size_t sz, int index)
|
const char **out_strs, size_t sz, int index)
|
||||||
{
|
{
|
||||||
|
@ -571,7 +571,7 @@ static inline int of_property_read_u64(const struct device_node *np,
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int of_property_match_string(struct device_node *np,
|
static inline int of_property_match_string(const struct device_node *np,
|
||||||
const char *propname,
|
const char *propname,
|
||||||
const char *string)
|
const char *string)
|
||||||
{
|
{
|
||||||
|
@ -773,7 +773,7 @@ static inline int of_property_count_u64_elems(const struct device_node *np,
|
||||||
*
|
*
|
||||||
* If @out_strs is NULL, the number of strings in the property is returned.
|
* If @out_strs is NULL, the number of strings in the property is returned.
|
||||||
*/
|
*/
|
||||||
static inline int of_property_read_string_array(struct device_node *np,
|
static inline int of_property_read_string_array(const struct device_node *np,
|
||||||
const char *propname, const char **out_strs,
|
const char *propname, const char **out_strs,
|
||||||
size_t sz)
|
size_t sz)
|
||||||
{
|
{
|
||||||
|
@ -792,7 +792,7 @@ static inline int of_property_read_string_array(struct device_node *np,
|
||||||
* does not have a value, and -EILSEQ if the string is not null-terminated
|
* does not have a value, and -EILSEQ if the string is not null-terminated
|
||||||
* within the length of the property data.
|
* within the length of the property data.
|
||||||
*/
|
*/
|
||||||
static inline int of_property_count_strings(struct device_node *np,
|
static inline int of_property_count_strings(const struct device_node *np,
|
||||||
const char *propname)
|
const char *propname)
|
||||||
{
|
{
|
||||||
return of_property_read_string_helper(np, propname, NULL, 0, 0);
|
return of_property_read_string_helper(np, propname, NULL, 0, 0);
|
||||||
|
@ -816,7 +816,7 @@ static inline int of_property_count_strings(struct device_node *np,
|
||||||
*
|
*
|
||||||
* The out_string pointer is modified only if a valid string can be decoded.
|
* The out_string pointer is modified only if a valid string can be decoded.
|
||||||
*/
|
*/
|
||||||
static inline int of_property_read_string_index(struct device_node *np,
|
static inline int of_property_read_string_index(const struct device_node *np,
|
||||||
const char *propname,
|
const char *propname,
|
||||||
int index, const char **output)
|
int index, const char **output)
|
||||||
{
|
{
|
||||||
|
|
|
@ -269,6 +269,7 @@ cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -n -f -9 > $@) || \
|
||||||
|
|
||||||
# DTC
|
# DTC
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
DTC ?= $(objtree)/scripts/dtc/dtc
|
||||||
|
|
||||||
# Generate an assembly file to wrap the output of the device tree compiler
|
# Generate an assembly file to wrap the output of the device tree compiler
|
||||||
quiet_cmd_dt_S_dtb= DTB $@
|
quiet_cmd_dt_S_dtb= DTB $@
|
||||||
|
@ -291,7 +292,7 @@ $(obj)/%.dtb.S: $(obj)/%.dtb
|
||||||
quiet_cmd_dtc = DTC $@
|
quiet_cmd_dtc = DTC $@
|
||||||
cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \
|
cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \
|
||||||
$(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
|
$(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
|
||||||
$(objtree)/scripts/dtc/dtc -O dtb -o $@ -b 0 \
|
$(DTC) -O dtb -o $@ -b 0 \
|
||||||
-i $(dir $<) $(DTC_FLAGS) \
|
-i $(dir $<) $(DTC_FLAGS) \
|
||||||
-d $(depfile).dtc.tmp $(dtc-tmp) ; \
|
-d $(depfile).dtc.tmp $(dtc-tmp) ; \
|
||||||
cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile)
|
cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile)
|
||||||
|
|
|
@ -560,7 +560,7 @@ static void check_reg_format(struct check *c, struct node *dt,
|
||||||
size_cells = node_size_cells(node->parent);
|
size_cells = node_size_cells(node->parent);
|
||||||
entrylen = (addr_cells + size_cells) * sizeof(cell_t);
|
entrylen = (addr_cells + size_cells) * sizeof(cell_t);
|
||||||
|
|
||||||
if ((prop->val.len % entrylen) != 0)
|
if (!entrylen || (prop->val.len % entrylen) != 0)
|
||||||
FAIL(c, "\"reg\" property in %s has invalid length (%d bytes) "
|
FAIL(c, "\"reg\" property in %s has invalid length (%d bytes) "
|
||||||
"(#address-cells == %d, #size-cells == %d)",
|
"(#address-cells == %d, #size-cells == %d)",
|
||||||
node->fullpath, prop->val.len, addr_cells, size_cells);
|
node->fullpath, prop->val.len, addr_cells, size_cells);
|
||||||
|
|
|
@ -73,24 +73,32 @@ static void lexical_error(const char *fmt, ...);
|
||||||
}
|
}
|
||||||
|
|
||||||
<*>^"#"(line)?[ \t]+[0-9]+[ \t]+{STRING}([ \t]+[0-9]+)? {
|
<*>^"#"(line)?[ \t]+[0-9]+[ \t]+{STRING}([ \t]+[0-9]+)? {
|
||||||
char *line, *tmp, *fn;
|
char *line, *fnstart, *fnend;
|
||||||
|
struct data fn;
|
||||||
/* skip text before line # */
|
/* skip text before line # */
|
||||||
line = yytext;
|
line = yytext;
|
||||||
while (!isdigit((unsigned char)*line))
|
while (!isdigit((unsigned char)*line))
|
||||||
line++;
|
line++;
|
||||||
/* skip digits in line # */
|
|
||||||
tmp = line;
|
/* regexp ensures that first and list "
|
||||||
while (!isspace((unsigned char)*tmp))
|
* in the whole yytext are those at
|
||||||
tmp++;
|
* beginning and end of the filename string */
|
||||||
/* "NULL"-terminate line # */
|
fnstart = memchr(yytext, '"', yyleng);
|
||||||
*tmp = '\0';
|
for (fnend = yytext + yyleng - 1;
|
||||||
/* start of filename */
|
*fnend != '"'; fnend--)
|
||||||
fn = strchr(tmp + 1, '"') + 1;
|
;
|
||||||
/* strip trailing " from filename */
|
assert(fnstart && fnend && (fnend > fnstart));
|
||||||
tmp = strchr(fn, '"');
|
|
||||||
*tmp = 0;
|
fn = data_copy_escape_string(fnstart + 1,
|
||||||
|
fnend - fnstart - 1);
|
||||||
|
|
||||||
|
/* Don't allow nuls in filenames */
|
||||||
|
if (memchr(fn.val, '\0', fn.len - 1))
|
||||||
|
lexical_error("nul in line number directive");
|
||||||
|
|
||||||
/* -1 since #line is the number of the next line */
|
/* -1 since #line is the number of the next line */
|
||||||
srcpos_set_line(xstrdup(fn), atoi(line) - 1);
|
srcpos_set_line(xstrdup(fn.val), atoi(line) - 1);
|
||||||
|
data_free(fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
<*><<EOF>> {
|
<*><<EOF>> {
|
||||||
|
@ -153,7 +161,10 @@ static void lexical_error(const char *fmt, ...);
|
||||||
errno = 0;
|
errno = 0;
|
||||||
yylval.integer = strtoull(yytext, &e, 0);
|
yylval.integer = strtoull(yytext, &e, 0);
|
||||||
|
|
||||||
assert(!(*e) || !e[strspn(e, "UL")]);
|
if (*e && e[strspn(e, "UL")]) {
|
||||||
|
lexical_error("Bad integer literal '%s'",
|
||||||
|
yytext);
|
||||||
|
}
|
||||||
|
|
||||||
if (errno == ERANGE)
|
if (errno == ERANGE)
|
||||||
lexical_error("Integer literal '%s' out of range",
|
lexical_error("Integer literal '%s' out of range",
|
||||||
|
|
|
@ -951,31 +951,39 @@ case 2:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 75 "dtc-lexer.l"
|
#line 75 "dtc-lexer.l"
|
||||||
{
|
{
|
||||||
char *line, *tmp, *fn;
|
char *line, *fnstart, *fnend;
|
||||||
|
struct data fn;
|
||||||
/* skip text before line # */
|
/* skip text before line # */
|
||||||
line = yytext;
|
line = yytext;
|
||||||
while (!isdigit((unsigned char)*line))
|
while (!isdigit((unsigned char)*line))
|
||||||
line++;
|
line++;
|
||||||
/* skip digits in line # */
|
|
||||||
tmp = line;
|
/* regexp ensures that first and list "
|
||||||
while (!isspace((unsigned char)*tmp))
|
* in the whole yytext are those at
|
||||||
tmp++;
|
* beginning and end of the filename string */
|
||||||
/* "NULL"-terminate line # */
|
fnstart = memchr(yytext, '"', yyleng);
|
||||||
*tmp = '\0';
|
for (fnend = yytext + yyleng - 1;
|
||||||
/* start of filename */
|
*fnend != '"'; fnend--)
|
||||||
fn = strchr(tmp + 1, '"') + 1;
|
;
|
||||||
/* strip trailing " from filename */
|
assert(fnstart && fnend && (fnend > fnstart));
|
||||||
tmp = strchr(fn, '"');
|
|
||||||
*tmp = 0;
|
fn = data_copy_escape_string(fnstart + 1,
|
||||||
|
fnend - fnstart - 1);
|
||||||
|
|
||||||
|
/* Don't allow nuls in filenames */
|
||||||
|
if (memchr(fn.val, '\0', fn.len - 1))
|
||||||
|
lexical_error("nul in line number directive");
|
||||||
|
|
||||||
/* -1 since #line is the number of the next line */
|
/* -1 since #line is the number of the next line */
|
||||||
srcpos_set_line(xstrdup(fn), atoi(line) - 1);
|
srcpos_set_line(xstrdup(fn.val), atoi(line) - 1);
|
||||||
|
data_free(fn);
|
||||||
}
|
}
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case YY_STATE_EOF(INITIAL):
|
case YY_STATE_EOF(INITIAL):
|
||||||
case YY_STATE_EOF(BYTESTRING):
|
case YY_STATE_EOF(BYTESTRING):
|
||||||
case YY_STATE_EOF(PROPNODENAME):
|
case YY_STATE_EOF(PROPNODENAME):
|
||||||
case YY_STATE_EOF(V1):
|
case YY_STATE_EOF(V1):
|
||||||
#line 96 "dtc-lexer.l"
|
#line 104 "dtc-lexer.l"
|
||||||
{
|
{
|
||||||
if (!pop_input_file()) {
|
if (!pop_input_file()) {
|
||||||
yyterminate();
|
yyterminate();
|
||||||
|
@ -985,7 +993,7 @@ case YY_STATE_EOF(V1):
|
||||||
case 3:
|
case 3:
|
||||||
/* rule 3 can match eol */
|
/* rule 3 can match eol */
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 102 "dtc-lexer.l"
|
#line 110 "dtc-lexer.l"
|
||||||
{
|
{
|
||||||
DPRINT("String: %s\n", yytext);
|
DPRINT("String: %s\n", yytext);
|
||||||
yylval.data = data_copy_escape_string(yytext+1,
|
yylval.data = data_copy_escape_string(yytext+1,
|
||||||
|
@ -995,7 +1003,7 @@ YY_RULE_SETUP
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 4:
|
case 4:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 109 "dtc-lexer.l"
|
#line 117 "dtc-lexer.l"
|
||||||
{
|
{
|
||||||
DPRINT("Keyword: /dts-v1/\n");
|
DPRINT("Keyword: /dts-v1/\n");
|
||||||
dts_version = 1;
|
dts_version = 1;
|
||||||
|
@ -1005,7 +1013,7 @@ YY_RULE_SETUP
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 5:
|
case 5:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 116 "dtc-lexer.l"
|
#line 124 "dtc-lexer.l"
|
||||||
{
|
{
|
||||||
DPRINT("Keyword: /memreserve/\n");
|
DPRINT("Keyword: /memreserve/\n");
|
||||||
BEGIN_DEFAULT();
|
BEGIN_DEFAULT();
|
||||||
|
@ -1014,7 +1022,7 @@ YY_RULE_SETUP
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 6:
|
case 6:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 122 "dtc-lexer.l"
|
#line 130 "dtc-lexer.l"
|
||||||
{
|
{
|
||||||
DPRINT("Keyword: /bits/\n");
|
DPRINT("Keyword: /bits/\n");
|
||||||
BEGIN_DEFAULT();
|
BEGIN_DEFAULT();
|
||||||
|
@ -1023,7 +1031,7 @@ YY_RULE_SETUP
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 7:
|
case 7:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 128 "dtc-lexer.l"
|
#line 136 "dtc-lexer.l"
|
||||||
{
|
{
|
||||||
DPRINT("Keyword: /delete-property/\n");
|
DPRINT("Keyword: /delete-property/\n");
|
||||||
DPRINT("<PROPNODENAME>\n");
|
DPRINT("<PROPNODENAME>\n");
|
||||||
|
@ -1033,7 +1041,7 @@ YY_RULE_SETUP
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 8:
|
case 8:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 135 "dtc-lexer.l"
|
#line 143 "dtc-lexer.l"
|
||||||
{
|
{
|
||||||
DPRINT("Keyword: /delete-node/\n");
|
DPRINT("Keyword: /delete-node/\n");
|
||||||
DPRINT("<PROPNODENAME>\n");
|
DPRINT("<PROPNODENAME>\n");
|
||||||
|
@ -1043,7 +1051,7 @@ YY_RULE_SETUP
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 9:
|
case 9:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 142 "dtc-lexer.l"
|
#line 150 "dtc-lexer.l"
|
||||||
{
|
{
|
||||||
DPRINT("Label: %s\n", yytext);
|
DPRINT("Label: %s\n", yytext);
|
||||||
yylval.labelref = xstrdup(yytext);
|
yylval.labelref = xstrdup(yytext);
|
||||||
|
@ -1053,7 +1061,7 @@ YY_RULE_SETUP
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 10:
|
case 10:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 149 "dtc-lexer.l"
|
#line 157 "dtc-lexer.l"
|
||||||
{
|
{
|
||||||
char *e;
|
char *e;
|
||||||
DPRINT("Integer Literal: '%s'\n", yytext);
|
DPRINT("Integer Literal: '%s'\n", yytext);
|
||||||
|
@ -1061,7 +1069,10 @@ YY_RULE_SETUP
|
||||||
errno = 0;
|
errno = 0;
|
||||||
yylval.integer = strtoull(yytext, &e, 0);
|
yylval.integer = strtoull(yytext, &e, 0);
|
||||||
|
|
||||||
assert(!(*e) || !e[strspn(e, "UL")]);
|
if (*e && e[strspn(e, "UL")]) {
|
||||||
|
lexical_error("Bad integer literal '%s'",
|
||||||
|
yytext);
|
||||||
|
}
|
||||||
|
|
||||||
if (errno == ERANGE)
|
if (errno == ERANGE)
|
||||||
lexical_error("Integer literal '%s' out of range",
|
lexical_error("Integer literal '%s' out of range",
|
||||||
|
@ -1076,7 +1087,7 @@ YY_RULE_SETUP
|
||||||
case 11:
|
case 11:
|
||||||
/* rule 11 can match eol */
|
/* rule 11 can match eol */
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 168 "dtc-lexer.l"
|
#line 179 "dtc-lexer.l"
|
||||||
{
|
{
|
||||||
struct data d;
|
struct data d;
|
||||||
DPRINT("Character literal: %s\n", yytext);
|
DPRINT("Character literal: %s\n", yytext);
|
||||||
|
@ -1100,7 +1111,7 @@ YY_RULE_SETUP
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 12:
|
case 12:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 189 "dtc-lexer.l"
|
#line 200 "dtc-lexer.l"
|
||||||
{ /* label reference */
|
{ /* label reference */
|
||||||
DPRINT("Ref: %s\n", yytext+1);
|
DPRINT("Ref: %s\n", yytext+1);
|
||||||
yylval.labelref = xstrdup(yytext+1);
|
yylval.labelref = xstrdup(yytext+1);
|
||||||
|
@ -1109,7 +1120,7 @@ YY_RULE_SETUP
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 13:
|
case 13:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 195 "dtc-lexer.l"
|
#line 206 "dtc-lexer.l"
|
||||||
{ /* new-style path reference */
|
{ /* new-style path reference */
|
||||||
yytext[yyleng-1] = '\0';
|
yytext[yyleng-1] = '\0';
|
||||||
DPRINT("Ref: %s\n", yytext+2);
|
DPRINT("Ref: %s\n", yytext+2);
|
||||||
|
@ -1119,7 +1130,7 @@ YY_RULE_SETUP
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 14:
|
case 14:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 202 "dtc-lexer.l"
|
#line 213 "dtc-lexer.l"
|
||||||
{
|
{
|
||||||
yylval.byte = strtol(yytext, NULL, 16);
|
yylval.byte = strtol(yytext, NULL, 16);
|
||||||
DPRINT("Byte: %02x\n", (int)yylval.byte);
|
DPRINT("Byte: %02x\n", (int)yylval.byte);
|
||||||
|
@ -1128,7 +1139,7 @@ YY_RULE_SETUP
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 15:
|
case 15:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 208 "dtc-lexer.l"
|
#line 219 "dtc-lexer.l"
|
||||||
{
|
{
|
||||||
DPRINT("/BYTESTRING\n");
|
DPRINT("/BYTESTRING\n");
|
||||||
BEGIN_DEFAULT();
|
BEGIN_DEFAULT();
|
||||||
|
@ -1137,7 +1148,7 @@ YY_RULE_SETUP
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 16:
|
case 16:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 214 "dtc-lexer.l"
|
#line 225 "dtc-lexer.l"
|
||||||
{
|
{
|
||||||
DPRINT("PropNodeName: %s\n", yytext);
|
DPRINT("PropNodeName: %s\n", yytext);
|
||||||
yylval.propnodename = xstrdup((yytext[0] == '\\') ?
|
yylval.propnodename = xstrdup((yytext[0] == '\\') ?
|
||||||
|
@ -1148,7 +1159,7 @@ YY_RULE_SETUP
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 17:
|
case 17:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 222 "dtc-lexer.l"
|
#line 233 "dtc-lexer.l"
|
||||||
{
|
{
|
||||||
DPRINT("Binary Include\n");
|
DPRINT("Binary Include\n");
|
||||||
return DT_INCBIN;
|
return DT_INCBIN;
|
||||||
|
@ -1157,64 +1168,64 @@ YY_RULE_SETUP
|
||||||
case 18:
|
case 18:
|
||||||
/* rule 18 can match eol */
|
/* rule 18 can match eol */
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 227 "dtc-lexer.l"
|
#line 238 "dtc-lexer.l"
|
||||||
/* eat whitespace */
|
/* eat whitespace */
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 19:
|
case 19:
|
||||||
/* rule 19 can match eol */
|
/* rule 19 can match eol */
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 228 "dtc-lexer.l"
|
#line 239 "dtc-lexer.l"
|
||||||
/* eat C-style comments */
|
/* eat C-style comments */
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 20:
|
case 20:
|
||||||
/* rule 20 can match eol */
|
/* rule 20 can match eol */
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 229 "dtc-lexer.l"
|
#line 240 "dtc-lexer.l"
|
||||||
/* eat C++-style comments */
|
/* eat C++-style comments */
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 21:
|
case 21:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 231 "dtc-lexer.l"
|
#line 242 "dtc-lexer.l"
|
||||||
{ return DT_LSHIFT; };
|
{ return DT_LSHIFT; };
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 22:
|
case 22:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 232 "dtc-lexer.l"
|
#line 243 "dtc-lexer.l"
|
||||||
{ return DT_RSHIFT; };
|
{ return DT_RSHIFT; };
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 23:
|
case 23:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 233 "dtc-lexer.l"
|
#line 244 "dtc-lexer.l"
|
||||||
{ return DT_LE; };
|
{ return DT_LE; };
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 24:
|
case 24:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 234 "dtc-lexer.l"
|
#line 245 "dtc-lexer.l"
|
||||||
{ return DT_GE; };
|
{ return DT_GE; };
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 25:
|
case 25:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 235 "dtc-lexer.l"
|
#line 246 "dtc-lexer.l"
|
||||||
{ return DT_EQ; };
|
{ return DT_EQ; };
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 26:
|
case 26:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 236 "dtc-lexer.l"
|
#line 247 "dtc-lexer.l"
|
||||||
{ return DT_NE; };
|
{ return DT_NE; };
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 27:
|
case 27:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 237 "dtc-lexer.l"
|
#line 248 "dtc-lexer.l"
|
||||||
{ return DT_AND; };
|
{ return DT_AND; };
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 28:
|
case 28:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 238 "dtc-lexer.l"
|
#line 249 "dtc-lexer.l"
|
||||||
{ return DT_OR; };
|
{ return DT_OR; };
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 29:
|
case 29:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 240 "dtc-lexer.l"
|
#line 251 "dtc-lexer.l"
|
||||||
{
|
{
|
||||||
DPRINT("Char: %c (\\x%02x)\n", yytext[0],
|
DPRINT("Char: %c (\\x%02x)\n", yytext[0],
|
||||||
(unsigned)yytext[0]);
|
(unsigned)yytext[0]);
|
||||||
|
@ -1232,10 +1243,10 @@ YY_RULE_SETUP
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 30:
|
case 30:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 255 "dtc-lexer.l"
|
#line 266 "dtc-lexer.l"
|
||||||
ECHO;
|
ECHO;
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
#line 1239 "dtc-lexer.lex.c"
|
#line 1250 "dtc-lexer.lex.c"
|
||||||
|
|
||||||
case YY_END_OF_BUFFER:
|
case YY_END_OF_BUFFER:
|
||||||
{
|
{
|
||||||
|
@ -2195,7 +2206,7 @@ void yyfree (void * ptr )
|
||||||
|
|
||||||
#define YYTABLES_NAME "yytables"
|
#define YYTABLES_NAME "yytables"
|
||||||
|
|
||||||
#line 254 "dtc-lexer.l"
|
#line 265 "dtc-lexer.l"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -499,9 +499,9 @@ static const yytype_uint16 yyrline[] =
|
||||||
298, 303, 322, 336, 343, 344, 345, 352, 356, 357,
|
298, 303, 322, 336, 343, 344, 345, 352, 356, 357,
|
||||||
361, 362, 366, 367, 371, 372, 376, 377, 381, 382,
|
361, 362, 366, 367, 371, 372, 376, 377, 381, 382,
|
||||||
386, 387, 388, 392, 393, 394, 395, 396, 400, 401,
|
386, 387, 388, 392, 393, 394, 395, 396, 400, 401,
|
||||||
402, 406, 407, 408, 412, 413, 414, 415, 419, 420,
|
402, 406, 407, 408, 412, 413, 422, 431, 435, 436,
|
||||||
421, 422, 427, 430, 434, 442, 445, 449, 457, 461,
|
437, 438, 443, 446, 450, 458, 461, 465, 473, 477,
|
||||||
465
|
481
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1909,111 +1909,125 @@ yyreduce:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 65:
|
case 65:
|
||||||
#line 413 "dtc-parser.y" /* yacc.c:1646 */
|
#line 414 "dtc-parser.y" /* yacc.c:1646 */
|
||||||
{ (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer); }
|
{
|
||||||
#line 1915 "dtc-parser.tab.c" /* yacc.c:1646 */
|
if ((yyvsp[0].integer) != 0) {
|
||||||
|
(yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer);
|
||||||
|
} else {
|
||||||
|
ERROR(&(yyloc), "Division by zero");
|
||||||
|
(yyval.integer) = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#line 1922 "dtc-parser.tab.c" /* yacc.c:1646 */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 66:
|
case 66:
|
||||||
#line 414 "dtc-parser.y" /* yacc.c:1646 */
|
#line 423 "dtc-parser.y" /* yacc.c:1646 */
|
||||||
{ (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer); }
|
{
|
||||||
#line 1921 "dtc-parser.tab.c" /* yacc.c:1646 */
|
if ((yyvsp[0].integer) != 0) {
|
||||||
|
(yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer);
|
||||||
|
} else {
|
||||||
|
ERROR(&(yyloc), "Division by zero");
|
||||||
|
(yyval.integer) = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#line 1935 "dtc-parser.tab.c" /* yacc.c:1646 */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 69:
|
case 69:
|
||||||
#line 420 "dtc-parser.y" /* yacc.c:1646 */
|
#line 436 "dtc-parser.y" /* yacc.c:1646 */
|
||||||
{ (yyval.integer) = -(yyvsp[0].integer); }
|
{ (yyval.integer) = -(yyvsp[0].integer); }
|
||||||
#line 1927 "dtc-parser.tab.c" /* yacc.c:1646 */
|
#line 1941 "dtc-parser.tab.c" /* yacc.c:1646 */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 70:
|
case 70:
|
||||||
#line 421 "dtc-parser.y" /* yacc.c:1646 */
|
#line 437 "dtc-parser.y" /* yacc.c:1646 */
|
||||||
{ (yyval.integer) = ~(yyvsp[0].integer); }
|
{ (yyval.integer) = ~(yyvsp[0].integer); }
|
||||||
#line 1933 "dtc-parser.tab.c" /* yacc.c:1646 */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 71:
|
|
||||||
#line 422 "dtc-parser.y" /* yacc.c:1646 */
|
|
||||||
{ (yyval.integer) = !(yyvsp[0].integer); }
|
|
||||||
#line 1939 "dtc-parser.tab.c" /* yacc.c:1646 */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 72:
|
|
||||||
#line 427 "dtc-parser.y" /* yacc.c:1646 */
|
|
||||||
{
|
|
||||||
(yyval.data) = empty_data;
|
|
||||||
}
|
|
||||||
#line 1947 "dtc-parser.tab.c" /* yacc.c:1646 */
|
#line 1947 "dtc-parser.tab.c" /* yacc.c:1646 */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 71:
|
||||||
|
#line 438 "dtc-parser.y" /* yacc.c:1646 */
|
||||||
|
{ (yyval.integer) = !(yyvsp[0].integer); }
|
||||||
|
#line 1953 "dtc-parser.tab.c" /* yacc.c:1646 */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 72:
|
||||||
|
#line 443 "dtc-parser.y" /* yacc.c:1646 */
|
||||||
|
{
|
||||||
|
(yyval.data) = empty_data;
|
||||||
|
}
|
||||||
|
#line 1961 "dtc-parser.tab.c" /* yacc.c:1646 */
|
||||||
|
break;
|
||||||
|
|
||||||
case 73:
|
case 73:
|
||||||
#line 431 "dtc-parser.y" /* yacc.c:1646 */
|
#line 447 "dtc-parser.y" /* yacc.c:1646 */
|
||||||
{
|
{
|
||||||
(yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte));
|
(yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte));
|
||||||
}
|
}
|
||||||
#line 1955 "dtc-parser.tab.c" /* yacc.c:1646 */
|
#line 1969 "dtc-parser.tab.c" /* yacc.c:1646 */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 74:
|
case 74:
|
||||||
#line 435 "dtc-parser.y" /* yacc.c:1646 */
|
#line 451 "dtc-parser.y" /* yacc.c:1646 */
|
||||||
{
|
{
|
||||||
(yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
|
(yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
|
||||||
}
|
}
|
||||||
#line 1963 "dtc-parser.tab.c" /* yacc.c:1646 */
|
#line 1977 "dtc-parser.tab.c" /* yacc.c:1646 */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 75:
|
case 75:
|
||||||
#line 442 "dtc-parser.y" /* yacc.c:1646 */
|
#line 458 "dtc-parser.y" /* yacc.c:1646 */
|
||||||
{
|
{
|
||||||
(yyval.nodelist) = NULL;
|
(yyval.nodelist) = NULL;
|
||||||
}
|
}
|
||||||
#line 1971 "dtc-parser.tab.c" /* yacc.c:1646 */
|
#line 1985 "dtc-parser.tab.c" /* yacc.c:1646 */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 76:
|
case 76:
|
||||||
#line 446 "dtc-parser.y" /* yacc.c:1646 */
|
#line 462 "dtc-parser.y" /* yacc.c:1646 */
|
||||||
{
|
{
|
||||||
(yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist));
|
(yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist));
|
||||||
}
|
}
|
||||||
#line 1979 "dtc-parser.tab.c" /* yacc.c:1646 */
|
#line 1993 "dtc-parser.tab.c" /* yacc.c:1646 */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 77:
|
case 77:
|
||||||
#line 450 "dtc-parser.y" /* yacc.c:1646 */
|
#line 466 "dtc-parser.y" /* yacc.c:1646 */
|
||||||
{
|
{
|
||||||
ERROR(&(yylsp[0]), "Properties must precede subnodes");
|
ERROR(&(yylsp[0]), "Properties must precede subnodes");
|
||||||
YYERROR;
|
YYERROR;
|
||||||
}
|
}
|
||||||
#line 1988 "dtc-parser.tab.c" /* yacc.c:1646 */
|
#line 2002 "dtc-parser.tab.c" /* yacc.c:1646 */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 78:
|
case 78:
|
||||||
#line 458 "dtc-parser.y" /* yacc.c:1646 */
|
#line 474 "dtc-parser.y" /* yacc.c:1646 */
|
||||||
{
|
{
|
||||||
(yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename));
|
(yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename));
|
||||||
}
|
}
|
||||||
#line 1996 "dtc-parser.tab.c" /* yacc.c:1646 */
|
#line 2010 "dtc-parser.tab.c" /* yacc.c:1646 */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 79:
|
case 79:
|
||||||
#line 462 "dtc-parser.y" /* yacc.c:1646 */
|
#line 478 "dtc-parser.y" /* yacc.c:1646 */
|
||||||
{
|
{
|
||||||
(yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename));
|
(yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename));
|
||||||
}
|
}
|
||||||
#line 2004 "dtc-parser.tab.c" /* yacc.c:1646 */
|
#line 2018 "dtc-parser.tab.c" /* yacc.c:1646 */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 80:
|
case 80:
|
||||||
#line 466 "dtc-parser.y" /* yacc.c:1646 */
|
#line 482 "dtc-parser.y" /* yacc.c:1646 */
|
||||||
{
|
{
|
||||||
add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref));
|
add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref));
|
||||||
(yyval.node) = (yyvsp[0].node);
|
(yyval.node) = (yyvsp[0].node);
|
||||||
}
|
}
|
||||||
#line 2013 "dtc-parser.tab.c" /* yacc.c:1646 */
|
#line 2027 "dtc-parser.tab.c" /* yacc.c:1646 */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
#line 2017 "dtc-parser.tab.c" /* yacc.c:1646 */
|
#line 2031 "dtc-parser.tab.c" /* yacc.c:1646 */
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
/* User semantic actions sometimes alter yychar, and that requires
|
/* User semantic actions sometimes alter yychar, and that requires
|
||||||
|
@ -2248,7 +2262,7 @@ yyreturn:
|
||||||
#endif
|
#endif
|
||||||
return yyresult;
|
return yyresult;
|
||||||
}
|
}
|
||||||
#line 472 "dtc-parser.y" /* yacc.c:1906 */
|
#line 488 "dtc-parser.y" /* yacc.c:1906 */
|
||||||
|
|
||||||
|
|
||||||
void yyerror(char const *s)
|
void yyerror(char const *s)
|
||||||
|
|
|
@ -410,8 +410,24 @@ integer_add:
|
||||||
|
|
||||||
integer_mul:
|
integer_mul:
|
||||||
integer_mul '*' integer_unary { $$ = $1 * $3; }
|
integer_mul '*' integer_unary { $$ = $1 * $3; }
|
||||||
| integer_mul '/' integer_unary { $$ = $1 / $3; }
|
| integer_mul '/' integer_unary
|
||||||
| integer_mul '%' integer_unary { $$ = $1 % $3; }
|
{
|
||||||
|
if ($3 != 0) {
|
||||||
|
$$ = $1 / $3;
|
||||||
|
} else {
|
||||||
|
ERROR(&@$, "Division by zero");
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
| integer_mul '%' integer_unary
|
||||||
|
{
|
||||||
|
if ($3 != 0) {
|
||||||
|
$$ = $1 % $3;
|
||||||
|
} else {
|
||||||
|
ERROR(&@$, "Division by zero");
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
| integer_unary
|
| integer_unary
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
* USA
|
* USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include "dtc.h"
|
#include "dtc.h"
|
||||||
#include "srcpos.h"
|
#include "srcpos.h"
|
||||||
|
|
||||||
|
@ -104,11 +106,56 @@ static const char * const usage_opts_help[] = {
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char *guess_type_by_name(const char *fname, const char *fallback)
|
||||||
|
{
|
||||||
|
const char *s;
|
||||||
|
|
||||||
|
s = strrchr(fname, '.');
|
||||||
|
if (s == NULL)
|
||||||
|
return fallback;
|
||||||
|
if (!strcasecmp(s, ".dts"))
|
||||||
|
return "dts";
|
||||||
|
if (!strcasecmp(s, ".dtb"))
|
||||||
|
return "dtb";
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *guess_input_format(const char *fname, const char *fallback)
|
||||||
|
{
|
||||||
|
struct stat statbuf;
|
||||||
|
uint32_t magic;
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
|
if (stat(fname, &statbuf) != 0)
|
||||||
|
return fallback;
|
||||||
|
|
||||||
|
if (S_ISDIR(statbuf.st_mode))
|
||||||
|
return "fs";
|
||||||
|
|
||||||
|
if (!S_ISREG(statbuf.st_mode))
|
||||||
|
return fallback;
|
||||||
|
|
||||||
|
f = fopen(fname, "r");
|
||||||
|
if (f == NULL)
|
||||||
|
return fallback;
|
||||||
|
if (fread(&magic, 4, 1, f) != 1) {
|
||||||
|
fclose(f);
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
magic = fdt32_to_cpu(magic);
|
||||||
|
if (magic == FDT_MAGIC)
|
||||||
|
return "dtb";
|
||||||
|
|
||||||
|
return guess_type_by_name(fname, fallback);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct boot_info *bi;
|
struct boot_info *bi;
|
||||||
const char *inform = "dts";
|
const char *inform = NULL;
|
||||||
const char *outform = "dts";
|
const char *outform = NULL;
|
||||||
const char *outname = "-";
|
const char *outname = "-";
|
||||||
const char *depname = NULL;
|
const char *depname = NULL;
|
||||||
bool force = false, sort = false;
|
bool force = false, sort = false;
|
||||||
|
@ -213,6 +260,17 @@ int main(int argc, char *argv[])
|
||||||
fprintf(depfile, "%s:", outname);
|
fprintf(depfile, "%s:", outname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (inform == NULL)
|
||||||
|
inform = guess_input_format(arg, "dts");
|
||||||
|
if (outform == NULL) {
|
||||||
|
outform = guess_type_by_name(outname, NULL);
|
||||||
|
if (outform == NULL) {
|
||||||
|
if (streq(inform, "dts"))
|
||||||
|
outform = "dtb";
|
||||||
|
else
|
||||||
|
outform = "dts";
|
||||||
|
}
|
||||||
|
}
|
||||||
if (streq(inform, "dts"))
|
if (streq(inform, "dts"))
|
||||||
bi = dt_from_source(arg);
|
bi = dt_from_source(arg);
|
||||||
else if (streq(inform, "fs"))
|
else if (streq(inform, "fs"))
|
||||||
|
|
|
@ -0,0 +1,349 @@
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
# Copyright (C) 2015 Frank Rowand
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
|
||||||
|
# use spaces instead of tabs in the usage message
|
||||||
|
cat >&2 <<eod
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
`basename $0` DTx
|
||||||
|
decompile DTx
|
||||||
|
|
||||||
|
`basename $0` DTx_1 DTx_2
|
||||||
|
diff DTx_1 and DTx_2
|
||||||
|
|
||||||
|
|
||||||
|
-f print full dts in diff (--unified=99999)
|
||||||
|
-h synonym for --help
|
||||||
|
-help synonym for --help
|
||||||
|
--help print this message and exit
|
||||||
|
-s SRCTREE linux kernel source tree is at path SRCTREE
|
||||||
|
(default is current directory)
|
||||||
|
-S linux kernel source tree is at root of current git repo
|
||||||
|
-u unsorted, do not sort DTx
|
||||||
|
|
||||||
|
|
||||||
|
Each DTx is processed by the dtc compiler to produce a sorted dts source
|
||||||
|
file. If DTx is a dts source file then it is pre-processed in the same
|
||||||
|
manner as done for the compile of the dts source file in the Linux kernel
|
||||||
|
build system ('#include' and '/include/' directives are processed).
|
||||||
|
|
||||||
|
If two DTx are provided, the resulting dts source files are diffed.
|
||||||
|
|
||||||
|
If DTx is a directory, it is treated as a DT subtree, such as
|
||||||
|
/proc/device-tree.
|
||||||
|
|
||||||
|
If DTx contains the binary blob magic value in the first four bytes,
|
||||||
|
it is treated as a binary blob (aka .dtb or FDT).
|
||||||
|
|
||||||
|
Otherwise DTx is treated as a dts source file (aka .dts).
|
||||||
|
|
||||||
|
If this script is not run from the root of the linux source tree,
|
||||||
|
and DTx utilizes '#include' or '/include/' then the path of the
|
||||||
|
linux source tree can be provided by '-s SRCTREE' or '-S' so that
|
||||||
|
include paths will be set properly.
|
||||||
|
|
||||||
|
The shell variable \${ARCH} must provide the architecture containing
|
||||||
|
the dts source file for include paths to be set properly for '#include'
|
||||||
|
or '/include/' to be processed.
|
||||||
|
|
||||||
|
If DTx_1 and DTx_2 are in different architectures, then this script
|
||||||
|
may not work since \${ARCH} is part of the include path. Two possible
|
||||||
|
workarounds:
|
||||||
|
|
||||||
|
`basename $0` \\
|
||||||
|
<(ARCH=arch_of_dtx_1 `basename $0` DTx_1) \\
|
||||||
|
<(ARCH=arch_of_dtx_2 `basename $0` DTx_2)
|
||||||
|
|
||||||
|
`basename $0` ARCH=arch_of_dtx_1 DTx_1 >tmp_dtx_1.dts
|
||||||
|
`basename $0` ARCH=arch_of_dtx_2 DTx_2 >tmp_dtx_2.dts
|
||||||
|
`basename $0` tmp_dtx_1.dts tmp_dtx_2.dts
|
||||||
|
rm tmp_dtx_1.dts tmp_dtx_2.dts
|
||||||
|
|
||||||
|
If DTx_1 and DTx_2 are in different directories, then this script will
|
||||||
|
add the path of DTx_1 and DTx_2 to the include paths. If DTx_2 includes
|
||||||
|
a local file that exists in both the path of DTx_1 and DTx_2 then the
|
||||||
|
file in the path of DTx_1 will incorrectly be included. Possible
|
||||||
|
workaround:
|
||||||
|
|
||||||
|
`basename $0` DTx_1 >tmp_dtx_1.dts
|
||||||
|
`basename $0` DTx_2 >tmp_dtx_2.dts
|
||||||
|
`basename $0` tmp_dtx_1.dts tmp_dtx_2.dts
|
||||||
|
rm tmp_dtx_1.dts tmp_dtx_2.dts
|
||||||
|
|
||||||
|
eod
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
compile_to_dts() {
|
||||||
|
|
||||||
|
dtx="$1"
|
||||||
|
|
||||||
|
if [ -d "${dtx}" ] ; then
|
||||||
|
|
||||||
|
# ----- input is file tree
|
||||||
|
|
||||||
|
if ( ! ${DTC} -I fs ${dtx} ) ; then
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
|
||||||
|
elif [ -f "${dtx}" ] && [ -r "${dtx}" ] ; then
|
||||||
|
|
||||||
|
magic=`hexdump -n 4 -e '/1 "%02x"' ${dtx}`
|
||||||
|
if [ "${magic}" = "d00dfeed" ] ; then
|
||||||
|
|
||||||
|
# ----- input is FDT (binary blob)
|
||||||
|
|
||||||
|
if ( ! ${DTC} -I dtb ${dtx} ) ; then
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ----- input is DTS (source)
|
||||||
|
|
||||||
|
if ( cpp ${cpp_flags} -x assembler-with-cpp ${dtx} \
|
||||||
|
| ${DTC} -I dts ) ; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "" >&2
|
||||||
|
echo "Possible hints to resolve the above error:" >&2
|
||||||
|
echo " (hints might not fix the problem)" >&2
|
||||||
|
|
||||||
|
hint_given=0
|
||||||
|
|
||||||
|
if [ "${ARCH}" = "" ] ; then
|
||||||
|
hint_given=1
|
||||||
|
echo "" >&2
|
||||||
|
echo " shell variable \$ARCH not set" >&2
|
||||||
|
fi
|
||||||
|
|
||||||
|
dtx_arch=`echo "/${dtx}" | sed -e 's|.*/arch/||' -e 's|/.*||'`
|
||||||
|
|
||||||
|
if [ "${dtx_arch}" != "" -a "${dtx_arch}" != "${ARCH}" ] ; then
|
||||||
|
hint_given=1
|
||||||
|
echo "" >&2
|
||||||
|
echo " architecture ${dtx_arch} is in file path," >&2
|
||||||
|
echo " but does not match shell variable \$ARCH" >&2
|
||||||
|
echo " >>\$ARCH<< is: >>${ARCH}<<" >&2
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -d ${srctree}/arch/${ARCH} ] ; then
|
||||||
|
hint_given=1
|
||||||
|
echo "" >&2
|
||||||
|
echo " ${srctree}/arch/${ARCH}/ does not exist" >&2
|
||||||
|
echo " Is \$ARCH='${ARCH}' correct?" >&2
|
||||||
|
echo " Possible fix: use '-s' option" >&2
|
||||||
|
|
||||||
|
git_root=`git rev-parse --show-toplevel 2>/dev/null`
|
||||||
|
if [ -d ${git_root}/arch/ ] ; then
|
||||||
|
echo " Possible fix: use '-S' option" >&2
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $hint_given = 0 ] ; then
|
||||||
|
echo "" >&2
|
||||||
|
echo " No hints available." >&2
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "" >&2
|
||||||
|
|
||||||
|
exit 3
|
||||||
|
|
||||||
|
else
|
||||||
|
echo "" >&2
|
||||||
|
echo "ERROR: ${dtx} does not exist or is not readable" >&2
|
||||||
|
echo "" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# ----- start of script
|
||||||
|
|
||||||
|
cmd_diff=0
|
||||||
|
diff_flags="-u"
|
||||||
|
dtx_file_1=""
|
||||||
|
dtx_file_2=""
|
||||||
|
dtc_sort="-s"
|
||||||
|
help=0
|
||||||
|
srctree=""
|
||||||
|
|
||||||
|
|
||||||
|
while [ $# -gt 0 ] ; do
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
|
||||||
|
-f )
|
||||||
|
diff_flags="--unified=999999"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
|
||||||
|
-h | -help | --help )
|
||||||
|
help=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
|
||||||
|
-s )
|
||||||
|
srctree="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
|
||||||
|
-S )
|
||||||
|
git_root=`git rev-parse --show-toplevel 2>/dev/null`
|
||||||
|
srctree="${git_root}"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
|
||||||
|
-u )
|
||||||
|
dtc_sort=""
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
if [ "${dtx_file_1}" = "" ] ; then
|
||||||
|
dtx_file_1="$1"
|
||||||
|
elif [ "${dtx_file_2}" = "" ] ; then
|
||||||
|
dtx_file_2="$1"
|
||||||
|
else
|
||||||
|
echo "" >&2
|
||||||
|
echo "ERROR: Unexpected parameter: $1" >&2
|
||||||
|
echo "" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
|
||||||
|
esac
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "${srctree}" = "" ] ; then
|
||||||
|
srctree="."
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${dtx_file_2}" != "" ]; then
|
||||||
|
cmd_diff=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if (( ${help} )) ; then
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# this must follow check for ${help}
|
||||||
|
if [ "${dtx_file_1}" = "" ]; then
|
||||||
|
echo "" >&2
|
||||||
|
echo "ERROR: parameter DTx required" >&2
|
||||||
|
echo "" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# ----- prefer dtc from linux kernel, allow fallback to dtc in $PATH
|
||||||
|
|
||||||
|
if [ "${KBUILD_OUTPUT:0:2}" = ".." ] ; then
|
||||||
|
__KBUILD_OUTPUT="${srctree}/${KBUILD_OUTPUT}"
|
||||||
|
elif [ "${KBUILD_OUTPUT}" = "" ] ; then
|
||||||
|
__KBUILD_OUTPUT="."
|
||||||
|
else
|
||||||
|
__KBUILD_OUTPUT="${KBUILD_OUTPUT}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
DTC="${__KBUILD_OUTPUT}/scripts/dtc/dtc"
|
||||||
|
|
||||||
|
if [ ! -x ${DTC} ] ; then
|
||||||
|
__DTC="dtc"
|
||||||
|
if grep -q "^CONFIG_DTC=y" ${__KBUILD_OUTPUT}/.config ; then
|
||||||
|
make_command='
|
||||||
|
make scripts'
|
||||||
|
else
|
||||||
|
make_command='
|
||||||
|
Enable CONFIG_DTC in the kernel configuration
|
||||||
|
make scripts'
|
||||||
|
fi
|
||||||
|
if ( ! which ${__DTC} >/dev/null ) ; then
|
||||||
|
|
||||||
|
# use spaces instead of tabs in the error message
|
||||||
|
cat >&2 <<eod
|
||||||
|
|
||||||
|
ERROR: unable to find a 'dtc' program
|
||||||
|
|
||||||
|
Preferred 'dtc' (built from Linux kernel source tree) was not found or
|
||||||
|
is not executable.
|
||||||
|
|
||||||
|
'dtc' is: ${DTC}
|
||||||
|
|
||||||
|
If it does not exist, create it from the root of the Linux source tree:
|
||||||
|
${make_command}
|
||||||
|
|
||||||
|
If not at the root of the Linux kernel source tree -s SRCTREE or -S
|
||||||
|
may need to be specified to find 'dtc'.
|
||||||
|
|
||||||
|
If 'O=\${dir}' is specified in your Linux builds, this script requires
|
||||||
|
'export KBUILD_OUTPUT=\${dir}' or add \${dir}/scripts/dtc to \$PATH
|
||||||
|
before running.
|
||||||
|
|
||||||
|
If \${KBUILD_OUTPUT} is a relative path, then '-s SRCDIR', -S, or run
|
||||||
|
this script from the root of the Linux kernel source tree is required.
|
||||||
|
|
||||||
|
Fallback '${__DTC}' was also not in \${PATH} or is not executable.
|
||||||
|
|
||||||
|
eod
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
DTC=${__DTC}
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# ----- cpp and dtc flags same as for linux source tree build of .dtb files,
|
||||||
|
# plus directories of the dtx file(s)
|
||||||
|
|
||||||
|
dtx_path_1_dtc_include="-i `dirname ${dtx_file_1}`"
|
||||||
|
|
||||||
|
dtx_path_2_dtc_include=""
|
||||||
|
if (( ${cmd_diff} )) ; then
|
||||||
|
dtx_path_2_dtc_include="-i `dirname ${dtx_file_2}`"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cpp_flags="\
|
||||||
|
-nostdinc \
|
||||||
|
-I${srctree}/arch/${ARCH}/boot/dts \
|
||||||
|
-I${srctree}/arch/${ARCH}/boot/dts/include \
|
||||||
|
-I${srctree}/drivers/of/testcase-data \
|
||||||
|
-undef -D__DTS__"
|
||||||
|
|
||||||
|
dtc_flags="\
|
||||||
|
-i ${srctree}/arch/${ARCH}/boot/dts/ \
|
||||||
|
-i ${srctree}/kernel/dts \
|
||||||
|
${dtx_path_1_dtc_include} \
|
||||||
|
${dtx_path_2_dtc_include}"
|
||||||
|
|
||||||
|
DTC="${DTC} ${dtc_flags} -O dts -qq -f ${dtc_sort} -o -"
|
||||||
|
|
||||||
|
|
||||||
|
# ----- do the diff or decompile
|
||||||
|
|
||||||
|
if (( ${cmd_diff} )) ; then
|
||||||
|
|
||||||
|
diff ${diff_flags} \
|
||||||
|
<(compile_to_dts "${dtx_file_1}") \
|
||||||
|
<(compile_to_dts "${dtx_file_2}")
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
compile_to_dts "${dtx_file_1}"
|
||||||
|
|
||||||
|
fi
|
|
@ -76,18 +76,19 @@ int fdt_check_header(const void *fdt)
|
||||||
|
|
||||||
const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
|
const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
|
||||||
{
|
{
|
||||||
const char *p;
|
unsigned absoffset = offset + fdt_off_dt_struct(fdt);
|
||||||
|
|
||||||
|
if ((absoffset < offset)
|
||||||
|
|| ((absoffset + len) < absoffset)
|
||||||
|
|| (absoffset + len) > fdt_totalsize(fdt))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
if (fdt_version(fdt) >= 0x11)
|
if (fdt_version(fdt) >= 0x11)
|
||||||
if (((offset + len) < offset)
|
if (((offset + len) < offset)
|
||||||
|| ((offset + len) > fdt_size_dt_struct(fdt)))
|
|| ((offset + len) > fdt_size_dt_struct(fdt)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
p = _fdt_offset_ptr(fdt, offset);
|
return _fdt_offset_ptr(fdt, offset);
|
||||||
|
|
||||||
if (p + len < p)
|
|
||||||
return NULL;
|
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
|
uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
|
||||||
|
|
|
@ -538,6 +538,106 @@ int fdt_stringlist_contains(const char *strlist, int listlen, const char *str)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property)
|
||||||
|
{
|
||||||
|
const char *list, *end;
|
||||||
|
int length, count = 0;
|
||||||
|
|
||||||
|
list = fdt_getprop(fdt, nodeoffset, property, &length);
|
||||||
|
if (!list)
|
||||||
|
return -length;
|
||||||
|
|
||||||
|
end = list + length;
|
||||||
|
|
||||||
|
while (list < end) {
|
||||||
|
length = strnlen(list, end - list) + 1;
|
||||||
|
|
||||||
|
/* Abort if the last string isn't properly NUL-terminated. */
|
||||||
|
if (list + length > end)
|
||||||
|
return -FDT_ERR_BADVALUE;
|
||||||
|
|
||||||
|
list += length;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property,
|
||||||
|
const char *string)
|
||||||
|
{
|
||||||
|
int length, len, idx = 0;
|
||||||
|
const char *list, *end;
|
||||||
|
|
||||||
|
list = fdt_getprop(fdt, nodeoffset, property, &length);
|
||||||
|
if (!list)
|
||||||
|
return -length;
|
||||||
|
|
||||||
|
len = strlen(string) + 1;
|
||||||
|
end = list + length;
|
||||||
|
|
||||||
|
while (list < end) {
|
||||||
|
length = strnlen(list, end - list) + 1;
|
||||||
|
|
||||||
|
/* Abort if the last string isn't properly NUL-terminated. */
|
||||||
|
if (list + length > end)
|
||||||
|
return -FDT_ERR_BADVALUE;
|
||||||
|
|
||||||
|
if (length == len && memcmp(list, string, length) == 0)
|
||||||
|
return idx;
|
||||||
|
|
||||||
|
list += length;
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -FDT_ERR_NOTFOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *fdt_stringlist_get(const void *fdt, int nodeoffset,
|
||||||
|
const char *property, int idx,
|
||||||
|
int *lenp)
|
||||||
|
{
|
||||||
|
const char *list, *end;
|
||||||
|
int length;
|
||||||
|
|
||||||
|
list = fdt_getprop(fdt, nodeoffset, property, &length);
|
||||||
|
if (!list) {
|
||||||
|
if (lenp)
|
||||||
|
*lenp = length;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
end = list + length;
|
||||||
|
|
||||||
|
while (list < end) {
|
||||||
|
length = strnlen(list, end - list) + 1;
|
||||||
|
|
||||||
|
/* Abort if the last string isn't properly NUL-terminated. */
|
||||||
|
if (list + length > end) {
|
||||||
|
if (lenp)
|
||||||
|
*lenp = -FDT_ERR_BADVALUE;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx == 0) {
|
||||||
|
if (lenp)
|
||||||
|
*lenp = length - 1;
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
list += length;
|
||||||
|
idx--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lenp)
|
||||||
|
*lenp = -FDT_ERR_NOTFOUND;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int fdt_node_check_compatible(const void *fdt, int nodeoffset,
|
int fdt_node_check_compatible(const void *fdt, int nodeoffset,
|
||||||
const char *compatible)
|
const char *compatible)
|
||||||
{
|
{
|
||||||
|
|
|
@ -101,6 +101,8 @@ static int _fdt_splice(void *fdt, void *splicepoint, int oldlen, int newlen)
|
||||||
|
|
||||||
if (((p + oldlen) < p) || ((p + oldlen) > end))
|
if (((p + oldlen) < p) || ((p + oldlen) > end))
|
||||||
return -FDT_ERR_BADOFFSET;
|
return -FDT_ERR_BADOFFSET;
|
||||||
|
if ((p < (char *)fdt) || ((end - oldlen + newlen) < (char *)fdt))
|
||||||
|
return -FDT_ERR_BADOFFSET;
|
||||||
if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt)))
|
if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt)))
|
||||||
return -FDT_ERR_NOSPACE;
|
return -FDT_ERR_NOSPACE;
|
||||||
memmove(p + newlen, p + oldlen, end - p - oldlen);
|
memmove(p + newlen, p + oldlen, end - p - oldlen);
|
||||||
|
|
|
@ -121,7 +121,12 @@
|
||||||
/* FDT_ERR_BADNCELLS: Device tree has a #address-cells, #size-cells
|
/* FDT_ERR_BADNCELLS: Device tree has a #address-cells, #size-cells
|
||||||
* or similar property with a bad format or value */
|
* or similar property with a bad format or value */
|
||||||
|
|
||||||
#define FDT_ERR_MAX 14
|
#define FDT_ERR_BADVALUE 15
|
||||||
|
/* FDT_ERR_BADVALUE: Device tree has a property with an unexpected
|
||||||
|
* value. For example: a property expected to contain a string list
|
||||||
|
* is not NUL-terminated within the length of its value. */
|
||||||
|
|
||||||
|
#define FDT_ERR_MAX 15
|
||||||
|
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
/* Low-level functions (you probably don't need these) */
|
/* Low-level functions (you probably don't need these) */
|
||||||
|
@ -457,8 +462,8 @@ const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
|
||||||
* @namelen: number of characters of name to consider
|
* @namelen: number of characters of name to consider
|
||||||
* @lenp: pointer to an integer variable (will be overwritten) or NULL
|
* @lenp: pointer to an integer variable (will be overwritten) or NULL
|
||||||
*
|
*
|
||||||
* Identical to fdt_get_property_namelen(), but only examine the first
|
* Identical to fdt_get_property(), but only examine the first namelen
|
||||||
* namelen characters of name for matching the property name.
|
* characters of name for matching the property name.
|
||||||
*/
|
*/
|
||||||
const struct fdt_property *fdt_get_property_namelen(const void *fdt,
|
const struct fdt_property *fdt_get_property_namelen(const void *fdt,
|
||||||
int nodeoffset,
|
int nodeoffset,
|
||||||
|
@ -868,6 +873,68 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
|
||||||
*/
|
*/
|
||||||
int fdt_stringlist_contains(const char *strlist, int listlen, const char *str);
|
int fdt_stringlist_contains(const char *strlist, int listlen, const char *str);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fdt_stringlist_count - count the number of strings in a string list
|
||||||
|
* @fdt: pointer to the device tree blob
|
||||||
|
* @nodeoffset: offset of a tree node
|
||||||
|
* @property: name of the property containing the string list
|
||||||
|
* @return:
|
||||||
|
* the number of strings in the given property
|
||||||
|
* -FDT_ERR_BADVALUE if the property value is not NUL-terminated
|
||||||
|
* -FDT_ERR_NOTFOUND if the property does not exist
|
||||||
|
*/
|
||||||
|
int fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fdt_stringlist_search - find a string in a string list and return its index
|
||||||
|
* @fdt: pointer to the device tree blob
|
||||||
|
* @nodeoffset: offset of a tree node
|
||||||
|
* @property: name of the property containing the string list
|
||||||
|
* @string: string to look up in the string list
|
||||||
|
*
|
||||||
|
* Note that it is possible for this function to succeed on property values
|
||||||
|
* that are not NUL-terminated. That's because the function will stop after
|
||||||
|
* finding the first occurrence of @string. This can for example happen with
|
||||||
|
* small-valued cell properties, such as #address-cells, when searching for
|
||||||
|
* the empty string.
|
||||||
|
*
|
||||||
|
* @return:
|
||||||
|
* the index of the string in the list of strings
|
||||||
|
* -FDT_ERR_BADVALUE if the property value is not NUL-terminated
|
||||||
|
* -FDT_ERR_NOTFOUND if the property does not exist or does not contain
|
||||||
|
* the given string
|
||||||
|
*/
|
||||||
|
int fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property,
|
||||||
|
const char *string);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fdt_stringlist_get() - obtain the string at a given index in a string list
|
||||||
|
* @fdt: pointer to the device tree blob
|
||||||
|
* @nodeoffset: offset of a tree node
|
||||||
|
* @property: name of the property containing the string list
|
||||||
|
* @index: index of the string to return
|
||||||
|
* @lenp: return location for the string length or an error code on failure
|
||||||
|
*
|
||||||
|
* Note that this will successfully extract strings from properties with
|
||||||
|
* non-NUL-terminated values. For example on small-valued cell properties
|
||||||
|
* this function will return the empty string.
|
||||||
|
*
|
||||||
|
* If non-NULL, the length of the string (on success) or a negative error-code
|
||||||
|
* (on failure) will be stored in the integer pointer to by lenp.
|
||||||
|
*
|
||||||
|
* @return:
|
||||||
|
* A pointer to the string at the given index in the string list or NULL on
|
||||||
|
* failure. On success the length of the string will be stored in the memory
|
||||||
|
* location pointed to by the lenp parameter, if non-NULL. On failure one of
|
||||||
|
* the following negative error codes will be returned in the lenp parameter
|
||||||
|
* (if non-NULL):
|
||||||
|
* -FDT_ERR_BADVALUE if the property value is not NUL-terminated
|
||||||
|
* -FDT_ERR_NOTFOUND if the property does not exist
|
||||||
|
*/
|
||||||
|
const char *fdt_stringlist_get(const void *fdt, int nodeoffset,
|
||||||
|
const char *property, int index,
|
||||||
|
int *lenp);
|
||||||
|
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
/* Read-only functions (addressing related) */
|
/* Read-only functions (addressing related) */
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
|
|
|
@ -152,7 +152,6 @@ char get_escape_char(const char *s, int *i)
|
||||||
int j = *i + 1;
|
int j = *i + 1;
|
||||||
char val;
|
char val;
|
||||||
|
|
||||||
assert(c);
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'a':
|
case 'a':
|
||||||
val = '\a';
|
val = '\a';
|
||||||
|
@ -349,7 +348,6 @@ int utilfdt_decode_type(const char *fmt, int *type, int *size)
|
||||||
void utilfdt_print_data(const char *data, int len)
|
void utilfdt_print_data(const char *data, int len)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
const char *p = data;
|
|
||||||
const char *s;
|
const char *s;
|
||||||
|
|
||||||
/* no data, don't print */
|
/* no data, don't print */
|
||||||
|
@ -376,6 +374,7 @@ void utilfdt_print_data(const char *data, int len)
|
||||||
i < (len - 1) ? " " : "");
|
i < (len - 1) ? " " : "");
|
||||||
printf(">");
|
printf(">");
|
||||||
} else {
|
} else {
|
||||||
|
const unsigned char *p = (const unsigned char *)data;
|
||||||
printf(" = [");
|
printf(" = [");
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
printf("%02x%s", *p++, i < len - 1 ? " " : "");
|
printf("%02x%s", *p++, i < len - 1 ? " " : "");
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
#define DTC_VERSION "DTC 1.4.1-g9d3649bd"
|
#define DTC_VERSION "DTC 1.4.1-gb06e55c8"
|
||||||
|
|
Loading…
Reference in New Issue