aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-03 12:44:08 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-03 12:44:08 -0400
commita54dfb1a845c38a97686268d8c4086a63d9493aa (patch)
tree3b31c81672fa89102aae929cc6c1e48e6e9382f4
parenteb0ad9c06d51edb5d18a7007fd4d77a8805b2ba7 (diff)
parent36165f55055781a0e4bf32d775241796414504b0 (diff)
Merge tag 'dt-for-3.7' of git://sources.calxeda.com/kernel/linux
Pull devicetree updates from Rob Herring: - Import of latest upstream device tree compiler (dtc) - New function of_get_child_by_name - Support for #size-cells of 0 and #addr-cells of >2 - Couple of DT binding documentation updates Fix up trivial conflicts due to of_get_child_by_name() having been added next to the new of_get_next_available_child(). * tag 'dt-for-3.7' of git://sources.calxeda.com/kernel/linux: MAINTAINERS: add scripts/dtc under Devicetree maintainers dtc: import latest upstream dtc dt: Document general interrupt controller bindings dt/s3c64xx/spi: Use of_get_child_by_name to get a named child dt: introduce of_get_child_by_name to get child node by name of: i2c: add support for wakeup-source property of/address: Handle #address-cells > 2 specially DT: export of_irq_to_resource_table() devicetree: serial: Add documentation for imx serial devicetree: pwm: mxs-pwm.txt: Fix reg field annotation of: Allow busses with #size-cells=0
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/interrupts.txt95
-rw-r--r--Documentation/devicetree/bindings/pwm/mxs-pwm.txt2
-rw-r--r--Documentation/devicetree/bindings/serial/fsl-imx-uart.txt35
-rw-r--r--MAINTAINERS1
-rw-r--r--drivers/of/address.c35
-rw-r--r--drivers/of/base.c23
-rw-r--r--drivers/of/irq.c1
-rw-r--r--drivers/of/of_i2c.c3
-rw-r--r--drivers/of/platform.c16
-rw-r--r--drivers/spi/spi-s3c64xx.c7
-rw-r--r--include/linux/of.h2
-rw-r--r--include/linux/of_address.h1
-rw-r--r--scripts/dtc/Makefile.dtc13
-rw-r--r--scripts/dtc/checks.c203
-rw-r--r--scripts/dtc/data.c124
-rw-r--r--scripts/dtc/dtc-lexer.l65
-rw-r--r--scripts/dtc/dtc-lexer.lex.c_shipped503
-rw-r--r--scripts/dtc/dtc-parser.tab.c_shipped780
-rw-r--r--scripts/dtc/dtc-parser.tab.h_shipped47
-rw-r--r--scripts/dtc/dtc-parser.y255
-rw-r--r--scripts/dtc/dtc.c21
-rw-r--r--scripts/dtc/dtc.h51
-rw-r--r--scripts/dtc/fdtdump.c162
-rw-r--r--scripts/dtc/fdtget.c366
-rw-r--r--scripts/dtc/fdtput.c362
-rw-r--r--scripts/dtc/flattree.c3
-rw-r--r--scripts/dtc/libfdt/Makefile.libfdt6
-rw-r--r--scripts/dtc/libfdt/fdt.c61
-rw-r--r--scripts/dtc/libfdt/fdt_empty_tree.c84
-rw-r--r--scripts/dtc/libfdt/fdt_ro.c275
-rw-r--r--scripts/dtc/libfdt/fdt_rw.c29
-rw-r--r--scripts/dtc/libfdt/fdt_sw.c11
-rw-r--r--scripts/dtc/libfdt/fdt_wip.c41
-rw-r--r--scripts/dtc/libfdt/libfdt.h440
-rw-r--r--scripts/dtc/libfdt/libfdt_env.h16
-rw-r--r--scripts/dtc/libfdt/libfdt_internal.h2
-rw-r--r--scripts/dtc/livetree.c128
-rw-r--r--scripts/dtc/srcpos.c98
-rw-r--r--scripts/dtc/srcpos.h31
-rw-r--r--scripts/dtc/treesource.c2
-rw-r--r--scripts/dtc/util.c272
-rw-r--r--scripts/dtc/util.h97
42 files changed, 4057 insertions, 712 deletions
diff --git a/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt b/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
new file mode 100644
index 000000000000..72a06c0ab1db
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
@@ -0,0 +1,95 @@
1Specifying interrupt information for devices
2============================================
3
41) Interrupt client nodes
5-------------------------
6
7Nodes that describe devices which generate interrupts must contain an
8"interrupts" property. This property must contain a list of interrupt
9specifiers, one per output interrupt. The format of the interrupt specifier is
10determined by the interrupt controller to which the interrupts are routed; see
11section 2 below for details.
12
13The "interrupt-parent" property is used to specify the controller to which
14interrupts are routed and contains a single phandle referring to the interrupt
15controller node. This property is inherited, so it may be specified in an
16interrupt client node or in any of its parent nodes.
17
182) Interrupt controller nodes
19-----------------------------
20
21A device is marked as an interrupt controller with the "interrupt-controller"
22property. This is a empty, boolean property. An additional "#interrupt-cells"
23property defines the number of cells needed to specify a single interrupt.
24
25It is the responsibility of the interrupt controller's binding to define the
26length and format of the interrupt specifier. The following two variants are
27commonly used:
28
29 a) one cell
30 -----------
31 The #interrupt-cells property is set to 1 and the single cell defines the
32 index of the interrupt within the controller.
33
34 Example:
35
36 vic: intc@10140000 {
37 compatible = "arm,versatile-vic";
38 interrupt-controller;
39 #interrupt-cells = <1>;
40 reg = <0x10140000 0x1000>;
41 };
42
43 sic: intc@10003000 {
44 compatible = "arm,versatile-sic";
45 interrupt-controller;
46 #interrupt-cells = <1>;
47 reg = <0x10003000 0x1000>;
48 interrupt-parent = <&vic>;
49 interrupts = <31>; /* Cascaded to vic */
50 };
51
52 b) two cells
53 ------------
54 The #interrupt-cells property is set to 2 and the first cell defines the
55 index of the interrupt within the controller, while the second cell is used
56 to specify any of the following flags:
57 - bits[3:0] trigger type and level flags
58 1 = low-to-high edge triggered
59 2 = high-to-low edge triggered
60 4 = active high level-sensitive
61 8 = active low level-sensitive
62
63 Example:
64
65 i2c@7000c000 {
66 gpioext: gpio-adnp@41 {
67 compatible = "ad,gpio-adnp";
68 reg = <0x41>;
69
70 interrupt-parent = <&gpio>;
71 interrupts = <160 1>;
72
73 gpio-controller;
74 #gpio-cells = <1>;
75
76 interrupt-controller;
77 #interrupt-cells = <2>;
78
79 nr-gpios = <64>;
80 };
81
82 sx8634@2b {
83 compatible = "smtc,sx8634";
84 reg = <0x2b>;
85
86 interrupt-parent = <&gpioext>;
87 interrupts = <3 0x8>;
88
89 #address-cells = <1>;
90 #size-cells = <0>;
91
92 threshold = <0x40>;
93 sensitivity = <7>;
94 };
95 };
diff --git a/Documentation/devicetree/bindings/pwm/mxs-pwm.txt b/Documentation/devicetree/bindings/pwm/mxs-pwm.txt
index b16f4a57d111..11963e4d6bc4 100644
--- a/Documentation/devicetree/bindings/pwm/mxs-pwm.txt
+++ b/Documentation/devicetree/bindings/pwm/mxs-pwm.txt
@@ -11,7 +11,7 @@ Example:
11 11
12pwm: pwm@80064000 { 12pwm: pwm@80064000 {
13 compatible = "fsl,imx28-pwm", "fsl,imx23-pwm"; 13 compatible = "fsl,imx28-pwm", "fsl,imx23-pwm";
14 reg = <0x80064000 2000>; 14 reg = <0x80064000 0x2000>;
15 #pwm-cells = <2>; 15 #pwm-cells = <2>;
16 fsl,pwm-number = <8>; 16 fsl,pwm-number = <8>;
17}; 17};
diff --git a/Documentation/devicetree/bindings/serial/fsl-imx-uart.txt b/Documentation/devicetree/bindings/serial/fsl-imx-uart.txt
new file mode 100644
index 000000000000..c58573b5b1a4
--- /dev/null
+++ b/Documentation/devicetree/bindings/serial/fsl-imx-uart.txt
@@ -0,0 +1,35 @@
1* Freescale i.MX UART controller
2
3Required properties:
4- compatible : should be "fsl,imx21-uart"
5- reg : Address and length of the register set for the device
6- interrupts : Should contain UART interrupt number
7
8Optional properties:
9- fsl,uart-has-rtscts: indicate that RTS/CTS signals are used
10
11Note: Each uart controller should have an alias correctly numbered
12in "aliases" node.
13
14Example:
15
16- From imx51.dtsi:
17aliases {
18 serial0 = &uart1;
19 serial1 = &uart2;
20 serial2 = &uart3;
21};
22
23uart1: serial@73fbc000 {
24 compatible = "fsl,imx51-uart", "fsl,imx21-uart";
25 reg = <0x73fbc000 0x4000>;
26 interrupts = <31>;
27 status = "disabled";
28}
29
30- From imx51-babbage.dts:
31uart1: serial@73fbc000 {
32 fsl,uart-has-rtscts;
33 status = "okay";
34};
35
diff --git a/MAINTAINERS b/MAINTAINERS
index 28167d0f8b42..d919e3d4a0db 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5067,6 +5067,7 @@ S: Maintained
5067F: Documentation/devicetree 5067F: Documentation/devicetree
5068F: drivers/of 5068F: drivers/of
5069F: include/linux/of*.h 5069F: include/linux/of*.h
5070F: scripts/dtc
5070K: of_get_property 5071K: of_get_property
5071K: of_match_table 5072K: of_match_table
5072 5073
diff --git a/drivers/of/address.c b/drivers/of/address.c
index 7e262a6124c5..72e496f1e9b0 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -9,8 +9,8 @@
9 9
10/* Max address size we deal with */ 10/* Max address size we deal with */
11#define OF_MAX_ADDR_CELLS 4 11#define OF_MAX_ADDR_CELLS 4
12#define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \ 12#define OF_CHECK_ADDR_COUNT(na) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS)
13 (ns) > 0) 13#define OF_CHECK_COUNTS(na, ns) (OF_CHECK_ADDR_COUNT(na) && (ns) > 0)
14 14
15static struct of_bus *of_match_bus(struct device_node *np); 15static struct of_bus *of_match_bus(struct device_node *np);
16static int __of_address_to_resource(struct device_node *dev, 16static int __of_address_to_resource(struct device_node *dev,
@@ -69,6 +69,14 @@ static u64 of_bus_default_map(u32 *addr, const __be32 *range,
69 (unsigned long long)cp, (unsigned long long)s, 69 (unsigned long long)cp, (unsigned long long)s,
70 (unsigned long long)da); 70 (unsigned long long)da);
71 71
72 /*
73 * If the number of address cells is larger than 2 we assume the
74 * mapping doesn't specify a physical address. Rather, the address
75 * specifies an identifier that must match exactly.
76 */
77 if (na > 2 && memcmp(range, addr, na * 4) != 0)
78 return OF_BAD_ADDR;
79
72 if (da < cp || da >= (cp + s)) 80 if (da < cp || da >= (cp + s))
73 return OF_BAD_ADDR; 81 return OF_BAD_ADDR;
74 return da - cp; 82 return da - cp;
@@ -182,7 +190,7 @@ const __be32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
182 } 190 }
183 bus->count_cells(dev, &na, &ns); 191 bus->count_cells(dev, &na, &ns);
184 of_node_put(parent); 192 of_node_put(parent);
185 if (!OF_CHECK_COUNTS(na, ns)) 193 if (!OF_CHECK_ADDR_COUNT(na))
186 return NULL; 194 return NULL;
187 195
188 /* Get "reg" or "assigned-addresses" property */ 196 /* Get "reg" or "assigned-addresses" property */
@@ -490,6 +498,25 @@ u64 of_translate_dma_address(struct device_node *dev, const __be32 *in_addr)
490} 498}
491EXPORT_SYMBOL(of_translate_dma_address); 499EXPORT_SYMBOL(of_translate_dma_address);
492 500
501bool of_can_translate_address(struct device_node *dev)
502{
503 struct device_node *parent;
504 struct of_bus *bus;
505 int na, ns;
506
507 parent = of_get_parent(dev);
508 if (parent == NULL)
509 return false;
510
511 bus = of_match_bus(parent);
512 bus->count_cells(dev, &na, &ns);
513
514 of_node_put(parent);
515
516 return OF_CHECK_COUNTS(na, ns);
517}
518EXPORT_SYMBOL(of_can_translate_address);
519
493const __be32 *of_get_address(struct device_node *dev, int index, u64 *size, 520const __be32 *of_get_address(struct device_node *dev, int index, u64 *size,
494 unsigned int *flags) 521 unsigned int *flags)
495{ 522{
@@ -506,7 +533,7 @@ const __be32 *of_get_address(struct device_node *dev, int index, u64 *size,
506 bus = of_match_bus(parent); 533 bus = of_match_bus(parent);
507 bus->count_cells(dev, &na, &ns); 534 bus->count_cells(dev, &na, &ns);
508 of_node_put(parent); 535 of_node_put(parent);
509 if (!OF_CHECK_COUNTS(na, ns)) 536 if (!OF_CHECK_ADDR_COUNT(na))
510 return NULL; 537 return NULL;
511 538
512 /* Get "reg" or "assigned-addresses" property */ 539 /* Get "reg" or "assigned-addresses" property */
diff --git a/drivers/of/base.c b/drivers/of/base.c
index d4a1c9a043e1..af3b22ac7627 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -391,6 +391,29 @@ struct device_node *of_get_next_available_child(const struct device_node *node,
391EXPORT_SYMBOL(of_get_next_available_child); 391EXPORT_SYMBOL(of_get_next_available_child);
392 392
393/** 393/**
394 * of_get_child_by_name - Find the child node by name for a given parent
395 * @node: parent node
396 * @name: child name to look for.
397 *
398 * This function looks for child node for given matching name
399 *
400 * Returns a node pointer if found, with refcount incremented, use
401 * of_node_put() on it when done.
402 * Returns NULL if node is not found.
403 */
404struct device_node *of_get_child_by_name(const struct device_node *node,
405 const char *name)
406{
407 struct device_node *child;
408
409 for_each_child_of_node(node, child)
410 if (child->name && (of_node_cmp(child->name, name) == 0))
411 break;
412 return child;
413}
414EXPORT_SYMBOL(of_get_child_by_name);
415
416/**
394 * of_find_node_by_path - Find a node matching a full OF path 417 * of_find_node_by_path - Find a node matching a full OF path
395 * @path: The full path to match 418 * @path: The full path to match
396 * 419 *
diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index ff8ab7b27373..a23ec7779997 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -392,6 +392,7 @@ int of_irq_to_resource_table(struct device_node *dev, struct resource *res,
392 392
393 return i; 393 return i;
394} 394}
395EXPORT_SYMBOL_GPL(of_irq_to_resource_table);
395 396
396struct intc_desc { 397struct intc_desc {
397 struct list_head list; 398 struct list_head list;
diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c
index 1e173f357674..3550f3bf4f92 100644
--- a/drivers/of/of_i2c.c
+++ b/drivers/of/of_i2c.c
@@ -61,6 +61,9 @@ void of_i2c_register_devices(struct i2c_adapter *adap)
61 info.of_node = of_node_get(node); 61 info.of_node = of_node_get(node);
62 info.archdata = &dev_ad; 62 info.archdata = &dev_ad;
63 63
64 if (of_get_property(node, "wakeup-source", NULL))
65 info.flags |= I2C_CLIENT_WAKE;
66
64 request_module("%s%s", I2C_MODULE_PREFIX, info.type); 67 request_module("%s%s", I2C_MODULE_PREFIX, info.type);
65 68
66 result = i2c_new_device(adap, &info); 69 result = i2c_new_device(adap, &info);
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index e44f8c2d239d..9bdeaf30b17d 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -78,6 +78,7 @@ void of_device_make_bus_id(struct device *dev)
78 struct device_node *node = dev->of_node; 78 struct device_node *node = dev->of_node;
79 const u32 *reg; 79 const u32 *reg;
80 u64 addr; 80 u64 addr;
81 const __be32 *addrp;
81 int magic; 82 int magic;
82 83
83#ifdef CONFIG_PPC_DCR 84#ifdef CONFIG_PPC_DCR
@@ -105,7 +106,15 @@ void of_device_make_bus_id(struct device *dev)
105 */ 106 */
106 reg = of_get_property(node, "reg", NULL); 107 reg = of_get_property(node, "reg", NULL);
107 if (reg) { 108 if (reg) {
108 addr = of_translate_address(node, reg); 109 if (of_can_translate_address(node)) {
110 addr = of_translate_address(node, reg);
111 } else {
112 addrp = of_get_address(node, 0, NULL, NULL);
113 if (addrp)
114 addr = of_read_number(addrp, 1);
115 else
116 addr = OF_BAD_ADDR;
117 }
109 if (addr != OF_BAD_ADDR) { 118 if (addr != OF_BAD_ADDR) {
110 dev_set_name(dev, "%llx.%s", 119 dev_set_name(dev, "%llx.%s",
111 (unsigned long long)addr, node->name); 120 (unsigned long long)addr, node->name);
@@ -140,8 +149,9 @@ struct platform_device *of_device_alloc(struct device_node *np,
140 return NULL; 149 return NULL;
141 150
142 /* count the io and irq resources */ 151 /* count the io and irq resources */
143 while (of_address_to_resource(np, num_reg, &temp_res) == 0) 152 if (of_can_translate_address(np))
144 num_reg++; 153 while (of_address_to_resource(np, num_reg, &temp_res) == 0)
154 num_reg++;
145 num_irq = of_irq_count(np); 155 num_irq = of_irq_count(np);
146 156
147 /* Populate the resource table */ 157 /* Populate the resource table */
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 1860c3aca7e2..1a81c90a4a71 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -835,9 +835,7 @@ static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata(
835 return ERR_PTR(-EINVAL); 835 return ERR_PTR(-EINVAL);
836 } 836 }
837 837
838 for_each_child_of_node(slave_np, data_np) 838 data_np = of_get_child_by_name(slave_np, "controller-data");
839 if (!strcmp(data_np->name, "controller-data"))
840 break;
841 if (!data_np) { 839 if (!data_np) {
842 dev_err(&spi->dev, "child node 'controller-data' not found\n"); 840 dev_err(&spi->dev, "child node 'controller-data' not found\n");
843 return ERR_PTR(-EINVAL); 841 return ERR_PTR(-EINVAL);
@@ -847,6 +845,7 @@ static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata(
847 if (!cs) { 845 if (!cs) {
848 dev_err(&spi->dev, "could not allocate memory for controller" 846 dev_err(&spi->dev, "could not allocate memory for controller"
849 " data\n"); 847 " data\n");
848 of_node_put(data_np);
850 return ERR_PTR(-ENOMEM); 849 return ERR_PTR(-ENOMEM);
851 } 850 }
852 851
@@ -855,11 +854,13 @@ static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata(
855 dev_err(&spi->dev, "chip select gpio is not specified or " 854 dev_err(&spi->dev, "chip select gpio is not specified or "
856 "invalid\n"); 855 "invalid\n");
857 kfree(cs); 856 kfree(cs);
857 of_node_put(data_np);
858 return ERR_PTR(-EINVAL); 858 return ERR_PTR(-EINVAL);
859 } 859 }
860 860
861 of_property_read_u32(data_np, "samsung,spi-feedback-delay", &fb_delay); 861 of_property_read_u32(data_np, "samsung,spi-feedback-delay", &fb_delay);
862 cs->fb_delay = fb_delay; 862 cs->fb_delay = fb_delay;
863 of_node_put(data_np);
863 return cs; 864 return cs;
864} 865}
865 866
diff --git a/include/linux/of.h b/include/linux/of.h
index 1b1163225f3b..f594c528842f 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -193,6 +193,8 @@ extern struct device_node *of_get_next_child(const struct device_node *node,
193extern struct device_node *of_get_next_available_child( 193extern struct device_node *of_get_next_available_child(
194 const struct device_node *node, struct device_node *prev); 194 const struct device_node *node, struct device_node *prev);
195 195
196extern struct device_node *of_get_child_by_name(const struct device_node *node,
197 const char *name);
196#define for_each_child_of_node(parent, child) \ 198#define for_each_child_of_node(parent, child) \
197 for (child = of_get_next_child(parent, NULL); child != NULL; \ 199 for (child = of_get_next_child(parent, NULL); child != NULL; \
198 child = of_get_next_child(parent, child)) 200 child = of_get_next_child(parent, child))
diff --git a/include/linux/of_address.h b/include/linux/of_address.h
index 01b925ad8d78..c3cdc1025c30 100644
--- a/include/linux/of_address.h
+++ b/include/linux/of_address.h
@@ -6,6 +6,7 @@
6 6
7#ifdef CONFIG_OF_ADDRESS 7#ifdef CONFIG_OF_ADDRESS
8extern u64 of_translate_address(struct device_node *np, const __be32 *addr); 8extern u64 of_translate_address(struct device_node *np, const __be32 *addr);
9extern bool of_can_translate_address(struct device_node *dev);
9extern int of_address_to_resource(struct device_node *dev, int index, 10extern int of_address_to_resource(struct device_node *dev, int index,
10 struct resource *r); 11 struct resource *r);
11extern struct device_node *of_find_matching_node_by_address( 12extern struct device_node *of_find_matching_node_by_address(
diff --git a/scripts/dtc/Makefile.dtc b/scripts/dtc/Makefile.dtc
index 6ddf9ecac669..bece49b35535 100644
--- a/scripts/dtc/Makefile.dtc
+++ b/scripts/dtc/Makefile.dtc
@@ -3,7 +3,16 @@
3# This is not a complete Makefile of itself. Instead, it is designed to 3# This is not a complete Makefile of itself. Instead, it is designed to
4# be easily embeddable into other systems of Makefiles. 4# be easily embeddable into other systems of Makefiles.
5# 5#
6DTC_SRCS = dtc.c flattree.c fstree.c data.c livetree.c treesource.c srcpos.c \ 6DTC_SRCS = \
7 checks.c 7 checks.c \
8 data.c \
9 dtc.c \
10 flattree.c \
11 fstree.c \
12 livetree.c \
13 srcpos.c \
14 treesource.c \
15 util.c
16
8DTC_GEN_SRCS = dtc-lexer.lex.c dtc-parser.tab.c 17DTC_GEN_SRCS = dtc-lexer.lex.c dtc-parser.tab.c
9DTC_OBJS = $(DTC_SRCS:%.c=%.o) $(DTC_GEN_SRCS:%.c=%.o) 18DTC_OBJS = $(DTC_SRCS:%.c=%.o) $(DTC_GEN_SRCS:%.c=%.o)
diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c
index a662a0044798..ee96a2519eff 100644
--- a/scripts/dtc/checks.c
+++ b/scripts/dtc/checks.c
@@ -31,12 +31,6 @@
31#define TRACE(c, fmt, ...) do { } while (0) 31#define TRACE(c, fmt, ...) do { } while (0)
32#endif 32#endif
33 33
34enum checklevel {
35 IGNORE = 0,
36 WARN = 1,
37 ERROR = 2,
38};
39
40enum checkstatus { 34enum checkstatus {
41 UNCHECKED = 0, 35 UNCHECKED = 0,
42 PREREQ, 36 PREREQ,
@@ -57,14 +51,14 @@ struct check {
57 node_check_fn node_fn; 51 node_check_fn node_fn;
58 prop_check_fn prop_fn; 52 prop_check_fn prop_fn;
59 void *data; 53 void *data;
60 enum checklevel level; 54 bool warn, error;
61 enum checkstatus status; 55 enum checkstatus status;
62 int inprogress; 56 int inprogress;
63 int num_prereqs; 57 int num_prereqs;
64 struct check **prereq; 58 struct check **prereq;
65}; 59};
66 60
67#define CHECK(nm, tfn, nfn, pfn, d, lvl, ...) \ 61#define CHECK_ENTRY(nm, tfn, nfn, pfn, d, w, e, ...) \
68 static struct check *nm##_prereqs[] = { __VA_ARGS__ }; \ 62 static struct check *nm##_prereqs[] = { __VA_ARGS__ }; \
69 static struct check nm = { \ 63 static struct check nm = { \
70 .name = #nm, \ 64 .name = #nm, \
@@ -72,20 +66,37 @@ struct check {
72 .node_fn = (nfn), \ 66 .node_fn = (nfn), \
73 .prop_fn = (pfn), \ 67 .prop_fn = (pfn), \
74 .data = (d), \ 68 .data = (d), \
75 .level = (lvl), \ 69 .warn = (w), \
70 .error = (e), \
76 .status = UNCHECKED, \ 71 .status = UNCHECKED, \
77 .num_prereqs = ARRAY_SIZE(nm##_prereqs), \ 72 .num_prereqs = ARRAY_SIZE(nm##_prereqs), \
78 .prereq = nm##_prereqs, \ 73 .prereq = nm##_prereqs, \
79 }; 74 };
80 75#define WARNING(nm, tfn, nfn, pfn, d, ...) \
81#define TREE_CHECK(nm, d, lvl, ...) \ 76 CHECK_ENTRY(nm, tfn, nfn, pfn, d, true, false, __VA_ARGS__)
82 CHECK(nm, check_##nm, NULL, NULL, d, lvl, __VA_ARGS__) 77#define ERROR(nm, tfn, nfn, pfn, d, ...) \
83#define NODE_CHECK(nm, d, lvl, ...) \ 78 CHECK_ENTRY(nm, tfn, nfn, pfn, d, false, true, __VA_ARGS__)
84 CHECK(nm, NULL, check_##nm, NULL, d, lvl, __VA_ARGS__) 79#define CHECK(nm, tfn, nfn, pfn, d, ...) \
85#define PROP_CHECK(nm, d, lvl, ...) \ 80 CHECK_ENTRY(nm, tfn, nfn, pfn, d, false, false, __VA_ARGS__)
86 CHECK(nm, NULL, NULL, check_##nm, d, lvl, __VA_ARGS__) 81
87#define BATCH_CHECK(nm, lvl, ...) \ 82#define TREE_WARNING(nm, d, ...) \
88 CHECK(nm, NULL, NULL, NULL, NULL, lvl, __VA_ARGS__) 83 WARNING(nm, check_##nm, NULL, NULL, d, __VA_ARGS__)
84#define TREE_ERROR(nm, d, ...) \
85 ERROR(nm, check_##nm, NULL, NULL, d, __VA_ARGS__)
86#define TREE_CHECK(nm, d, ...) \
87 CHECK(nm, check_##nm, NULL, NULL, d, __VA_ARGS__)
88#define NODE_WARNING(nm, d, ...) \
89 WARNING(nm, NULL, check_##nm, NULL, d, __VA_ARGS__)
90#define NODE_ERROR(nm, d, ...) \
91 ERROR(nm, NULL, check_##nm, NULL, d, __VA_ARGS__)
92#define NODE_CHECK(nm, d, ...) \
93 CHECK(nm, NULL, check_##nm, NULL, d, __VA_ARGS__)
94#define PROP_WARNING(nm, d, ...) \
95 WARNING(nm, NULL, NULL, check_##nm, d, __VA_ARGS__)
96#define PROP_ERROR(nm, d, ...) \
97 ERROR(nm, NULL, NULL, check_##nm, d, __VA_ARGS__)
98#define PROP_CHECK(nm, d, ...) \
99 CHECK(nm, NULL, NULL, check_##nm, d, __VA_ARGS__)
89 100
90#ifdef __GNUC__ 101#ifdef __GNUC__
91static inline void check_msg(struct check *c, const char *fmt, ...) __attribute__((format (printf, 2, 3))); 102static inline void check_msg(struct check *c, const char *fmt, ...) __attribute__((format (printf, 2, 3)));
@@ -95,13 +106,13 @@ static inline void check_msg(struct check *c, const char *fmt, ...)
95 va_list ap; 106 va_list ap;
96 va_start(ap, fmt); 107 va_start(ap, fmt);
97 108
98 if ((c->level < WARN) || (c->level <= quiet)) 109 if ((c->warn && (quiet < 1))
99 return; /* Suppress message */ 110 || (c->error && (quiet < 2))) {
100 111 fprintf(stderr, "%s (%s): ",
101 fprintf(stderr, "%s (%s): ", 112 (c->error) ? "ERROR" : "Warning", c->name);
102 (c->level == ERROR) ? "ERROR" : "Warning", c->name); 113 vfprintf(stderr, fmt, ap);
103 vfprintf(stderr, fmt, ap); 114 fprintf(stderr, "\n");
104 fprintf(stderr, "\n"); 115 }
105} 116}
106 117
107#define FAIL(c, ...) \ 118#define FAIL(c, ...) \
@@ -167,7 +178,7 @@ static int run_check(struct check *c, struct node *dt)
167 178
168out: 179out:
169 c->inprogress = 0; 180 c->inprogress = 0;
170 if ((c->status != PASSED) && (c->level == ERROR)) 181 if ((c->status != PASSED) && (c->error))
171 error = 1; 182 error = 1;
172 return error; 183 return error;
173} 184}
@@ -176,6 +187,13 @@ out:
176 * Utility check functions 187 * Utility check functions
177 */ 188 */
178 189
190/* A check which always fails, for testing purposes only */
191static inline void check_always_fail(struct check *c, struct node *dt)
192{
193 FAIL(c, "always_fail check");
194}
195TREE_CHECK(always_fail, NULL);
196
179static void check_is_string(struct check *c, struct node *root, 197static void check_is_string(struct check *c, struct node *root,
180 struct node *node) 198 struct node *node)
181{ 199{
@@ -190,8 +208,10 @@ static void check_is_string(struct check *c, struct node *root,
190 FAIL(c, "\"%s\" property in %s is not a string", 208 FAIL(c, "\"%s\" property in %s is not a string",
191 propname, node->fullpath); 209 propname, node->fullpath);
192} 210}
193#define CHECK_IS_STRING(nm, propname, lvl) \ 211#define WARNING_IF_NOT_STRING(nm, propname) \
194 CHECK(nm, NULL, check_is_string, NULL, (propname), (lvl)) 212 WARNING(nm, NULL, check_is_string, NULL, (propname))
213#define ERROR_IF_NOT_STRING(nm, propname) \
214 ERROR(nm, NULL, check_is_string, NULL, (propname))
195 215
196static void check_is_cell(struct check *c, struct node *root, 216static void check_is_cell(struct check *c, struct node *root,
197 struct node *node) 217 struct node *node)
@@ -207,8 +227,10 @@ static void check_is_cell(struct check *c, struct node *root,
207 FAIL(c, "\"%s\" property in %s is not a single cell", 227 FAIL(c, "\"%s\" property in %s is not a single cell",
208 propname, node->fullpath); 228 propname, node->fullpath);
209} 229}
210#define CHECK_IS_CELL(nm, propname, lvl) \ 230#define WARNING_IF_NOT_CELL(nm, propname) \
211 CHECK(nm, NULL, check_is_cell, NULL, (propname), (lvl)) 231 WARNING(nm, NULL, check_is_cell, NULL, (propname))
232#define ERROR_IF_NOT_CELL(nm, propname) \
233 ERROR(nm, NULL, check_is_cell, NULL, (propname))
212 234
213/* 235/*
214 * Structural check functions 236 * Structural check functions
@@ -227,20 +249,24 @@ static void check_duplicate_node_names(struct check *c, struct node *dt,
227 FAIL(c, "Duplicate node name %s", 249 FAIL(c, "Duplicate node name %s",
228 child->fullpath); 250 child->fullpath);
229} 251}
230NODE_CHECK(duplicate_node_names, NULL, ERROR); 252NODE_ERROR(duplicate_node_names, NULL);
231 253
232static void check_duplicate_property_names(struct check *c, struct node *dt, 254static void check_duplicate_property_names(struct check *c, struct node *dt,
233 struct node *node) 255 struct node *node)
234{ 256{
235 struct property *prop, *prop2; 257 struct property *prop, *prop2;
236 258
237 for_each_property(node, prop) 259 for_each_property(node, prop) {
238 for (prop2 = prop->next; prop2; prop2 = prop2->next) 260 for (prop2 = prop->next; prop2; prop2 = prop2->next) {
261 if (prop2->deleted)
262 continue;
239 if (streq(prop->name, prop2->name)) 263 if (streq(prop->name, prop2->name))
240 FAIL(c, "Duplicate property name %s in %s", 264 FAIL(c, "Duplicate property name %s in %s",
241 prop->name, node->fullpath); 265 prop->name, node->fullpath);
266 }
267 }
242} 268}
243NODE_CHECK(duplicate_property_names, NULL, ERROR); 269NODE_ERROR(duplicate_property_names, NULL);
244 270
245#define LOWERCASE "abcdefghijklmnopqrstuvwxyz" 271#define LOWERCASE "abcdefghijklmnopqrstuvwxyz"
246#define UPPERCASE "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 272#define UPPERCASE "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
@@ -256,7 +282,7 @@ static void check_node_name_chars(struct check *c, struct node *dt,
256 FAIL(c, "Bad character '%c' in node %s", 282 FAIL(c, "Bad character '%c' in node %s",
257 node->name[n], node->fullpath); 283 node->name[n], node->fullpath);
258} 284}
259NODE_CHECK(node_name_chars, PROPNODECHARS "@", ERROR); 285NODE_ERROR(node_name_chars, PROPNODECHARS "@");
260 286
261static void check_node_name_format(struct check *c, struct node *dt, 287static void check_node_name_format(struct check *c, struct node *dt,
262 struct node *node) 288 struct node *node)
@@ -265,7 +291,7 @@ static void check_node_name_format(struct check *c, struct node *dt,
265 FAIL(c, "Node %s has multiple '@' characters in name", 291 FAIL(c, "Node %s has multiple '@' characters in name",
266 node->fullpath); 292 node->fullpath);
267} 293}
268NODE_CHECK(node_name_format, NULL, ERROR, &node_name_chars); 294NODE_ERROR(node_name_format, NULL, &node_name_chars);
269 295
270static void check_property_name_chars(struct check *c, struct node *dt, 296static void check_property_name_chars(struct check *c, struct node *dt,
271 struct node *node, struct property *prop) 297 struct node *node, struct property *prop)
@@ -276,7 +302,7 @@ static void check_property_name_chars(struct check *c, struct node *dt,
276 FAIL(c, "Bad character '%c' in property name \"%s\", node %s", 302 FAIL(c, "Bad character '%c' in property name \"%s\", node %s",
277 prop->name[n], prop->name, node->fullpath); 303 prop->name[n], prop->name, node->fullpath);
278} 304}
279PROP_CHECK(property_name_chars, PROPNODECHARS, ERROR); 305PROP_ERROR(property_name_chars, PROPNODECHARS);
280 306
281#define DESCLABEL_FMT "%s%s%s%s%s" 307#define DESCLABEL_FMT "%s%s%s%s%s"
282#define DESCLABEL_ARGS(node,prop,mark) \ 308#define DESCLABEL_ARGS(node,prop,mark) \
@@ -331,8 +357,8 @@ static void check_duplicate_label_prop(struct check *c, struct node *dt,
331 for_each_marker_of_type(m, LABEL) 357 for_each_marker_of_type(m, LABEL)
332 check_duplicate_label(c, dt, m->ref, node, prop, m); 358 check_duplicate_label(c, dt, m->ref, node, prop, m);
333} 359}
334CHECK(duplicate_label, NULL, check_duplicate_label_node, 360ERROR(duplicate_label, NULL, check_duplicate_label_node,
335 check_duplicate_label_prop, NULL, ERROR); 361 check_duplicate_label_prop, NULL);
336 362
337static void check_explicit_phandles(struct check *c, struct node *root, 363static void check_explicit_phandles(struct check *c, struct node *root,
338 struct node *node, struct property *prop) 364 struct node *node, struct property *prop)
@@ -391,7 +417,7 @@ static void check_explicit_phandles(struct check *c, struct node *root,
391 417
392 node->phandle = phandle; 418 node->phandle = phandle;
393} 419}
394PROP_CHECK(explicit_phandles, NULL, ERROR); 420PROP_ERROR(explicit_phandles, NULL);
395 421
396static void check_name_properties(struct check *c, struct node *root, 422static void check_name_properties(struct check *c, struct node *root,
397 struct node *node) 423 struct node *node)
@@ -420,8 +446,8 @@ static void check_name_properties(struct check *c, struct node *root,
420 free(prop); 446 free(prop);
421 } 447 }
422} 448}
423CHECK_IS_STRING(name_is_string, "name", ERROR); 449ERROR_IF_NOT_STRING(name_is_string, "name");
424NODE_CHECK(name_properties, NULL, ERROR, &name_is_string); 450NODE_ERROR(name_properties, NULL, &name_is_string);
425 451
426/* 452/*
427 * Reference fixup functions 453 * Reference fixup functions
@@ -448,7 +474,7 @@ static void fixup_phandle_references(struct check *c, struct node *dt,
448 *((cell_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle); 474 *((cell_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle);
449 } 475 }
450} 476}
451CHECK(phandle_references, NULL, NULL, fixup_phandle_references, NULL, ERROR, 477ERROR(phandle_references, NULL, NULL, fixup_phandle_references, NULL,
452 &duplicate_node_names, &explicit_phandles); 478 &duplicate_node_names, &explicit_phandles);
453 479
454static void fixup_path_references(struct check *c, struct node *dt, 480static void fixup_path_references(struct check *c, struct node *dt,
@@ -473,19 +499,19 @@ static void fixup_path_references(struct check *c, struct node *dt,
473 strlen(path) + 1); 499 strlen(path) + 1);
474 } 500 }
475} 501}
476CHECK(path_references, NULL, NULL, fixup_path_references, NULL, ERROR, 502ERROR(path_references, NULL, NULL, fixup_path_references, NULL,
477 &duplicate_node_names); 503 &duplicate_node_names);
478 504
479/* 505/*
480 * Semantic checks 506 * Semantic checks
481 */ 507 */
482CHECK_IS_CELL(address_cells_is_cell, "#address-cells", WARN); 508WARNING_IF_NOT_CELL(address_cells_is_cell, "#address-cells");
483CHECK_IS_CELL(size_cells_is_cell, "#size-cells", WARN); 509WARNING_IF_NOT_CELL(size_cells_is_cell, "#size-cells");
484CHECK_IS_CELL(interrupt_cells_is_cell, "#interrupt-cells", WARN); 510WARNING_IF_NOT_CELL(interrupt_cells_is_cell, "#interrupt-cells");
485 511
486CHECK_IS_STRING(device_type_is_string, "device_type", WARN); 512WARNING_IF_NOT_STRING(device_type_is_string, "device_type");
487CHECK_IS_STRING(model_is_string, "model", WARN); 513WARNING_IF_NOT_STRING(model_is_string, "model");
488CHECK_IS_STRING(status_is_string, "status", WARN); 514WARNING_IF_NOT_STRING(status_is_string, "status");
489 515
490static void fixup_addr_size_cells(struct check *c, struct node *dt, 516static void fixup_addr_size_cells(struct check *c, struct node *dt,
491 struct node *node) 517 struct node *node)
@@ -503,8 +529,8 @@ static void fixup_addr_size_cells(struct check *c, struct node *dt,
503 if (prop) 529 if (prop)
504 node->size_cells = propval_cell(prop); 530 node->size_cells = propval_cell(prop);
505} 531}
506CHECK(addr_size_cells, NULL, fixup_addr_size_cells, NULL, NULL, WARN, 532WARNING(addr_size_cells, NULL, fixup_addr_size_cells, NULL, NULL,
507 &address_cells_is_cell, &size_cells_is_cell); 533 &address_cells_is_cell, &size_cells_is_cell);
508 534
509#define node_addr_cells(n) \ 535#define node_addr_cells(n) \
510 (((n)->addr_cells == -1) ? 2 : (n)->addr_cells) 536 (((n)->addr_cells == -1) ? 2 : (n)->addr_cells)
@@ -538,7 +564,7 @@ static void check_reg_format(struct check *c, struct node *dt,
538 "(#address-cells == %d, #size-cells == %d)", 564 "(#address-cells == %d, #size-cells == %d)",
539 node->fullpath, prop->val.len, addr_cells, size_cells); 565 node->fullpath, prop->val.len, addr_cells, size_cells);
540} 566}
541NODE_CHECK(reg_format, NULL, WARN, &addr_size_cells); 567NODE_WARNING(reg_format, NULL, &addr_size_cells);
542 568
543static void check_ranges_format(struct check *c, struct node *dt, 569static void check_ranges_format(struct check *c, struct node *dt,
544 struct node *node) 570 struct node *node)
@@ -579,7 +605,7 @@ static void check_ranges_format(struct check *c, struct node *dt,
579 p_addr_cells, c_addr_cells, c_size_cells); 605 p_addr_cells, c_addr_cells, c_size_cells);
580 } 606 }
581} 607}
582NODE_CHECK(ranges_format, NULL, WARN, &addr_size_cells); 608NODE_WARNING(ranges_format, NULL, &addr_size_cells);
583 609
584/* 610/*
585 * Style checks 611 * Style checks
@@ -606,7 +632,7 @@ static void check_avoid_default_addr_size(struct check *c, struct node *dt,
606 FAIL(c, "Relying on default #size-cells value for %s", 632 FAIL(c, "Relying on default #size-cells value for %s",
607 node->fullpath); 633 node->fullpath);
608} 634}
609NODE_CHECK(avoid_default_addr_size, NULL, WARN, &addr_size_cells); 635NODE_WARNING(avoid_default_addr_size, NULL, &addr_size_cells);
610 636
611static void check_obsolete_chosen_interrupt_controller(struct check *c, 637static void check_obsolete_chosen_interrupt_controller(struct check *c,
612 struct node *dt) 638 struct node *dt)
@@ -623,7 +649,7 @@ static void check_obsolete_chosen_interrupt_controller(struct check *c,
623 FAIL(c, "/chosen has obsolete \"interrupt-controller\" " 649 FAIL(c, "/chosen has obsolete \"interrupt-controller\" "
624 "property"); 650 "property");
625} 651}
626TREE_CHECK(obsolete_chosen_interrupt_controller, NULL, WARN); 652TREE_WARNING(obsolete_chosen_interrupt_controller, NULL);
627 653
628static struct check *check_table[] = { 654static struct check *check_table[] = {
629 &duplicate_node_names, &duplicate_property_names, 655 &duplicate_node_names, &duplicate_property_names,
@@ -642,8 +668,71 @@ static struct check *check_table[] = {
642 668
643 &avoid_default_addr_size, 669 &avoid_default_addr_size,
644 &obsolete_chosen_interrupt_controller, 670 &obsolete_chosen_interrupt_controller,
671
672 &always_fail,
645}; 673};
646 674
675static void enable_warning_error(struct check *c, bool warn, bool error)
676{
677 int i;
678
679 /* Raising level, also raise it for prereqs */
680 if ((warn && !c->warn) || (error && !c->error))
681 for (i = 0; i < c->num_prereqs; i++)
682 enable_warning_error(c->prereq[i], warn, error);
683
684 c->warn = c->warn || warn;
685 c->error = c->error || error;
686}
687
688static void disable_warning_error(struct check *c, bool warn, bool error)
689{
690 int i;
691
692 /* Lowering level, also lower it for things this is the prereq
693 * for */
694 if ((warn && c->warn) || (error && c->error)) {
695 for (i = 0; i < ARRAY_SIZE(check_table); i++) {
696 struct check *cc = check_table[i];
697 int j;
698
699 for (j = 0; j < cc->num_prereqs; j++)
700 if (cc->prereq[j] == c)
701 disable_warning_error(cc, warn, error);
702 }
703 }
704
705 c->warn = c->warn && !warn;
706 c->error = c->error && !error;
707}
708
709void parse_checks_option(bool warn, bool error, const char *optarg)
710{
711 int i;
712 const char *name = optarg;
713 bool enable = true;
714
715 if ((strncmp(optarg, "no-", 3) == 0)
716 || (strncmp(optarg, "no_", 3) == 0)) {
717 name = optarg + 3;
718 enable = false;
719 }
720
721 for (i = 0; i < ARRAY_SIZE(check_table); i++) {
722 struct check *c = check_table[i];
723
724 if (streq(c->name, name)) {
725 if (enable)
726 enable_warning_error(c, warn, error);
727 else
728 disable_warning_error(c, warn, error);
729 return;
730 }
731 }
732
733 die("Unrecognized check name \"%s\"\n", name);
734}
735
647void process_checks(int force, struct boot_info *bi) 736void process_checks(int force, struct boot_info *bi)
648{ 737{
649 struct node *dt = bi->dt; 738 struct node *dt = bi->dt;
@@ -653,7 +742,7 @@ void process_checks(int force, struct boot_info *bi)
653 for (i = 0; i < ARRAY_SIZE(check_table); i++) { 742 for (i = 0; i < ARRAY_SIZE(check_table); i++) {
654 struct check *c = check_table[i]; 743 struct check *c = check_table[i];
655 744
656 if (c->level != IGNORE) 745 if (c->warn || c->error)
657 error = error || run_check(c, dt); 746 error = error || run_check(c, dt);
658 } 747 }
659 748
diff --git a/scripts/dtc/data.c b/scripts/dtc/data.c
index fe555e819bf8..4a40c5b92474 100644
--- a/scripts/dtc/data.c
+++ b/scripts/dtc/data.c
@@ -68,40 +68,6 @@ struct data data_copy_mem(const char *mem, int len)
68 return d; 68 return d;
69} 69}
70 70
71static char get_oct_char(const char *s, int *i)
72{
73 char x[4];
74 char *endx;
75 long val;
76
77 x[3] = '\0';
78 strncpy(x, s + *i, 3);
79
80 val = strtol(x, &endx, 8);
81
82 assert(endx > x);
83
84 (*i) += endx - x;
85 return val;
86}
87
88static char get_hex_char(const char *s, int *i)
89{
90 char x[3];
91 char *endx;
92 long val;
93
94 x[2] = '\0';
95 strncpy(x, s + *i, 2);
96
97 val = strtol(x, &endx, 16);
98 if (!(endx > x))
99 die("\\x used with no following hex digits\n");
100
101 (*i) += endx - x;
102 return val;
103}
104
105struct data data_copy_escape_string(const char *s, int len) 71struct data data_copy_escape_string(const char *s, int len)
106{ 72{
107 int i = 0; 73 int i = 0;
@@ -114,53 +80,10 @@ struct data data_copy_escape_string(const char *s, int len)
114 while (i < len) { 80 while (i < len) {
115 char c = s[i++]; 81 char c = s[i++];
116 82
117 if (c != '\\') { 83 if (c == '\\')
118 q[d.len++] = c; 84 c = get_escape_char(s, &i);
119 continue; 85
120 } 86 q[d.len++] = c;
121
122 c = s[i++];
123 assert(c);
124 switch (c) {
125 case 'a':
126 q[d.len++] = '\a';
127 break;
128 case 'b':
129 q[d.len++] = '\b';
130 break;
131 case 't':
132 q[d.len++] = '\t';
133 break;
134 case 'n':
135 q[d.len++] = '\n';
136 break;
137 case 'v':
138 q[d.len++] = '\v';
139 break;
140 case 'f':
141 q[d.len++] = '\f';
142 break;
143 case 'r':
144 q[d.len++] = '\r';
145 break;
146 case '0':
147 case '1':
148 case '2':
149 case '3':
150 case '4':
151 case '5':
152 case '6':
153 case '7':
154 i--; /* need to re-read the first digit as
155 * part of the octal value */
156 q[d.len++] = get_oct_char(s, &i);
157 break;
158 case 'x':
159 q[d.len++] = get_hex_char(s, &i);
160 break;
161 default:
162 q[d.len++] = c;
163 }
164 } 87 }
165 88
166 q[d.len++] = '\0'; 89 q[d.len++] = '\0';
@@ -245,11 +168,33 @@ struct data data_merge(struct data d1, struct data d2)
245 return d; 168 return d;
246} 169}
247 170
248struct data data_append_cell(struct data d, cell_t word) 171struct data data_append_integer(struct data d, uint64_t value, int bits)
249{ 172{
250 cell_t beword = cpu_to_fdt32(word); 173 uint8_t value_8;
251 174 uint16_t value_16;
252 return data_append_data(d, &beword, sizeof(beword)); 175 uint32_t value_32;
176 uint64_t value_64;
177
178 switch (bits) {
179 case 8:
180 value_8 = value;
181 return data_append_data(d, &value_8, 1);
182
183 case 16:
184 value_16 = cpu_to_fdt16(value);
185 return data_append_data(d, &value_16, 2);
186
187 case 32:
188 value_32 = cpu_to_fdt32(value);
189 return data_append_data(d, &value_32, 4);
190
191 case 64:
192 value_64 = cpu_to_fdt64(value);
193 return data_append_data(d, &value_64, 8);
194
195 default:
196 die("Invalid literal size (%d)\n", bits);
197 }
253} 198}
254 199
255struct data data_append_re(struct data d, const struct fdt_reserve_entry *re) 200struct data data_append_re(struct data d, const struct fdt_reserve_entry *re)
@@ -262,11 +207,14 @@ struct data data_append_re(struct data d, const struct fdt_reserve_entry *re)
262 return data_append_data(d, &bere, sizeof(bere)); 207 return data_append_data(d, &bere, sizeof(bere));
263} 208}
264 209
265struct data data_append_addr(struct data d, uint64_t addr) 210struct data data_append_cell(struct data d, cell_t word)
266{ 211{
267 uint64_t beaddr = cpu_to_fdt64(addr); 212 return data_append_integer(d, word, sizeof(word) * 8);
213}
268 214
269 return data_append_data(d, &beaddr, sizeof(beaddr)); 215struct data data_append_addr(struct data d, uint64_t addr)
216{
217 return data_append_integer(d, addr, sizeof(addr) * 8);
270} 218}
271 219
272struct data data_append_byte(struct data d, uint8_t byte) 220struct data data_append_byte(struct data d, uint8_t byte)
diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l
index e866ea5166ac..254d5af88956 100644
--- a/scripts/dtc/dtc-lexer.l
+++ b/scripts/dtc/dtc-lexer.l
@@ -29,6 +29,7 @@ PROPNODECHAR [a-zA-Z0-9,._+*#?@-]
29PATHCHAR ({PROPNODECHAR}|[/]) 29PATHCHAR ({PROPNODECHAR}|[/])
30LABEL [a-zA-Z_][a-zA-Z0-9_]* 30LABEL [a-zA-Z_][a-zA-Z0-9_]*
31STRING \"([^\\"]|\\.)*\" 31STRING \"([^\\"]|\\.)*\"
32CHAR_LITERAL '([^']|\\')*'
32WS [[:space:]] 33WS [[:space:]]
33COMMENT "/*"([^*]|\*+[^*/])*\*+"/" 34COMMENT "/*"([^*]|\*+[^*/])*\*+"/"
34LINECOMMENT "//".*\n 35LINECOMMENT "//".*\n
@@ -70,6 +71,27 @@ static int pop_input_file(void);
70 push_input_file(name); 71 push_input_file(name);
71 } 72 }
72 73
74<*>^"#"(line)?{WS}+[0-9]+{WS}+{STRING}({WS}+[0-9]+)? {
75 char *line, *tmp, *fn;
76 /* skip text before line # */
77 line = yytext;
78 while (!isdigit(*line))
79 line++;
80 /* skip digits in line # */
81 tmp = line;
82 while (!isspace(*tmp))
83 tmp++;
84 /* "NULL"-terminate line # */
85 *tmp = '\0';
86 /* start of filename */
87 fn = strchr(tmp + 1, '"') + 1;
88 /* strip trailing " from filename */
89 tmp = strchr(fn, '"');
90 *tmp = 0;
91 /* -1 since #line is the number of the next line */
92 srcpos_set_line(xstrdup(fn), atoi(line) - 1);
93 }
94
73<*><<EOF>> { 95<*><<EOF>> {
74 if (!pop_input_file()) { 96 if (!pop_input_file()) {
75 yyterminate(); 97 yyterminate();
@@ -96,6 +118,26 @@ static int pop_input_file(void);
96 return DT_MEMRESERVE; 118 return DT_MEMRESERVE;
97 } 119 }
98 120
121<*>"/bits/" {
122 DPRINT("Keyword: /bits/\n");
123 BEGIN_DEFAULT();
124 return DT_BITS;
125 }
126
127<*>"/delete-property/" {
128 DPRINT("Keyword: /delete-property/\n");
129 DPRINT("<PROPNODENAME>\n");
130 BEGIN(PROPNODENAME);
131 return DT_DEL_PROP;
132 }
133
134<*>"/delete-node/" {
135 DPRINT("Keyword: /delete-node/\n");
136 DPRINT("<PROPNODENAME>\n");
137 BEGIN(PROPNODENAME);
138 return DT_DEL_NODE;
139 }
140
99<*>{LABEL}: { 141<*>{LABEL}: {
100 DPRINT("Label: %s\n", yytext); 142 DPRINT("Label: %s\n", yytext);
101 yylval.labelref = xstrdup(yytext); 143 yylval.labelref = xstrdup(yytext);
@@ -103,12 +145,19 @@ static int pop_input_file(void);
103 return DT_LABEL; 145 return DT_LABEL;
104 } 146 }
105 147
106<V1>[0-9]+|0[xX][0-9a-fA-F]+ { 148<V1>([0-9]+|0[xX][0-9a-fA-F]+)(U|L|UL|LL|ULL)? {
107 yylval.literal = xstrdup(yytext); 149 yylval.literal = xstrdup(yytext);
108 DPRINT("Literal: '%s'\n", yylval.literal); 150 DPRINT("Literal: '%s'\n", yylval.literal);
109 return DT_LITERAL; 151 return DT_LITERAL;
110 } 152 }
111 153
154<*>{CHAR_LITERAL} {
155 yytext[yyleng-1] = '\0';
156 yylval.literal = xstrdup(yytext+1);
157 DPRINT("Character literal: %s\n", yylval.literal);
158 return DT_CHAR_LITERAL;
159 }
160
112<*>\&{LABEL} { /* label reference */ 161<*>\&{LABEL} { /* label reference */
113 DPRINT("Ref: %s\n", yytext+1); 162 DPRINT("Ref: %s\n", yytext+1);
114 yylval.labelref = xstrdup(yytext+1); 163 yylval.labelref = xstrdup(yytext+1);
@@ -134,9 +183,10 @@ static int pop_input_file(void);
134 return ']'; 183 return ']';
135 } 184 }
136 185
137<PROPNODENAME>{PROPNODECHAR}+ { 186<PROPNODENAME>\\?{PROPNODECHAR}+ {
138 DPRINT("PropNodeName: %s\n", yytext); 187 DPRINT("PropNodeName: %s\n", yytext);
139 yylval.propnodename = xstrdup(yytext); 188 yylval.propnodename = xstrdup((yytext[0] == '\\') ?
189 yytext + 1 : yytext);
140 BEGIN_DEFAULT(); 190 BEGIN_DEFAULT();
141 return DT_PROPNODENAME; 191 return DT_PROPNODENAME;
142 } 192 }
@@ -150,6 +200,15 @@ static int pop_input_file(void);
150<*>{COMMENT}+ /* eat C-style comments */ 200<*>{COMMENT}+ /* eat C-style comments */
151<*>{LINECOMMENT}+ /* eat C++-style comments */ 201<*>{LINECOMMENT}+ /* eat C++-style comments */
152 202
203<*>"<<" { return DT_LSHIFT; };
204<*>">>" { return DT_RSHIFT; };
205<*>"<=" { return DT_LE; };
206<*>">=" { return DT_GE; };
207<*>"==" { return DT_EQ; };
208<*>"!=" { return DT_NE; };
209<*>"&&" { return DT_AND; };
210<*>"||" { return DT_OR; };
211
153<*>. { 212<*>. {
154 DPRINT("Char: %c (\\x%02x)\n", yytext[0], 213 DPRINT("Char: %c (\\x%02x)\n", yytext[0],
155 (unsigned)yytext[0]); 214 (unsigned)yytext[0]);
diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped
index 8bbe12817050..a6c5fcdfc032 100644
--- a/scripts/dtc/dtc-lexer.lex.c_shipped
+++ b/scripts/dtc/dtc-lexer.lex.c_shipped
@@ -1,5 +1,6 @@
1#line 2 "dtc-lexer.lex.c"
1 2
2#line 3 "scripts/dtc/dtc-lexer.lex.c_shipped" 3#line 4 "dtc-lexer.lex.c"
3 4
4#define YY_INT_ALIGNED short int 5#define YY_INT_ALIGNED short int
5 6
@@ -53,7 +54,6 @@ typedef int flex_int32_t;
53typedef unsigned char flex_uint8_t; 54typedef unsigned char flex_uint8_t;
54typedef unsigned short int flex_uint16_t; 55typedef unsigned short int flex_uint16_t;
55typedef unsigned int flex_uint32_t; 56typedef unsigned int flex_uint32_t;
56#endif /* ! C99 */
57 57
58/* Limits of integral types. */ 58/* Limits of integral types. */
59#ifndef INT8_MIN 59#ifndef INT8_MIN
@@ -84,6 +84,8 @@ typedef unsigned int flex_uint32_t;
84#define UINT32_MAX (4294967295U) 84#define UINT32_MAX (4294967295U)
85#endif 85#endif
86 86
87#endif /* ! C99 */
88
87#endif /* ! FLEXINT_H */ 89#endif /* ! FLEXINT_H */
88 90
89#ifdef __cplusplus 91#ifdef __cplusplus
@@ -140,7 +142,15 @@ typedef unsigned int flex_uint32_t;
140 142
141/* Size of default input buffer. */ 143/* Size of default input buffer. */
142#ifndef YY_BUF_SIZE 144#ifndef YY_BUF_SIZE
145#ifdef __ia64__
146/* On IA-64, the buffer size is 16k, not 8k.
147 * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
148 * Ditto for the __ia64__ case accordingly.
149 */
150#define YY_BUF_SIZE 32768
151#else
143#define YY_BUF_SIZE 16384 152#define YY_BUF_SIZE 16384
153#endif /* __ia64__ */
144#endif 154#endif
145 155
146/* The state buf must be large enough to hold one state per character in the main buffer. 156/* The state buf must be large enough to hold one state per character in the main buffer.
@@ -362,8 +372,8 @@ static void yy_fatal_error (yyconst char msg[] );
362 *yy_cp = '\0'; \ 372 *yy_cp = '\0'; \
363 (yy_c_buf_p) = yy_cp; 373 (yy_c_buf_p) = yy_cp;
364 374
365#define YY_NUM_RULES 17 375#define YY_NUM_RULES 30
366#define YY_END_OF_BUFFER 18 376#define YY_END_OF_BUFFER 31
367/* This struct is not used in this scanner, 377/* This struct is not used in this scanner,
368 but its presence is necessary. */ 378 but its presence is necessary. */
369struct yy_trans_info 379struct yy_trans_info
@@ -371,19 +381,25 @@ struct yy_trans_info
371 flex_int32_t yy_verify; 381 flex_int32_t yy_verify;
372 flex_int32_t yy_nxt; 382 flex_int32_t yy_nxt;
373 }; 383 };
374static yyconst flex_int16_t yy_accept[94] = 384static yyconst flex_int16_t yy_accept[161] =
375 { 0, 385 { 0,
376 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 386 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
377 18, 16, 13, 13, 16, 16, 16, 16, 16, 16, 387 31, 29, 18, 18, 29, 29, 29, 29, 29, 29,
378 16, 10, 11, 11, 6, 6, 13, 0, 2, 0, 388 29, 29, 29, 29, 29, 29, 29, 29, 15, 16,
379 7, 0, 0, 0, 0, 0, 0, 0, 5, 0, 389 16, 29, 16, 10, 10, 18, 26, 0, 3, 0,
380 9, 9, 11, 11, 6, 0, 7, 0, 0, 0, 390 27, 12, 0, 0, 11, 0, 0, 0, 0, 0,
381 0, 15, 0, 0, 0, 0, 6, 0, 14, 0, 391 0, 0, 21, 23, 25, 24, 22, 0, 9, 28,
382 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 392 0, 0, 0, 14, 14, 16, 16, 16, 10, 10,
383 0, 0, 0, 0, 0, 0, 0, 0, 3, 12, 393 10, 0, 12, 0, 11, 0, 0, 0, 20, 0,
384 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 394 0, 0, 0, 0, 0, 0, 0, 16, 10, 10,
385 0, 4, 0 395 10, 0, 19, 0, 0, 0, 0, 0, 0, 0,
386 396
397 0, 0, 16, 13, 0, 0, 0, 0, 0, 0,
398 0, 0, 0, 16, 6, 0, 0, 0, 0, 0,
399 0, 2, 0, 0, 0, 0, 0, 0, 0, 0,
400 4, 17, 0, 0, 2, 0, 0, 0, 0, 0,
401 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
402 0, 0, 5, 8, 0, 0, 0, 0, 7, 0
387 } ; 403 } ;
388 404
389static yyconst flex_int32_t yy_ec[256] = 405static yyconst flex_int32_t yy_ec[256] =
@@ -391,17 +407,17 @@ static yyconst flex_int32_t yy_ec[256] =
391 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 407 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
392 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 408 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
393 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 409 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
394 1, 2, 1, 4, 5, 1, 1, 6, 1, 1, 410 1, 2, 4, 5, 6, 1, 1, 7, 8, 1,
395 1, 7, 5, 5, 8, 5, 9, 10, 11, 12, 411 1, 9, 10, 10, 11, 10, 12, 13, 14, 15,
396 12, 12, 12, 12, 12, 12, 12, 13, 1, 1, 412 15, 15, 15, 15, 15, 15, 15, 16, 1, 17,
397 1, 1, 5, 5, 14, 14, 14, 14, 14, 14, 413 18, 19, 10, 10, 20, 20, 20, 20, 20, 20,
398 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 414 21, 21, 21, 21, 21, 22, 21, 21, 21, 21,
399 15, 15, 15, 15, 15, 15, 15, 16, 15, 15, 415 21, 21, 21, 21, 23, 21, 21, 24, 21, 21,
400 1, 17, 18, 1, 15, 1, 14, 19, 20, 21, 416 1, 25, 26, 1, 21, 1, 20, 27, 28, 29,
401 417
402 22, 14, 15, 15, 23, 15, 15, 24, 25, 26, 418 30, 20, 21, 21, 31, 21, 21, 32, 33, 34,
403 15, 15, 15, 27, 28, 29, 30, 31, 15, 16, 419 35, 36, 21, 37, 38, 39, 40, 41, 21, 24,
404 15, 15, 32, 1, 33, 1, 1, 1, 1, 1, 420 42, 21, 43, 44, 45, 1, 1, 1, 1, 1,
405 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 421 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
406 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 422 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
407 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 423 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -418,112 +434,163 @@ static yyconst flex_int32_t yy_ec[256] =
418 1, 1, 1, 1, 1 434 1, 1, 1, 1, 1
419 } ; 435 } ;
420 436
421static yyconst flex_int32_t yy_meta[34] = 437static yyconst flex_int32_t yy_meta[46] =
422 { 0, 438 { 0,
423 1, 1, 1, 1, 2, 1, 2, 2, 3, 4, 439 1, 1, 1, 1, 1, 2, 3, 1, 2, 2,
424 4, 4, 5, 6, 7, 7, 1, 1, 6, 6, 440 2, 4, 5, 5, 5, 6, 1, 1, 1, 7,
425 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 441 8, 8, 8, 8, 1, 1, 7, 7, 7, 7,
426 7, 8, 1 442 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
443 8, 8, 3, 1, 1
427 } ; 444 } ;
428 445
429static yyconst flex_int16_t yy_base[106] = 446static yyconst flex_int16_t yy_base[175] =
430 { 0, 447 { 0,
431 0, 0, 237, 236, 25, 0, 47, 0, 30, 71, 448 0, 388, 381, 40, 41, 386, 71, 385, 34, 44,
432 244, 247, 82, 84, 84, 211, 95, 229, 218, 0, 449 390, 395, 60, 62, 371, 112, 111, 111, 111, 104,
433 111, 247, 0, 84, 83, 95, 106, 86, 247, 237, 450 370, 106, 371, 342, 124, 119, 0, 144, 395, 0,
434 0, 230, 231, 234, 207, 209, 212, 220, 247, 206, 451 123, 0, 159, 153, 165, 167, 395, 130, 395, 382,
435 247, 218, 0, 106, 116, 0, 0, 0, 223, 89, 452 395, 0, 372, 122, 395, 157, 374, 379, 350, 21,
436 226, 219, 199, 206, 200, 204, 0, 190, 213, 212, 453 346, 349, 395, 395, 395, 395, 395, 362, 395, 395,
437 202, 91, 178, 161, 247, 172, 144, 150, 140, 130, 454 181, 346, 342, 395, 359, 0, 191, 343, 190, 351,
438 140, 124, 128, 120, 138, 137, 123, 122, 247, 247, 455 350, 0, 0, 0, 173, 362, 177, 367, 357, 329,
439 134, 114, 132, 86, 135, 125, 90, 136, 247, 97, 456 335, 328, 337, 331, 206, 329, 334, 327, 395, 338,
440 29, 247, 247, 153, 156, 161, 165, 170, 176, 180, 457 170, 314, 346, 345, 318, 325, 343, 158, 316, 212,
441 458
442 187, 195, 200, 205, 212 459 322, 319, 320, 395, 340, 336, 308, 305, 314, 304,
460 295, 138, 208, 220, 395, 292, 305, 265, 264, 254,
461 201, 222, 285, 275, 273, 270, 236, 235, 225, 115,
462 395, 395, 252, 216, 216, 217, 214, 230, 209, 220,
463 213, 239, 211, 217, 216, 209, 229, 395, 240, 225,
464 206, 169, 395, 395, 116, 106, 99, 54, 395, 395,
465 254, 260, 268, 272, 276, 282, 289, 293, 301, 309,
466 313, 319, 327, 335
443 } ; 467 } ;
444 468
445static yyconst flex_int16_t yy_def[106] = 469static yyconst flex_int16_t yy_def[175] =
446 { 0, 470 { 0,
447 93, 1, 1, 1, 1, 5, 93, 7, 1, 1, 471 160, 1, 1, 1, 1, 5, 160, 7, 1, 1,
448 93, 93, 93, 93, 94, 95, 93, 96, 17, 97, 472 160, 160, 160, 160, 160, 161, 162, 163, 160, 160,
449 96, 93, 98, 99, 93, 93, 93, 94, 93, 94, 473 160, 160, 164, 160, 160, 160, 165, 164, 160, 166,
450 100, 93, 101, 102, 93, 93, 93, 96, 93, 93, 474 167, 166, 166, 160, 160, 160, 160, 161, 160, 161,
451 93, 96, 98, 99, 93, 103, 100, 104, 101, 101, 475 160, 168, 160, 163, 160, 163, 169, 170, 160, 160,
452 102, 93, 93, 93, 93, 93, 103, 104, 93, 93, 476 160, 160, 160, 160, 160, 160, 160, 164, 160, 160,
453 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 477 160, 160, 160, 160, 164, 166, 167, 166, 160, 160,
454 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 478 160, 171, 168, 172, 163, 169, 169, 170, 160, 160,
455 93, 93, 93, 93, 93, 105, 93, 105, 93, 105, 479 160, 160, 160, 160, 160, 160, 160, 166, 160, 160,
456 93, 93, 0, 93, 93, 93, 93, 93, 93, 93, 480 171, 172, 160, 160, 160, 160, 160, 160, 160, 160,
457 481
458 93, 93, 93, 93, 93 482 160, 160, 166, 160, 160, 160, 160, 160, 160, 160,
483 160, 173, 160, 166, 160, 160, 160, 160, 160, 160,
484 173, 160, 173, 160, 160, 160, 160, 160, 160, 160,
485 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
486 160, 160, 174, 160, 160, 160, 174, 160, 174, 160,
487 160, 160, 160, 160, 160, 160, 160, 160, 160, 0,
488 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
489 160, 160, 160, 160
459 } ; 490 } ;
460 491
461static yyconst flex_int16_t yy_nxt[281] = 492static yyconst flex_int16_t yy_nxt[441] =
462 { 0, 493 { 0,
463 12, 13, 14, 15, 12, 16, 12, 12, 17, 12, 494 12, 13, 14, 15, 16, 12, 17, 18, 12, 12,
464 12, 12, 12, 18, 18, 18, 12, 12, 18, 18, 495 12, 19, 12, 12, 12, 12, 20, 21, 22, 23,
465 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 496 23, 23, 23, 23, 12, 12, 23, 23, 23, 23,
466 18, 12, 12, 19, 20, 20, 20, 92, 21, 25, 497 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
467 26, 26, 22, 21, 21, 21, 21, 12, 13, 14, 498 23, 23, 12, 24, 12, 25, 34, 35, 35, 25,
468 15, 23, 16, 23, 23, 19, 23, 23, 23, 12, 499 81, 26, 26, 27, 27, 27, 34, 35, 35, 82,
469 24, 24, 24, 12, 12, 24, 24, 24, 24, 24, 500 28, 36, 36, 36, 36, 159, 29, 28, 28, 28,
470 24, 24, 24, 24, 24, 24, 24, 24, 12, 12, 501 28, 12, 13, 14, 15, 16, 30, 17, 18, 30,
471 25, 26, 26, 27, 27, 27, 27, 29, 43, 29, 502 30, 30, 26, 30, 30, 30, 12, 20, 21, 22,
472 43, 43, 45, 45, 45, 50, 39, 59, 46, 93, 503 31, 31, 31, 31, 31, 32, 12, 31, 31, 31,
473 504
474 30, 33, 30, 34, 45, 45, 45, 27, 27, 68, 505 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
475 43, 91, 43, 43, 69, 35, 87, 36, 39, 37, 506 31, 31, 31, 12, 24, 12, 39, 41, 45, 47,
476 42, 42, 42, 39, 42, 45, 45, 45, 89, 42, 507 53, 54, 48, 56, 57, 61, 61, 47, 66, 45,
477 42, 42, 42, 85, 85, 86, 85, 85, 86, 89, 508 48, 66, 66, 66, 39, 46, 40, 49, 59, 50,
478 84, 90, 83, 82, 81, 80, 79, 78, 77, 76, 509 158, 51, 122, 52, 157, 49, 46, 50, 136, 63,
479 75, 74, 90, 28, 28, 28, 28, 28, 28, 28, 510 137, 52, 156, 43, 40, 62, 65, 65, 65, 59,
480 28, 31, 31, 31, 38, 38, 38, 38, 41, 73, 511 61, 61, 123, 65, 75, 69, 69, 69, 36, 36,
481 41, 43, 72, 43, 71, 43, 43, 44, 33, 44, 512 65, 65, 65, 65, 70, 71, 72, 69, 69, 69,
482 44, 44, 44, 47, 69, 47, 47, 49, 49, 49, 513 45, 46, 61, 61, 109, 77, 70, 71, 93, 110,
483 49, 49, 49, 49, 49, 51, 51, 51, 51, 51, 514 68, 70, 71, 85, 85, 85, 66, 46, 155, 66,
484 515
485 51, 51, 51, 57, 70, 57, 58, 58, 58, 67, 516 66, 66, 69, 69, 69, 122, 59, 100, 100, 61,
486 58, 58, 88, 88, 88, 88, 88, 88, 88, 88, 517 61, 70, 71, 100, 100, 148, 112, 154, 85, 85,
487 34, 66, 65, 64, 63, 62, 61, 60, 52, 50, 518 85, 61, 61, 129, 129, 123, 129, 129, 135, 135,
488 39, 56, 39, 55, 54, 53, 52, 50, 48, 93, 519 135, 142, 142, 148, 143, 149, 153, 135, 135, 135,
489 40, 39, 32, 93, 19, 19, 11, 93, 93, 93, 520 142, 142, 160, 143, 152, 151, 150, 146, 145, 144,
490 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 521 141, 140, 139, 149, 38, 38, 38, 38, 38, 38,
491 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 522 38, 38, 42, 138, 134, 133, 42, 42, 44, 44,
492 93, 93, 93, 93, 93, 93, 93, 93, 93, 93 523 44, 44, 44, 44, 44, 44, 58, 58, 58, 58,
524 64, 132, 64, 66, 131, 130, 66, 160, 66, 66,
525 67, 128, 127, 67, 67, 67, 67, 73, 126, 73,
526
527 73, 76, 76, 76, 76, 76, 76, 76, 76, 78,
528 78, 78, 78, 78, 78, 78, 78, 91, 125, 91,
529 92, 124, 92, 92, 120, 92, 92, 121, 121, 121,
530 121, 121, 121, 121, 121, 147, 147, 147, 147, 147,
531 147, 147, 147, 119, 118, 117, 116, 115, 47, 114,
532 110, 113, 111, 108, 107, 106, 48, 105, 104, 89,
533 103, 102, 101, 99, 98, 97, 96, 95, 94, 79,
534 77, 90, 89, 88, 59, 87, 86, 59, 84, 83,
535 80, 79, 77, 74, 160, 60, 59, 55, 37, 160,
536 33, 25, 26, 25, 11, 160, 160, 160, 160, 160,
537
538 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
539 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
540 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
541 160, 160, 160, 160, 160, 160, 160, 160, 160, 160
493 } ; 542 } ;
494 543
495static yyconst flex_int16_t yy_chk[281] = 544static yyconst flex_int16_t yy_chk[441] =
496 { 0, 545 { 0,
497 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 546 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
498 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 547 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
499 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 548 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
500 1, 1, 1, 5, 5, 5, 5, 91, 5, 9, 549 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
501 9, 9, 5, 5, 5, 5, 5, 7, 7, 7, 550 1, 1, 1, 1, 1, 4, 9, 9, 9, 10,
551 50, 4, 5, 5, 5, 5, 10, 10, 10, 50,
552 5, 13, 13, 14, 14, 158, 5, 5, 5, 5,
553 5, 7, 7, 7, 7, 7, 7, 7, 7, 7,
502 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 554 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
503 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 555 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
556
504 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 557 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
505 10, 10, 10, 13, 13, 14, 14, 15, 24, 28, 558 7, 7, 7, 7, 7, 7, 16, 17, 18, 19,
506 24, 24, 25, 25, 25, 50, 24, 50, 25, 90, 559 20, 20, 19, 22, 22, 25, 25, 26, 31, 44,
507 560 26, 31, 31, 31, 38, 18, 16, 19, 31, 19,
508 15, 17, 28, 17, 26, 26, 26, 27, 27, 62, 561 157, 19, 112, 19, 156, 26, 44, 26, 130, 26,
509 44, 87, 44, 44, 62, 17, 84, 17, 44, 17, 562 130, 26, 155, 17, 38, 25, 28, 28, 28, 28,
510 21, 21, 21, 21, 21, 45, 45, 45, 86, 21, 563 33, 33, 112, 28, 46, 34, 34, 34, 36, 36,
511 21, 21, 21, 83, 83, 83, 85, 85, 85, 88, 564 28, 28, 28, 28, 34, 34, 34, 35, 35, 35,
512 82, 86, 81, 78, 77, 76, 75, 74, 73, 72, 565 75, 46, 61, 61, 98, 77, 35, 35, 77, 98,
513 71, 70, 88, 94, 94, 94, 94, 94, 94, 94, 566 33, 91, 91, 61, 61, 61, 67, 75, 152, 67,
514 94, 95, 95, 95, 96, 96, 96, 96, 97, 69, 567
515 97, 98, 68, 98, 67, 98, 98, 99, 66, 99, 568 67, 67, 69, 69, 69, 121, 67, 85, 85, 113,
516 99, 99, 99, 100, 64, 100, 100, 101, 101, 101, 569 113, 69, 69, 100, 100, 143, 100, 151, 85, 85,
517 101, 101, 101, 101, 101, 102, 102, 102, 102, 102, 570 85, 114, 114, 122, 122, 121, 129, 129, 135, 135,
518 571 135, 138, 138, 147, 138, 143, 150, 129, 129, 129,
519 102, 102, 102, 103, 63, 103, 104, 104, 104, 61, 572 142, 142, 149, 142, 146, 145, 144, 141, 140, 139,
520 104, 104, 105, 105, 105, 105, 105, 105, 105, 105, 573 137, 136, 134, 147, 161, 161, 161, 161, 161, 161,
521 60, 59, 58, 56, 55, 54, 53, 52, 51, 49, 574 161, 161, 162, 133, 128, 127, 162, 162, 163, 163,
522 42, 40, 38, 37, 36, 35, 34, 33, 32, 30, 575 163, 163, 163, 163, 163, 163, 164, 164, 164, 164,
523 19, 18, 16, 11, 4, 3, 93, 93, 93, 93, 576 165, 126, 165, 166, 125, 124, 166, 123, 166, 166,
524 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 577 167, 120, 119, 167, 167, 167, 167, 168, 118, 168,
525 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 578
526 93, 93, 93, 93, 93, 93, 93, 93, 93, 93 579 168, 169, 169, 169, 169, 169, 169, 169, 169, 170,
580 170, 170, 170, 170, 170, 170, 170, 171, 117, 171,
581 172, 116, 172, 172, 111, 172, 172, 173, 173, 173,
582 173, 173, 173, 173, 173, 174, 174, 174, 174, 174,
583 174, 174, 174, 110, 109, 108, 107, 106, 105, 103,
584 102, 101, 99, 97, 96, 95, 94, 93, 92, 90,
585 88, 87, 86, 84, 83, 82, 81, 80, 79, 78,
586 76, 71, 70, 68, 65, 63, 62, 58, 52, 51,
587 49, 48, 47, 43, 40, 24, 23, 21, 15, 11,
588 8, 6, 3, 2, 160, 160, 160, 160, 160, 160,
589
590 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
591 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
592 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
593 160, 160, 160, 160, 160, 160, 160, 160, 160, 160
527 } ; 594 } ;
528 595
529static yy_state_type yy_last_accepting_state; 596static yy_state_type yy_last_accepting_state;
@@ -540,6 +607,7 @@ int yy_flex_debug = 0;
540#define YY_MORE_ADJ 0 607#define YY_MORE_ADJ 0
541#define YY_RESTORE_YY_MORE_OFFSET 608#define YY_RESTORE_YY_MORE_OFFSET
542char *yytext; 609char *yytext;
610#line 1 "dtc-lexer.l"
543/* 611/*
544 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005. 612 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
545 * 613 *
@@ -561,6 +629,10 @@ char *yytext;
561 */ 629 */
562#define YY_NO_INPUT 1 630#define YY_NO_INPUT 1
563 631
632
633
634
635#line 38 "dtc-lexer.l"
564#include "dtc.h" 636#include "dtc.h"
565#include "srcpos.h" 637#include "srcpos.h"
566#include "dtc-parser.tab.h" 638#include "dtc-parser.tab.h"
@@ -588,6 +660,7 @@ static int dts_version = 1;
588 660
589static void push_input_file(const char *filename); 661static void push_input_file(const char *filename);
590static int pop_input_file(void); 662static int pop_input_file(void);
663#line 664 "dtc-lexer.lex.c"
591 664
592#define INITIAL 0 665#define INITIAL 0
593#define INCLUDE 1 666#define INCLUDE 1
@@ -670,7 +743,12 @@ static int input (void );
670 743
671/* Amount of stuff to slurp up with each read. */ 744/* Amount of stuff to slurp up with each read. */
672#ifndef YY_READ_BUF_SIZE 745#ifndef YY_READ_BUF_SIZE
746#ifdef __ia64__
747/* On IA-64, the buffer size is 16k, not 8k */
748#define YY_READ_BUF_SIZE 16384
749#else
673#define YY_READ_BUF_SIZE 8192 750#define YY_READ_BUF_SIZE 8192
751#endif /* __ia64__ */
674#endif 752#endif
675 753
676/* Copy whatever the last rule matched to the standard output. */ 754/* Copy whatever the last rule matched to the standard output. */
@@ -689,7 +767,7 @@ static int input (void );
689 if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ 767 if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
690 { \ 768 { \
691 int c = '*'; \ 769 int c = '*'; \
692 unsigned n; \ 770 size_t n; \
693 for ( n = 0; n < max_size && \ 771 for ( n = 0; n < max_size && \
694 (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ 772 (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
695 buf[n] = (char) c; \ 773 buf[n] = (char) c; \
@@ -761,6 +839,9 @@ extern int yylex (void);
761#endif 839#endif
762 840
763#define YY_RULE_SETUP \ 841#define YY_RULE_SETUP \
842 if ( yyleng > 0 ) \
843 YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \
844 (yytext[yyleng - 1] == '\n'); \
764 YY_USER_ACTION 845 YY_USER_ACTION
765 846
766/** The main scanner function which does all the work. 847/** The main scanner function which does all the work.
@@ -771,6 +852,10 @@ YY_DECL
771 register char *yy_cp, *yy_bp; 852 register char *yy_cp, *yy_bp;
772 register int yy_act; 853 register int yy_act;
773 854
855#line 67 "dtc-lexer.l"
856
857#line 858 "dtc-lexer.lex.c"
858
774 if ( !(yy_init) ) 859 if ( !(yy_init) )
775 { 860 {
776 (yy_init) = 1; 861 (yy_init) = 1;
@@ -810,6 +895,7 @@ YY_DECL
810 yy_bp = yy_cp; 895 yy_bp = yy_cp;
811 896
812 yy_current_state = (yy_start); 897 yy_current_state = (yy_start);
898 yy_current_state += YY_AT_BOL();
813yy_match: 899yy_match:
814 do 900 do
815 { 901 {
@@ -822,13 +908,13 @@ yy_match:
822 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) 908 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
823 { 909 {
824 yy_current_state = (int) yy_def[yy_current_state]; 910 yy_current_state = (int) yy_def[yy_current_state];
825 if ( yy_current_state >= 94 ) 911 if ( yy_current_state >= 161 )
826 yy_c = yy_meta[(unsigned int) yy_c]; 912 yy_c = yy_meta[(unsigned int) yy_c];
827 } 913 }
828 yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; 914 yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
829 ++yy_cp; 915 ++yy_cp;
830 } 916 }
831 while ( yy_current_state != 93 ); 917 while ( yy_current_state != 160 );
832 yy_cp = (yy_last_accepting_cpos); 918 yy_cp = (yy_last_accepting_cpos);
833 yy_current_state = (yy_last_accepting_state); 919 yy_current_state = (yy_last_accepting_state);
834 920
@@ -851,26 +937,54 @@ do_action: /* This label is used only to access EOF actions. */
851case 1: 937case 1:
852/* rule 1 can match eol */ 938/* rule 1 can match eol */
853YY_RULE_SETUP 939YY_RULE_SETUP
940#line 68 "dtc-lexer.l"
854{ 941{
855 char *name = strchr(yytext, '\"') + 1; 942 char *name = strchr(yytext, '\"') + 1;
856 yytext[yyleng-1] = '\0'; 943 yytext[yyleng-1] = '\0';
857 push_input_file(name); 944 push_input_file(name);
858 } 945 }
859 YY_BREAK 946 YY_BREAK
947case 2:
948/* rule 2 can match eol */
949YY_RULE_SETUP
950#line 74 "dtc-lexer.l"
951{
952 char *line, *tmp, *fn;
953 /* skip text before line # */
954 line = yytext;
955 while (!isdigit(*line))
956 line++;
957 /* skip digits in line # */
958 tmp = line;
959 while (!isspace(*tmp))
960 tmp++;
961 /* "NULL"-terminate line # */
962 *tmp = '\0';
963 /* start of filename */
964 fn = strchr(tmp + 1, '"') + 1;
965 /* strip trailing " from filename */
966 tmp = strchr(fn, '"');
967 *tmp = 0;
968 /* -1 since #line is the number of the next line */
969 srcpos_set_line(xstrdup(fn), atoi(line) - 1);
970 }
971 YY_BREAK
860case YY_STATE_EOF(INITIAL): 972case YY_STATE_EOF(INITIAL):
861case YY_STATE_EOF(INCLUDE): 973case YY_STATE_EOF(INCLUDE):
862case YY_STATE_EOF(BYTESTRING): 974case YY_STATE_EOF(BYTESTRING):
863case YY_STATE_EOF(PROPNODENAME): 975case YY_STATE_EOF(PROPNODENAME):
864case YY_STATE_EOF(V1): 976case YY_STATE_EOF(V1):
977#line 95 "dtc-lexer.l"
865{ 978{
866 if (!pop_input_file()) { 979 if (!pop_input_file()) {
867 yyterminate(); 980 yyterminate();
868 } 981 }
869 } 982 }
870 YY_BREAK 983 YY_BREAK
871case 2: 984case 3:
872/* rule 2 can match eol */ 985/* rule 3 can match eol */
873YY_RULE_SETUP 986YY_RULE_SETUP
987#line 101 "dtc-lexer.l"
874{ 988{
875 DPRINT("String: %s\n", yytext); 989 DPRINT("String: %s\n", yytext);
876 yylval.data = data_copy_escape_string(yytext+1, 990 yylval.data = data_copy_escape_string(yytext+1,
@@ -878,8 +992,9 @@ YY_RULE_SETUP
878 return DT_STRING; 992 return DT_STRING;
879 } 993 }
880 YY_BREAK 994 YY_BREAK
881case 3: 995case 4:
882YY_RULE_SETUP 996YY_RULE_SETUP
997#line 108 "dtc-lexer.l"
883{ 998{
884 DPRINT("Keyword: /dts-v1/\n"); 999 DPRINT("Keyword: /dts-v1/\n");
885 dts_version = 1; 1000 dts_version = 1;
@@ -887,16 +1002,47 @@ YY_RULE_SETUP
887 return DT_V1; 1002 return DT_V1;
888 } 1003 }
889 YY_BREAK 1004 YY_BREAK
890case 4: 1005case 5:
891YY_RULE_SETUP 1006YY_RULE_SETUP
1007#line 115 "dtc-lexer.l"
892{ 1008{
893 DPRINT("Keyword: /memreserve/\n"); 1009 DPRINT("Keyword: /memreserve/\n");
894 BEGIN_DEFAULT(); 1010 BEGIN_DEFAULT();
895 return DT_MEMRESERVE; 1011 return DT_MEMRESERVE;
896 } 1012 }
897 YY_BREAK 1013 YY_BREAK
898case 5: 1014case 6:
1015YY_RULE_SETUP
1016#line 121 "dtc-lexer.l"
1017{
1018 DPRINT("Keyword: /bits/\n");
1019 BEGIN_DEFAULT();
1020 return DT_BITS;
1021 }
1022 YY_BREAK
1023case 7:
899YY_RULE_SETUP 1024YY_RULE_SETUP
1025#line 127 "dtc-lexer.l"
1026{
1027 DPRINT("Keyword: /delete-property/\n");
1028 DPRINT("<PROPNODENAME>\n");
1029 BEGIN(PROPNODENAME);
1030 return DT_DEL_PROP;
1031 }
1032 YY_BREAK
1033case 8:
1034YY_RULE_SETUP
1035#line 134 "dtc-lexer.l"
1036{
1037 DPRINT("Keyword: /delete-node/\n");
1038 DPRINT("<PROPNODENAME>\n");
1039 BEGIN(PROPNODENAME);
1040 return DT_DEL_NODE;
1041 }
1042 YY_BREAK
1043case 9:
1044YY_RULE_SETUP
1045#line 141 "dtc-lexer.l"
900{ 1046{
901 DPRINT("Label: %s\n", yytext); 1047 DPRINT("Label: %s\n", yytext);
902 yylval.labelref = xstrdup(yytext); 1048 yylval.labelref = xstrdup(yytext);
@@ -904,24 +1050,38 @@ YY_RULE_SETUP
904 return DT_LABEL; 1050 return DT_LABEL;
905 } 1051 }
906 YY_BREAK 1052 YY_BREAK
907case 6: 1053case 10:
908YY_RULE_SETUP 1054YY_RULE_SETUP
1055#line 148 "dtc-lexer.l"
909{ 1056{
910 yylval.literal = xstrdup(yytext); 1057 yylval.literal = xstrdup(yytext);
911 DPRINT("Literal: '%s'\n", yylval.literal); 1058 DPRINT("Literal: '%s'\n", yylval.literal);
912 return DT_LITERAL; 1059 return DT_LITERAL;
913 } 1060 }
914 YY_BREAK 1061 YY_BREAK
915case 7: 1062case 11:
1063/* rule 11 can match eol */
1064YY_RULE_SETUP
1065#line 154 "dtc-lexer.l"
1066{
1067 yytext[yyleng-1] = '\0';
1068 yylval.literal = xstrdup(yytext+1);
1069 DPRINT("Character literal: %s\n", yylval.literal);
1070 return DT_CHAR_LITERAL;
1071 }
1072 YY_BREAK
1073case 12:
916YY_RULE_SETUP 1074YY_RULE_SETUP
1075#line 161 "dtc-lexer.l"
917{ /* label reference */ 1076{ /* label reference */
918 DPRINT("Ref: %s\n", yytext+1); 1077 DPRINT("Ref: %s\n", yytext+1);
919 yylval.labelref = xstrdup(yytext+1); 1078 yylval.labelref = xstrdup(yytext+1);
920 return DT_REF; 1079 return DT_REF;
921 } 1080 }
922 YY_BREAK 1081 YY_BREAK
923case 8: 1082case 13:
924YY_RULE_SETUP 1083YY_RULE_SETUP
1084#line 167 "dtc-lexer.l"
925{ /* new-style path reference */ 1085{ /* new-style path reference */
926 yytext[yyleng-1] = '\0'; 1086 yytext[yyleng-1] = '\0';
927 DPRINT("Ref: %s\n", yytext+2); 1087 DPRINT("Ref: %s\n", yytext+2);
@@ -929,55 +1089,104 @@ YY_RULE_SETUP
929 return DT_REF; 1089 return DT_REF;
930 } 1090 }
931 YY_BREAK 1091 YY_BREAK
932case 9: 1092case 14:
933YY_RULE_SETUP 1093YY_RULE_SETUP
1094#line 174 "dtc-lexer.l"
934{ 1095{
935 yylval.byte = strtol(yytext, NULL, 16); 1096 yylval.byte = strtol(yytext, NULL, 16);
936 DPRINT("Byte: %02x\n", (int)yylval.byte); 1097 DPRINT("Byte: %02x\n", (int)yylval.byte);
937 return DT_BYTE; 1098 return DT_BYTE;
938 } 1099 }
939 YY_BREAK 1100 YY_BREAK
940case 10: 1101case 15:
941YY_RULE_SETUP 1102YY_RULE_SETUP
1103#line 180 "dtc-lexer.l"
942{ 1104{
943 DPRINT("/BYTESTRING\n"); 1105 DPRINT("/BYTESTRING\n");
944 BEGIN_DEFAULT(); 1106 BEGIN_DEFAULT();
945 return ']'; 1107 return ']';
946 } 1108 }
947 YY_BREAK 1109 YY_BREAK
948case 11: 1110case 16:
949YY_RULE_SETUP 1111YY_RULE_SETUP
1112#line 186 "dtc-lexer.l"
950{ 1113{
951 DPRINT("PropNodeName: %s\n", yytext); 1114 DPRINT("PropNodeName: %s\n", yytext);
952 yylval.propnodename = xstrdup(yytext); 1115 yylval.propnodename = xstrdup((yytext[0] == '\\') ?
1116 yytext + 1 : yytext);
953 BEGIN_DEFAULT(); 1117 BEGIN_DEFAULT();
954 return DT_PROPNODENAME; 1118 return DT_PROPNODENAME;
955 } 1119 }
956 YY_BREAK 1120 YY_BREAK
957case 12: 1121case 17:
958YY_RULE_SETUP 1122YY_RULE_SETUP
1123#line 194 "dtc-lexer.l"
959{ 1124{
960 DPRINT("Binary Include\n"); 1125 DPRINT("Binary Include\n");
961 return DT_INCBIN; 1126 return DT_INCBIN;
962 } 1127 }
963 YY_BREAK 1128 YY_BREAK
964case 13: 1129case 18:
965/* rule 13 can match eol */ 1130/* rule 18 can match eol */
966YY_RULE_SETUP 1131YY_RULE_SETUP
1132#line 199 "dtc-lexer.l"
967/* eat whitespace */ 1133/* eat whitespace */
968 YY_BREAK 1134 YY_BREAK
969case 14: 1135case 19:
970/* rule 14 can match eol */ 1136/* rule 19 can match eol */
971YY_RULE_SETUP 1137YY_RULE_SETUP
1138#line 200 "dtc-lexer.l"
972/* eat C-style comments */ 1139/* eat C-style comments */
973 YY_BREAK 1140 YY_BREAK
974case 15: 1141case 20:
975/* rule 15 can match eol */ 1142/* rule 20 can match eol */
976YY_RULE_SETUP 1143YY_RULE_SETUP
1144#line 201 "dtc-lexer.l"
977/* eat C++-style comments */ 1145/* eat C++-style comments */
978 YY_BREAK 1146 YY_BREAK
979case 16: 1147case 21:
980YY_RULE_SETUP 1148YY_RULE_SETUP
1149#line 203 "dtc-lexer.l"
1150{ return DT_LSHIFT; };
1151 YY_BREAK
1152case 22:
1153YY_RULE_SETUP
1154#line 204 "dtc-lexer.l"
1155{ return DT_RSHIFT; };
1156 YY_BREAK
1157case 23:
1158YY_RULE_SETUP
1159#line 205 "dtc-lexer.l"
1160{ return DT_LE; };
1161 YY_BREAK
1162case 24:
1163YY_RULE_SETUP
1164#line 206 "dtc-lexer.l"
1165{ return DT_GE; };
1166 YY_BREAK
1167case 25:
1168YY_RULE_SETUP
1169#line 207 "dtc-lexer.l"
1170{ return DT_EQ; };
1171 YY_BREAK
1172case 26:
1173YY_RULE_SETUP
1174#line 208 "dtc-lexer.l"
1175{ return DT_NE; };
1176 YY_BREAK
1177case 27:
1178YY_RULE_SETUP
1179#line 209 "dtc-lexer.l"
1180{ return DT_AND; };
1181 YY_BREAK
1182case 28:
1183YY_RULE_SETUP
1184#line 210 "dtc-lexer.l"
1185{ return DT_OR; };
1186 YY_BREAK
1187case 29:
1188YY_RULE_SETUP
1189#line 212 "dtc-lexer.l"
981{ 1190{
982 DPRINT("Char: %c (\\x%02x)\n", yytext[0], 1191 DPRINT("Char: %c (\\x%02x)\n", yytext[0],
983 (unsigned)yytext[0]); 1192 (unsigned)yytext[0]);
@@ -993,10 +1202,12 @@ YY_RULE_SETUP
993 return yytext[0]; 1202 return yytext[0];
994 } 1203 }
995 YY_BREAK 1204 YY_BREAK
996case 17: 1205case 30:
997YY_RULE_SETUP 1206YY_RULE_SETUP
1207#line 227 "dtc-lexer.l"
998ECHO; 1208ECHO;
999 YY_BREAK 1209 YY_BREAK
1210#line 1211 "dtc-lexer.lex.c"
1000 1211
1001 case YY_END_OF_BUFFER: 1212 case YY_END_OF_BUFFER:
1002 { 1213 {
@@ -1275,6 +1486,7 @@ static int yy_get_next_buffer (void)
1275 register char *yy_cp; 1486 register char *yy_cp;
1276 1487
1277 yy_current_state = (yy_start); 1488 yy_current_state = (yy_start);
1489 yy_current_state += YY_AT_BOL();
1278 1490
1279 for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) 1491 for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
1280 { 1492 {
@@ -1287,7 +1499,7 @@ static int yy_get_next_buffer (void)
1287 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) 1499 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
1288 { 1500 {
1289 yy_current_state = (int) yy_def[yy_current_state]; 1501 yy_current_state = (int) yy_def[yy_current_state];
1290 if ( yy_current_state >= 94 ) 1502 if ( yy_current_state >= 161 )
1291 yy_c = yy_meta[(unsigned int) yy_c]; 1503 yy_c = yy_meta[(unsigned int) yy_c];
1292 } 1504 }
1293 yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; 1505 yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1315,11 +1527,11 @@ static int yy_get_next_buffer (void)
1315 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) 1527 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
1316 { 1528 {
1317 yy_current_state = (int) yy_def[yy_current_state]; 1529 yy_current_state = (int) yy_def[yy_current_state];
1318 if ( yy_current_state >= 94 ) 1530 if ( yy_current_state >= 161 )
1319 yy_c = yy_meta[(unsigned int) yy_c]; 1531 yy_c = yy_meta[(unsigned int) yy_c];
1320 } 1532 }
1321 yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; 1533 yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
1322 yy_is_jam = (yy_current_state == 93); 1534 yy_is_jam = (yy_current_state == 160);
1323 1535
1324 return yy_is_jam ? 0 : yy_current_state; 1536 return yy_is_jam ? 0 : yy_current_state;
1325} 1537}
@@ -1394,6 +1606,8 @@ static int yy_get_next_buffer (void)
1394 *(yy_c_buf_p) = '\0'; /* preserve yytext */ 1606 *(yy_c_buf_p) = '\0'; /* preserve yytext */
1395 (yy_hold_char) = *++(yy_c_buf_p); 1607 (yy_hold_char) = *++(yy_c_buf_p);
1396 1608
1609 YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n');
1610
1397 return c; 1611 return c;
1398} 1612}
1399#endif /* ifndef YY_NO_INPUT */ 1613#endif /* ifndef YY_NO_INPUT */
@@ -1712,8 +1926,8 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
1712 1926
1713/** Setup the input buffer state to scan the given bytes. The next call to yylex() will 1927/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
1714 * scan from a @e copy of @a bytes. 1928 * scan from a @e copy of @a bytes.
1715 * @param bytes the byte buffer to scan 1929 * @param yybytes the byte buffer to scan
1716 * @param len the number of bytes in the buffer pointed to by @a bytes. 1930 * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
1717 * 1931 *
1718 * @return the newly allocated buffer state object. 1932 * @return the newly allocated buffer state object.
1719 */ 1933 */
@@ -1952,6 +2166,10 @@ void yyfree (void * ptr )
1952 2166
1953#define YYTABLES_NAME "yytables" 2167#define YYTABLES_NAME "yytables"
1954 2168
2169#line 227 "dtc-lexer.l"
2170
2171
2172
1955static void push_input_file(const char *filename) 2173static void push_input_file(const char *filename)
1956{ 2174{
1957 assert(filename); 2175 assert(filename);
@@ -1963,6 +2181,7 @@ static void push_input_file(const char *filename)
1963 yypush_buffer_state(yy_create_buffer(yyin,YY_BUF_SIZE)); 2181 yypush_buffer_state(yy_create_buffer(yyin,YY_BUF_SIZE));
1964} 2182}
1965 2183
2184
1966static int pop_input_file(void) 2185static int pop_input_file(void)
1967{ 2186{
1968 if (srcfile_pop() == 0) 2187 if (srcfile_pop() == 0)
diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped
index b05921e1e848..4af55900a15b 100644
--- a/scripts/dtc/dtc-parser.tab.c_shipped
+++ b/scripts/dtc/dtc-parser.tab.c_shipped
@@ -1,9 +1,10 @@
1/* A Bison parser, made by GNU Bison 2.4.3. */ 1
2/* A Bison parser, made by GNU Bison 2.4.1. */
2 3
3/* Skeleton implementation for Bison's Yacc-like parsers in C 4/* Skeleton implementation for Bison's Yacc-like parsers in C
4 5
5 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 6 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
6 2009, 2010 Free Software Foundation, Inc. 7 Free Software Foundation, Inc.
7 8
8 This program is free software: you can redistribute it and/or modify 9 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by 10 it under the terms of the GNU General Public License as published by
@@ -45,7 +46,7 @@
45#define YYBISON 1 46#define YYBISON 1
46 47
47/* Bison version. */ 48/* Bison version. */
48#define YYBISON_VERSION "2.4.3" 49#define YYBISON_VERSION "2.4.1"
49 50
50/* Skeleton name. */ 51/* Skeleton name. */
51#define YYSKELETON_NAME "yacc.c" 52#define YYSKELETON_NAME "yacc.c"
@@ -66,6 +67,8 @@
66 67
67/* Copy the first part of user declarations. */ 68/* Copy the first part of user declarations. */
68 69
70/* Line 189 of yacc.c */
71#line 21 "dtc-parser.y"
69 72
70#include <stdio.h> 73#include <stdio.h>
71 74
@@ -82,12 +85,15 @@ extern struct boot_info *the_boot_info;
82extern int treesource_error; 85extern int treesource_error;
83 86
84static unsigned long long eval_literal(const char *s, int base, int bits); 87static unsigned long long eval_literal(const char *s, int base, int bits);
88static unsigned char eval_char_literal(const char *s);
85 89
86 90
91/* Line 189 of yacc.c */
92#line 93 "dtc-parser.tab.c"
87 93
88/* Enabling traces. */ 94/* Enabling traces. */
89#ifndef YYDEBUG 95#ifndef YYDEBUG
90# define YYDEBUG 1 96# define YYDEBUG 0
91#endif 97#endif
92 98
93/* Enabling verbose error messages. */ 99/* Enabling verbose error messages. */
@@ -112,14 +118,26 @@ static unsigned long long eval_literal(const char *s, int base, int bits);
112 enum yytokentype { 118 enum yytokentype {
113 DT_V1 = 258, 119 DT_V1 = 258,
114 DT_MEMRESERVE = 259, 120 DT_MEMRESERVE = 259,
115 DT_PROPNODENAME = 260, 121 DT_LSHIFT = 260,
116 DT_LITERAL = 261, 122 DT_RSHIFT = 261,
117 DT_BASE = 262, 123 DT_LE = 262,
118 DT_BYTE = 263, 124 DT_GE = 263,
119 DT_STRING = 264, 125 DT_EQ = 264,
120 DT_LABEL = 265, 126 DT_NE = 265,
121 DT_REF = 266, 127 DT_AND = 266,
122 DT_INCBIN = 267 128 DT_OR = 267,
129 DT_BITS = 268,
130 DT_DEL_PROP = 269,
131 DT_DEL_NODE = 270,
132 DT_PROPNODENAME = 271,
133 DT_LITERAL = 272,
134 DT_CHAR_LITERAL = 273,
135 DT_BASE = 274,
136 DT_BYTE = 275,
137 DT_STRING = 276,
138 DT_LABEL = 277,
139 DT_REF = 278,
140 DT_INCBIN = 279
123 }; 141 };
124#endif 142#endif
125 143
@@ -129,6 +147,8 @@ static unsigned long long eval_literal(const char *s, int base, int bits);
129typedef union YYSTYPE 147typedef union YYSTYPE
130{ 148{
131 149
150/* Line 214 of yacc.c */
151#line 40 "dtc-parser.y"
132 152
133 char *propnodename; 153 char *propnodename;
134 char *literal; 154 char *literal;
@@ -137,16 +157,22 @@ typedef union YYSTYPE
137 uint8_t byte; 157 uint8_t byte;
138 struct data data; 158 struct data data;
139 159
140 uint64_t addr; 160 struct {
141 cell_t cell; 161 struct data data;
162 int bits;
163 } array;
164
142 struct property *prop; 165 struct property *prop;
143 struct property *proplist; 166 struct property *proplist;
144 struct node *node; 167 struct node *node;
145 struct node *nodelist; 168 struct node *nodelist;
146 struct reserve_info *re; 169 struct reserve_info *re;
170 uint64_t integer;
147 171
148 172
149 173
174/* Line 214 of yacc.c */
175#line 176 "dtc-parser.tab.c"
150} YYSTYPE; 176} YYSTYPE;
151# define YYSTYPE_IS_TRIVIAL 1 177# define YYSTYPE_IS_TRIVIAL 1
152# define yystype YYSTYPE /* obsolescent; will be withdrawn */ 178# define yystype YYSTYPE /* obsolescent; will be withdrawn */
@@ -157,6 +183,8 @@ typedef union YYSTYPE
157/* Copy the second part of user declarations. */ 183/* Copy the second part of user declarations. */
158 184
159 185
186/* Line 264 of yacc.c */
187#line 188 "dtc-parser.tab.c"
160 188
161#ifdef short 189#ifdef short
162# undef short 190# undef short
@@ -206,7 +234,7 @@ typedef short int yytype_int16;
206#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) 234#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
207 235
208#ifndef YY_ 236#ifndef YY_
209# if defined YYENABLE_NLS && YYENABLE_NLS 237# if YYENABLE_NLS
210# if ENABLE_NLS 238# if ENABLE_NLS
211# include <libintl.h> /* INFRINGES ON USER NAME SPACE */ 239# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
212# define YY_(msgid) dgettext ("bison-runtime", msgid) 240# define YY_(msgid) dgettext ("bison-runtime", msgid)
@@ -371,20 +399,20 @@ union yyalloc
371/* YYFINAL -- State number of the termination state. */ 399/* YYFINAL -- State number of the termination state. */
372#define YYFINAL 4 400#define YYFINAL 4
373/* YYLAST -- Last index in YYTABLE. */ 401/* YYLAST -- Last index in YYTABLE. */
374#define YYLAST 56 402#define YYLAST 133
375 403
376/* YYNTOKENS -- Number of terminals. */ 404/* YYNTOKENS -- Number of terminals. */
377#define YYNTOKENS 25 405#define YYNTOKENS 48
378/* YYNNTS -- Number of nonterminals. */ 406/* YYNNTS -- Number of nonterminals. */
379#define YYNNTS 16 407#define YYNNTS 28
380/* YYNRULES -- Number of rules. */ 408/* YYNRULES -- Number of rules. */
381#define YYNRULES 39 409#define YYNRULES 79
382/* YYNRULES -- Number of states. */ 410/* YYNRULES -- Number of states. */
383#define YYNSTATES 67 411#define YYNSTATES 141
384 412
385/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ 413/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
386#define YYUNDEFTOK 2 414#define YYUNDEFTOK 2
387#define YYMAXUTOK 267 415#define YYMAXUTOK 279
388 416
389#define YYTRANSLATE(YYX) \ 417#define YYTRANSLATE(YYX) \
390 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) 418 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -395,16 +423,16 @@ static const yytype_uint8 yytranslate[] =
395 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 423 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
396 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 424 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
397 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 425 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
398 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 426 2, 2, 2, 47, 2, 2, 2, 45, 41, 2,
399 22, 24, 2, 2, 23, 2, 2, 14, 2, 2, 427 33, 35, 44, 42, 34, 43, 2, 26, 2, 2,
400 2, 2, 2, 2, 2, 2, 2, 2, 2, 13, 428 2, 2, 2, 2, 2, 2, 2, 2, 38, 25,
401 18, 17, 19, 2, 2, 2, 2, 2, 2, 2, 429 36, 29, 30, 37, 2, 2, 2, 2, 2, 2,
402 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 430 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
403 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 431 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
404 2, 20, 2, 21, 2, 2, 2, 2, 2, 2, 432 2, 31, 2, 32, 40, 2, 2, 2, 2, 2,
405 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 433 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
406 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 434 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
407 2, 2, 2, 15, 2, 16, 2, 2, 2, 2, 435 2, 2, 2, 27, 39, 28, 46, 2, 2, 2,
408 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 436 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
409 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 437 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
410 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 438 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -418,45 +446,68 @@ static const yytype_uint8 yytranslate[] =
418 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 446 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
419 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 447 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
420 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 448 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
421 5, 6, 7, 8, 9, 10, 11, 12 449 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
450 15, 16, 17, 18, 19, 20, 21, 22, 23, 24
422}; 451};
423 452
424#if YYDEBUG 453#if YYDEBUG
425/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in 454/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
426 YYRHS. */ 455 YYRHS. */
427static const yytype_uint8 yyprhs[] = 456static const yytype_uint16 yyprhs[] =
428{ 457{
429 0, 0, 3, 8, 9, 12, 17, 20, 22, 25, 458 0, 0, 3, 8, 9, 12, 17, 20, 23, 27,
430 29, 33, 39, 40, 43, 48, 51, 54, 57, 62, 459 31, 36, 42, 43, 46, 51, 54, 58, 61, 64,
431 67, 70, 80, 86, 89, 90, 93, 96, 97, 100, 460 68, 73, 76, 86, 92, 95, 96, 99, 102, 106,
432 103, 106, 108, 109, 112, 115, 116, 119, 122, 125 461 108, 111, 114, 117, 119, 121, 125, 127, 129, 135,
462 137, 141, 143, 147, 149, 153, 155, 159, 161, 165,
463 167, 171, 175, 177, 181, 185, 189, 193, 197, 201,
464 203, 207, 211, 213, 217, 221, 225, 227, 229, 232,
465 235, 238, 239, 242, 245, 246, 249, 252, 255, 259
433}; 466};
434 467
435/* YYRHS -- A `-1'-separated list of the rules' RHS. */ 468/* YYRHS -- A `-1'-separated list of the rules' RHS. */
436static const yytype_int8 yyrhs[] = 469static const yytype_int8 yyrhs[] =
437{ 470{
438 26, 0, -1, 3, 13, 27, 30, -1, -1, 28, 471 49, 0, -1, 3, 25, 50, 52, -1, -1, 51,
439 27, -1, 4, 29, 29, 13, -1, 10, 28, -1, 472 50, -1, 4, 59, 59, 25, -1, 22, 51, -1,
440 6, -1, 14, 31, -1, 30, 14, 31, -1, 30, 473 26, 53, -1, 52, 26, 53, -1, 52, 23, 53,
441 11, 31, -1, 15, 32, 39, 16, 13, -1, -1, 474 -1, 52, 15, 23, 25, -1, 27, 54, 74, 28,
442 32, 33, -1, 5, 17, 34, 13, -1, 5, 13, 475 25, -1, -1, 54, 55, -1, 16, 29, 56, 25,
443 -1, 10, 33, -1, 35, 9, -1, 35, 18, 36, 476 -1, 16, 25, -1, 14, 16, 25, -1, 22, 55,
444 19, -1, 35, 20, 38, 21, -1, 35, 11, -1, 477 -1, 57, 21, -1, 57, 58, 30, -1, 57, 31,
445 35, 12, 22, 9, 23, 29, 23, 29, 24, -1, 478 73, 32, -1, 57, 23, -1, 57, 24, 33, 21,
446 35, 12, 22, 9, 24, -1, 34, 10, -1, -1, 479 34, 59, 34, 59, 35, -1, 57, 24, 33, 21,
447 34, 23, -1, 35, 10, -1, -1, 36, 37, -1, 480 35, -1, 56, 22, -1, -1, 56, 34, -1, 57,
448 36, 11, -1, 36, 10, -1, 6, -1, -1, 38, 481 22, -1, 13, 17, 36, -1, 36, -1, 58, 59,
449 8, -1, 38, 10, -1, -1, 40, 39, -1, 40, 482 -1, 58, 23, -1, 58, 22, -1, 17, -1, 18,
450 33, -1, 5, 31, -1, 10, 40, -1 483 -1, 33, 60, 35, -1, 61, -1, 62, -1, 62,
484 37, 60, 38, 61, -1, 63, -1, 62, 12, 63,
485 -1, 64, -1, 63, 11, 64, -1, 65, -1, 64,
486 39, 65, -1, 66, -1, 65, 40, 66, -1, 67,
487 -1, 66, 41, 67, -1, 68, -1, 67, 9, 68,
488 -1, 67, 10, 68, -1, 69, -1, 68, 36, 69,
489 -1, 68, 30, 69, -1, 68, 7, 69, -1, 68,
490 8, 69, -1, 69, 5, 70, -1, 69, 6, 70,
491 -1, 70, -1, 70, 42, 71, -1, 70, 43, 71,
492 -1, 71, -1, 71, 44, 72, -1, 71, 26, 72,
493 -1, 71, 45, 72, -1, 72, -1, 59, -1, 43,
494 72, -1, 46, 72, -1, 47, 72, -1, -1, 73,
495 20, -1, 73, 22, -1, -1, 75, 74, -1, 75,
496 55, -1, 16, 53, -1, 15, 16, 25, -1, 22,
497 75, -1
451}; 498};
452 499
453/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ 500/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
454static const yytype_uint16 yyrline[] = 501static const yytype_uint16 yyrline[] =
455{ 502{
456 0, 86, 86, 95, 98, 105, 109, 117, 124, 128, 503 0, 109, 109, 118, 121, 128, 132, 140, 144, 148,
457 132, 145, 153, 156, 163, 167, 171, 179, 183, 187, 504 158, 172, 180, 183, 190, 194, 198, 202, 210, 214,
458 191, 195, 212, 222, 230, 233, 237, 245, 248, 252, 505 218, 222, 226, 243, 253, 261, 264, 268, 275, 290,
459 257, 264, 272, 275, 279, 287, 290, 294, 302, 306 506 295, 315, 329, 336, 340, 344, 351, 355, 356, 360,
507 361, 365, 366, 370, 371, 375, 376, 380, 381, 385,
508 386, 387, 391, 392, 393, 394, 395, 399, 400, 401,
509 405, 406, 407, 411, 412, 413, 414, 418, 419, 420,
510 421, 426, 429, 433, 441, 444, 448, 456, 460, 464
460}; 511};
461#endif 512#endif
462 513
@@ -465,13 +516,19 @@ static const yytype_uint16 yyrline[] =
465 First, the terminals, then, starting at YYNTOKENS, nonterminals. */ 516 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
466static const char *const yytname[] = 517static const char *const yytname[] =
467{ 518{
468 "$end", "error", "$undefined", "DT_V1", "DT_MEMRESERVE", 519 "$end", "error", "$undefined", "DT_V1", "DT_MEMRESERVE", "DT_LSHIFT",
469 "DT_PROPNODENAME", "DT_LITERAL", "DT_BASE", "DT_BYTE", "DT_STRING", 520 "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND", "DT_OR",
470 "DT_LABEL", "DT_REF", "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", 521 "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME", "DT_LITERAL",
471 "'<'", "'>'", "'['", "']'", "'('", "','", "')'", "$accept", "sourcefile", 522 "DT_CHAR_LITERAL", "DT_BASE", "DT_BYTE", "DT_STRING", "DT_LABEL",
472 "memreserves", "memreserve", "addr", "devicetree", "nodedef", "proplist", 523 "DT_REF", "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['",
473 "propdef", "propdata", "propdataprefix", "celllist", "cellval", 524 "']'", "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'",
474 "bytestring", "subnodes", "subnode", 0 525 "'+'", "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile",
526 "memreserves", "memreserve", "devicetree", "nodedef", "proplist",
527 "propdef", "propdata", "propdataprefix", "arrayprefix", "integer_prim",
528 "integer_expr", "integer_trinary", "integer_or", "integer_and",
529 "integer_bitor", "integer_bitxor", "integer_bitand", "integer_eq",
530 "integer_rela", "integer_shift", "integer_add", "integer_mul",
531 "integer_unary", "bytestring", "subnodes", "subnode", 0
475}; 532};
476#endif 533#endif
477 534
@@ -481,27 +538,37 @@ static const char *const yytname[] =
481static const yytype_uint16 yytoknum[] = 538static const yytype_uint16 yytoknum[] =
482{ 539{
483 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 540 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
484 265, 266, 267, 59, 47, 123, 125, 61, 60, 62, 541 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
485 91, 93, 40, 44, 41 542 275, 276, 277, 278, 279, 59, 47, 123, 125, 61,
543 62, 91, 93, 40, 44, 41, 60, 63, 58, 124,
544 94, 38, 43, 45, 42, 37, 126, 33
486}; 545};
487# endif 546# endif
488 547
489/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ 548/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
490static const yytype_uint8 yyr1[] = 549static const yytype_uint8 yyr1[] =
491{ 550{
492 0, 25, 26, 27, 27, 28, 28, 29, 30, 30, 551 0, 48, 49, 50, 50, 51, 51, 52, 52, 52,
493 30, 31, 32, 32, 33, 33, 33, 34, 34, 34, 552 52, 53, 54, 54, 55, 55, 55, 55, 56, 56,
494 34, 34, 34, 34, 35, 35, 35, 36, 36, 36, 553 56, 56, 56, 56, 56, 57, 57, 57, 58, 58,
495 36, 37, 38, 38, 38, 39, 39, 39, 40, 40 554 58, 58, 58, 59, 59, 59, 60, 61, 61, 62,
555 62, 63, 63, 64, 64, 65, 65, 66, 66, 67,
556 67, 67, 68, 68, 68, 68, 68, 69, 69, 69,
557 70, 70, 70, 71, 71, 71, 71, 72, 72, 72,
558 72, 73, 73, 73, 74, 74, 74, 75, 75, 75
496}; 559};
497 560
498/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ 561/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
499static const yytype_uint8 yyr2[] = 562static const yytype_uint8 yyr2[] =
500{ 563{
501 0, 2, 4, 0, 2, 4, 2, 1, 2, 3, 564 0, 2, 4, 0, 2, 4, 2, 2, 3, 3,
502 3, 5, 0, 2, 4, 2, 2, 2, 4, 4, 565 4, 5, 0, 2, 4, 2, 3, 2, 2, 3,
503 2, 9, 5, 2, 0, 2, 2, 0, 2, 2, 566 4, 2, 9, 5, 2, 0, 2, 2, 3, 1,
504 2, 1, 0, 2, 2, 0, 2, 2, 2, 2 567 2, 2, 2, 1, 1, 3, 1, 1, 5, 1,
568 3, 1, 3, 1, 3, 1, 3, 1, 3, 1,
569 3, 3, 1, 3, 3, 3, 3, 3, 3, 1,
570 3, 3, 1, 3, 3, 3, 1, 1, 2, 2,
571 2, 0, 2, 2, 0, 2, 2, 2, 3, 2
505}; 572};
506 573
507/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state 574/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -509,41 +576,59 @@ static const yytype_uint8 yyr2[] =
509 means the default is an error. */ 576 means the default is an error. */
510static const yytype_uint8 yydefact[] = 577static const yytype_uint8 yydefact[] =
511{ 578{
512 0, 0, 0, 3, 1, 0, 0, 0, 3, 7, 579 0, 0, 0, 3, 1, 0, 0, 0, 3, 33,
513 0, 6, 0, 2, 4, 0, 12, 8, 0, 0, 580 34, 0, 0, 6, 0, 2, 4, 0, 0, 0,
514 5, 35, 10, 9, 0, 0, 13, 0, 35, 15, 581 67, 0, 36, 37, 39, 41, 43, 45, 47, 49,
515 24, 38, 16, 39, 0, 37, 36, 0, 0, 11, 582 52, 59, 62, 66, 0, 12, 7, 0, 0, 0,
516 23, 14, 25, 17, 26, 20, 0, 27, 32, 0, 583 68, 69, 70, 35, 0, 0, 0, 0, 0, 0,
517 0, 0, 0, 31, 30, 29, 18, 28, 33, 34, 584 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
518 19, 0, 22, 0, 0, 0, 21 585 0, 0, 0, 5, 74, 0, 9, 8, 40, 0,
586 42, 44, 46, 48, 50, 51, 55, 56, 54, 53,
587 57, 58, 60, 61, 64, 63, 65, 0, 0, 0,
588 0, 13, 0, 74, 10, 0, 0, 0, 15, 25,
589 77, 17, 79, 0, 76, 75, 38, 16, 78, 0,
590 0, 11, 24, 14, 26, 0, 18, 27, 21, 0,
591 71, 29, 0, 0, 0, 0, 32, 31, 19, 30,
592 28, 0, 72, 73, 20, 0, 23, 0, 0, 0,
593 22
519}; 594};
520 595
521/* YYDEFGOTO[NTERM-NUM]. */ 596/* YYDEFGOTO[NTERM-NUM]. */
522static const yytype_int8 yydefgoto[] = 597static const yytype_int8 yydefgoto[] =
523{ 598{
524 -1, 2, 7, 8, 10, 13, 17, 21, 26, 37, 599 -1, 2, 7, 8, 15, 36, 64, 91, 109, 110,
525 38, 50, 57, 51, 27, 28 600 122, 20, 21, 22, 23, 24, 25, 26, 27, 28,
601 29, 30, 31, 32, 33, 125, 92, 93
526}; 602};
527 603
528/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing 604/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
529 STATE-NUM. */ 605 STATE-NUM. */
530#define YYPACT_NINF -12 606#define YYPACT_NINF -78
531static const yytype_int8 yypact[] = 607static const yytype_int8 yypact[] =
532{ 608{
533 10, -11, 18, -1, -12, 22, -1, 15, -1, -12, 609 22, 11, 51, 10, -78, 23, 10, 2, 10, -78,
534 22, -12, 20, 1, -12, 17, -12, -12, 20, 20, 610 -78, -9, 23, -78, 30, 38, -78, -9, -9, -9,
535 -12, 6, -12, -12, 21, 6, -12, 23, 6, -12, 611 -78, 35, -78, -6, 52, 29, 48, 49, 33, 3,
536 -12, -12, -12, -12, 28, -12, -12, -6, 13, -12, 612 71, 36, 0, -78, 64, -78, -78, 68, 30, 30,
537 -12, -12, -12, -12, -12, -12, 24, -12, -12, 33, 613 -78, -78, -78, -78, -9, -9, -9, -9, -9, -9,
538 -5, 0, -4, -12, -12, -12, -12, -12, -12, -12, 614 -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
539 -12, 22, -12, 25, 22, 19, -12 615 -9, -9, -9, -78, 44, 67, -78, -78, 52, 55,
616 29, 48, 49, 33, 3, 3, 71, 71, 71, 71,
617 36, 36, 0, 0, -78, -78, -78, 78, 79, 42,
618 44, -78, 69, 44, -78, -9, 73, 74, -78, -78,
619 -78, -78, -78, 75, -78, -78, -78, -78, -78, -7,
620 -1, -78, -78, -78, -78, 84, -78, -78, -78, 63,
621 -78, -78, 32, 66, 82, -3, -78, -78, -78, -78,
622 -78, 46, -78, -78, -78, 23, -78, 70, 23, 72,
623 -78
540}; 624};
541 625
542/* YYPGOTO[NTERM-NUM]. */ 626/* YYPGOTO[NTERM-NUM]. */
543static const yytype_int8 yypgoto[] = 627static const yytype_int8 yypgoto[] =
544{ 628{
545 -12, -12, 36, 39, -10, -12, 8, -12, 12, -12, 629 -78, -78, 97, 100, -78, -37, -78, -77, -78, -78,
546 -12, -12, -12, -12, 27, 31 630 -78, -5, 65, 13, -78, 76, 77, 62, 80, 83,
631 34, 20, 26, 28, -14, -78, 18, 24
547}; 632};
548 633
549/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If 634/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
@@ -553,35 +638,59 @@ static const yytype_int8 yypgoto[] =
553#define YYTABLE_NINF -1 638#define YYTABLE_NINF -1
554static const yytype_uint8 yytable[] = 639static const yytype_uint8 yytable[] =
555{ 640{
556 15, 53, 3, 5, 40, 54, 55, 41, 58, 6, 641 12, 66, 67, 40, 41, 42, 44, 34, 9, 10,
557 59, 24, 18, 1, 56, 19, 25, 42, 4, 61, 642 52, 53, 115, 101, 5, 112, 104, 132, 113, 133,
558 62, 60, 43, 44, 45, 46, 22, 23, 9, 12, 643 116, 117, 118, 119, 11, 1, 60, 114, 14, 134,
559 20, 47, 31, 48, 29, 16, 16, 32, 30, 34, 644 120, 45, 6, 54, 17, 121, 3, 18, 19, 55,
560 35, 39, 52, 66, 14, 11, 49, 0, 64, 0, 645 9, 10, 50, 51, 61, 62, 84, 85, 86, 9,
561 0, 63, 0, 0, 65, 36, 33 646 10, 4, 100, 37, 126, 127, 11, 35, 87, 88,
647 89, 38, 128, 46, 39, 11, 90, 98, 47, 35,
648 43, 99, 76, 77, 78, 79, 56, 57, 58, 59,
649 135, 136, 80, 81, 74, 75, 82, 83, 48, 63,
650 49, 65, 94, 95, 96, 97, 124, 103, 107, 108,
651 111, 123, 130, 131, 138, 16, 13, 140, 106, 71,
652 69, 105, 0, 0, 102, 0, 0, 129, 0, 0,
653 68, 0, 0, 70, 0, 0, 0, 0, 72, 0,
654 137, 0, 73, 139
562}; 655};
563 656
564static const yytype_int8 yycheck[] = 657static const yytype_int16 yycheck[] =
565{ 658{
566 10, 6, 13, 4, 10, 10, 11, 13, 8, 10, 659 5, 38, 39, 17, 18, 19, 12, 12, 17, 18,
567 10, 5, 11, 3, 19, 14, 10, 23, 0, 23, 660 7, 8, 13, 90, 4, 22, 93, 20, 25, 22,
568 24, 21, 9, 10, 11, 12, 18, 19, 6, 14, 661 21, 22, 23, 24, 33, 3, 26, 34, 26, 32,
569 13, 18, 24, 20, 13, 15, 15, 25, 17, 16, 662 31, 37, 22, 30, 43, 36, 25, 46, 47, 36,
570 28, 13, 9, 24, 8, 6, 22, -1, 23, -1, 663 17, 18, 9, 10, 44, 45, 60, 61, 62, 17,
571 -1, 61, -1, -1, 64, 28, 25 664 18, 0, 89, 15, 22, 23, 33, 27, 14, 15,
665 16, 23, 30, 11, 26, 33, 22, 25, 39, 27,
666 35, 29, 52, 53, 54, 55, 5, 6, 42, 43,
667 34, 35, 56, 57, 50, 51, 58, 59, 40, 25,
668 41, 23, 25, 38, 16, 16, 33, 28, 25, 25,
669 25, 17, 36, 21, 34, 8, 6, 35, 95, 47,
670 45, 93, -1, -1, 90, -1, -1, 122, -1, -1,
671 44, -1, -1, 46, -1, -1, -1, -1, 48, -1,
672 135, -1, 49, 138
572}; 673};
573 674
574/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing 675/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
575 symbol of state STATE-NUM. */ 676 symbol of state STATE-NUM. */
576static const yytype_uint8 yystos[] = 677static const yytype_uint8 yystos[] =
577{ 678{
578 0, 3, 26, 13, 0, 4, 10, 27, 28, 6, 679 0, 3, 49, 25, 0, 4, 22, 50, 51, 17,
579 29, 28, 14, 30, 27, 29, 15, 31, 11, 14, 680 18, 33, 59, 51, 26, 52, 50, 43, 46, 47,
580 13, 32, 31, 31, 5, 10, 33, 39, 40, 13, 681 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
581 17, 31, 33, 40, 16, 33, 39, 34, 35, 13, 682 69, 70, 71, 72, 59, 27, 53, 15, 23, 26,
582 10, 13, 23, 9, 10, 11, 12, 18, 20, 22, 683 72, 72, 72, 35, 12, 37, 11, 39, 40, 41,
583 36, 38, 9, 6, 10, 11, 19, 37, 8, 10, 684 9, 10, 7, 8, 30, 36, 5, 6, 42, 43,
584 21, 23, 24, 29, 23, 29, 24 685 26, 44, 45, 25, 54, 23, 53, 53, 63, 60,
686 64, 65, 66, 67, 68, 68, 69, 69, 69, 69,
687 70, 70, 71, 71, 72, 72, 72, 14, 15, 16,
688 22, 55, 74, 75, 25, 38, 16, 16, 25, 29,
689 53, 55, 75, 28, 55, 74, 61, 25, 25, 56,
690 57, 25, 22, 25, 34, 13, 21, 22, 23, 24,
691 31, 36, 58, 17, 33, 73, 22, 23, 30, 59,
692 36, 21, 20, 22, 32, 34, 35, 59, 34, 59,
693 35
585}; 694};
586 695
587#define yyerrok (yyerrstatus = 0) 696#define yyerrok (yyerrstatus = 0)
@@ -596,18 +705,9 @@ static const yytype_uint8 yystos[] =
596 705
597/* Like YYERROR except do call yyerror. This remains here temporarily 706/* Like YYERROR except do call yyerror. This remains here temporarily
598 to ease the transition to the new meaning of YYERROR, for GCC. 707 to ease the transition to the new meaning of YYERROR, for GCC.
599 Once GCC version 2 has supplanted version 1, this can go. However, 708 Once GCC version 2 has supplanted version 1, this can go. */
600 YYFAIL appears to be in use. Nevertheless, it is formally deprecated
601 in Bison 2.4.2's NEWS entry, where a plan to phase it out is
602 discussed. */
603 709
604#define YYFAIL goto yyerrlab 710#define YYFAIL goto yyerrlab
605#if defined YYFAIL
606 /* This is here to suppress warnings from the GCC cpp's
607 -Wunused-macros. Normally we don't worry about that warning, but
608 some users do, and we want to make it easy for users to remove
609 YYFAIL uses, which will produce warnings from Bison 2.5. */
610#endif
611 711
612#define YYRECOVERING() (!!yyerrstatus) 712#define YYRECOVERING() (!!yyerrstatus)
613 713
@@ -664,7 +764,7 @@ while (YYID (0))
664 we won't break user code: when these are the locations we know. */ 764 we won't break user code: when these are the locations we know. */
665 765
666#ifndef YY_LOCATION_PRINT 766#ifndef YY_LOCATION_PRINT
667# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL 767# if YYLTYPE_IS_TRIVIAL
668# define YY_LOCATION_PRINT(File, Loc) \ 768# define YY_LOCATION_PRINT(File, Loc) \
669 fprintf (File, "%d.%d-%d.%d", \ 769 fprintf (File, "%d.%d-%d.%d", \
670 (Loc).first_line, (Loc).first_column, \ 770 (Loc).first_line, (Loc).first_column, \
@@ -1403,6 +1503,8 @@ yyreduce:
1403 { 1503 {
1404 case 2: 1504 case 2:
1405 1505
1506/* Line 1455 of yacc.c */
1507#line 110 "dtc-parser.y"
1406 { 1508 {
1407 the_boot_info = build_boot_info((yyvsp[(3) - (4)].re), (yyvsp[(4) - (4)].node), 1509 the_boot_info = build_boot_info((yyvsp[(3) - (4)].re), (yyvsp[(4) - (4)].node),
1408 guess_boot_cpuid((yyvsp[(4) - (4)].node))); 1510 guess_boot_cpuid((yyvsp[(4) - (4)].node)));
@@ -1411,6 +1513,8 @@ yyreduce:
1411 1513
1412 case 3: 1514 case 3:
1413 1515
1516/* Line 1455 of yacc.c */
1517#line 118 "dtc-parser.y"
1414 { 1518 {
1415 (yyval.re) = NULL; 1519 (yyval.re) = NULL;
1416 ;} 1520 ;}
@@ -1418,6 +1522,8 @@ yyreduce:
1418 1522
1419 case 4: 1523 case 4:
1420 1524
1525/* Line 1455 of yacc.c */
1526#line 122 "dtc-parser.y"
1421 { 1527 {
1422 (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re)); 1528 (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re));
1423 ;} 1529 ;}
@@ -1425,13 +1531,17 @@ yyreduce:
1425 1531
1426 case 5: 1532 case 5:
1427 1533
1534/* Line 1455 of yacc.c */
1535#line 129 "dtc-parser.y"
1428 { 1536 {
1429 (yyval.re) = build_reserve_entry((yyvsp[(2) - (4)].addr), (yyvsp[(3) - (4)].addr)); 1537 (yyval.re) = build_reserve_entry((yyvsp[(2) - (4)].integer), (yyvsp[(3) - (4)].integer));
1430 ;} 1538 ;}
1431 break; 1539 break;
1432 1540
1433 case 6: 1541 case 6:
1434 1542
1543/* Line 1455 of yacc.c */
1544#line 133 "dtc-parser.y"
1435 { 1545 {
1436 add_label(&(yyvsp[(2) - (2)].re)->labels, (yyvsp[(1) - (2)].labelref)); 1546 add_label(&(yyvsp[(2) - (2)].re)->labels, (yyvsp[(1) - (2)].labelref));
1437 (yyval.re) = (yyvsp[(2) - (2)].re); 1547 (yyval.re) = (yyvsp[(2) - (2)].re);
@@ -1440,40 +1550,57 @@ yyreduce:
1440 1550
1441 case 7: 1551 case 7:
1442 1552
1553/* Line 1455 of yacc.c */
1554#line 141 "dtc-parser.y"
1443 { 1555 {
1444 (yyval.addr) = eval_literal((yyvsp[(1) - (1)].literal), 0, 64); 1556 (yyval.node) = name_node((yyvsp[(2) - (2)].node), "");
1445 ;} 1557 ;}
1446 break; 1558 break;
1447 1559
1448 case 8: 1560 case 8:
1449 1561
1562/* Line 1455 of yacc.c */
1563#line 145 "dtc-parser.y"
1450 { 1564 {
1451 (yyval.node) = name_node((yyvsp[(2) - (2)].node), ""); 1565 (yyval.node) = merge_nodes((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
1452 ;} 1566 ;}
1453 break; 1567 break;
1454 1568
1455 case 9: 1569 case 9:
1456 1570
1571/* Line 1455 of yacc.c */
1572#line 149 "dtc-parser.y"
1457 { 1573 {
1458 (yyval.node) = merge_nodes((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); 1574 struct node *target = get_node_by_ref((yyvsp[(1) - (3)].node), (yyvsp[(2) - (3)].labelref));
1575
1576 if (target)
1577 merge_nodes(target, (yyvsp[(3) - (3)].node));
1578 else
1579 print_error("label or path, '%s', not found", (yyvsp[(2) - (3)].labelref));
1580 (yyval.node) = (yyvsp[(1) - (3)].node);
1459 ;} 1581 ;}
1460 break; 1582 break;
1461 1583
1462 case 10: 1584 case 10:
1463 1585
1586/* Line 1455 of yacc.c */
1587#line 159 "dtc-parser.y"
1464 { 1588 {
1465 struct node *target = get_node_by_ref((yyvsp[(1) - (3)].node), (yyvsp[(2) - (3)].labelref)); 1589 struct node *target = get_node_by_ref((yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].labelref));
1466 1590
1467 if (target) 1591 if (!target)
1468 merge_nodes(target, (yyvsp[(3) - (3)].node)); 1592 print_error("label or path, '%s', not found", (yyvsp[(3) - (4)].labelref));
1469 else 1593 else
1470 print_error("label or path, '%s', not found", (yyvsp[(2) - (3)].labelref)); 1594 delete_node(target);
1471 (yyval.node) = (yyvsp[(1) - (3)].node); 1595
1596 (yyval.node) = (yyvsp[(1) - (4)].node);
1472 ;} 1597 ;}
1473 break; 1598 break;
1474 1599
1475 case 11: 1600 case 11:
1476 1601
1602/* Line 1455 of yacc.c */
1603#line 173 "dtc-parser.y"
1477 { 1604 {
1478 (yyval.node) = build_node((yyvsp[(2) - (5)].proplist), (yyvsp[(3) - (5)].nodelist)); 1605 (yyval.node) = build_node((yyvsp[(2) - (5)].proplist), (yyvsp[(3) - (5)].nodelist));
1479 ;} 1606 ;}
@@ -1481,6 +1608,8 @@ yyreduce:
1481 1608
1482 case 12: 1609 case 12:
1483 1610
1611/* Line 1455 of yacc.c */
1612#line 180 "dtc-parser.y"
1484 { 1613 {
1485 (yyval.proplist) = NULL; 1614 (yyval.proplist) = NULL;
1486 ;} 1615 ;}
@@ -1488,6 +1617,8 @@ yyreduce:
1488 1617
1489 case 13: 1618 case 13:
1490 1619
1620/* Line 1455 of yacc.c */
1621#line 184 "dtc-parser.y"
1491 { 1622 {
1492 (yyval.proplist) = chain_property((yyvsp[(2) - (2)].prop), (yyvsp[(1) - (2)].proplist)); 1623 (yyval.proplist) = chain_property((yyvsp[(2) - (2)].prop), (yyvsp[(1) - (2)].proplist));
1493 ;} 1624 ;}
@@ -1495,6 +1626,8 @@ yyreduce:
1495 1626
1496 case 14: 1627 case 14:
1497 1628
1629/* Line 1455 of yacc.c */
1630#line 191 "dtc-parser.y"
1498 { 1631 {
1499 (yyval.prop) = build_property((yyvsp[(1) - (4)].propnodename), (yyvsp[(3) - (4)].data)); 1632 (yyval.prop) = build_property((yyvsp[(1) - (4)].propnodename), (yyvsp[(3) - (4)].data));
1500 ;} 1633 ;}
@@ -1502,6 +1635,8 @@ yyreduce:
1502 1635
1503 case 15: 1636 case 15:
1504 1637
1638/* Line 1455 of yacc.c */
1639#line 195 "dtc-parser.y"
1505 { 1640 {
1506 (yyval.prop) = build_property((yyvsp[(1) - (2)].propnodename), empty_data); 1641 (yyval.prop) = build_property((yyvsp[(1) - (2)].propnodename), empty_data);
1507 ;} 1642 ;}
@@ -1509,62 +1644,85 @@ yyreduce:
1509 1644
1510 case 16: 1645 case 16:
1511 1646
1647/* Line 1455 of yacc.c */
1648#line 199 "dtc-parser.y"
1512 { 1649 {
1513 add_label(&(yyvsp[(2) - (2)].prop)->labels, (yyvsp[(1) - (2)].labelref)); 1650 (yyval.prop) = build_property_delete((yyvsp[(2) - (3)].propnodename));
1514 (yyval.prop) = (yyvsp[(2) - (2)].prop);
1515 ;} 1651 ;}
1516 break; 1652 break;
1517 1653
1518 case 17: 1654 case 17:
1519 1655
1656/* Line 1455 of yacc.c */
1657#line 203 "dtc-parser.y"
1520 { 1658 {
1521 (yyval.data) = data_merge((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].data)); 1659 add_label(&(yyvsp[(2) - (2)].prop)->labels, (yyvsp[(1) - (2)].labelref));
1660 (yyval.prop) = (yyvsp[(2) - (2)].prop);
1522 ;} 1661 ;}
1523 break; 1662 break;
1524 1663
1525 case 18: 1664 case 18:
1526 1665
1666/* Line 1455 of yacc.c */
1667#line 211 "dtc-parser.y"
1527 { 1668 {
1528 (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data)); 1669 (yyval.data) = data_merge((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].data));
1529 ;} 1670 ;}
1530 break; 1671 break;
1531 1672
1532 case 19: 1673 case 19:
1533 1674
1675/* Line 1455 of yacc.c */
1676#line 215 "dtc-parser.y"
1534 { 1677 {
1535 (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data)); 1678 (yyval.data) = data_merge((yyvsp[(1) - (3)].data), (yyvsp[(2) - (3)].array).data);
1536 ;} 1679 ;}
1537 break; 1680 break;
1538 1681
1539 case 20: 1682 case 20:
1540 1683
1684/* Line 1455 of yacc.c */
1685#line 219 "dtc-parser.y"
1541 { 1686 {
1542 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), REF_PATH, (yyvsp[(2) - (2)].labelref)); 1687 (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data));
1543 ;} 1688 ;}
1544 break; 1689 break;
1545 1690
1546 case 21: 1691 case 21:
1547 1692
1693/* Line 1455 of yacc.c */
1694#line 223 "dtc-parser.y"
1695 {
1696 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), REF_PATH, (yyvsp[(2) - (2)].labelref));
1697 ;}
1698 break;
1699
1700 case 22:
1701
1702/* Line 1455 of yacc.c */
1703#line 227 "dtc-parser.y"
1548 { 1704 {
1549 FILE *f = srcfile_relative_open((yyvsp[(4) - (9)].data).val, NULL); 1705 FILE *f = srcfile_relative_open((yyvsp[(4) - (9)].data).val, NULL);
1550 struct data d; 1706 struct data d;
1551 1707
1552 if ((yyvsp[(6) - (9)].addr) != 0) 1708 if ((yyvsp[(6) - (9)].integer) != 0)
1553 if (fseek(f, (yyvsp[(6) - (9)].addr), SEEK_SET) != 0) 1709 if (fseek(f, (yyvsp[(6) - (9)].integer), SEEK_SET) != 0)
1554 print_error("Couldn't seek to offset %llu in \"%s\": %s", 1710 print_error("Couldn't seek to offset %llu in \"%s\": %s",
1555 (unsigned long long)(yyvsp[(6) - (9)].addr), 1711 (unsigned long long)(yyvsp[(6) - (9)].integer),
1556 (yyvsp[(4) - (9)].data).val, 1712 (yyvsp[(4) - (9)].data).val,
1557 strerror(errno)); 1713 strerror(errno));
1558 1714
1559 d = data_copy_file(f, (yyvsp[(8) - (9)].addr)); 1715 d = data_copy_file(f, (yyvsp[(8) - (9)].integer));
1560 1716
1561 (yyval.data) = data_merge((yyvsp[(1) - (9)].data), d); 1717 (yyval.data) = data_merge((yyvsp[(1) - (9)].data), d);
1562 fclose(f); 1718 fclose(f);
1563 ;} 1719 ;}
1564 break; 1720 break;
1565 1721
1566 case 22: 1722 case 23:
1567 1723
1724/* Line 1455 of yacc.c */
1725#line 244 "dtc-parser.y"
1568 { 1726 {
1569 FILE *f = srcfile_relative_open((yyvsp[(4) - (5)].data).val, NULL); 1727 FILE *f = srcfile_relative_open((yyvsp[(4) - (5)].data).val, NULL);
1570 struct data d = empty_data; 1728 struct data d = empty_data;
@@ -1576,122 +1734,383 @@ yyreduce:
1576 ;} 1734 ;}
1577 break; 1735 break;
1578 1736
1579 case 23:
1580
1581 {
1582 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
1583 ;}
1584 break;
1585
1586 case 24: 1737 case 24:
1587 1738
1739/* Line 1455 of yacc.c */
1740#line 254 "dtc-parser.y"
1588 { 1741 {
1589 (yyval.data) = empty_data; 1742 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
1590 ;} 1743 ;}
1591 break; 1744 break;
1592 1745
1593 case 25: 1746 case 25:
1594 1747
1748/* Line 1455 of yacc.c */
1749#line 261 "dtc-parser.y"
1595 { 1750 {
1596 (yyval.data) = (yyvsp[(1) - (2)].data); 1751 (yyval.data) = empty_data;
1597 ;} 1752 ;}
1598 break; 1753 break;
1599 1754
1600 case 26: 1755 case 26:
1601 1756
1757/* Line 1455 of yacc.c */
1758#line 265 "dtc-parser.y"
1602 { 1759 {
1603 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); 1760 (yyval.data) = (yyvsp[(1) - (2)].data);
1604 ;} 1761 ;}
1605 break; 1762 break;
1606 1763
1607 case 27: 1764 case 27:
1608 1765
1766/* Line 1455 of yacc.c */
1767#line 269 "dtc-parser.y"
1609 { 1768 {
1610 (yyval.data) = empty_data; 1769 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
1611 ;} 1770 ;}
1612 break; 1771 break;
1613 1772
1614 case 28: 1773 case 28:
1615 1774
1775/* Line 1455 of yacc.c */
1776#line 276 "dtc-parser.y"
1616 { 1777 {
1617 (yyval.data) = data_append_cell((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].cell)); 1778 (yyval.array).data = empty_data;
1779 (yyval.array).bits = eval_literal((yyvsp[(2) - (3)].literal), 0, 7);
1780
1781 if (((yyval.array).bits != 8) &&
1782 ((yyval.array).bits != 16) &&
1783 ((yyval.array).bits != 32) &&
1784 ((yyval.array).bits != 64))
1785 {
1786 print_error("Only 8, 16, 32 and 64-bit elements"
1787 " are currently supported");
1788 (yyval.array).bits = 32;
1789 }
1618 ;} 1790 ;}
1619 break; 1791 break;
1620 1792
1621 case 29: 1793 case 29:
1622 1794
1795/* Line 1455 of yacc.c */
1796#line 291 "dtc-parser.y"
1623 { 1797 {
1624 (yyval.data) = data_append_cell(data_add_marker((yyvsp[(1) - (2)].data), REF_PHANDLE, 1798 (yyval.array).data = empty_data;
1625 (yyvsp[(2) - (2)].labelref)), -1); 1799 (yyval.array).bits = 32;
1626 ;} 1800 ;}
1627 break; 1801 break;
1628 1802
1629 case 30: 1803 case 30:
1630 1804
1805/* Line 1455 of yacc.c */
1806#line 296 "dtc-parser.y"
1631 { 1807 {
1632 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); 1808 if ((yyvsp[(1) - (2)].array).bits < 64) {
1809 uint64_t mask = (1ULL << (yyvsp[(1) - (2)].array).bits) - 1;
1810 /*
1811 * Bits above mask must either be all zero
1812 * (positive within range of mask) or all one
1813 * (negative and sign-extended). The second
1814 * condition is true if when we set all bits
1815 * within the mask to one (i.e. | in the
1816 * mask), all bits are one.
1817 */
1818 if (((yyvsp[(2) - (2)].integer) > mask) && (((yyvsp[(2) - (2)].integer) | mask) != -1ULL))
1819 print_error(
1820 "integer value out of range "
1821 "%016lx (%d bits)", (yyvsp[(1) - (2)].array).bits);
1822 }
1823
1824 (yyval.array).data = data_append_integer((yyvsp[(1) - (2)].array).data, (yyvsp[(2) - (2)].integer), (yyvsp[(1) - (2)].array).bits);
1633 ;} 1825 ;}
1634 break; 1826 break;
1635 1827
1636 case 31: 1828 case 31:
1637 1829
1830/* Line 1455 of yacc.c */
1831#line 316 "dtc-parser.y"
1638 { 1832 {
1639 (yyval.cell) = eval_literal((yyvsp[(1) - (1)].literal), 0, 32); 1833 uint64_t val = ~0ULL >> (64 - (yyvsp[(1) - (2)].array).bits);
1834
1835 if ((yyvsp[(1) - (2)].array).bits == 32)
1836 (yyvsp[(1) - (2)].array).data = data_add_marker((yyvsp[(1) - (2)].array).data,
1837 REF_PHANDLE,
1838 (yyvsp[(2) - (2)].labelref));
1839 else
1840 print_error("References are only allowed in "
1841 "arrays with 32-bit elements.");
1842
1843 (yyval.array).data = data_append_integer((yyvsp[(1) - (2)].array).data, val, (yyvsp[(1) - (2)].array).bits);
1640 ;} 1844 ;}
1641 break; 1845 break;
1642 1846
1643 case 32: 1847 case 32:
1644 1848
1849/* Line 1455 of yacc.c */
1850#line 330 "dtc-parser.y"
1645 { 1851 {
1646 (yyval.data) = empty_data; 1852 (yyval.array).data = data_add_marker((yyvsp[(1) - (2)].array).data, LABEL, (yyvsp[(2) - (2)].labelref));
1647 ;} 1853 ;}
1648 break; 1854 break;
1649 1855
1650 case 33: 1856 case 33:
1651 1857
1858/* Line 1455 of yacc.c */
1859#line 337 "dtc-parser.y"
1652 { 1860 {
1653 (yyval.data) = data_append_byte((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].byte)); 1861 (yyval.integer) = eval_literal((yyvsp[(1) - (1)].literal), 0, 64);
1654 ;} 1862 ;}
1655 break; 1863 break;
1656 1864
1657 case 34: 1865 case 34:
1658 1866
1867/* Line 1455 of yacc.c */
1868#line 341 "dtc-parser.y"
1659 { 1869 {
1660 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); 1870 (yyval.integer) = eval_char_literal((yyvsp[(1) - (1)].literal));
1661 ;} 1871 ;}
1662 break; 1872 break;
1663 1873
1664 case 35: 1874 case 35:
1665 1875
1876/* Line 1455 of yacc.c */
1877#line 345 "dtc-parser.y"
1878 {
1879 (yyval.integer) = (yyvsp[(2) - (3)].integer);
1880 ;}
1881 break;
1882
1883 case 38:
1884
1885/* Line 1455 of yacc.c */
1886#line 356 "dtc-parser.y"
1887 { (yyval.integer) = (yyvsp[(1) - (5)].integer) ? (yyvsp[(3) - (5)].integer) : (yyvsp[(5) - (5)].integer); ;}
1888 break;
1889
1890 case 40:
1891
1892/* Line 1455 of yacc.c */
1893#line 361 "dtc-parser.y"
1894 { (yyval.integer) = (yyvsp[(1) - (3)].integer) || (yyvsp[(3) - (3)].integer); ;}
1895 break;
1896
1897 case 42:
1898
1899/* Line 1455 of yacc.c */
1900#line 366 "dtc-parser.y"
1901 { (yyval.integer) = (yyvsp[(1) - (3)].integer) && (yyvsp[(3) - (3)].integer); ;}
1902 break;
1903
1904 case 44:
1905
1906/* Line 1455 of yacc.c */
1907#line 371 "dtc-parser.y"
1908 { (yyval.integer) = (yyvsp[(1) - (3)].integer) | (yyvsp[(3) - (3)].integer); ;}
1909 break;
1910
1911 case 46:
1912
1913/* Line 1455 of yacc.c */
1914#line 376 "dtc-parser.y"
1915 { (yyval.integer) = (yyvsp[(1) - (3)].integer) ^ (yyvsp[(3) - (3)].integer); ;}
1916 break;
1917
1918 case 48:
1919
1920/* Line 1455 of yacc.c */
1921#line 381 "dtc-parser.y"
1922 { (yyval.integer) = (yyvsp[(1) - (3)].integer) & (yyvsp[(3) - (3)].integer); ;}
1923 break;
1924
1925 case 50:
1926
1927/* Line 1455 of yacc.c */
1928#line 386 "dtc-parser.y"
1929 { (yyval.integer) = (yyvsp[(1) - (3)].integer) == (yyvsp[(3) - (3)].integer); ;}
1930 break;
1931
1932 case 51:
1933
1934/* Line 1455 of yacc.c */
1935#line 387 "dtc-parser.y"
1936 { (yyval.integer) = (yyvsp[(1) - (3)].integer) != (yyvsp[(3) - (3)].integer); ;}
1937 break;
1938
1939 case 53:
1940
1941/* Line 1455 of yacc.c */
1942#line 392 "dtc-parser.y"
1943 { (yyval.integer) = (yyvsp[(1) - (3)].integer) < (yyvsp[(3) - (3)].integer); ;}
1944 break;
1945
1946 case 54:
1947
1948/* Line 1455 of yacc.c */
1949#line 393 "dtc-parser.y"
1950 { (yyval.integer) = (yyvsp[(1) - (3)].integer) > (yyvsp[(3) - (3)].integer); ;}
1951 break;
1952
1953 case 55:
1954
1955/* Line 1455 of yacc.c */
1956#line 394 "dtc-parser.y"
1957 { (yyval.integer) = (yyvsp[(1) - (3)].integer) <= (yyvsp[(3) - (3)].integer); ;}
1958 break;
1959
1960 case 56:
1961
1962/* Line 1455 of yacc.c */
1963#line 395 "dtc-parser.y"
1964 { (yyval.integer) = (yyvsp[(1) - (3)].integer) >= (yyvsp[(3) - (3)].integer); ;}
1965 break;
1966
1967 case 57:
1968
1969/* Line 1455 of yacc.c */
1970#line 399 "dtc-parser.y"
1971 { (yyval.integer) = (yyvsp[(1) - (3)].integer) << (yyvsp[(3) - (3)].integer); ;}
1972 break;
1973
1974 case 58:
1975
1976/* Line 1455 of yacc.c */
1977#line 400 "dtc-parser.y"
1978 { (yyval.integer) = (yyvsp[(1) - (3)].integer) >> (yyvsp[(3) - (3)].integer); ;}
1979 break;
1980
1981 case 60:
1982
1983/* Line 1455 of yacc.c */
1984#line 405 "dtc-parser.y"
1985 { (yyval.integer) = (yyvsp[(1) - (3)].integer) + (yyvsp[(3) - (3)].integer); ;}
1986 break;
1987
1988 case 61:
1989
1990/* Line 1455 of yacc.c */
1991#line 406 "dtc-parser.y"
1992 { (yyval.integer) = (yyvsp[(1) - (3)].integer) - (yyvsp[(3) - (3)].integer); ;}
1993 break;
1994
1995 case 63:
1996
1997/* Line 1455 of yacc.c */
1998#line 411 "dtc-parser.y"
1999 { (yyval.integer) = (yyvsp[(1) - (3)].integer) * (yyvsp[(3) - (3)].integer); ;}
2000 break;
2001
2002 case 64:
2003
2004/* Line 1455 of yacc.c */
2005#line 412 "dtc-parser.y"
2006 { (yyval.integer) = (yyvsp[(1) - (3)].integer) / (yyvsp[(3) - (3)].integer); ;}
2007 break;
2008
2009 case 65:
2010
2011/* Line 1455 of yacc.c */
2012#line 413 "dtc-parser.y"
2013 { (yyval.integer) = (yyvsp[(1) - (3)].integer) % (yyvsp[(3) - (3)].integer); ;}
2014 break;
2015
2016 case 68:
2017
2018/* Line 1455 of yacc.c */
2019#line 419 "dtc-parser.y"
2020 { (yyval.integer) = -(yyvsp[(2) - (2)].integer); ;}
2021 break;
2022
2023 case 69:
2024
2025/* Line 1455 of yacc.c */
2026#line 420 "dtc-parser.y"
2027 { (yyval.integer) = ~(yyvsp[(2) - (2)].integer); ;}
2028 break;
2029
2030 case 70:
2031
2032/* Line 1455 of yacc.c */
2033#line 421 "dtc-parser.y"
2034 { (yyval.integer) = !(yyvsp[(2) - (2)].integer); ;}
2035 break;
2036
2037 case 71:
2038
2039/* Line 1455 of yacc.c */
2040#line 426 "dtc-parser.y"
2041 {
2042 (yyval.data) = empty_data;
2043 ;}
2044 break;
2045
2046 case 72:
2047
2048/* Line 1455 of yacc.c */
2049#line 430 "dtc-parser.y"
2050 {
2051 (yyval.data) = data_append_byte((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].byte));
2052 ;}
2053 break;
2054
2055 case 73:
2056
2057/* Line 1455 of yacc.c */
2058#line 434 "dtc-parser.y"
2059 {
2060 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
2061 ;}
2062 break;
2063
2064 case 74:
2065
2066/* Line 1455 of yacc.c */
2067#line 441 "dtc-parser.y"
1666 { 2068 {
1667 (yyval.nodelist) = NULL; 2069 (yyval.nodelist) = NULL;
1668 ;} 2070 ;}
1669 break; 2071 break;
1670 2072
1671 case 36: 2073 case 75:
1672 2074
2075/* Line 1455 of yacc.c */
2076#line 445 "dtc-parser.y"
1673 { 2077 {
1674 (yyval.nodelist) = chain_node((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].nodelist)); 2078 (yyval.nodelist) = chain_node((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].nodelist));
1675 ;} 2079 ;}
1676 break; 2080 break;
1677 2081
1678 case 37: 2082 case 76:
1679 2083
2084/* Line 1455 of yacc.c */
2085#line 449 "dtc-parser.y"
1680 { 2086 {
1681 print_error("syntax error: properties must precede subnodes"); 2087 print_error("syntax error: properties must precede subnodes");
1682 YYERROR; 2088 YYERROR;
1683 ;} 2089 ;}
1684 break; 2090 break;
1685 2091
1686 case 38: 2092 case 77:
1687 2093
2094/* Line 1455 of yacc.c */
2095#line 457 "dtc-parser.y"
1688 { 2096 {
1689 (yyval.node) = name_node((yyvsp[(2) - (2)].node), (yyvsp[(1) - (2)].propnodename)); 2097 (yyval.node) = name_node((yyvsp[(2) - (2)].node), (yyvsp[(1) - (2)].propnodename));
1690 ;} 2098 ;}
1691 break; 2099 break;
1692 2100
1693 case 39: 2101 case 78:
2102
2103/* Line 1455 of yacc.c */
2104#line 461 "dtc-parser.y"
2105 {
2106 (yyval.node) = name_node(build_node_delete(), (yyvsp[(2) - (3)].propnodename));
2107 ;}
2108 break;
2109
2110 case 79:
1694 2111
2112/* Line 1455 of yacc.c */
2113#line 465 "dtc-parser.y"
1695 { 2114 {
1696 add_label(&(yyvsp[(2) - (2)].node)->labels, (yyvsp[(1) - (2)].labelref)); 2115 add_label(&(yyvsp[(2) - (2)].node)->labels, (yyvsp[(1) - (2)].labelref));
1697 (yyval.node) = (yyvsp[(2) - (2)].node); 2116 (yyval.node) = (yyvsp[(2) - (2)].node);
@@ -1700,6 +2119,8 @@ yyreduce:
1700 2119
1701 2120
1702 2121
2122/* Line 1455 of yacc.c */
2123#line 2124 "dtc-parser.tab.c"
1703 default: break; 2124 default: break;
1704 } 2125 }
1705 YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); 2126 YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -1910,6 +2331,8 @@ yyreturn:
1910 2331
1911 2332
1912 2333
2334/* Line 1675 of yacc.c */
2335#line 471 "dtc-parser.y"
1913 2336
1914 2337
1915void print_error(char const *fmt, ...) 2338void print_error(char const *fmt, ...)
@@ -1934,9 +2357,12 @@ static unsigned long long eval_literal(const char *s, int base, int bits)
1934 2357
1935 errno = 0; 2358 errno = 0;
1936 val = strtoull(s, &e, base); 2359 val = strtoull(s, &e, base);
1937 if (*e) 2360 if (*e) {
1938 print_error("bad characters in literal"); 2361 size_t uls = strspn(e, "UL");
1939 else if ((errno == ERANGE) 2362 if (e[uls])
2363 print_error("bad characters in literal");
2364 }
2365 if ((errno == ERANGE)
1940 || ((bits < 64) && (val >= (1ULL << bits)))) 2366 || ((bits < 64) && (val >= (1ULL << bits))))
1941 print_error("literal out of range"); 2367 print_error("literal out of range");
1942 else if (errno != 0) 2368 else if (errno != 0)
@@ -1944,3 +2370,29 @@ static unsigned long long eval_literal(const char *s, int base, int bits)
1944 return val; 2370 return val;
1945} 2371}
1946 2372
2373static unsigned char eval_char_literal(const char *s)
2374{
2375 int i = 1;
2376 char c = s[0];
2377
2378 if (c == '\0')
2379 {
2380 print_error("empty character literal");
2381 return 0;
2382 }
2383
2384 /*
2385 * If the first character in the character literal is a \ then process
2386 * the remaining characters as an escape encoding. If the first
2387 * character is neither an escape or a terminator it should be the only
2388 * character in the literal and will be returned.
2389 */
2390 if (c == '\\')
2391 c = get_escape_char(s, &i);
2392
2393 if (s[i] != '\0')
2394 print_error("malformed character literal");
2395
2396 return c;
2397}
2398
diff --git a/scripts/dtc/dtc-parser.tab.h_shipped b/scripts/dtc/dtc-parser.tab.h_shipped
index 4ee682bb7d33..9d2dce41211f 100644
--- a/scripts/dtc/dtc-parser.tab.h_shipped
+++ b/scripts/dtc/dtc-parser.tab.h_shipped
@@ -1,9 +1,10 @@
1/* A Bison parser, made by GNU Bison 2.4.3. */ 1
2/* A Bison parser, made by GNU Bison 2.4.1. */
2 3
3/* Skeleton interface for Bison's Yacc-like parsers in C 4/* Skeleton interface for Bison's Yacc-like parsers in C
4 5
5 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 6 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
6 2009, 2010 Free Software Foundation, Inc. 7 Free Software Foundation, Inc.
7 8
8 This program is free software: you can redistribute it and/or modify 9 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by 10 it under the terms of the GNU General Public License as published by
@@ -40,14 +41,26 @@
40 enum yytokentype { 41 enum yytokentype {
41 DT_V1 = 258, 42 DT_V1 = 258,
42 DT_MEMRESERVE = 259, 43 DT_MEMRESERVE = 259,
43 DT_PROPNODENAME = 260, 44 DT_LSHIFT = 260,
44 DT_LITERAL = 261, 45 DT_RSHIFT = 261,
45 DT_BASE = 262, 46 DT_LE = 262,
46 DT_BYTE = 263, 47 DT_GE = 263,
47 DT_STRING = 264, 48 DT_EQ = 264,
48 DT_LABEL = 265, 49 DT_NE = 265,
49 DT_REF = 266, 50 DT_AND = 266,
50 DT_INCBIN = 267 51 DT_OR = 267,
52 DT_BITS = 268,
53 DT_DEL_PROP = 269,
54 DT_DEL_NODE = 270,
55 DT_PROPNODENAME = 271,
56 DT_LITERAL = 272,
57 DT_CHAR_LITERAL = 273,
58 DT_BASE = 274,
59 DT_BYTE = 275,
60 DT_STRING = 276,
61 DT_LABEL = 277,
62 DT_REF = 278,
63 DT_INCBIN = 279
51 }; 64 };
52#endif 65#endif
53 66
@@ -57,6 +70,8 @@
57typedef union YYSTYPE 70typedef union YYSTYPE
58{ 71{
59 72
73/* Line 1676 of yacc.c */
74#line 40 "dtc-parser.y"
60 75
61 char *propnodename; 76 char *propnodename;
62 char *literal; 77 char *literal;
@@ -65,16 +80,22 @@ typedef union YYSTYPE
65 uint8_t byte; 80 uint8_t byte;
66 struct data data; 81 struct data data;
67 82
68 uint64_t addr; 83 struct {
69 cell_t cell; 84 struct data data;
85 int bits;
86 } array;
87
70 struct property *prop; 88 struct property *prop;
71 struct property *proplist; 89 struct property *proplist;
72 struct node *node; 90 struct node *node;
73 struct node *nodelist; 91 struct node *nodelist;
74 struct reserve_info *re; 92 struct reserve_info *re;
93 uint64_t integer;
75 94
76 95
77 96
97/* Line 1676 of yacc.c */
98#line 99 "dtc-parser.tab.h"
78} YYSTYPE; 99} YYSTYPE;
79# define YYSTYPE_IS_TRIVIAL 1 100# define YYSTYPE_IS_TRIVIAL 1
80# define yystype YYSTYPE /* obsolescent; will be withdrawn */ 101# define yystype YYSTYPE /* obsolescent; will be withdrawn */
diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y
index 5e84a67fc1d2..f412460f94d7 100644
--- a/scripts/dtc/dtc-parser.y
+++ b/scripts/dtc/dtc-parser.y
@@ -34,6 +34,7 @@ extern struct boot_info *the_boot_info;
34extern int treesource_error; 34extern int treesource_error;
35 35
36static unsigned long long eval_literal(const char *s, int base, int bits); 36static unsigned long long eval_literal(const char *s, int base, int bits);
37static unsigned char eval_char_literal(const char *s);
37%} 38%}
38 39
39%union { 40%union {
@@ -44,19 +45,28 @@ static unsigned long long eval_literal(const char *s, int base, int bits);
44 uint8_t byte; 45 uint8_t byte;
45 struct data data; 46 struct data data;
46 47
47 uint64_t addr; 48 struct {
48 cell_t cell; 49 struct data data;
50 int bits;
51 } array;
52
49 struct property *prop; 53 struct property *prop;
50 struct property *proplist; 54 struct property *proplist;
51 struct node *node; 55 struct node *node;
52 struct node *nodelist; 56 struct node *nodelist;
53 struct reserve_info *re; 57 struct reserve_info *re;
58 uint64_t integer;
54} 59}
55 60
56%token DT_V1 61%token DT_V1
57%token DT_MEMRESERVE 62%token DT_MEMRESERVE
63%token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR
64%token DT_BITS
65%token DT_DEL_PROP
66%token DT_DEL_NODE
58%token <propnodename> DT_PROPNODENAME 67%token <propnodename> DT_PROPNODENAME
59%token <literal> DT_LITERAL 68%token <literal> DT_LITERAL
69%token <literal> DT_CHAR_LITERAL
60%token <cbase> DT_BASE 70%token <cbase> DT_BASE
61%token <byte> DT_BYTE 71%token <byte> DT_BYTE
62%token <data> DT_STRING 72%token <data> DT_STRING
@@ -68,9 +78,7 @@ static unsigned long long eval_literal(const char *s, int base, int bits);
68%type <data> propdataprefix 78%type <data> propdataprefix
69%type <re> memreserve 79%type <re> memreserve
70%type <re> memreserves 80%type <re> memreserves
71%type <addr> addr 81%type <array> arrayprefix
72%type <data> celllist
73%type <cell> cellval
74%type <data> bytestring 82%type <data> bytestring
75%type <prop> propdef 83%type <prop> propdef
76%type <proplist> proplist 84%type <proplist> proplist
@@ -80,6 +88,21 @@ static unsigned long long eval_literal(const char *s, int base, int bits);
80%type <node> subnode 88%type <node> subnode
81%type <nodelist> subnodes 89%type <nodelist> subnodes
82 90
91%type <integer> integer_prim
92%type <integer> integer_unary
93%type <integer> integer_mul
94%type <integer> integer_add
95%type <integer> integer_shift
96%type <integer> integer_rela
97%type <integer> integer_eq
98%type <integer> integer_bitand
99%type <integer> integer_bitxor
100%type <integer> integer_bitor
101%type <integer> integer_and
102%type <integer> integer_or
103%type <integer> integer_trinary
104%type <integer> integer_expr
105
83%% 106%%
84 107
85sourcefile: 108sourcefile:
@@ -102,7 +125,7 @@ memreserves:
102 ; 125 ;
103 126
104memreserve: 127memreserve:
105 DT_MEMRESERVE addr addr ';' 128 DT_MEMRESERVE integer_prim integer_prim ';'
106 { 129 {
107 $$ = build_reserve_entry($2, $3); 130 $$ = build_reserve_entry($2, $3);
108 } 131 }
@@ -113,13 +136,6 @@ memreserve:
113 } 136 }
114 ; 137 ;
115 138
116addr:
117 DT_LITERAL
118 {
119 $$ = eval_literal($1, 0, 64);
120 }
121 ;
122
123devicetree: 139devicetree:
124 '/' nodedef 140 '/' nodedef
125 { 141 {
@@ -139,6 +155,17 @@ devicetree:
139 print_error("label or path, '%s', not found", $2); 155 print_error("label or path, '%s', not found", $2);
140 $$ = $1; 156 $$ = $1;
141 } 157 }
158 | devicetree DT_DEL_NODE DT_REF ';'
159 {
160 struct node *target = get_node_by_ref($1, $3);
161
162 if (!target)
163 print_error("label or path, '%s', not found", $3);
164 else
165 delete_node(target);
166
167 $$ = $1;
168 }
142 ; 169 ;
143 170
144nodedef: 171nodedef:
@@ -168,6 +195,10 @@ propdef:
168 { 195 {
169 $$ = build_property($1, empty_data); 196 $$ = build_property($1, empty_data);
170 } 197 }
198 | DT_DEL_PROP DT_PROPNODENAME ';'
199 {
200 $$ = build_property_delete($2);
201 }
171 | DT_LABEL propdef 202 | DT_LABEL propdef
172 { 203 {
173 add_label(&$2->labels, $1); 204 add_label(&$2->labels, $1);
@@ -180,9 +211,9 @@ propdata:
180 { 211 {
181 $$ = data_merge($1, $2); 212 $$ = data_merge($1, $2);
182 } 213 }
183 | propdataprefix '<' celllist '>' 214 | propdataprefix arrayprefix '>'
184 { 215 {
185 $$ = data_merge($1, $3); 216 $$ = data_merge($1, $2.data);
186 } 217 }
187 | propdataprefix '[' bytestring ']' 218 | propdataprefix '[' bytestring ']'
188 { 219 {
@@ -192,7 +223,7 @@ propdata:
192 { 223 {
193 $$ = data_add_marker($1, REF_PATH, $2); 224 $$ = data_add_marker($1, REF_PATH, $2);
194 } 225 }
195 | propdataprefix DT_INCBIN '(' DT_STRING ',' addr ',' addr ')' 226 | propdataprefix DT_INCBIN '(' DT_STRING ',' integer_prim ',' integer_prim ')'
196 { 227 {
197 FILE *f = srcfile_relative_open($4.val, NULL); 228 FILE *f = srcfile_relative_open($4.val, NULL);
198 struct data d; 229 struct data d;
@@ -240,31 +271,154 @@ propdataprefix:
240 } 271 }
241 ; 272 ;
242 273
243celllist: 274arrayprefix:
244 /* empty */ 275 DT_BITS DT_LITERAL '<'
276 {
277 $$.data = empty_data;
278 $$.bits = eval_literal($2, 0, 7);
279
280 if (($$.bits != 8) &&
281 ($$.bits != 16) &&
282 ($$.bits != 32) &&
283 ($$.bits != 64))
284 {
285 print_error("Only 8, 16, 32 and 64-bit elements"
286 " are currently supported");
287 $$.bits = 32;
288 }
289 }
290 | '<'
291 {
292 $$.data = empty_data;
293 $$.bits = 32;
294 }
295 | arrayprefix integer_prim
296 {
297 if ($1.bits < 64) {
298 uint64_t mask = (1ULL << $1.bits) - 1;
299 /*
300 * Bits above mask must either be all zero
301 * (positive within range of mask) or all one
302 * (negative and sign-extended). The second
303 * condition is true if when we set all bits
304 * within the mask to one (i.e. | in the
305 * mask), all bits are one.
306 */
307 if (($2 > mask) && (($2 | mask) != -1ULL))
308 print_error(
309 "integer value out of range "
310 "%016lx (%d bits)", $1.bits);
311 }
312
313 $$.data = data_append_integer($1.data, $2, $1.bits);
314 }
315 | arrayprefix DT_REF
316 {
317 uint64_t val = ~0ULL >> (64 - $1.bits);
318
319 if ($1.bits == 32)
320 $1.data = data_add_marker($1.data,
321 REF_PHANDLE,
322 $2);
323 else
324 print_error("References are only allowed in "
325 "arrays with 32-bit elements.");
326
327 $$.data = data_append_integer($1.data, val, $1.bits);
328 }
329 | arrayprefix DT_LABEL
245 { 330 {
246 $$ = empty_data; 331 $$.data = data_add_marker($1.data, LABEL, $2);
247 } 332 }
248 | celllist cellval 333 ;
334
335integer_prim:
336 DT_LITERAL
249 { 337 {
250 $$ = data_append_cell($1, $2); 338 $$ = eval_literal($1, 0, 64);
251 } 339 }
252 | celllist DT_REF 340 | DT_CHAR_LITERAL
253 { 341 {
254 $$ = data_append_cell(data_add_marker($1, REF_PHANDLE, 342 $$ = eval_char_literal($1);
255 $2), -1);
256 } 343 }
257 | celllist DT_LABEL 344 | '(' integer_expr ')'
258 { 345 {
259 $$ = data_add_marker($1, LABEL, $2); 346 $$ = $2;
260 } 347 }
261 ; 348 ;
262 349
263cellval: 350integer_expr:
264 DT_LITERAL 351 integer_trinary
265 { 352 ;
266 $$ = eval_literal($1, 0, 32); 353
267 } 354integer_trinary:
355 integer_or
356 | integer_or '?' integer_expr ':' integer_trinary { $$ = $1 ? $3 : $5; }
357 ;
358
359integer_or:
360 integer_and
361 | integer_or DT_OR integer_and { $$ = $1 || $3; }
362 ;
363
364integer_and:
365 integer_bitor
366 | integer_and DT_AND integer_bitor { $$ = $1 && $3; }
367 ;
368
369integer_bitor:
370 integer_bitxor
371 | integer_bitor '|' integer_bitxor { $$ = $1 | $3; }
372 ;
373
374integer_bitxor:
375 integer_bitand
376 | integer_bitxor '^' integer_bitand { $$ = $1 ^ $3; }
377 ;
378
379integer_bitand:
380 integer_eq
381 | integer_bitand '&' integer_eq { $$ = $1 & $3; }
382 ;
383
384integer_eq:
385 integer_rela
386 | integer_eq DT_EQ integer_rela { $$ = $1 == $3; }
387 | integer_eq DT_NE integer_rela { $$ = $1 != $3; }
388 ;
389
390integer_rela:
391 integer_shift
392 | integer_rela '<' integer_shift { $$ = $1 < $3; }
393 | integer_rela '>' integer_shift { $$ = $1 > $3; }
394 | integer_rela DT_LE integer_shift { $$ = $1 <= $3; }
395 | integer_rela DT_GE integer_shift { $$ = $1 >= $3; }
396 ;
397
398integer_shift:
399 integer_shift DT_LSHIFT integer_add { $$ = $1 << $3; }
400 | integer_shift DT_RSHIFT integer_add { $$ = $1 >> $3; }
401 | integer_add
402 ;
403
404integer_add:
405 integer_add '+' integer_mul { $$ = $1 + $3; }
406 | integer_add '-' integer_mul { $$ = $1 - $3; }
407 | integer_mul
408 ;
409
410integer_mul:
411 integer_mul '*' integer_unary { $$ = $1 * $3; }
412 | integer_mul '/' integer_unary { $$ = $1 / $3; }
413 | integer_mul '%' integer_unary { $$ = $1 % $3; }
414 | integer_unary
415 ;
416
417integer_unary:
418 integer_prim
419 | '-' integer_unary { $$ = -$2; }
420 | '~' integer_unary { $$ = ~$2; }
421 | '!' integer_unary { $$ = !$2; }
268 ; 422 ;
269 423
270bytestring: 424bytestring:
@@ -303,6 +457,10 @@ subnode:
303 { 457 {
304 $$ = name_node($2, $1); 458 $$ = name_node($2, $1);
305 } 459 }
460 | DT_DEL_NODE DT_PROPNODENAME ';'
461 {
462 $$ = name_node(build_node_delete(), $2);
463 }
306 | DT_LABEL subnode 464 | DT_LABEL subnode
307 { 465 {
308 add_label(&$2->labels, $1); 466 add_label(&$2->labels, $1);
@@ -334,12 +492,41 @@ static unsigned long long eval_literal(const char *s, int base, int bits)
334 492
335 errno = 0; 493 errno = 0;
336 val = strtoull(s, &e, base); 494 val = strtoull(s, &e, base);
337 if (*e) 495 if (*e) {
338 print_error("bad characters in literal"); 496 size_t uls = strspn(e, "UL");
339 else if ((errno == ERANGE) 497 if (e[uls])
498 print_error("bad characters in literal");
499 }
500 if ((errno == ERANGE)
340 || ((bits < 64) && (val >= (1ULL << bits)))) 501 || ((bits < 64) && (val >= (1ULL << bits))))
341 print_error("literal out of range"); 502 print_error("literal out of range");
342 else if (errno != 0) 503 else if (errno != 0)
343 print_error("bad literal"); 504 print_error("bad literal");
344 return val; 505 return val;
345} 506}
507
508static unsigned char eval_char_literal(const char *s)
509{
510 int i = 1;
511 char c = s[0];
512
513 if (c == '\0')
514 {
515 print_error("empty character literal");
516 return 0;
517 }
518
519 /*
520 * If the first character in the character literal is a \ then process
521 * the remaining characters as an escape encoding. If the first
522 * character is neither an escape or a terminator it should be the only
523 * character in the literal and will be returned.
524 */
525 if (c == '\\')
526 c = get_escape_char(s, &i);
527
528 if (s[i] != '\0')
529 print_error("malformed character literal");
530
531 return c;
532}
diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c
index 2ef5e2e3dd38..a375683c1534 100644
--- a/scripts/dtc/dtc.c
+++ b/scripts/dtc/dtc.c
@@ -82,6 +82,8 @@ static void __attribute__ ((noreturn)) usage(void)
82 fprintf(stderr, "\t\tSet the physical boot cpu\n"); 82 fprintf(stderr, "\t\tSet the physical boot cpu\n");
83 fprintf(stderr, "\t-f\n"); 83 fprintf(stderr, "\t-f\n");
84 fprintf(stderr, "\t\tForce - try to produce output even if the input tree has errors\n"); 84 fprintf(stderr, "\t\tForce - try to produce output even if the input tree has errors\n");
85 fprintf(stderr, "\t-i\n");
86 fprintf(stderr, "\t\tAdd a path to search for include files\n");
85 fprintf(stderr, "\t-s\n"); 87 fprintf(stderr, "\t-s\n");
86 fprintf(stderr, "\t\tSort nodes and properties before outputting (only useful for\n\t\tcomparing trees)\n"); 88 fprintf(stderr, "\t\tSort nodes and properties before outputting (only useful for\n\t\tcomparing trees)\n");
87 fprintf(stderr, "\t-v\n"); 89 fprintf(stderr, "\t-v\n");
@@ -91,6 +93,9 @@ static void __attribute__ ((noreturn)) usage(void)
91 fprintf(stderr, "\t\t\tlegacy - \"linux,phandle\" properties only\n"); 93 fprintf(stderr, "\t\t\tlegacy - \"linux,phandle\" properties only\n");
92 fprintf(stderr, "\t\t\tepapr - \"phandle\" properties only\n"); 94 fprintf(stderr, "\t\t\tepapr - \"phandle\" properties only\n");
93 fprintf(stderr, "\t\t\tboth - Both \"linux,phandle\" and \"phandle\" properties\n"); 95 fprintf(stderr, "\t\t\tboth - Both \"linux,phandle\" and \"phandle\" properties\n");
96 fprintf(stderr, "\t-W [no-]<checkname>\n");
97 fprintf(stderr, "\t-E [no-]<checkname>\n");
98 fprintf(stderr, "\t\t\tenable or disable warnings and errors\n");
94 exit(3); 99 exit(3);
95} 100}
96 101
@@ -113,7 +118,7 @@ int main(int argc, char *argv[])
113 minsize = 0; 118 minsize = 0;
114 padsize = 0; 119 padsize = 0;
115 120
116 while ((opt = getopt(argc, argv, "hI:O:o:V:d:R:S:p:fcqb:vH:s")) 121 while ((opt = getopt(argc, argv, "hI:O:o:V:d:R:S:p:fqb:i:vH:sW:E:"))
117 != EOF) { 122 != EOF) {
118 switch (opt) { 123 switch (opt) {
119 case 'I': 124 case 'I':
@@ -149,6 +154,9 @@ int main(int argc, char *argv[])
149 case 'b': 154 case 'b':
150 cmdline_boot_cpuid = strtoll(optarg, NULL, 0); 155 cmdline_boot_cpuid = strtoll(optarg, NULL, 0);
151 break; 156 break;
157 case 'i':
158 srcfile_add_search_path(optarg);
159 break;
152 case 'v': 160 case 'v':
153 printf("Version: %s\n", DTC_VERSION); 161 printf("Version: %s\n", DTC_VERSION);
154 exit(0); 162 exit(0);
@@ -168,6 +176,14 @@ int main(int argc, char *argv[])
168 sort = 1; 176 sort = 1;
169 break; 177 break;
170 178
179 case 'W':
180 parse_checks_option(true, false, optarg);
181 break;
182
183 case 'E':
184 parse_checks_option(false, true, optarg);
185 break;
186
171 case 'h': 187 case 'h':
172 default: 188 default:
173 usage(); 189 usage();
@@ -188,9 +204,6 @@ int main(int argc, char *argv[])
188 if (minsize) 204 if (minsize)
189 fprintf(stderr, "DTC: Use of \"-S\" is deprecated; it will be removed soon, use \"-p\" instead\n"); 205 fprintf(stderr, "DTC: Use of \"-S\" is deprecated; it will be removed soon, use \"-p\" instead\n");
190 206
191 fprintf(stderr, "DTC: %s->%s on file \"%s\"\n",
192 inform, outform, arg);
193
194 if (depname) { 207 if (depname) {
195 depfile = fopen(depname, "w"); 208 depfile = fopen(depname, "w");
196 if (!depfile) 209 if (!depfile)
diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h
index f37c97eb3dfc..d501c8605f26 100644
--- a/scripts/dtc/dtc.h
+++ b/scripts/dtc/dtc.h
@@ -25,6 +25,7 @@
25#include <string.h> 25#include <string.h>
26#include <stdlib.h> 26#include <stdlib.h>
27#include <stdint.h> 27#include <stdint.h>
28#include <stdbool.h>
28#include <stdarg.h> 29#include <stdarg.h>
29#include <assert.h> 30#include <assert.h>
30#include <ctype.h> 31#include <ctype.h>
@@ -109,6 +110,7 @@ struct data data_insert_at_marker(struct data d, struct marker *m,
109 const void *p, int len); 110 const void *p, int len);
110struct data data_merge(struct data d1, struct data d2); 111struct data data_merge(struct data d1, struct data d2);
111struct data data_append_cell(struct data d, cell_t word); 112struct data data_append_cell(struct data d, cell_t word);
113struct data data_append_integer(struct data d, uint64_t word, int bits);
112struct data data_append_re(struct data d, const struct fdt_reserve_entry *re); 114struct data data_append_re(struct data d, const struct fdt_reserve_entry *re);
113struct data data_append_addr(struct data d, uint64_t addr); 115struct data data_append_addr(struct data d, uint64_t addr);
114struct data data_append_byte(struct data d, uint8_t byte); 116struct data data_append_byte(struct data d, uint8_t byte);
@@ -126,11 +128,13 @@ int data_is_one_string(struct data d);
126 128
127/* Live trees */ 129/* Live trees */
128struct label { 130struct label {
131 int deleted;
129 char *label; 132 char *label;
130 struct label *next; 133 struct label *next;
131}; 134};
132 135
133struct property { 136struct property {
137 int deleted;
134 char *name; 138 char *name;
135 struct data val; 139 struct data val;
136 140
@@ -140,6 +144,7 @@ struct property {
140}; 144};
141 145
142struct node { 146struct node {
147 int deleted;
143 char *name; 148 char *name;
144 struct property *proplist; 149 struct property *proplist;
145 struct node *children; 150 struct node *children;
@@ -156,28 +161,71 @@ struct node {
156 struct label *labels; 161 struct label *labels;
157}; 162};
158 163
164static inline struct label *for_each_label_next(struct label *l)
165{
166 do {
167 l = l->next;
168 } while (l && l->deleted);
169
170 return l;
171}
172
159#define for_each_label(l0, l) \ 173#define for_each_label(l0, l) \
174 for ((l) = (l0); (l); (l) = for_each_label_next(l))
175
176#define for_each_label_withdel(l0, l) \
160 for ((l) = (l0); (l); (l) = (l)->next) 177 for ((l) = (l0); (l); (l) = (l)->next)
161 178
179static inline struct property *for_each_property_next(struct property *p)
180{
181 do {
182 p = p->next;
183 } while (p && p->deleted);
184
185 return p;
186}
187
162#define for_each_property(n, p) \ 188#define for_each_property(n, p) \
189 for ((p) = (n)->proplist; (p); (p) = for_each_property_next(p))
190
191#define for_each_property_withdel(n, p) \
163 for ((p) = (n)->proplist; (p); (p) = (p)->next) 192 for ((p) = (n)->proplist; (p); (p) = (p)->next)
164 193
165#define for_each_child(n, c) \ 194static inline struct node *for_each_child_next(struct node *c)
195{
196 do {
197 c = c->next_sibling;
198 } while (c && c->deleted);
199
200 return c;
201}
202
203#define for_each_child(n, c) \
204 for ((c) = (n)->children; (c); (c) = for_each_child_next(c))
205
206#define for_each_child_withdel(n, c) \
166 for ((c) = (n)->children; (c); (c) = (c)->next_sibling) 207 for ((c) = (n)->children; (c); (c) = (c)->next_sibling)
167 208
168void add_label(struct label **labels, char *label); 209void add_label(struct label **labels, char *label);
210void delete_labels(struct label **labels);
169 211
170struct property *build_property(char *name, struct data val); 212struct property *build_property(char *name, struct data val);
213struct property *build_property_delete(char *name);
171struct property *chain_property(struct property *first, struct property *list); 214struct property *chain_property(struct property *first, struct property *list);
172struct property *reverse_properties(struct property *first); 215struct property *reverse_properties(struct property *first);
173 216
174struct node *build_node(struct property *proplist, struct node *children); 217struct node *build_node(struct property *proplist, struct node *children);
218struct node *build_node_delete(void);
175struct node *name_node(struct node *node, char *name); 219struct node *name_node(struct node *node, char *name);
176struct node *chain_node(struct node *first, struct node *list); 220struct node *chain_node(struct node *first, struct node *list);
177struct node *merge_nodes(struct node *old_node, struct node *new_node); 221struct node *merge_nodes(struct node *old_node, struct node *new_node);
178 222
179void add_property(struct node *node, struct property *prop); 223void add_property(struct node *node, struct property *prop);
224void delete_property_by_name(struct node *node, char *name);
225void delete_property(struct property *prop);
180void add_child(struct node *parent, struct node *child); 226void add_child(struct node *parent, struct node *child);
227void delete_node_by_name(struct node *parent, char *name);
228void delete_node(struct node *node);
181 229
182const char *get_unitname(struct node *node); 230const char *get_unitname(struct node *node);
183struct property *get_property(struct node *node, const char *propname); 231struct property *get_property(struct node *node, const char *propname);
@@ -224,6 +272,7 @@ void sort_tree(struct boot_info *bi);
224 272
225/* Checks */ 273/* Checks */
226 274
275void parse_checks_option(bool warn, bool error, const char *optarg);
227void process_checks(int force, struct boot_info *bi); 276void process_checks(int force, struct boot_info *bi);
228 277
229/* Flattened trees */ 278/* Flattened trees */
diff --git a/scripts/dtc/fdtdump.c b/scripts/dtc/fdtdump.c
new file mode 100644
index 000000000000..207a46d64864
--- /dev/null
+++ b/scripts/dtc/fdtdump.c
@@ -0,0 +1,162 @@
1/*
2 * fdtdump.c - Contributed by Pantelis Antoniou <pantelis.antoniou AT gmail.com>
3 */
4
5#include <stdint.h>
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9#include <ctype.h>
10
11#include <fdt.h>
12#include <libfdt_env.h>
13
14#include "util.h"
15
16#define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1))
17#define PALIGN(p, a) ((void *)(ALIGN((unsigned long)(p), (a))))
18#define GET_CELL(p) (p += 4, *((const uint32_t *)(p-4)))
19
20static void print_data(const char *data, int len)
21{
22 int i;
23 const char *p = data;
24
25 /* no data, don't print */
26 if (len == 0)
27 return;
28
29 if (util_is_printable_string(data, len)) {
30 printf(" = \"%s\"", (const char *)data);
31 } else if ((len % 4) == 0) {
32 printf(" = <");
33 for (i = 0; i < len; i += 4)
34 printf("0x%08x%s", fdt32_to_cpu(GET_CELL(p)),
35 i < (len - 4) ? " " : "");
36 printf(">");
37 } else {
38 printf(" = [");
39 for (i = 0; i < len; i++)
40 printf("%02x%s", *p++, i < len - 1 ? " " : "");
41 printf("]");
42 }
43}
44
45static void dump_blob(void *blob)
46{
47 struct fdt_header *bph = blob;
48 uint32_t off_mem_rsvmap = fdt32_to_cpu(bph->off_mem_rsvmap);
49 uint32_t off_dt = fdt32_to_cpu(bph->off_dt_struct);
50 uint32_t off_str = fdt32_to_cpu(bph->off_dt_strings);
51 struct fdt_reserve_entry *p_rsvmap =
52 (struct fdt_reserve_entry *)((char *)blob + off_mem_rsvmap);
53 const char *p_struct = (const char *)blob + off_dt;
54 const char *p_strings = (const char *)blob + off_str;
55 uint32_t version = fdt32_to_cpu(bph->version);
56 uint32_t totalsize = fdt32_to_cpu(bph->totalsize);
57 uint32_t tag;
58 const char *p, *s, *t;
59 int depth, sz, shift;
60 int i;
61 uint64_t addr, size;
62
63 depth = 0;
64 shift = 4;
65
66 printf("/dts-v1/;\n");
67 printf("// magic:\t\t0x%x\n", fdt32_to_cpu(bph->magic));
68 printf("// totalsize:\t\t0x%x (%d)\n", totalsize, totalsize);
69 printf("// off_dt_struct:\t0x%x\n", off_dt);
70 printf("// off_dt_strings:\t0x%x\n", off_str);
71 printf("// off_mem_rsvmap:\t0x%x\n", off_mem_rsvmap);
72 printf("// version:\t\t%d\n", version);
73 printf("// last_comp_version:\t%d\n",
74 fdt32_to_cpu(bph->last_comp_version));
75 if (version >= 2)
76 printf("// boot_cpuid_phys:\t0x%x\n",
77 fdt32_to_cpu(bph->boot_cpuid_phys));
78
79 if (version >= 3)
80 printf("// size_dt_strings:\t0x%x\n",
81 fdt32_to_cpu(bph->size_dt_strings));
82 if (version >= 17)
83 printf("// size_dt_struct:\t0x%x\n",
84 fdt32_to_cpu(bph->size_dt_struct));
85 printf("\n");
86
87 for (i = 0; ; i++) {
88 addr = fdt64_to_cpu(p_rsvmap[i].address);
89 size = fdt64_to_cpu(p_rsvmap[i].size);
90 if (addr == 0 && size == 0)
91 break;
92
93 printf("/memreserve/ %llx %llx;\n",
94 (unsigned long long)addr, (unsigned long long)size);
95 }
96
97 p = p_struct;
98 while ((tag = fdt32_to_cpu(GET_CELL(p))) != FDT_END) {
99
100 /* printf("tag: 0x%08x (%d)\n", tag, p - p_struct); */
101
102 if (tag == FDT_BEGIN_NODE) {
103 s = p;
104 p = PALIGN(p + strlen(s) + 1, 4);
105
106 if (*s == '\0')
107 s = "/";
108
109 printf("%*s%s {\n", depth * shift, "", s);
110
111 depth++;
112 continue;
113 }
114
115 if (tag == FDT_END_NODE) {
116 depth--;
117
118 printf("%*s};\n", depth * shift, "");
119 continue;
120 }
121
122 if (tag == FDT_NOP) {
123 printf("%*s// [NOP]\n", depth * shift, "");
124 continue;
125 }
126
127 if (tag != FDT_PROP) {
128 fprintf(stderr, "%*s ** Unknown tag 0x%08x\n", depth * shift, "", tag);
129 break;
130 }
131 sz = fdt32_to_cpu(GET_CELL(p));
132 s = p_strings + fdt32_to_cpu(GET_CELL(p));
133 if (version < 16 && sz >= 8)
134 p = PALIGN(p, 8);
135 t = p;
136
137 p = PALIGN(p + sz, 4);
138
139 printf("%*s%s", depth * shift, "", s);
140 print_data(t, sz);
141 printf(";\n");
142 }
143}
144
145
146int main(int argc, char *argv[])
147{
148 char *buf;
149
150 if (argc < 2) {
151 fprintf(stderr, "supply input filename\n");
152 return 5;
153 }
154
155 buf = utilfdt_read(argv[1]);
156 if (buf)
157 dump_blob(buf);
158 else
159 return 10;
160
161 return 0;
162}
diff --git a/scripts/dtc/fdtget.c b/scripts/dtc/fdtget.c
new file mode 100644
index 000000000000..c2fbab2a5476
--- /dev/null
+++ b/scripts/dtc/fdtget.c
@@ -0,0 +1,366 @@
1/*
2 * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
3 *
4 * Portions from U-Boot cmd_fdt.c (C) Copyright 2007
5 * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com
6 * Based on code written by:
7 * Pantelis Antoniou <pantelis.antoniou@gmail.com> and
8 * Matthew McClintock <msm@freescale.com>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
23 * MA 02111-1307 USA
24 */
25
26#include <assert.h>
27#include <ctype.h>
28#include <getopt.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32
33#include <libfdt.h>
34
35#include "util.h"
36
37enum display_mode {
38 MODE_SHOW_VALUE, /* show values for node properties */
39 MODE_LIST_PROPS, /* list the properties for a node */
40 MODE_LIST_SUBNODES, /* list the subnodes of a node */
41};
42
43/* Holds information which controls our output and options */
44struct display_info {
45 int type; /* data type (s/i/u/x or 0 for default) */
46 int size; /* data size (1/2/4) */
47 enum display_mode mode; /* display mode that we are using */
48 const char *default_val; /* default value if node/property not found */
49};
50
51static void report_error(const char *where, int err)
52{
53 fprintf(stderr, "Error at '%s': %s\n", where, fdt_strerror(err));
54}
55
56/**
57 * Displays data of a given length according to selected options
58 *
59 * If a specific data type is provided in disp, then this is used. Otherwise
60 * we try to guess the data type / size from the contents.
61 *
62 * @param disp Display information / options
63 * @param data Data to display
64 * @param len Maximum length of buffer
65 * @return 0 if ok, -1 if data does not match format
66 */
67static int show_data(struct display_info *disp, const char *data, int len)
68{
69 int i, size;
70 const uint8_t *p = (const uint8_t *)data;
71 const char *s;
72 int value;
73 int is_string;
74 char fmt[3];
75
76 /* no data, don't print */
77 if (len == 0)
78 return 0;
79
80 is_string = (disp->type) == 's' ||
81 (!disp->type && util_is_printable_string(data, len));
82 if (is_string) {
83 if (data[len - 1] != '\0') {
84 fprintf(stderr, "Unterminated string\n");
85 return -1;
86 }
87 for (s = data; s - data < len; s += strlen(s) + 1) {
88 if (s != data)
89 printf(" ");
90 printf("%s", (const char *)s);
91 }
92 return 0;
93 }
94 size = disp->size;
95 if (size == -1) {
96 size = (len % 4) == 0 ? 4 : 1;
97 } else if (len % size) {
98 fprintf(stderr, "Property length must be a multiple of "
99 "selected data size\n");
100 return -1;
101 }
102 fmt[0] = '%';
103 fmt[1] = disp->type ? disp->type : 'd';
104 fmt[2] = '\0';
105 for (i = 0; i < len; i += size, p += size) {
106 if (i)
107 printf(" ");
108 value = size == 4 ? fdt32_to_cpu(*(const uint32_t *)p) :
109 size == 2 ? (*p << 8) | p[1] : *p;
110 printf(fmt, value);
111 }
112 return 0;
113}
114
115/**
116 * List all properties in a node, one per line.
117 *
118 * @param blob FDT blob
119 * @param node Node to display
120 * @return 0 if ok, or FDT_ERR... if not.
121 */
122static int list_properties(const void *blob, int node)
123{
124 const struct fdt_property *data;
125 const char *name;
126 int prop;
127
128 prop = fdt_first_property_offset(blob, node);
129 do {
130 /* Stop silently when there are no more properties */
131 if (prop < 0)
132 return prop == -FDT_ERR_NOTFOUND ? 0 : prop;
133 data = fdt_get_property_by_offset(blob, prop, NULL);
134 name = fdt_string(blob, fdt32_to_cpu(data->nameoff));
135 if (name)
136 puts(name);
137 prop = fdt_next_property_offset(blob, prop);
138 } while (1);
139}
140
141#define MAX_LEVEL 32 /* how deeply nested we will go */
142
143/**
144 * List all subnodes in a node, one per line
145 *
146 * @param blob FDT blob
147 * @param node Node to display
148 * @return 0 if ok, or FDT_ERR... if not.
149 */
150static int list_subnodes(const void *blob, int node)
151{
152 int nextoffset; /* next node offset from libfdt */
153 uint32_t tag; /* current tag */
154 int level = 0; /* keep track of nesting level */
155 const char *pathp;
156 int depth = 1; /* the assumed depth of this node */
157
158 while (level >= 0) {
159 tag = fdt_next_tag(blob, node, &nextoffset);
160 switch (tag) {
161 case FDT_BEGIN_NODE:
162 pathp = fdt_get_name(blob, node, NULL);
163 if (level <= depth) {
164 if (pathp == NULL)
165 pathp = "/* NULL pointer error */";
166 if (*pathp == '\0')
167 pathp = "/"; /* root is nameless */
168 if (level == 1)
169 puts(pathp);
170 }
171 level++;
172 if (level >= MAX_LEVEL) {
173 printf("Nested too deep, aborting.\n");
174 return 1;
175 }
176 break;
177 case FDT_END_NODE:
178 level--;
179 if (level == 0)
180 level = -1; /* exit the loop */
181 break;
182 case FDT_END:
183 return 1;
184 case FDT_PROP:
185 break;
186 default:
187 if (level <= depth)
188 printf("Unknown tag 0x%08X\n", tag);
189 return 1;
190 }
191 node = nextoffset;
192 }
193 return 0;
194}
195
196/**
197 * Show the data for a given node (and perhaps property) according to the
198 * display option provided.
199 *
200 * @param blob FDT blob
201 * @param disp Display information / options
202 * @param node Node to display
203 * @param property Name of property to display, or NULL if none
204 * @return 0 if ok, -ve on error
205 */
206static int show_data_for_item(const void *blob, struct display_info *disp,
207 int node, const char *property)
208{
209 const void *value = NULL;
210 int len, err = 0;
211
212 switch (disp->mode) {
213 case MODE_LIST_PROPS:
214 err = list_properties(blob, node);
215 break;
216
217 case MODE_LIST_SUBNODES:
218 err = list_subnodes(blob, node);
219 break;
220
221 default:
222 assert(property);
223 value = fdt_getprop(blob, node, property, &len);
224 if (value) {
225 if (show_data(disp, value, len))
226 err = -1;
227 else
228 printf("\n");
229 } else if (disp->default_val) {
230 puts(disp->default_val);
231 } else {
232 report_error(property, len);
233 err = -1;
234 }
235 break;
236 }
237
238 return err;
239}
240
241/**
242 * Run the main fdtget operation, given a filename and valid arguments
243 *
244 * @param disp Display information / options
245 * @param filename Filename of blob file
246 * @param arg List of arguments to process
247 * @param arg_count Number of arguments
248 * @param return 0 if ok, -ve on error
249 */
250static int do_fdtget(struct display_info *disp, const char *filename,
251 char **arg, int arg_count, int args_per_step)
252{
253 char *blob;
254 const char *prop;
255 int i, node;
256
257 blob = utilfdt_read(filename);
258 if (!blob)
259 return -1;
260
261 for (i = 0; i + args_per_step <= arg_count; i += args_per_step) {
262 node = fdt_path_offset(blob, arg[i]);
263 if (node < 0) {
264 if (disp->default_val) {
265 puts(disp->default_val);
266 continue;
267 } else {
268 report_error(arg[i], node);
269 return -1;
270 }
271 }
272 prop = args_per_step == 1 ? NULL : arg[i + 1];
273
274 if (show_data_for_item(blob, disp, node, prop))
275 return -1;
276 }
277 return 0;
278}
279
280static const char *usage_msg =
281 "fdtget - read values from device tree\n"
282 "\n"
283 "Each value is printed on a new line.\n\n"
284 "Usage:\n"
285 " fdtget <options> <dt file> [<node> <property>]...\n"
286 " fdtget -p <options> <dt file> [<node> ]...\n"
287 "Options:\n"
288 "\t-t <type>\tType of data\n"
289 "\t-p\t\tList properties for each node\n"
290 "\t-l\t\tList subnodes for each node\n"
291 "\t-d\t\tDefault value to display when the property is "
292 "missing\n"
293 "\t-h\t\tPrint this help\n\n"
294 USAGE_TYPE_MSG;
295
296static void usage(const char *msg)
297{
298 if (msg)
299 fprintf(stderr, "Error: %s\n\n", msg);
300
301 fprintf(stderr, "%s", usage_msg);
302 exit(2);
303}
304
305int main(int argc, char *argv[])
306{
307 char *filename = NULL;
308 struct display_info disp;
309 int args_per_step = 2;
310
311 /* set defaults */
312 memset(&disp, '\0', sizeof(disp));
313 disp.size = -1;
314 disp.mode = MODE_SHOW_VALUE;
315 for (;;) {
316 int c = getopt(argc, argv, "d:hlpt:");
317 if (c == -1)
318 break;
319
320 switch (c) {
321 case 'h':
322 case '?':
323 usage(NULL);
324
325 case 't':
326 if (utilfdt_decode_type(optarg, &disp.type,
327 &disp.size))
328 usage("Invalid type string");
329 break;
330
331 case 'p':
332 disp.mode = MODE_LIST_PROPS;
333 args_per_step = 1;
334 break;
335
336 case 'l':
337 disp.mode = MODE_LIST_SUBNODES;
338 args_per_step = 1;
339 break;
340
341 case 'd':
342 disp.default_val = optarg;
343 break;
344 }
345 }
346
347 if (optind < argc)
348 filename = argv[optind++];
349 if (!filename)
350 usage("Missing filename");
351
352 argv += optind;
353 argc -= optind;
354
355 /* Allow no arguments, and silently succeed */
356 if (!argc)
357 return 0;
358
359 /* Check for node, property arguments */
360 if (args_per_step == 2 && (argc % 2))
361 usage("Must have an even number of arguments");
362
363 if (do_fdtget(&disp, filename, argv, argc, args_per_step))
364 return 1;
365 return 0;
366}
diff --git a/scripts/dtc/fdtput.c b/scripts/dtc/fdtput.c
new file mode 100644
index 000000000000..f2197f51930b
--- /dev/null
+++ b/scripts/dtc/fdtput.c
@@ -0,0 +1,362 @@
1/*
2 * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of
7 * the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
17 * MA 02111-1307 USA
18 */
19
20#include <assert.h>
21#include <ctype.h>
22#include <getopt.h>
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26
27#include <libfdt.h>
28
29#include "util.h"
30
31/* These are the operations we support */
32enum oper_type {
33 OPER_WRITE_PROP, /* Write a property in a node */
34 OPER_CREATE_NODE, /* Create a new node */
35};
36
37struct display_info {
38 enum oper_type oper; /* operation to perform */
39 int type; /* data type (s/i/u/x or 0 for default) */
40 int size; /* data size (1/2/4) */
41 int verbose; /* verbose output */
42 int auto_path; /* automatically create all path components */
43};
44
45
46/**
47 * Report an error with a particular node.
48 *
49 * @param name Node name to report error on
50 * @param namelen Length of node name, or -1 to use entire string
51 * @param err Error number to report (-FDT_ERR_...)
52 */
53static void report_error(const char *name, int namelen, int err)
54{
55 if (namelen == -1)
56 namelen = strlen(name);
57 fprintf(stderr, "Error at '%1.*s': %s\n", namelen, name,
58 fdt_strerror(err));
59}
60
61/**
62 * Encode a series of arguments in a property value.
63 *
64 * @param disp Display information / options
65 * @param arg List of arguments from command line
66 * @param arg_count Number of arguments (may be 0)
67 * @param valuep Returns buffer containing value
68 * @param *value_len Returns length of value encoded
69 */
70static int encode_value(struct display_info *disp, char **arg, int arg_count,
71 char **valuep, int *value_len)
72{
73 char *value = NULL; /* holding area for value */
74 int value_size = 0; /* size of holding area */
75 char *ptr; /* pointer to current value position */
76 int len; /* length of this cell/string/byte */
77 int ival;
78 int upto; /* the number of bytes we have written to buf */
79 char fmt[3];
80
81 upto = 0;
82
83 if (disp->verbose)
84 fprintf(stderr, "Decoding value:\n");
85
86 fmt[0] = '%';
87 fmt[1] = disp->type ? disp->type : 'd';
88 fmt[2] = '\0';
89 for (; arg_count > 0; arg++, arg_count--, upto += len) {
90 /* assume integer unless told otherwise */
91 if (disp->type == 's')
92 len = strlen(*arg) + 1;
93 else
94 len = disp->size == -1 ? 4 : disp->size;
95
96 /* enlarge our value buffer by a suitable margin if needed */
97 if (upto + len > value_size) {
98 value_size = (upto + len) + 500;
99 value = realloc(value, value_size);
100 if (!value) {
101 fprintf(stderr, "Out of mmory: cannot alloc "
102 "%d bytes\n", value_size);
103 return -1;
104 }
105 }
106
107 ptr = value + upto;
108 if (disp->type == 's') {
109 memcpy(ptr, *arg, len);
110 if (disp->verbose)
111 fprintf(stderr, "\tstring: '%s'\n", ptr);
112 } else {
113 int *iptr = (int *)ptr;
114 sscanf(*arg, fmt, &ival);
115 if (len == 4)
116 *iptr = cpu_to_fdt32(ival);
117 else
118 *ptr = (uint8_t)ival;
119 if (disp->verbose) {
120 fprintf(stderr, "\t%s: %d\n",
121 disp->size == 1 ? "byte" :
122 disp->size == 2 ? "short" : "int",
123 ival);
124 }
125 }
126 }
127 *value_len = upto;
128 *valuep = value;
129 if (disp->verbose)
130 fprintf(stderr, "Value size %d\n", upto);
131 return 0;
132}
133
134static int store_key_value(void *blob, const char *node_name,
135 const char *property, const char *buf, int len)
136{
137 int node;
138 int err;
139
140 node = fdt_path_offset(blob, node_name);
141 if (node < 0) {
142 report_error(node_name, -1, node);
143 return -1;
144 }
145
146 err = fdt_setprop(blob, node, property, buf, len);
147 if (err) {
148 report_error(property, -1, err);
149 return -1;
150 }
151 return 0;
152}
153
154/**
155 * Create paths as needed for all components of a path
156 *
157 * Any components of the path that do not exist are created. Errors are
158 * reported.
159 *
160 * @param blob FDT blob to write into
161 * @param in_path Path to process
162 * @return 0 if ok, -1 on error
163 */
164static int create_paths(void *blob, const char *in_path)
165{
166 const char *path = in_path;
167 const char *sep;
168 int node, offset = 0;
169
170 /* skip leading '/' */
171 while (*path == '/')
172 path++;
173
174 for (sep = path; *sep; path = sep + 1, offset = node) {
175 /* equivalent to strchrnul(), but it requires _GNU_SOURCE */
176 sep = strchr(path, '/');
177 if (!sep)
178 sep = path + strlen(path);
179
180 node = fdt_subnode_offset_namelen(blob, offset, path,
181 sep - path);
182 if (node == -FDT_ERR_NOTFOUND) {
183 node = fdt_add_subnode_namelen(blob, offset, path,
184 sep - path);
185 }
186 if (node < 0) {
187 report_error(path, sep - path, node);
188 return -1;
189 }
190 }
191
192 return 0;
193}
194
195/**
196 * Create a new node in the fdt.
197 *
198 * This will overwrite the node_name string. Any error is reported.
199 *
200 * TODO: Perhaps create fdt_path_offset_namelen() so we don't need to do this.
201 *
202 * @param blob FDT blob to write into
203 * @param node_name Name of node to create
204 * @return new node offset if found, or -1 on failure
205 */
206static int create_node(void *blob, const char *node_name)
207{
208 int node = 0;
209 char *p;
210
211 p = strrchr(node_name, '/');
212 if (!p) {
213 report_error(node_name, -1, -FDT_ERR_BADPATH);
214 return -1;
215 }
216 *p = '\0';
217
218 if (p > node_name) {
219 node = fdt_path_offset(blob, node_name);
220 if (node < 0) {
221 report_error(node_name, -1, node);
222 return -1;
223 }
224 }
225
226 node = fdt_add_subnode(blob, node, p + 1);
227 if (node < 0) {
228 report_error(p + 1, -1, node);
229 return -1;
230 }
231
232 return 0;
233}
234
235static int do_fdtput(struct display_info *disp, const char *filename,
236 char **arg, int arg_count)
237{
238 char *value;
239 char *blob;
240 int len, ret = 0;
241
242 blob = utilfdt_read(filename);
243 if (!blob)
244 return -1;
245
246 switch (disp->oper) {
247 case OPER_WRITE_PROP:
248 /*
249 * Convert the arguments into a single binary value, then
250 * store them into the property.
251 */
252 assert(arg_count >= 2);
253 if (disp->auto_path && create_paths(blob, *arg))
254 return -1;
255 if (encode_value(disp, arg + 2, arg_count - 2, &value, &len) ||
256 store_key_value(blob, *arg, arg[1], value, len))
257 ret = -1;
258 break;
259 case OPER_CREATE_NODE:
260 for (; ret >= 0 && arg_count--; arg++) {
261 if (disp->auto_path)
262 ret = create_paths(blob, *arg);
263 else
264 ret = create_node(blob, *arg);
265 }
266 break;
267 }
268 if (ret >= 0)
269 ret = utilfdt_write(filename, blob);
270
271 free(blob);
272 return ret;
273}
274
275static const char *usage_msg =
276 "fdtput - write a property value to a device tree\n"
277 "\n"
278 "The command line arguments are joined together into a single value.\n"
279 "\n"
280 "Usage:\n"
281 " fdtput <options> <dt file> <node> <property> [<value>...]\n"
282 " fdtput -c <options> <dt file> [<node>...]\n"
283 "Options:\n"
284 "\t-c\t\tCreate nodes if they don't already exist\n"
285 "\t-p\t\tAutomatically create nodes as needed for the node path\n"
286 "\t-t <type>\tType of data\n"
287 "\t-v\t\tVerbose: display each value decoded from command line\n"
288 "\t-h\t\tPrint this help\n\n"
289 USAGE_TYPE_MSG;
290
291static void usage(const char *msg)
292{
293 if (msg)
294 fprintf(stderr, "Error: %s\n\n", msg);
295
296 fprintf(stderr, "%s", usage_msg);
297 exit(2);
298}
299
300int main(int argc, char *argv[])
301{
302 struct display_info disp;
303 char *filename = NULL;
304
305 memset(&disp, '\0', sizeof(disp));
306 disp.size = -1;
307 disp.oper = OPER_WRITE_PROP;
308 for (;;) {
309 int c = getopt(argc, argv, "chpt:v");
310 if (c == -1)
311 break;
312
313 /*
314 * TODO: add options to:
315 * - delete property
316 * - delete node (optionally recursively)
317 * - rename node
318 * - pack fdt before writing
319 * - set amount of free space when writing
320 * - expand fdt if value doesn't fit
321 */
322 switch (c) {
323 case 'c':
324 disp.oper = OPER_CREATE_NODE;
325 break;
326 case 'h':
327 case '?':
328 usage(NULL);
329 case 'p':
330 disp.auto_path = 1;
331 break;
332 case 't':
333 if (utilfdt_decode_type(optarg, &disp.type,
334 &disp.size))
335 usage("Invalid type string");
336 break;
337
338 case 'v':
339 disp.verbose = 1;
340 break;
341 }
342 }
343
344 if (optind < argc)
345 filename = argv[optind++];
346 if (!filename)
347 usage("Missing filename");
348
349 argv += optind;
350 argc -= optind;
351
352 if (disp.oper == OPER_WRITE_PROP) {
353 if (argc < 1)
354 usage("Missing node");
355 if (argc < 2)
356 usage("Missing property");
357 }
358
359 if (do_fdtput(&disp, filename, argv, argc))
360 return 1;
361 return 0;
362}
diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c
index 28d0b2381df6..665dad7bb465 100644
--- a/scripts/dtc/flattree.c
+++ b/scripts/dtc/flattree.c
@@ -263,6 +263,9 @@ static void flatten_tree(struct node *tree, struct emitter *emit,
263 struct node *child; 263 struct node *child;
264 int seen_name_prop = 0; 264 int seen_name_prop = 0;
265 265
266 if (tree->deleted)
267 return;
268
266 emit->beginnode(etarget, tree->labels); 269 emit->beginnode(etarget, tree->labels);
267 270
268 if (vi->flags & FTF_FULLPATH) 271 if (vi->flags & FTF_FULLPATH)
diff --git a/scripts/dtc/libfdt/Makefile.libfdt b/scripts/dtc/libfdt/Makefile.libfdt
index 6c42acfa21ec..91126c000a1e 100644
--- a/scripts/dtc/libfdt/Makefile.libfdt
+++ b/scripts/dtc/libfdt/Makefile.libfdt
@@ -3,6 +3,8 @@
3# This is not a complete Makefile of itself. Instead, it is designed to 3# This is not a complete Makefile of itself. Instead, it is designed to
4# be easily embeddable into other systems of Makefiles. 4# be easily embeddable into other systems of Makefiles.
5# 5#
6LIBFDT_INCLUDES = fdt.h libfdt.h 6LIBFDT_soname = libfdt.$(SHAREDLIB_EXT).1
7LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c 7LIBFDT_INCLUDES = fdt.h libfdt.h libfdt_env.h
8LIBFDT_VERSION = version.lds
9LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c fdt_empty_tree.c
8LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o) 10LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o)
diff --git a/scripts/dtc/libfdt/fdt.c b/scripts/dtc/libfdt/fdt.c
index 2acaec5923ae..e56833ae9b6f 100644
--- a/scripts/dtc/libfdt/fdt.c
+++ b/scripts/dtc/libfdt/fdt.c
@@ -74,7 +74,7 @@ int fdt_check_header(const void *fdt)
74 return 0; 74 return 0;
75} 75}
76 76
77const void *fdt_offset_ptr(const void *fdt, int offset, int len) 77const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
78{ 78{
79 const char *p; 79 const char *p;
80 80
@@ -90,42 +90,53 @@ const void *fdt_offset_ptr(const void *fdt, int offset, int len)
90 return p; 90 return p;
91} 91}
92 92
93uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset) 93uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
94{ 94{
95 const uint32_t *tagp, *lenp; 95 const uint32_t *tagp, *lenp;
96 uint32_t tag; 96 uint32_t tag;
97 int offset = startoffset;
97 const char *p; 98 const char *p;
98 99
99 if (offset % FDT_TAGSIZE) 100 *nextoffset = -FDT_ERR_TRUNCATED;
100 return -1;
101
102 tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE); 101 tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE);
103 if (! tagp) 102 if (!tagp)
104 return FDT_END; /* premature end */ 103 return FDT_END; /* premature end */
105 tag = fdt32_to_cpu(*tagp); 104 tag = fdt32_to_cpu(*tagp);
106 offset += FDT_TAGSIZE; 105 offset += FDT_TAGSIZE;
107 106
107 *nextoffset = -FDT_ERR_BADSTRUCTURE;
108 switch (tag) { 108 switch (tag) {
109 case FDT_BEGIN_NODE: 109 case FDT_BEGIN_NODE:
110 /* skip name */ 110 /* skip name */
111 do { 111 do {
112 p = fdt_offset_ptr(fdt, offset++, 1); 112 p = fdt_offset_ptr(fdt, offset++, 1);
113 } while (p && (*p != '\0')); 113 } while (p && (*p != '\0'));
114 if (! p) 114 if (!p)
115 return FDT_END; 115 return FDT_END; /* premature end */
116 break; 116 break;
117
117 case FDT_PROP: 118 case FDT_PROP:
118 lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp)); 119 lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
119 if (! lenp) 120 if (!lenp)
120 return FDT_END; 121 return FDT_END; /* premature end */
121 /* skip name offset, length and value */ 122 /* skip-name offset, length and value */
122 offset += 2*FDT_TAGSIZE + fdt32_to_cpu(*lenp); 123 offset += sizeof(struct fdt_property) - FDT_TAGSIZE
124 + fdt32_to_cpu(*lenp);
125 break;
126
127 case FDT_END:
128 case FDT_END_NODE:
129 case FDT_NOP:
123 break; 130 break;
131
132 default:
133 return FDT_END;
124 } 134 }
125 135
126 if (nextoffset) 136 if (!fdt_offset_ptr(fdt, startoffset, offset - startoffset))
127 *nextoffset = FDT_TAGALIGN(offset); 137 return FDT_END; /* premature end */
128 138
139 *nextoffset = FDT_TAGALIGN(offset);
129 return tag; 140 return tag;
130} 141}
131 142
@@ -138,6 +149,15 @@ int _fdt_check_node_offset(const void *fdt, int offset)
138 return offset; 149 return offset;
139} 150}
140 151
152int _fdt_check_prop_offset(const void *fdt, int offset)
153{
154 if ((offset < 0) || (offset % FDT_TAGSIZE)
155 || (fdt_next_tag(fdt, offset, &offset) != FDT_PROP))
156 return -FDT_ERR_BADOFFSET;
157
158 return offset;
159}
160
141int fdt_next_node(const void *fdt, int offset, int *depth) 161int fdt_next_node(const void *fdt, int offset, int *depth)
142{ 162{
143 int nextoffset = 0; 163 int nextoffset = 0;
@@ -162,15 +182,16 @@ int fdt_next_node(const void *fdt, int offset, int *depth)
162 break; 182 break;
163 183
164 case FDT_END_NODE: 184 case FDT_END_NODE:
165 if (depth) 185 if (depth && ((--(*depth)) < 0))
166 (*depth)--; 186 return nextoffset;
167 break; 187 break;
168 188
169 case FDT_END: 189 case FDT_END:
170 return -FDT_ERR_NOTFOUND; 190 if ((nextoffset >= 0)
171 191 || ((nextoffset == -FDT_ERR_TRUNCATED) && !depth))
172 default: 192 return -FDT_ERR_NOTFOUND;
173 return -FDT_ERR_BADSTRUCTURE; 193 else
194 return nextoffset;
174 } 195 }
175 } while (tag != FDT_BEGIN_NODE); 196 } while (tag != FDT_BEGIN_NODE);
176 197
diff --git a/scripts/dtc/libfdt/fdt_empty_tree.c b/scripts/dtc/libfdt/fdt_empty_tree.c
new file mode 100644
index 000000000000..f72d13b1d19c
--- /dev/null
+++ b/scripts/dtc/libfdt/fdt_empty_tree.c
@@ -0,0 +1,84 @@
1/*
2 * libfdt - Flat Device Tree manipulation
3 * Copyright (C) 2012 David Gibson, IBM Corporation.
4 *
5 * libfdt is dual licensed: you can use it either under the terms of
6 * the GPL, or the BSD license, at your option.
7 *
8 * a) This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this library; if not, write to the Free
20 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
21 * MA 02110-1301 USA
22 *
23 * Alternatively,
24 *
25 * b) Redistribution and use in source and binary forms, with or
26 * without modification, are permitted provided that the following
27 * conditions are met:
28 *
29 * 1. Redistributions of source code must retain the above
30 * copyright notice, this list of conditions and the following
31 * disclaimer.
32 * 2. Redistributions in binary form must reproduce the above
33 * copyright notice, this list of conditions and the following
34 * disclaimer in the documentation and/or other materials
35 * provided with the distribution.
36 *
37 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
38 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
39 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
40 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
41 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
42 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
48 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
49 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50 */
51#include "libfdt_env.h"
52
53#include <fdt.h>
54#include <libfdt.h>
55
56#include "libfdt_internal.h"
57
58int fdt_create_empty_tree(void *buf, int bufsize)
59{
60 int err;
61
62 err = fdt_create(buf, bufsize);
63 if (err)
64 return err;
65
66 err = fdt_finish_reservemap(buf);
67 if (err)
68 return err;
69
70 err = fdt_begin_node(buf, "");
71 if (err)
72 return err;
73
74 err = fdt_end_node(buf);
75 if (err)
76 return err;
77
78 err = fdt_finish(buf);
79 if (err)
80 return err;
81
82 return fdt_open_into(buf, buf, bufsize);
83}
84
diff --git a/scripts/dtc/libfdt/fdt_ro.c b/scripts/dtc/libfdt/fdt_ro.c
index 22e692919ff9..02b6d687537f 100644
--- a/scripts/dtc/libfdt/fdt_ro.c
+++ b/scripts/dtc/libfdt/fdt_ro.c
@@ -80,6 +80,14 @@ const char *fdt_string(const void *fdt, int stroffset)
80 return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset; 80 return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset;
81} 81}
82 82
83static int _fdt_string_eq(const void *fdt, int stroffset,
84 const char *s, int len)
85{
86 const char *p = fdt_string(fdt, stroffset);
87
88 return (strlen(p) == len) && (memcmp(p, s, len) == 0);
89}
90
83int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size) 91int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
84{ 92{
85 FDT_CHECK_HEADER(fdt); 93 FDT_CHECK_HEADER(fdt);
@@ -97,6 +105,30 @@ int fdt_num_mem_rsv(const void *fdt)
97 return i; 105 return i;
98} 106}
99 107
108static int _nextprop(const void *fdt, int offset)
109{
110 uint32_t tag;
111 int nextoffset;
112
113 do {
114 tag = fdt_next_tag(fdt, offset, &nextoffset);
115
116 switch (tag) {
117 case FDT_END:
118 if (nextoffset >= 0)
119 return -FDT_ERR_BADSTRUCTURE;
120 else
121 return nextoffset;
122
123 case FDT_PROP:
124 return offset;
125 }
126 offset = nextoffset;
127 } while (tag == FDT_NOP);
128
129 return -FDT_ERR_NOTFOUND;
130}
131
100int fdt_subnode_offset_namelen(const void *fdt, int offset, 132int fdt_subnode_offset_namelen(const void *fdt, int offset,
101 const char *name, int namelen) 133 const char *name, int namelen)
102{ 134{
@@ -104,20 +136,16 @@ int fdt_subnode_offset_namelen(const void *fdt, int offset,
104 136
105 FDT_CHECK_HEADER(fdt); 137 FDT_CHECK_HEADER(fdt);
106 138
107 for (depth = 0, offset = fdt_next_node(fdt, offset, &depth); 139 for (depth = 0;
108 (offset >= 0) && (depth > 0); 140 (offset >= 0) && (depth >= 0);
109 offset = fdt_next_node(fdt, offset, &depth)) { 141 offset = fdt_next_node(fdt, offset, &depth))
110 if (depth < 0) 142 if ((depth == 1)
111 return -FDT_ERR_NOTFOUND; 143 && _fdt_nodename_eq(fdt, offset, name, namelen))
112 else if ((depth == 1)
113 && _fdt_nodename_eq(fdt, offset, name, namelen))
114 return offset; 144 return offset;
115 }
116 145
117 if (offset < 0) 146 if (depth < 0)
118 return offset; /* error */
119 else
120 return -FDT_ERR_NOTFOUND; 147 return -FDT_ERR_NOTFOUND;
148 return offset; /* error */
121} 149}
122 150
123int fdt_subnode_offset(const void *fdt, int parentoffset, 151int fdt_subnode_offset(const void *fdt, int parentoffset,
@@ -134,8 +162,20 @@ int fdt_path_offset(const void *fdt, const char *path)
134 162
135 FDT_CHECK_HEADER(fdt); 163 FDT_CHECK_HEADER(fdt);
136 164
137 if (*path != '/') 165 /* see if we have an alias */
138 return -FDT_ERR_BADPATH; 166 if (*path != '/') {
167 const char *q = strchr(path, '/');
168
169 if (!q)
170 q = end;
171
172 p = fdt_get_alias_namelen(fdt, p, q - p);
173 if (!p)
174 return -FDT_ERR_BADPATH;
175 offset = fdt_path_offset(fdt, p);
176
177 p = q;
178 }
139 179
140 while (*p) { 180 while (*p) {
141 const char *q; 181 const char *q;
@@ -178,93 +218,142 @@ const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)
178 return NULL; 218 return NULL;
179} 219}
180 220
181const struct fdt_property *fdt_get_property(const void *fdt, 221int fdt_first_property_offset(const void *fdt, int nodeoffset)
182 int nodeoffset, 222{
183 const char *name, int *lenp) 223 int offset;
224
225 if ((offset = _fdt_check_node_offset(fdt, nodeoffset)) < 0)
226 return offset;
227
228 return _nextprop(fdt, offset);
229}
230
231int fdt_next_property_offset(const void *fdt, int offset)
232{
233 if ((offset = _fdt_check_prop_offset(fdt, offset)) < 0)
234 return offset;
235
236 return _nextprop(fdt, offset);
237}
238
239const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
240 int offset,
241 int *lenp)
184{ 242{
185 uint32_t tag;
186 const struct fdt_property *prop;
187 int namestroff;
188 int offset, nextoffset;
189 int err; 243 int err;
244 const struct fdt_property *prop;
190 245
191 if (((err = fdt_check_header(fdt)) != 0) 246 if ((err = _fdt_check_prop_offset(fdt, offset)) < 0) {
192 || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0)) 247 if (lenp)
193 goto fail; 248 *lenp = err;
249 return NULL;
250 }
194 251
195 nextoffset = err; 252 prop = _fdt_offset_ptr(fdt, offset);
196 do {
197 offset = nextoffset;
198 253
199 tag = fdt_next_tag(fdt, offset, &nextoffset); 254 if (lenp)
200 switch (tag) { 255 *lenp = fdt32_to_cpu(prop->len);
201 case FDT_END:
202 err = -FDT_ERR_TRUNCATED;
203 goto fail;
204 256
205 case FDT_BEGIN_NODE: 257 return prop;
206 case FDT_END_NODE: 258}
207 case FDT_NOP:
208 break;
209 259
210 case FDT_PROP: 260const struct fdt_property *fdt_get_property_namelen(const void *fdt,
211 err = -FDT_ERR_BADSTRUCTURE; 261 int offset,
212 prop = fdt_offset_ptr(fdt, offset, sizeof(*prop)); 262 const char *name,
213 if (! prop) 263 int namelen, int *lenp)
214 goto fail; 264{
215 namestroff = fdt32_to_cpu(prop->nameoff); 265 for (offset = fdt_first_property_offset(fdt, offset);
216 if (strcmp(fdt_string(fdt, namestroff), name) == 0) { 266 (offset >= 0);
217 /* Found it! */ 267 (offset = fdt_next_property_offset(fdt, offset))) {
218 int len = fdt32_to_cpu(prop->len); 268 const struct fdt_property *prop;
219 prop = fdt_offset_ptr(fdt, offset,
220 sizeof(*prop)+len);
221 if (! prop)
222 goto fail;
223
224 if (lenp)
225 *lenp = len;
226
227 return prop;
228 }
229 break;
230 269
231 default: 270 if (!(prop = fdt_get_property_by_offset(fdt, offset, lenp))) {
232 err = -FDT_ERR_BADSTRUCTURE; 271 offset = -FDT_ERR_INTERNAL;
233 goto fail; 272 break;
234 } 273 }
235 } while ((tag != FDT_BEGIN_NODE) && (tag != FDT_END_NODE)); 274 if (_fdt_string_eq(fdt, fdt32_to_cpu(prop->nameoff),
275 name, namelen))
276 return prop;
277 }
236 278
237 err = -FDT_ERR_NOTFOUND;
238 fail:
239 if (lenp) 279 if (lenp)
240 *lenp = err; 280 *lenp = offset;
241 return NULL; 281 return NULL;
242} 282}
243 283
244const void *fdt_getprop(const void *fdt, int nodeoffset, 284const struct fdt_property *fdt_get_property(const void *fdt,
245 const char *name, int *lenp) 285 int nodeoffset,
286 const char *name, int *lenp)
287{
288 return fdt_get_property_namelen(fdt, nodeoffset, name,
289 strlen(name), lenp);
290}
291
292const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
293 const char *name, int namelen, int *lenp)
246{ 294{
247 const struct fdt_property *prop; 295 const struct fdt_property *prop;
248 296
249 prop = fdt_get_property(fdt, nodeoffset, name, lenp); 297 prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp);
250 if (! prop) 298 if (! prop)
251 return NULL; 299 return NULL;
252 300
253 return prop->data; 301 return prop->data;
254} 302}
255 303
304const void *fdt_getprop_by_offset(const void *fdt, int offset,
305 const char **namep, int *lenp)
306{
307 const struct fdt_property *prop;
308
309 prop = fdt_get_property_by_offset(fdt, offset, lenp);
310 if (!prop)
311 return NULL;
312 if (namep)
313 *namep = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
314 return prop->data;
315}
316
317const void *fdt_getprop(const void *fdt, int nodeoffset,
318 const char *name, int *lenp)
319{
320 return fdt_getprop_namelen(fdt, nodeoffset, name, strlen(name), lenp);
321}
322
256uint32_t fdt_get_phandle(const void *fdt, int nodeoffset) 323uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)
257{ 324{
258 const uint32_t *php; 325 const uint32_t *php;
259 int len; 326 int len;
260 327
261 php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len); 328 /* FIXME: This is a bit sub-optimal, since we potentially scan
262 if (!php || (len != sizeof(*php))) 329 * over all the properties twice. */
263 return 0; 330 php = fdt_getprop(fdt, nodeoffset, "phandle", &len);
331 if (!php || (len != sizeof(*php))) {
332 php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len);
333 if (!php || (len != sizeof(*php)))
334 return 0;
335 }
264 336
265 return fdt32_to_cpu(*php); 337 return fdt32_to_cpu(*php);
266} 338}
267 339
340const char *fdt_get_alias_namelen(const void *fdt,
341 const char *name, int namelen)
342{
343 int aliasoffset;
344
345 aliasoffset = fdt_path_offset(fdt, "/aliases");
346 if (aliasoffset < 0)
347 return NULL;
348
349 return fdt_getprop_namelen(fdt, aliasoffset, name, namelen, NULL);
350}
351
352const char *fdt_get_alias(const void *fdt, const char *name)
353{
354 return fdt_get_alias_namelen(fdt, name, strlen(name));
355}
356
268int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen) 357int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
269{ 358{
270 int pdepth = 0, p = 0; 359 int pdepth = 0, p = 0;
@@ -279,9 +368,6 @@ int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
279 for (offset = 0, depth = 0; 368 for (offset = 0, depth = 0;
280 (offset >= 0) && (offset <= nodeoffset); 369 (offset >= 0) && (offset <= nodeoffset);
281 offset = fdt_next_node(fdt, offset, &depth)) { 370 offset = fdt_next_node(fdt, offset, &depth)) {
282 if (pdepth < depth)
283 continue; /* overflowed buffer */
284
285 while (pdepth > depth) { 371 while (pdepth > depth) {
286 do { 372 do {
287 p--; 373 p--;
@@ -289,14 +375,16 @@ int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
289 pdepth--; 375 pdepth--;
290 } 376 }
291 377
292 name = fdt_get_name(fdt, offset, &namelen); 378 if (pdepth >= depth) {
293 if (!name) 379 name = fdt_get_name(fdt, offset, &namelen);
294 return namelen; 380 if (!name)
295 if ((p + namelen + 1) <= buflen) { 381 return namelen;
296 memcpy(buf + p, name, namelen); 382 if ((p + namelen + 1) <= buflen) {
297 p += namelen; 383 memcpy(buf + p, name, namelen);
298 buf[p++] = '/'; 384 p += namelen;
299 pdepth++; 385 buf[p++] = '/';
386 pdepth++;
387 }
300 } 388 }
301 389
302 if (offset == nodeoffset) { 390 if (offset == nodeoffset) {
@@ -306,7 +394,7 @@ int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
306 if (p > 1) /* special case so that root path is "/", not "" */ 394 if (p > 1) /* special case so that root path is "/", not "" */
307 p--; 395 p--;
308 buf[p] = '\0'; 396 buf[p] = '\0';
309 return p; 397 return 0;
310 } 398 }
311 } 399 }
312 400
@@ -404,14 +492,31 @@ int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
404 492
405int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle) 493int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
406{ 494{
495 int offset;
496
407 if ((phandle == 0) || (phandle == -1)) 497 if ((phandle == 0) || (phandle == -1))
408 return -FDT_ERR_BADPHANDLE; 498 return -FDT_ERR_BADPHANDLE;
409 phandle = cpu_to_fdt32(phandle); 499
410 return fdt_node_offset_by_prop_value(fdt, -1, "linux,phandle", 500 FDT_CHECK_HEADER(fdt);
411 &phandle, sizeof(phandle)); 501
502 /* FIXME: The algorithm here is pretty horrible: we
503 * potentially scan each property of a node in
504 * fdt_get_phandle(), then if that didn't find what
505 * we want, we scan over them again making our way to the next
506 * node. Still it's the easiest to implement approach;
507 * performance can come later. */
508 for (offset = fdt_next_node(fdt, -1, NULL);
509 offset >= 0;
510 offset = fdt_next_node(fdt, offset, NULL)) {
511 if (fdt_get_phandle(fdt, offset) == phandle)
512 return offset;
513 }
514
515 return offset; /* error from fdt_next_node() */
412} 516}
413 517
414static int _stringlist_contains(const char *strlist, int listlen, const char *str) 518static int _fdt_stringlist_contains(const char *strlist, int listlen,
519 const char *str)
415{ 520{
416 int len = strlen(str); 521 int len = strlen(str);
417 const char *p; 522 const char *p;
@@ -437,7 +542,7 @@ int fdt_node_check_compatible(const void *fdt, int nodeoffset,
437 prop = fdt_getprop(fdt, nodeoffset, "compatible", &len); 542 prop = fdt_getprop(fdt, nodeoffset, "compatible", &len);
438 if (!prop) 543 if (!prop)
439 return len; 544 return len;
440 if (_stringlist_contains(prop, len, compatible)) 545 if (_fdt_stringlist_contains(prop, len, compatible))
441 return 0; 546 return 0;
442 else 547 else
443 return 1; 548 return 1;
diff --git a/scripts/dtc/libfdt/fdt_rw.c b/scripts/dtc/libfdt/fdt_rw.c
index 8e7ec4cb7bcd..24437dfc32b8 100644
--- a/scripts/dtc/libfdt/fdt_rw.c
+++ b/scripts/dtc/libfdt/fdt_rw.c
@@ -289,6 +289,33 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,
289 return 0; 289 return 0;
290} 290}
291 291
292int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
293 const void *val, int len)
294{
295 struct fdt_property *prop;
296 int err, oldlen, newlen;
297
298 FDT_RW_CHECK_HEADER(fdt);
299
300 prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
301 if (prop) {
302 newlen = len + oldlen;
303 err = _fdt_splice_struct(fdt, prop->data,
304 FDT_TAGALIGN(oldlen),
305 FDT_TAGALIGN(newlen));
306 if (err)
307 return err;
308 prop->len = cpu_to_fdt32(newlen);
309 memcpy(prop->data + oldlen, val, len);
310 } else {
311 err = _fdt_add_property(fdt, nodeoffset, name, len, &prop);
312 if (err)
313 return err;
314 memcpy(prop->data, val, len);
315 }
316 return 0;
317}
318
292int fdt_delprop(void *fdt, int nodeoffset, const char *name) 319int fdt_delprop(void *fdt, int nodeoffset, const char *name)
293{ 320{
294 struct fdt_property *prop; 321 struct fdt_property *prop;
@@ -406,6 +433,8 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)
406 struct_size = 0; 433 struct_size = 0;
407 while (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END) 434 while (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END)
408 ; 435 ;
436 if (struct_size < 0)
437 return struct_size;
409 } 438 }
410 439
411 if (!_fdt_blocks_misordered(fdt, mem_rsv_size, struct_size)) { 440 if (!_fdt_blocks_misordered(fdt, mem_rsv_size, struct_size)) {
diff --git a/scripts/dtc/libfdt/fdt_sw.c b/scripts/dtc/libfdt/fdt_sw.c
index 698329e0ccaf..55ebebf1eb20 100644
--- a/scripts/dtc/libfdt/fdt_sw.c
+++ b/scripts/dtc/libfdt/fdt_sw.c
@@ -70,7 +70,7 @@ static int _fdt_sw_check_header(void *fdt)
70 return err; \ 70 return err; \
71 } 71 }
72 72
73static void *_fdt_grab_space(void *fdt, int len) 73static void *_fdt_grab_space(void *fdt, size_t len)
74{ 74{
75 int offset = fdt_size_dt_struct(fdt); 75 int offset = fdt_size_dt_struct(fdt);
76 int spaceleft; 76 int spaceleft;
@@ -82,7 +82,7 @@ static void *_fdt_grab_space(void *fdt, int len)
82 return NULL; 82 return NULL;
83 83
84 fdt_set_size_dt_struct(fdt, offset + len); 84 fdt_set_size_dt_struct(fdt, offset + len);
85 return fdt_offset_ptr_w(fdt, offset, len); 85 return _fdt_offset_ptr_w(fdt, offset);
86} 86}
87 87
88int fdt_create(void *buf, int bufsize) 88int fdt_create(void *buf, int bufsize)
@@ -237,18 +237,17 @@ int fdt_finish(void *fdt)
237 while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) { 237 while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) {
238 if (tag == FDT_PROP) { 238 if (tag == FDT_PROP) {
239 struct fdt_property *prop = 239 struct fdt_property *prop =
240 fdt_offset_ptr_w(fdt, offset, sizeof(*prop)); 240 _fdt_offset_ptr_w(fdt, offset);
241 int nameoff; 241 int nameoff;
242 242
243 if (! prop)
244 return -FDT_ERR_BADSTRUCTURE;
245
246 nameoff = fdt32_to_cpu(prop->nameoff); 243 nameoff = fdt32_to_cpu(prop->nameoff);
247 nameoff += fdt_size_dt_strings(fdt); 244 nameoff += fdt_size_dt_strings(fdt);
248 prop->nameoff = cpu_to_fdt32(nameoff); 245 prop->nameoff = cpu_to_fdt32(nameoff);
249 } 246 }
250 offset = nextoffset; 247 offset = nextoffset;
251 } 248 }
249 if (nextoffset < 0)
250 return nextoffset;
252 251
253 /* Finally, adjust the header */ 252 /* Finally, adjust the header */
254 fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt)); 253 fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt));
diff --git a/scripts/dtc/libfdt/fdt_wip.c b/scripts/dtc/libfdt/fdt_wip.c
index a4652c6e787e..6025fa1fe8fe 100644
--- a/scripts/dtc/libfdt/fdt_wip.c
+++ b/scripts/dtc/libfdt/fdt_wip.c
@@ -94,41 +94,14 @@ int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
94 return 0; 94 return 0;
95} 95}
96 96
97int _fdt_node_end_offset(void *fdt, int nodeoffset) 97int _fdt_node_end_offset(void *fdt, int offset)
98{ 98{
99 int level = 0; 99 int depth = 0;
100 uint32_t tag; 100
101 int offset, nextoffset; 101 while ((offset >= 0) && (depth >= 0))
102 102 offset = fdt_next_node(fdt, offset, &depth);
103 tag = fdt_next_tag(fdt, nodeoffset, &nextoffset); 103
104 if (tag != FDT_BEGIN_NODE) 104 return offset;
105 return -FDT_ERR_BADOFFSET;
106 do {
107 offset = nextoffset;
108 tag = fdt_next_tag(fdt, offset, &nextoffset);
109
110 switch (tag) {
111 case FDT_END:
112 return offset;
113
114 case FDT_BEGIN_NODE:
115 level++;
116 break;
117
118 case FDT_END_NODE:
119 level--;
120 break;
121
122 case FDT_PROP:
123 case FDT_NOP:
124 break;
125
126 default:
127 return -FDT_ERR_BADSTRUCTURE;
128 }
129 } while (level >= 0);
130
131 return nextoffset;
132} 105}
133 106
134int fdt_nop_node(void *fdt, int nodeoffset) 107int fdt_nop_node(void *fdt, int nodeoffset)
diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h
index ff6246f000ce..73f49759a5e7 100644
--- a/scripts/dtc/libfdt/libfdt.h
+++ b/scripts/dtc/libfdt/libfdt.h
@@ -61,7 +61,7 @@
61#define FDT_ERR_NOTFOUND 1 61#define FDT_ERR_NOTFOUND 1
62 /* FDT_ERR_NOTFOUND: The requested node or property does not exist */ 62 /* FDT_ERR_NOTFOUND: The requested node or property does not exist */
63#define FDT_ERR_EXISTS 2 63#define FDT_ERR_EXISTS 2
64 /* FDT_ERR_EXISTS: Attempted to create a node or property which 64 /* FDT_ERR_EXISTS: Attemped to create a node or property which
65 * already exists */ 65 * already exists */
66#define FDT_ERR_NOSPACE 3 66#define FDT_ERR_NOSPACE 3
67 /* FDT_ERR_NOSPACE: Operation needed to expand the device 67 /* FDT_ERR_NOSPACE: Operation needed to expand the device
@@ -122,7 +122,7 @@
122/* Low-level functions (you probably don't need these) */ 122/* Low-level functions (you probably don't need these) */
123/**********************************************************************/ 123/**********************************************************************/
124 124
125const void *fdt_offset_ptr(const void *fdt, int offset, int checklen); 125const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int checklen);
126static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen) 126static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen)
127{ 127{
128 return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen); 128 return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen);
@@ -156,7 +156,7 @@ int fdt_next_node(const void *fdt, int offset, int *depth);
156#define __fdt_set_hdr(name) \ 156#define __fdt_set_hdr(name) \
157 static inline void fdt_set_##name(void *fdt, uint32_t val) \ 157 static inline void fdt_set_##name(void *fdt, uint32_t val) \
158 { \ 158 { \
159 struct fdt_header *fdth = fdt; \ 159 struct fdt_header *fdth = (struct fdt_header*)fdt; \
160 fdth->name = cpu_to_fdt32(val); \ 160 fdth->name = cpu_to_fdt32(val); \
161 } 161 }
162__fdt_set_hdr(magic); 162__fdt_set_hdr(magic);
@@ -343,6 +343,91 @@ int fdt_path_offset(const void *fdt, const char *path);
343const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp); 343const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp);
344 344
345/** 345/**
346 * fdt_first_property_offset - find the offset of a node's first property
347 * @fdt: pointer to the device tree blob
348 * @nodeoffset: structure block offset of a node
349 *
350 * fdt_first_property_offset() finds the first property of the node at
351 * the given structure block offset.
352 *
353 * returns:
354 * structure block offset of the property (>=0), on success
355 * -FDT_ERR_NOTFOUND, if the requested node has no properties
356 * -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_BEGIN_NODE tag
357 * -FDT_ERR_BADMAGIC,
358 * -FDT_ERR_BADVERSION,
359 * -FDT_ERR_BADSTATE,
360 * -FDT_ERR_BADSTRUCTURE,
361 * -FDT_ERR_TRUNCATED, standard meanings.
362 */
363int fdt_first_property_offset(const void *fdt, int nodeoffset);
364
365/**
366 * fdt_next_property_offset - step through a node's properties
367 * @fdt: pointer to the device tree blob
368 * @offset: structure block offset of a property
369 *
370 * fdt_next_property_offset() finds the property immediately after the
371 * one at the given structure block offset. This will be a property
372 * of the same node as the given property.
373 *
374 * returns:
375 * structure block offset of the next property (>=0), on success
376 * -FDT_ERR_NOTFOUND, if the given property is the last in its node
377 * -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_PROP tag
378 * -FDT_ERR_BADMAGIC,
379 * -FDT_ERR_BADVERSION,
380 * -FDT_ERR_BADSTATE,
381 * -FDT_ERR_BADSTRUCTURE,
382 * -FDT_ERR_TRUNCATED, standard meanings.
383 */
384int fdt_next_property_offset(const void *fdt, int offset);
385
386/**
387 * fdt_get_property_by_offset - retrieve the property at a given offset
388 * @fdt: pointer to the device tree blob
389 * @offset: offset of the property to retrieve
390 * @lenp: pointer to an integer variable (will be overwritten) or NULL
391 *
392 * fdt_get_property_by_offset() retrieves a pointer to the
393 * fdt_property structure within the device tree blob at the given
394 * offset. If lenp is non-NULL, the length of the property value is
395 * also returned, in the integer pointed to by lenp.
396 *
397 * returns:
398 * pointer to the structure representing the property
399 * if lenp is non-NULL, *lenp contains the length of the property
400 * value (>=0)
401 * NULL, on error
402 * if lenp is non-NULL, *lenp contains an error code (<0):
403 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag
404 * -FDT_ERR_BADMAGIC,
405 * -FDT_ERR_BADVERSION,
406 * -FDT_ERR_BADSTATE,
407 * -FDT_ERR_BADSTRUCTURE,
408 * -FDT_ERR_TRUNCATED, standard meanings
409 */
410const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
411 int offset,
412 int *lenp);
413
414/**
415 * fdt_get_property_namelen - find a property based on substring
416 * @fdt: pointer to the device tree blob
417 * @nodeoffset: offset of the node whose property to find
418 * @name: name of the property to find
419 * @namelen: number of characters of name to consider
420 * @lenp: pointer to an integer variable (will be overwritten) or NULL
421 *
422 * Identical to fdt_get_property_namelen(), but only examine the first
423 * namelen characters of name for matching the property name.
424 */
425const struct fdt_property *fdt_get_property_namelen(const void *fdt,
426 int nodeoffset,
427 const char *name,
428 int namelen, int *lenp);
429
430/**
346 * fdt_get_property - find a given property in a given node 431 * fdt_get_property - find a given property in a given node
347 * @fdt: pointer to the device tree blob 432 * @fdt: pointer to the device tree blob
348 * @nodeoffset: offset of the node whose property to find 433 * @nodeoffset: offset of the node whose property to find
@@ -380,6 +465,54 @@ static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,
380} 465}
381 466
382/** 467/**
468 * fdt_getprop_by_offset - retrieve the value of a property at a given offset
469 * @fdt: pointer to the device tree blob
470 * @ffset: offset of the property to read
471 * @namep: pointer to a string variable (will be overwritten) or NULL
472 * @lenp: pointer to an integer variable (will be overwritten) or NULL
473 *
474 * fdt_getprop_by_offset() retrieves a pointer to the value of the
475 * property at structure block offset 'offset' (this will be a pointer
476 * to within the device blob itself, not a copy of the value). If
477 * lenp is non-NULL, the length of the property value is also
478 * returned, in the integer pointed to by lenp. If namep is non-NULL,
479 * the property's namne will also be returned in the char * pointed to
480 * by namep (this will be a pointer to within the device tree's string
481 * block, not a new copy of the name).
482 *
483 * returns:
484 * pointer to the property's value
485 * if lenp is non-NULL, *lenp contains the length of the property
486 * value (>=0)
487 * if namep is non-NULL *namep contiains a pointer to the property
488 * name.
489 * NULL, on error
490 * if lenp is non-NULL, *lenp contains an error code (<0):
491 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag
492 * -FDT_ERR_BADMAGIC,
493 * -FDT_ERR_BADVERSION,
494 * -FDT_ERR_BADSTATE,
495 * -FDT_ERR_BADSTRUCTURE,
496 * -FDT_ERR_TRUNCATED, standard meanings
497 */
498const void *fdt_getprop_by_offset(const void *fdt, int offset,
499 const char **namep, int *lenp);
500
501/**
502 * fdt_getprop_namelen - get property value based on substring
503 * @fdt: pointer to the device tree blob
504 * @nodeoffset: offset of the node whose property to find
505 * @name: name of the property to find
506 * @namelen: number of characters of name to consider
507 * @lenp: pointer to an integer variable (will be overwritten) or NULL
508 *
509 * Identical to fdt_getprop(), but only examine the first namelen
510 * characters of name for matching the property name.
511 */
512const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
513 const char *name, int namelen, int *lenp);
514
515/**
383 * fdt_getprop - retrieve the value of a given property 516 * fdt_getprop - retrieve the value of a given property
384 * @fdt: pointer to the device tree blob 517 * @fdt: pointer to the device tree blob
385 * @nodeoffset: offset of the node whose property to find 518 * @nodeoffset: offset of the node whose property to find
@@ -429,6 +562,32 @@ static inline void *fdt_getprop_w(void *fdt, int nodeoffset,
429uint32_t fdt_get_phandle(const void *fdt, int nodeoffset); 562uint32_t fdt_get_phandle(const void *fdt, int nodeoffset);
430 563
431/** 564/**
565 * fdt_get_alias_namelen - get alias based on substring
566 * @fdt: pointer to the device tree blob
567 * @name: name of the alias th look up
568 * @namelen: number of characters of name to consider
569 *
570 * Identical to fdt_get_alias(), but only examine the first namelen
571 * characters of name for matching the alias name.
572 */
573const char *fdt_get_alias_namelen(const void *fdt,
574 const char *name, int namelen);
575
576/**
577 * fdt_get_alias - retreive the path referenced by a given alias
578 * @fdt: pointer to the device tree blob
579 * @name: name of the alias th look up
580 *
581 * fdt_get_alias() retrieves the value of a given alias. That is, the
582 * value of the property named 'name' in the node /aliases.
583 *
584 * returns:
585 * a pointer to the expansion of the alias named 'name', of it exists
586 * NULL, if the given alias or the /aliases node does not exist
587 */
588const char *fdt_get_alias(const void *fdt, const char *name);
589
590/**
432 * fdt_get_path - determine the full path of a node 591 * fdt_get_path - determine the full path of a node
433 * @fdt: pointer to the device tree blob 592 * @fdt: pointer to the device tree blob
434 * @nodeoffset: offset of the node whose path to find 593 * @nodeoffset: offset of the node whose path to find
@@ -693,17 +852,17 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
693 const void *val, int len); 852 const void *val, int len);
694 853
695/** 854/**
696 * fdt_setprop_inplace_cell - change the value of a single-cell property 855 * fdt_setprop_inplace_u32 - change the value of a 32-bit integer property
697 * @fdt: pointer to the device tree blob 856 * @fdt: pointer to the device tree blob
698 * @nodeoffset: offset of the node whose property to change 857 * @nodeoffset: offset of the node whose property to change
699 * @name: name of the property to change 858 * @name: name of the property to change
700 * @val: cell (32-bit integer) value to replace the property with 859 * @val: 32-bit integer value to replace the property with
701 * 860 *
702 * fdt_setprop_inplace_cell() replaces the value of a given property 861 * fdt_setprop_inplace_u32() replaces the value of a given property
703 * with the 32-bit integer cell value in val, converting val to 862 * with the 32-bit integer value in val, converting val to big-endian
704 * big-endian if necessary. This function cannot change the size of a 863 * if necessary. This function cannot change the size of a property,
705 * property, and so will only work if the property already exists and 864 * and so will only work if the property already exists and has length
706 * has length 4. 865 * 4.
707 * 866 *
708 * This function will alter only the bytes in the blob which contain 867 * This function will alter only the bytes in the blob which contain
709 * the given property value, and will not alter or move any other part 868 * the given property value, and will not alter or move any other part
@@ -712,7 +871,7 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
712 * returns: 871 * returns:
713 * 0, on success 872 * 0, on success
714 * -FDT_ERR_NOSPACE, if the property's length is not equal to 4 873 * -FDT_ERR_NOSPACE, if the property's length is not equal to 4
715 * -FDT_ERR_NOTFOUND, node does not have the named property 874 * -FDT_ERR_NOTFOUND, node does not have the named property
716 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 875 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
717 * -FDT_ERR_BADMAGIC, 876 * -FDT_ERR_BADMAGIC,
718 * -FDT_ERR_BADVERSION, 877 * -FDT_ERR_BADVERSION,
@@ -720,14 +879,60 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
720 * -FDT_ERR_BADSTRUCTURE, 879 * -FDT_ERR_BADSTRUCTURE,
721 * -FDT_ERR_TRUNCATED, standard meanings 880 * -FDT_ERR_TRUNCATED, standard meanings
722 */ 881 */
723static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset, 882static inline int fdt_setprop_inplace_u32(void *fdt, int nodeoffset,
724 const char *name, uint32_t val) 883 const char *name, uint32_t val)
725{ 884{
726 val = cpu_to_fdt32(val); 885 val = cpu_to_fdt32(val);
727 return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val)); 886 return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val));
728} 887}
729 888
730/** 889/**
890 * fdt_setprop_inplace_u64 - change the value of a 64-bit integer property
891 * @fdt: pointer to the device tree blob
892 * @nodeoffset: offset of the node whose property to change
893 * @name: name of the property to change
894 * @val: 64-bit integer value to replace the property with
895 *
896 * fdt_setprop_inplace_u64() replaces the value of a given property
897 * with the 64-bit integer value in val, converting val to big-endian
898 * if necessary. This function cannot change the size of a property,
899 * and so will only work if the property already exists and has length
900 * 8.
901 *
902 * This function will alter only the bytes in the blob which contain
903 * the given property value, and will not alter or move any other part
904 * of the tree.
905 *
906 * returns:
907 * 0, on success
908 * -FDT_ERR_NOSPACE, if the property's length is not equal to 8
909 * -FDT_ERR_NOTFOUND, node does not have the named property
910 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
911 * -FDT_ERR_BADMAGIC,
912 * -FDT_ERR_BADVERSION,
913 * -FDT_ERR_BADSTATE,
914 * -FDT_ERR_BADSTRUCTURE,
915 * -FDT_ERR_TRUNCATED, standard meanings
916 */
917static inline int fdt_setprop_inplace_u64(void *fdt, int nodeoffset,
918 const char *name, uint64_t val)
919{
920 val = cpu_to_fdt64(val);
921 return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val));
922}
923
924/**
925 * fdt_setprop_inplace_cell - change the value of a single-cell property
926 *
927 * This is an alternative name for fdt_setprop_inplace_u32()
928 */
929static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
930 const char *name, uint32_t val)
931{
932 return fdt_setprop_inplace_u32(fdt, nodeoffset, name, val);
933}
934
935/**
731 * fdt_nop_property - replace a property with nop tags 936 * fdt_nop_property - replace a property with nop tags
732 * @fdt: pointer to the device tree blob 937 * @fdt: pointer to the device tree blob
733 * @nodeoffset: offset of the node whose property to nop 938 * @nodeoffset: offset of the node whose property to nop
@@ -786,11 +991,20 @@ int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size);
786int fdt_finish_reservemap(void *fdt); 991int fdt_finish_reservemap(void *fdt);
787int fdt_begin_node(void *fdt, const char *name); 992int fdt_begin_node(void *fdt, const char *name);
788int fdt_property(void *fdt, const char *name, const void *val, int len); 993int fdt_property(void *fdt, const char *name, const void *val, int len);
789static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val) 994static inline int fdt_property_u32(void *fdt, const char *name, uint32_t val)
790{ 995{
791 val = cpu_to_fdt32(val); 996 val = cpu_to_fdt32(val);
792 return fdt_property(fdt, name, &val, sizeof(val)); 997 return fdt_property(fdt, name, &val, sizeof(val));
793} 998}
999static inline int fdt_property_u64(void *fdt, const char *name, uint64_t val)
1000{
1001 val = cpu_to_fdt64(val);
1002 return fdt_property(fdt, name, &val, sizeof(val));
1003}
1004static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
1005{
1006 return fdt_property_u32(fdt, name, val);
1007}
794#define fdt_property_string(fdt, name, str) \ 1008#define fdt_property_string(fdt, name, str) \
795 fdt_property(fdt, name, str, strlen(str)+1) 1009 fdt_property(fdt, name, str, strlen(str)+1)
796int fdt_end_node(void *fdt); 1010int fdt_end_node(void *fdt);
@@ -800,6 +1014,7 @@ int fdt_finish(void *fdt);
800/* Read-write functions */ 1014/* Read-write functions */
801/**********************************************************************/ 1015/**********************************************************************/
802 1016
1017int fdt_create_empty_tree(void *buf, int bufsize);
803int fdt_open_into(const void *fdt, void *buf, int bufsize); 1018int fdt_open_into(const void *fdt, void *buf, int bufsize);
804int fdt_pack(void *fdt); 1019int fdt_pack(void *fdt);
805 1020
@@ -909,14 +1124,14 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,
909 const void *val, int len); 1124 const void *val, int len);
910 1125
911/** 1126/**
912 * fdt_setprop_cell - set a property to a single cell value 1127 * fdt_setprop_u32 - set a property to a 32-bit integer
913 * @fdt: pointer to the device tree blob 1128 * @fdt: pointer to the device tree blob
914 * @nodeoffset: offset of the node whose property to change 1129 * @nodeoffset: offset of the node whose property to change
915 * @name: name of the property to change 1130 * @name: name of the property to change
916 * @val: 32-bit integer value for the property (native endian) 1131 * @val: 32-bit integer value for the property (native endian)
917 * 1132 *
918 * fdt_setprop_cell() sets the value of the named property in the 1133 * fdt_setprop_u32() sets the value of the named property in the given
919 * given node to the given cell value (converting to big-endian if 1134 * node to the given 32-bit integer value (converting to big-endian if
920 * necessary), or creates a new property with that value if it does 1135 * necessary), or creates a new property with that value if it does
921 * not already exist. 1136 * not already exist.
922 * 1137 *
@@ -936,14 +1151,60 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,
936 * -FDT_ERR_BADLAYOUT, 1151 * -FDT_ERR_BADLAYOUT,
937 * -FDT_ERR_TRUNCATED, standard meanings 1152 * -FDT_ERR_TRUNCATED, standard meanings
938 */ 1153 */
939static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name, 1154static inline int fdt_setprop_u32(void *fdt, int nodeoffset, const char *name,
940 uint32_t val) 1155 uint32_t val)
941{ 1156{
942 val = cpu_to_fdt32(val); 1157 val = cpu_to_fdt32(val);
943 return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val)); 1158 return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val));
944} 1159}
945 1160
946/** 1161/**
1162 * fdt_setprop_u64 - set a property to a 64-bit integer
1163 * @fdt: pointer to the device tree blob
1164 * @nodeoffset: offset of the node whose property to change
1165 * @name: name of the property to change
1166 * @val: 64-bit integer value for the property (native endian)
1167 *
1168 * fdt_setprop_u64() sets the value of the named property in the given
1169 * node to the given 64-bit integer value (converting to big-endian if
1170 * necessary), or creates a new property with that value if it does
1171 * not already exist.
1172 *
1173 * This function may insert or delete data from the blob, and will
1174 * therefore change the offsets of some existing nodes.
1175 *
1176 * returns:
1177 * 0, on success
1178 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1179 * contain the new property value
1180 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1181 * -FDT_ERR_BADLAYOUT,
1182 * -FDT_ERR_BADMAGIC,
1183 * -FDT_ERR_BADVERSION,
1184 * -FDT_ERR_BADSTATE,
1185 * -FDT_ERR_BADSTRUCTURE,
1186 * -FDT_ERR_BADLAYOUT,
1187 * -FDT_ERR_TRUNCATED, standard meanings
1188 */
1189static inline int fdt_setprop_u64(void *fdt, int nodeoffset, const char *name,
1190 uint64_t val)
1191{
1192 val = cpu_to_fdt64(val);
1193 return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val));
1194}
1195
1196/**
1197 * fdt_setprop_cell - set a property to a single cell value
1198 *
1199 * This is an alternative name for fdt_setprop_u32()
1200 */
1201static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
1202 uint32_t val)
1203{
1204 return fdt_setprop_u32(fdt, nodeoffset, name, val);
1205}
1206
1207/**
947 * fdt_setprop_string - set a property to a string value 1208 * fdt_setprop_string - set a property to a string value
948 * @fdt: pointer to the device tree blob 1209 * @fdt: pointer to the device tree blob
949 * @nodeoffset: offset of the node whose property to change 1210 * @nodeoffset: offset of the node whose property to change
@@ -975,6 +1236,147 @@ static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
975 fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1) 1236 fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
976 1237
977/** 1238/**
1239 * fdt_appendprop - append to or create a property
1240 * @fdt: pointer to the device tree blob
1241 * @nodeoffset: offset of the node whose property to change
1242 * @name: name of the property to append to
1243 * @val: pointer to data to append to the property value
1244 * @len: length of the data to append to the property value
1245 *
1246 * fdt_appendprop() appends the value to the named property in the
1247 * given node, creating the property if it does not already exist.
1248 *
1249 * This function may insert data into the blob, and will therefore
1250 * change the offsets of some existing nodes.
1251 *
1252 * returns:
1253 * 0, on success
1254 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1255 * contain the new property value
1256 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1257 * -FDT_ERR_BADLAYOUT,
1258 * -FDT_ERR_BADMAGIC,
1259 * -FDT_ERR_BADVERSION,
1260 * -FDT_ERR_BADSTATE,
1261 * -FDT_ERR_BADSTRUCTURE,
1262 * -FDT_ERR_BADLAYOUT,
1263 * -FDT_ERR_TRUNCATED, standard meanings
1264 */
1265int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
1266 const void *val, int len);
1267
1268/**
1269 * fdt_appendprop_u32 - append a 32-bit integer value to a property
1270 * @fdt: pointer to the device tree blob
1271 * @nodeoffset: offset of the node whose property to change
1272 * @name: name of the property to change
1273 * @val: 32-bit integer value to append to the property (native endian)
1274 *
1275 * fdt_appendprop_u32() appends the given 32-bit integer value
1276 * (converting to big-endian if necessary) to the value of the named
1277 * property in the given node, or creates a new property with that
1278 * value if it does not already exist.
1279 *
1280 * This function may insert data into the blob, and will therefore
1281 * change the offsets of some existing nodes.
1282 *
1283 * returns:
1284 * 0, on success
1285 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1286 * contain the new property value
1287 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1288 * -FDT_ERR_BADLAYOUT,
1289 * -FDT_ERR_BADMAGIC,
1290 * -FDT_ERR_BADVERSION,
1291 * -FDT_ERR_BADSTATE,
1292 * -FDT_ERR_BADSTRUCTURE,
1293 * -FDT_ERR_BADLAYOUT,
1294 * -FDT_ERR_TRUNCATED, standard meanings
1295 */
1296static inline int fdt_appendprop_u32(void *fdt, int nodeoffset,
1297 const char *name, uint32_t val)
1298{
1299 val = cpu_to_fdt32(val);
1300 return fdt_appendprop(fdt, nodeoffset, name, &val, sizeof(val));
1301}
1302
1303/**
1304 * fdt_appendprop_u64 - append a 64-bit integer value to a property
1305 * @fdt: pointer to the device tree blob
1306 * @nodeoffset: offset of the node whose property to change
1307 * @name: name of the property to change
1308 * @val: 64-bit integer value to append to the property (native endian)
1309 *
1310 * fdt_appendprop_u64() appends the given 64-bit integer value
1311 * (converting to big-endian if necessary) to the value of the named
1312 * property in the given node, or creates a new property with that
1313 * value if it does not already exist.
1314 *
1315 * This function may insert data into the blob, and will therefore
1316 * change the offsets of some existing nodes.
1317 *
1318 * returns:
1319 * 0, on success
1320 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1321 * contain the new property value
1322 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1323 * -FDT_ERR_BADLAYOUT,
1324 * -FDT_ERR_BADMAGIC,
1325 * -FDT_ERR_BADVERSION,
1326 * -FDT_ERR_BADSTATE,
1327 * -FDT_ERR_BADSTRUCTURE,
1328 * -FDT_ERR_BADLAYOUT,
1329 * -FDT_ERR_TRUNCATED, standard meanings
1330 */
1331static inline int fdt_appendprop_u64(void *fdt, int nodeoffset,
1332 const char *name, uint64_t val)
1333{
1334 val = cpu_to_fdt64(val);
1335 return fdt_appendprop(fdt, nodeoffset, name, &val, sizeof(val));
1336}
1337
1338/**
1339 * fdt_appendprop_cell - append a single cell value to a property
1340 *
1341 * This is an alternative name for fdt_appendprop_u32()
1342 */
1343static inline int fdt_appendprop_cell(void *fdt, int nodeoffset,
1344 const char *name, uint32_t val)
1345{
1346 return fdt_appendprop_u32(fdt, nodeoffset, name, val);
1347}
1348
1349/**
1350 * fdt_appendprop_string - append a string to a property
1351 * @fdt: pointer to the device tree blob
1352 * @nodeoffset: offset of the node whose property to change
1353 * @name: name of the property to change
1354 * @str: string value to append to the property
1355 *
1356 * fdt_appendprop_string() appends the given string to the value of
1357 * the named property in the given node, or creates a new property
1358 * with that value if it does not already exist.
1359 *
1360 * This function may insert data into the blob, and will therefore
1361 * change the offsets of some existing nodes.
1362 *
1363 * returns:
1364 * 0, on success
1365 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1366 * contain the new property value
1367 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1368 * -FDT_ERR_BADLAYOUT,
1369 * -FDT_ERR_BADMAGIC,
1370 * -FDT_ERR_BADVERSION,
1371 * -FDT_ERR_BADSTATE,
1372 * -FDT_ERR_BADSTRUCTURE,
1373 * -FDT_ERR_BADLAYOUT,
1374 * -FDT_ERR_TRUNCATED, standard meanings
1375 */
1376#define fdt_appendprop_string(fdt, nodeoffset, name, str) \
1377 fdt_appendprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
1378
1379/**
978 * fdt_delprop - delete a property 1380 * fdt_delprop - delete a property
979 * @fdt: pointer to the device tree blob 1381 * @fdt: pointer to the device tree blob
980 * @nodeoffset: offset of the node whose property to nop 1382 * @nodeoffset: offset of the node whose property to nop
diff --git a/scripts/dtc/libfdt/libfdt_env.h b/scripts/dtc/libfdt/libfdt_env.h
index 449bf602daf1..213d7fb81c42 100644
--- a/scripts/dtc/libfdt/libfdt_env.h
+++ b/scripts/dtc/libfdt/libfdt_env.h
@@ -5,19 +5,25 @@
5#include <stdint.h> 5#include <stdint.h>
6#include <string.h> 6#include <string.h>
7 7
8#define _B(n) ((unsigned long long)((uint8_t *)&x)[n]) 8#define EXTRACT_BYTE(n) ((unsigned long long)((uint8_t *)&x)[n])
9static inline uint16_t fdt16_to_cpu(uint16_t x)
10{
11 return (EXTRACT_BYTE(0) << 8) | EXTRACT_BYTE(1);
12}
13#define cpu_to_fdt16(x) fdt16_to_cpu(x)
14
9static inline uint32_t fdt32_to_cpu(uint32_t x) 15static inline uint32_t fdt32_to_cpu(uint32_t x)
10{ 16{
11 return (_B(0) << 24) | (_B(1) << 16) | (_B(2) << 8) | _B(3); 17 return (EXTRACT_BYTE(0) << 24) | (EXTRACT_BYTE(1) << 16) | (EXTRACT_BYTE(2) << 8) | EXTRACT_BYTE(3);
12} 18}
13#define cpu_to_fdt32(x) fdt32_to_cpu(x) 19#define cpu_to_fdt32(x) fdt32_to_cpu(x)
14 20
15static inline uint64_t fdt64_to_cpu(uint64_t x) 21static inline uint64_t fdt64_to_cpu(uint64_t x)
16{ 22{
17 return (_B(0) << 56) | (_B(1) << 48) | (_B(2) << 40) | (_B(3) << 32) 23 return (EXTRACT_BYTE(0) << 56) | (EXTRACT_BYTE(1) << 48) | (EXTRACT_BYTE(2) << 40) | (EXTRACT_BYTE(3) << 32)
18 | (_B(4) << 24) | (_B(5) << 16) | (_B(6) << 8) | _B(7); 24 | (EXTRACT_BYTE(4) << 24) | (EXTRACT_BYTE(5) << 16) | (EXTRACT_BYTE(6) << 8) | EXTRACT_BYTE(7);
19} 25}
20#define cpu_to_fdt64(x) fdt64_to_cpu(x) 26#define cpu_to_fdt64(x) fdt64_to_cpu(x)
21#undef _B 27#undef EXTRACT_BYTE
22 28
23#endif /* _LIBFDT_ENV_H */ 29#endif /* _LIBFDT_ENV_H */
diff --git a/scripts/dtc/libfdt/libfdt_internal.h b/scripts/dtc/libfdt/libfdt_internal.h
index 46eb93e4af5c..381133ba81df 100644
--- a/scripts/dtc/libfdt/libfdt_internal.h
+++ b/scripts/dtc/libfdt/libfdt_internal.h
@@ -62,8 +62,8 @@
62 return err; \ 62 return err; \
63 } 63 }
64 64
65uint32_t _fdt_next_tag(const void *fdt, int startoffset, int *nextoffset);
66int _fdt_check_node_offset(const void *fdt, int offset); 65int _fdt_check_node_offset(const void *fdt, int offset);
66int _fdt_check_prop_offset(const void *fdt, int offset);
67const char *_fdt_find_string(const char *strtab, int tabsize, const char *s); 67const char *_fdt_find_string(const char *strtab, int tabsize, const char *s);
68int _fdt_node_end_offset(void *fdt, int nodeoffset); 68int _fdt_node_end_offset(void *fdt, int nodeoffset);
69 69
diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c
index 26d0e1e60c0c..b61465fb2f33 100644
--- a/scripts/dtc/livetree.c
+++ b/scripts/dtc/livetree.c
@@ -29,16 +29,27 @@ void add_label(struct label **labels, char *label)
29 struct label *new; 29 struct label *new;
30 30
31 /* Make sure the label isn't already there */ 31 /* Make sure the label isn't already there */
32 for_each_label(*labels, new) 32 for_each_label_withdel(*labels, new)
33 if (streq(new->label, label)) 33 if (streq(new->label, label)) {
34 new->deleted = 0;
34 return; 35 return;
36 }
35 37
36 new = xmalloc(sizeof(*new)); 38 new = xmalloc(sizeof(*new));
39 memset(new, 0, sizeof(*new));
37 new->label = label; 40 new->label = label;
38 new->next = *labels; 41 new->next = *labels;
39 *labels = new; 42 *labels = new;
40} 43}
41 44
45void delete_labels(struct label **labels)
46{
47 struct label *label;
48
49 for_each_label(*labels, label)
50 label->deleted = 1;
51}
52
42struct property *build_property(char *name, struct data val) 53struct property *build_property(char *name, struct data val)
43{ 54{
44 struct property *new = xmalloc(sizeof(*new)); 55 struct property *new = xmalloc(sizeof(*new));
@@ -51,6 +62,18 @@ struct property *build_property(char *name, struct data val)
51 return new; 62 return new;
52} 63}
53 64
65struct property *build_property_delete(char *name)
66{
67 struct property *new = xmalloc(sizeof(*new));
68
69 memset(new, 0, sizeof(*new));
70
71 new->name = name;
72 new->deleted = 1;
73
74 return new;
75}
76
54struct property *chain_property(struct property *first, struct property *list) 77struct property *chain_property(struct property *first, struct property *list)
55{ 78{
56 assert(first->next == NULL); 79 assert(first->next == NULL);
@@ -91,6 +114,17 @@ struct node *build_node(struct property *proplist, struct node *children)
91 return new; 114 return new;
92} 115}
93 116
117struct node *build_node_delete(void)
118{
119 struct node *new = xmalloc(sizeof(*new));
120
121 memset(new, 0, sizeof(*new));
122
123 new->deleted = 1;
124
125 return new;
126}
127
94struct node *name_node(struct node *node, char *name) 128struct node *name_node(struct node *node, char *name)
95{ 129{
96 assert(node->name == NULL); 130 assert(node->name == NULL);
@@ -106,8 +140,10 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
106 struct node *new_child, *old_child; 140 struct node *new_child, *old_child;
107 struct label *l; 141 struct label *l;
108 142
143 old_node->deleted = 0;
144
109 /* Add new node labels to old node */ 145 /* Add new node labels to old node */
110 for_each_label(new_node->labels, l) 146 for_each_label_withdel(new_node->labels, l)
111 add_label(&old_node->labels, l->label); 147 add_label(&old_node->labels, l->label);
112 148
113 /* Move properties from the new node to the old node. If there 149 /* Move properties from the new node to the old node. If there
@@ -118,14 +154,21 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
118 new_node->proplist = new_prop->next; 154 new_node->proplist = new_prop->next;
119 new_prop->next = NULL; 155 new_prop->next = NULL;
120 156
157 if (new_prop->deleted) {
158 delete_property_by_name(old_node, new_prop->name);
159 free(new_prop);
160 continue;
161 }
162
121 /* Look for a collision, set new value if there is */ 163 /* Look for a collision, set new value if there is */
122 for_each_property(old_node, old_prop) { 164 for_each_property_withdel(old_node, old_prop) {
123 if (streq(old_prop->name, new_prop->name)) { 165 if (streq(old_prop->name, new_prop->name)) {
124 /* Add new labels to old property */ 166 /* Add new labels to old property */
125 for_each_label(new_prop->labels, l) 167 for_each_label_withdel(new_prop->labels, l)
126 add_label(&old_prop->labels, l->label); 168 add_label(&old_prop->labels, l->label);
127 169
128 old_prop->val = new_prop->val; 170 old_prop->val = new_prop->val;
171 old_prop->deleted = 0;
129 free(new_prop); 172 free(new_prop);
130 new_prop = NULL; 173 new_prop = NULL;
131 break; 174 break;
@@ -146,8 +189,14 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
146 new_child->parent = NULL; 189 new_child->parent = NULL;
147 new_child->next_sibling = NULL; 190 new_child->next_sibling = NULL;
148 191
192 if (new_child->deleted) {
193 delete_node_by_name(old_node, new_child->name);
194 free(new_child);
195 continue;
196 }
197
149 /* Search for a collision. Merge if there is */ 198 /* Search for a collision. Merge if there is */
150 for_each_child(old_node, old_child) { 199 for_each_child_withdel(old_node, old_child) {
151 if (streq(old_child->name, new_child->name)) { 200 if (streq(old_child->name, new_child->name)) {
152 merge_nodes(old_child, new_child); 201 merge_nodes(old_child, new_child);
153 new_child = NULL; 202 new_child = NULL;
@@ -155,7 +204,7 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
155 } 204 }
156 } 205 }
157 206
158 /* if no collision occurred, add child to the old node. */ 207 /* if no collision occured, add child to the old node. */
159 if (new_child) 208 if (new_child)
160 add_child(old_node, new_child); 209 add_child(old_node, new_child);
161 } 210 }
@@ -188,6 +237,25 @@ void add_property(struct node *node, struct property *prop)
188 *p = prop; 237 *p = prop;
189} 238}
190 239
240void delete_property_by_name(struct node *node, char *name)
241{
242 struct property *prop = node->proplist;
243
244 while (prop) {
245 if (!strcmp(prop->name, name)) {
246 delete_property(prop);
247 return;
248 }
249 prop = prop->next;
250 }
251}
252
253void delete_property(struct property *prop)
254{
255 prop->deleted = 1;
256 delete_labels(&prop->labels);
257}
258
191void add_child(struct node *parent, struct node *child) 259void add_child(struct node *parent, struct node *child)
192{ 260{
193 struct node **p; 261 struct node **p;
@@ -202,6 +270,32 @@ void add_child(struct node *parent, struct node *child)
202 *p = child; 270 *p = child;
203} 271}
204 272
273void delete_node_by_name(struct node *parent, char *name)
274{
275 struct node *node = parent->children;
276
277 while (node) {
278 if (!strcmp(node->name, name)) {
279 delete_node(node);
280 return;
281 }
282 node = node->next_sibling;
283 }
284}
285
286void delete_node(struct node *node)
287{
288 struct property *prop;
289 struct node *child;
290
291 node->deleted = 1;
292 for_each_child(node, child)
293 delete_node(child);
294 for_each_property(node, prop)
295 delete_property(prop);
296 delete_labels(&node->labels);
297}
298
205struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size) 299struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size)
206{ 300{
207 struct reserve_info *new = xmalloc(sizeof(*new)); 301 struct reserve_info *new = xmalloc(sizeof(*new));
@@ -353,8 +447,11 @@ struct node *get_node_by_path(struct node *tree, const char *path)
353 const char *p; 447 const char *p;
354 struct node *child; 448 struct node *child;
355 449
356 if (!path || ! (*path)) 450 if (!path || ! (*path)) {
451 if (tree->deleted)
452 return NULL;
357 return tree; 453 return tree;
454 }
358 455
359 while (path[0] == '/') 456 while (path[0] == '/')
360 path++; 457 path++;
@@ -397,8 +494,11 @@ struct node *get_node_by_phandle(struct node *tree, cell_t phandle)
397 494
398 assert((phandle != 0) && (phandle != -1)); 495 assert((phandle != 0) && (phandle != -1));
399 496
400 if (tree->phandle == phandle) 497 if (tree->phandle == phandle) {
498 if (tree->deleted)
499 return NULL;
401 return tree; 500 return tree;
501 }
402 502
403 for_each_child(tree, child) { 503 for_each_child(tree, child) {
404 node = get_node_by_phandle(child, phandle); 504 node = get_node_by_phandle(child, phandle);
@@ -535,7 +635,7 @@ static void sort_properties(struct node *node)
535 int n = 0, i = 0; 635 int n = 0, i = 0;
536 struct property *prop, **tbl; 636 struct property *prop, **tbl;
537 637
538 for_each_property(node, prop) 638 for_each_property_withdel(node, prop)
539 n++; 639 n++;
540 640
541 if (n == 0) 641 if (n == 0)
@@ -543,7 +643,7 @@ static void sort_properties(struct node *node)
543 643
544 tbl = xmalloc(n * sizeof(*tbl)); 644 tbl = xmalloc(n * sizeof(*tbl));
545 645
546 for_each_property(node, prop) 646 for_each_property_withdel(node, prop)
547 tbl[i++] = prop; 647 tbl[i++] = prop;
548 648
549 qsort(tbl, n, sizeof(*tbl), cmp_prop); 649 qsort(tbl, n, sizeof(*tbl), cmp_prop);
@@ -571,7 +671,7 @@ static void sort_subnodes(struct node *node)
571 int n = 0, i = 0; 671 int n = 0, i = 0;
572 struct node *subnode, **tbl; 672 struct node *subnode, **tbl;
573 673
574 for_each_child(node, subnode) 674 for_each_child_withdel(node, subnode)
575 n++; 675 n++;
576 676
577 if (n == 0) 677 if (n == 0)
@@ -579,7 +679,7 @@ static void sort_subnodes(struct node *node)
579 679
580 tbl = xmalloc(n * sizeof(*tbl)); 680 tbl = xmalloc(n * sizeof(*tbl));
581 681
582 for_each_child(node, subnode) 682 for_each_child_withdel(node, subnode)
583 tbl[i++] = subnode; 683 tbl[i++] = subnode;
584 684
585 qsort(tbl, n, sizeof(*tbl), cmp_subnode); 685 qsort(tbl, n, sizeof(*tbl), cmp_subnode);
@@ -598,7 +698,7 @@ static void sort_node(struct node *node)
598 698
599 sort_properties(node); 699 sort_properties(node);
600 sort_subnodes(node); 700 sort_subnodes(node);
601 for_each_child(node, c) 701 for_each_child_withdel(node, c)
602 sort_node(c); 702 sort_node(c);
603} 703}
604 704
diff --git a/scripts/dtc/srcpos.c b/scripts/dtc/srcpos.c
index 36a38e9f1a2c..246ab4bc0d9d 100644
--- a/scripts/dtc/srcpos.c
+++ b/scripts/dtc/srcpos.c
@@ -24,6 +24,15 @@
24#include "dtc.h" 24#include "dtc.h"
25#include "srcpos.h" 25#include "srcpos.h"
26 26
27/* A node in our list of directories to search for source/include files */
28struct search_path {
29 struct search_path *next; /* next node in list, NULL for end */
30 const char *dirname; /* name of directory to search */
31};
32
33/* This is the list of directories that we search for source files */
34static struct search_path *search_path_head, **search_path_tail;
35
27 36
28static char *dirname(const char *path) 37static char *dirname(const char *path)
29{ 38{
@@ -47,6 +56,64 @@ struct srcfile_state *current_srcfile; /* = NULL */
47#define MAX_SRCFILE_DEPTH (100) 56#define MAX_SRCFILE_DEPTH (100)
48static int srcfile_depth; /* = 0 */ 57static int srcfile_depth; /* = 0 */
49 58
59
60/**
61 * Try to open a file in a given directory.
62 *
63 * If the filename is an absolute path, then dirname is ignored. If it is a
64 * relative path, then we look in that directory for the file.
65 *
66 * @param dirname Directory to look in, or NULL for none
67 * @param fname Filename to look for
68 * @param fp Set to NULL if file did not open
69 * @return allocated filename on success (caller must free), NULL on failure
70 */
71static char *try_open(const char *dirname, const char *fname, FILE **fp)
72{
73 char *fullname;
74
75 if (!dirname || fname[0] == '/')
76 fullname = xstrdup(fname);
77 else
78 fullname = join_path(dirname, fname);
79
80 *fp = fopen(fullname, "r");
81 if (!*fp) {
82 free(fullname);
83 fullname = NULL;
84 }
85
86 return fullname;
87}
88
89/**
90 * Open a file for read access
91 *
92 * If it is a relative filename, we search the full search path for it.
93 *
94 * @param fname Filename to open
95 * @param fp Returns pointer to opened FILE, or NULL on failure
96 * @return pointer to allocated filename, which caller must free
97 */
98static char *fopen_any_on_path(const char *fname, FILE **fp)
99{
100 const char *cur_dir = NULL;
101 struct search_path *node;
102 char *fullname;
103
104 /* Try current directory first */
105 assert(fp);
106 if (current_srcfile)
107 cur_dir = current_srcfile->dir;
108 fullname = try_open(cur_dir, fname, fp);
109
110 /* Failing that, try each search path in turn */
111 for (node = search_path_head; !*fp && node; node = node->next)
112 fullname = try_open(node->dirname, fname, fp);
113
114 return fullname;
115}
116
50FILE *srcfile_relative_open(const char *fname, char **fullnamep) 117FILE *srcfile_relative_open(const char *fname, char **fullnamep)
51{ 118{
52 FILE *f; 119 FILE *f;
@@ -56,13 +123,7 @@ FILE *srcfile_relative_open(const char *fname, char **fullnamep)
56 f = stdin; 123 f = stdin;
57 fullname = xstrdup("<stdin>"); 124 fullname = xstrdup("<stdin>");
58 } else { 125 } else {
59 if (!current_srcfile || !current_srcfile->dir 126 fullname = fopen_any_on_path(fname, &f);
60 || (fname[0] == '/'))
61 fullname = xstrdup(fname);
62 else
63 fullname = join_path(current_srcfile->dir, fname);
64
65 f = fopen(fullname, "r");
66 if (!f) 127 if (!f)
67 die("Couldn't open \"%s\": %s\n", fname, 128 die("Couldn't open \"%s\": %s\n", fname,
68 strerror(errno)); 129 strerror(errno));
@@ -119,6 +180,23 @@ int srcfile_pop(void)
119 return current_srcfile ? 1 : 0; 180 return current_srcfile ? 1 : 0;
120} 181}
121 182
183void srcfile_add_search_path(const char *dirname)
184{
185 struct search_path *node;
186
187 /* Create the node */
188 node = xmalloc(sizeof(*node));
189 node->next = NULL;
190 node->dirname = xstrdup(dirname);
191
192 /* Add to the end of our list */
193 if (search_path_tail)
194 *search_path_tail = node;
195 else
196 search_path_head = node;
197 search_path_tail = &node->next;
198}
199
122/* 200/*
123 * The empty source position. 201 * The empty source position.
124 */ 202 */
@@ -250,3 +328,9 @@ srcpos_warn(struct srcpos *pos, char const *fmt, ...)
250 328
251 va_end(va); 329 va_end(va);
252} 330}
331
332void srcpos_set_line(char *f, int l)
333{
334 current_srcfile->name = f;
335 current_srcfile->lineno = l;
336}
diff --git a/scripts/dtc/srcpos.h b/scripts/dtc/srcpos.h
index ce980cafe588..93a27123c2e9 100644
--- a/scripts/dtc/srcpos.h
+++ b/scripts/dtc/srcpos.h
@@ -33,10 +33,39 @@ struct srcfile_state {
33extern FILE *depfile; /* = NULL */ 33extern FILE *depfile; /* = NULL */
34extern struct srcfile_state *current_srcfile; /* = NULL */ 34extern struct srcfile_state *current_srcfile; /* = NULL */
35 35
36/**
37 * Open a source file.
38 *
39 * If the source file is a relative pathname, then it is searched for in the
40 * current directory (the directory of the last source file read) and after
41 * that in the search path.
42 *
43 * We work through the search path in order from the first path specified to
44 * the last.
45 *
46 * If the file is not found, then this function does not return, but calls
47 * die().
48 *
49 * @param fname Filename to search
50 * @param fullnamep If non-NULL, it is set to the allocated filename of the
51 * file that was opened. The caller is then responsible
52 * for freeing the pointer.
53 * @return pointer to opened FILE
54 */
36FILE *srcfile_relative_open(const char *fname, char **fullnamep); 55FILE *srcfile_relative_open(const char *fname, char **fullnamep);
56
37void srcfile_push(const char *fname); 57void srcfile_push(const char *fname);
38int srcfile_pop(void); 58int srcfile_pop(void);
39 59
60/**
61 * Add a new directory to the search path for input files
62 *
63 * The new path is added at the end of the list.
64 *
65 * @param dirname Directory to add
66 */
67void srcfile_add_search_path(const char *dirname);
68
40struct srcpos { 69struct srcpos {
41 int first_line; 70 int first_line;
42 int first_column; 71 int first_column;
@@ -84,4 +113,6 @@ extern void srcpos_error(struct srcpos *pos, char const *, ...)
84extern void srcpos_warn(struct srcpos *pos, char const *, ...) 113extern void srcpos_warn(struct srcpos *pos, char const *, ...)
85 __attribute__((format(printf, 2, 3))); 114 __attribute__((format(printf, 2, 3)));
86 115
116extern void srcpos_set_line(char *f, int l);
117
87#endif /* _SRCPOS_H_ */ 118#endif /* _SRCPOS_H_ */
diff --git a/scripts/dtc/treesource.c b/scripts/dtc/treesource.c
index c09aafade313..33eeba55fb4d 100644
--- a/scripts/dtc/treesource.c
+++ b/scripts/dtc/treesource.c
@@ -23,6 +23,7 @@
23 23
24extern FILE *yyin; 24extern FILE *yyin;
25extern int yyparse(void); 25extern int yyparse(void);
26extern YYLTYPE yylloc;
26 27
27struct boot_info *the_boot_info; 28struct boot_info *the_boot_info;
28int treesource_error; 29int treesource_error;
@@ -34,6 +35,7 @@ struct boot_info *dt_from_source(const char *fname)
34 35
35 srcfile_push(fname); 36 srcfile_push(fname);
36 yyin = current_srcfile->f; 37 yyin = current_srcfile->f;
38 yylloc.file = current_srcfile;
37 39
38 if (yyparse() != 0) 40 if (yyparse() != 0)
39 die("Unable to parse input tree\n"); 41 die("Unable to parse input tree\n");
diff --git a/scripts/dtc/util.c b/scripts/dtc/util.c
index d7ac27d2ae15..2422c34e11df 100644
--- a/scripts/dtc/util.c
+++ b/scripts/dtc/util.c
@@ -1,6 +1,10 @@
1/* 1/*
2 * Copyright 2011 The Chromium Authors, All Rights Reserved.
2 * Copyright 2008 Jon Loeliger, Freescale Semiconductor, Inc. 3 * Copyright 2008 Jon Loeliger, Freescale Semiconductor, Inc.
3 * 4 *
5 * util_is_printable_string contributed by
6 * Pantelis Antoniou <pantelis.antoniou AT gmail.com>
7 *
4 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as 9 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the 10 * published by the Free Software Foundation; either version 2 of the
@@ -17,11 +21,18 @@
17 * USA 21 * USA
18 */ 22 */
19 23
24#include <ctype.h>
20#include <stdio.h> 25#include <stdio.h>
21#include <stdlib.h> 26#include <stdlib.h>
22#include <stdarg.h> 27#include <stdarg.h>
23#include <string.h> 28#include <string.h>
29#include <assert.h>
30
31#include <errno.h>
32#include <fcntl.h>
33#include <unistd.h>
24 34
35#include "libfdt.h"
25#include "util.h" 36#include "util.h"
26 37
27char *xstrdup(const char *s) 38char *xstrdup(const char *s)
@@ -57,3 +68,264 @@ char *join_path(const char *path, const char *name)
57 memcpy(str+lenp, name, lenn+1); 68 memcpy(str+lenp, name, lenn+1);
58 return str; 69 return str;
59} 70}
71
72int util_is_printable_string(const void *data, int len)
73{
74 const char *s = data;
75 const char *ss;
76
77 /* zero length is not */
78 if (len == 0)
79 return 0;
80
81 /* must terminate with zero */
82 if (s[len - 1] != '\0')
83 return 0;
84
85 ss = s;
86 while (*s && isprint(*s))
87 s++;
88
89 /* not zero, or not done yet */
90 if (*s != '\0' || (s + 1 - ss) < len)
91 return 0;
92
93 return 1;
94}
95
96/*
97 * Parse a octal encoded character starting at index i in string s. The
98 * resulting character will be returned and the index i will be updated to
99 * point at the character directly after the end of the encoding, this may be
100 * the '\0' terminator of the string.
101 */
102static char get_oct_char(const char *s, int *i)
103{
104 char x[4];
105 char *endx;
106 long val;
107
108 x[3] = '\0';
109 strncpy(x, s + *i, 3);
110
111 val = strtol(x, &endx, 8);
112
113 assert(endx > x);
114
115 (*i) += endx - x;
116 return val;
117}
118
119/*
120 * Parse a hexadecimal encoded character starting at index i in string s. The
121 * resulting character will be returned and the index i will be updated to
122 * point at the character directly after the end of the encoding, this may be
123 * the '\0' terminator of the string.
124 */
125static char get_hex_char(const char *s, int *i)
126{
127 char x[3];
128 char *endx;
129 long val;
130
131 x[2] = '\0';
132 strncpy(x, s + *i, 2);
133
134 val = strtol(x, &endx, 16);
135 if (!(endx > x))
136 die("\\x used with no following hex digits\n");
137
138 (*i) += endx - x;
139 return val;
140}
141
142char get_escape_char(const char *s, int *i)
143{
144 char c = s[*i];
145 int j = *i + 1;
146 char val;
147
148 assert(c);
149 switch (c) {
150 case 'a':
151 val = '\a';
152 break;
153 case 'b':
154 val = '\b';
155 break;
156 case 't':
157 val = '\t';
158 break;
159 case 'n':
160 val = '\n';
161 break;
162 case 'v':
163 val = '\v';
164 break;
165 case 'f':
166 val = '\f';
167 break;
168 case 'r':
169 val = '\r';
170 break;
171 case '0':
172 case '1':
173 case '2':
174 case '3':
175 case '4':
176 case '5':
177 case '6':
178 case '7':
179 j--; /* need to re-read the first digit as
180 * part of the octal value */
181 val = get_oct_char(s, &j);
182 break;
183 case 'x':
184 val = get_hex_char(s, &j);
185 break;
186 default:
187 val = c;
188 }
189
190 (*i) = j;
191 return val;
192}
193
194int utilfdt_read_err(const char *filename, char **buffp)
195{
196 int fd = 0; /* assume stdin */
197 char *buf = NULL;
198 off_t bufsize = 1024, offset = 0;
199 int ret = 0;
200
201 *buffp = NULL;
202 if (strcmp(filename, "-") != 0) {
203 fd = open(filename, O_RDONLY);
204 if (fd < 0)
205 return errno;
206 }
207
208 /* Loop until we have read everything */
209 buf = malloc(bufsize);
210 do {
211 /* Expand the buffer to hold the next chunk */
212 if (offset == bufsize) {
213 bufsize *= 2;
214 buf = realloc(buf, bufsize);
215 if (!buf) {
216 ret = ENOMEM;
217 break;
218 }
219 }
220
221 ret = read(fd, &buf[offset], bufsize - offset);
222 if (ret < 0) {
223 ret = errno;
224 break;
225 }
226 offset += ret;
227 } while (ret != 0);
228
229 /* Clean up, including closing stdin; return errno on error */
230 close(fd);
231 if (ret)
232 free(buf);
233 else
234 *buffp = buf;
235 return ret;
236}
237
238char *utilfdt_read(const char *filename)
239{
240 char *buff;
241 int ret = utilfdt_read_err(filename, &buff);
242
243 if (ret) {
244 fprintf(stderr, "Couldn't open blob from '%s': %s\n", filename,
245 strerror(ret));
246 return NULL;
247 }
248 /* Successful read */
249 return buff;
250}
251
252int utilfdt_write_err(const char *filename, const void *blob)
253{
254 int fd = 1; /* assume stdout */
255 int totalsize;
256 int offset;
257 int ret = 0;
258 const char *ptr = blob;
259
260 if (strcmp(filename, "-") != 0) {
261 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
262 if (fd < 0)
263 return errno;
264 }
265
266 totalsize = fdt_totalsize(blob);
267 offset = 0;
268
269 while (offset < totalsize) {
270 ret = write(fd, ptr + offset, totalsize - offset);
271 if (ret < 0) {
272 ret = -errno;
273 break;
274 }
275 offset += ret;
276 }
277 /* Close the file/stdin; return errno on error */
278 if (fd != 1)
279 close(fd);
280 return ret < 0 ? -ret : 0;
281}
282
283
284int utilfdt_write(const char *filename, const void *blob)
285{
286 int ret = utilfdt_write_err(filename, blob);
287
288 if (ret) {
289 fprintf(stderr, "Couldn't write blob to '%s': %s\n", filename,
290 strerror(ret));
291 }
292 return ret ? -1 : 0;
293}
294
295int utilfdt_decode_type(const char *fmt, int *type, int *size)
296{
297 int qualifier = 0;
298
299 if (!*fmt)
300 return -1;
301
302 /* get the conversion qualifier */
303 *size = -1;
304 if (strchr("hlLb", *fmt)) {
305 qualifier = *fmt++;
306 if (qualifier == *fmt) {
307 switch (*fmt++) {
308/* TODO: case 'l': qualifier = 'L'; break;*/
309 case 'h':
310 qualifier = 'b';
311 break;
312 }
313 }
314 }
315
316 /* we should now have a type */
317 if ((*fmt == '\0') || !strchr("iuxs", *fmt))
318 return -1;
319
320 /* convert qualifier (bhL) to byte size */
321 if (*fmt != 's')
322 *size = qualifier == 'b' ? 1 :
323 qualifier == 'h' ? 2 :
324 qualifier == 'l' ? 4 : -1;
325 *type = *fmt++;
326
327 /* that should be it! */
328 if (*fmt)
329 return -1;
330 return 0;
331}
diff --git a/scripts/dtc/util.h b/scripts/dtc/util.h
index 9cead842c11e..c8eb45d9f04b 100644
--- a/scripts/dtc/util.h
+++ b/scripts/dtc/util.h
@@ -1,7 +1,10 @@
1#ifndef _UTIL_H 1#ifndef _UTIL_H
2#define _UTIL_H 2#define _UTIL_H
3 3
4#include <stdarg.h>
5
4/* 6/*
7 * Copyright 2011 The Chromium Authors, All Rights Reserved.
5 * Copyright 2008 Jon Loeliger, Freescale Semiconductor, Inc. 8 * Copyright 2008 Jon Loeliger, Freescale Semiconductor, Inc.
6 * 9 *
7 * This program is free software; you can redistribute it and/or 10 * This program is free software; you can redistribute it and/or
@@ -53,4 +56,98 @@ static inline void *xrealloc(void *p, size_t len)
53extern char *xstrdup(const char *s); 56extern char *xstrdup(const char *s);
54extern char *join_path(const char *path, const char *name); 57extern char *join_path(const char *path, const char *name);
55 58
59/**
60 * Check a string of a given length to see if it is all printable and
61 * has a valid terminator.
62 *
63 * @param data The string to check
64 * @param len The string length including terminator
65 * @return 1 if a valid printable string, 0 if not */
66int util_is_printable_string(const void *data, int len);
67
68/*
69 * Parse an escaped character starting at index i in string s. The resulting
70 * character will be returned and the index i will be updated to point at the
71 * character directly after the end of the encoding, this may be the '\0'
72 * terminator of the string.
73 */
74char get_escape_char(const char *s, int *i);
75
76/**
77 * Read a device tree file into a buffer. This will report any errors on
78 * stderr.
79 *
80 * @param filename The filename to read, or - for stdin
81 * @return Pointer to allocated buffer containing fdt, or NULL on error
82 */
83char *utilfdt_read(const char *filename);
84
85/**
86 * Read a device tree file into a buffer. Does not report errors, but only
87 * returns them. The value returned can be passed to strerror() to obtain
88 * an error message for the user.
89 *
90 * @param filename The filename to read, or - for stdin
91 * @param buffp Returns pointer to buffer containing fdt
92 * @return 0 if ok, else an errno value representing the error
93 */
94int utilfdt_read_err(const char *filename, char **buffp);
95
96
97/**
98 * Write a device tree buffer to a file. This will report any errors on
99 * stderr.
100 *
101 * @param filename The filename to write, or - for stdout
102 * @param blob Poiner to buffer containing fdt
103 * @return 0 if ok, -1 on error
104 */
105int utilfdt_write(const char *filename, const void *blob);
106
107/**
108 * Write a device tree buffer to a file. Does not report errors, but only
109 * returns them. The value returned can be passed to strerror() to obtain
110 * an error message for the user.
111 *
112 * @param filename The filename to write, or - for stdout
113 * @param blob Poiner to buffer containing fdt
114 * @return 0 if ok, else an errno value representing the error
115 */
116int utilfdt_write_err(const char *filename, const void *blob);
117
118/**
119 * Decode a data type string. The purpose of this string
120 *
121 * The string consists of an optional character followed by the type:
122 * Modifier characters:
123 * hh or b 1 byte
124 * h 2 byte
125 * l 4 byte, default
126 *
127 * Type character:
128 * s string
129 * i signed integer
130 * u unsigned integer
131 * x hex
132 *
133 * TODO: Implement ll modifier (8 bytes)
134 * TODO: Implement o type (octal)
135 *
136 * @param fmt Format string to process
137 * @param type Returns type found(s/d/u/x), or 0 if none
138 * @param size Returns size found(1,2,4,8) or 4 if none
139 * @return 0 if ok, -1 on error (no type given, or other invalid format)
140 */
141int utilfdt_decode_type(const char *fmt, int *type, int *size);
142
143/*
144 * This is a usage message fragment for the -t option. It is the format
145 * supported by utilfdt_decode_type.
146 */
147
148#define USAGE_TYPE_MSG \
149 "<type>\ts=string, i=int, u=unsigned, x=hex\n" \
150 "\tOptional modifier prefix:\n" \
151 "\t\thh or b=byte, h=2 byte, l=4 byte (default)\n";
152
56#endif /* _UTIL_H */ 153#endif /* _UTIL_H */