From: Fabien Parent <[email protected]>
Add the ability to check if a property has the correct type. Right now dtc only
handles the two trivial types: integer array, string array. Since at the end
everything is an array of byte which may or may not be terminated by a null
byte this was enough.
A nice thing to add for the future would be to be able to specify the types
more precisely.
Add as well two test files for this feature.
/ {
compatible = "abc";
abc = <0xa 0xb 0xc>;
def = "def", gef;
};
To check that the property abc is an integer array and that the property def
is a string array for the dts above one can use the following schema:
/ {
compatible = "abc";
abc {
type = "integer";
};
def {
type = "string";
};
};
Signed-off-by: Fabien Parent <[email protected]>
Signed-off-by: Benoit Cousson <[email protected]>
---
scripts/dtc/data.c | 22 ++++++++++++----
scripts/dtc/dtc.h | 9 +++++++
scripts/dtc/schema-test.c | 5 ++++
scripts/dtc/schema.c | 44 ++++++++++++++++++++++++++++++++
scripts/dtc/tests/schemas/types-1.schema | 12 +++++++++
scripts/dtc/tests/schemas/types-2.schema | 7 +++++
scripts/dtc/tests/test1.dts | 10 ++++++++
7 files changed, 104 insertions(+), 5 deletions(-)
create mode 100644 scripts/dtc/tests/schemas/types-1.schema
create mode 100644 scripts/dtc/tests/schemas/types-2.schema
create mode 100644 scripts/dtc/tests/test1.dts
diff --git a/scripts/dtc/data.c b/scripts/dtc/data.c
index 4a40c5b..9e03718 100644
--- a/scripts/dtc/data.c
+++ b/scripts/dtc/data.c
@@ -75,6 +75,7 @@ struct data data_copy_escape_string(const char *s, int len)
char *q;
d = data_grow_for(empty_data, strlen(s)+1);
+ d.type = STRING;
q = d.val;
while (i < len) {
@@ -93,6 +94,7 @@ struct data data_copy_escape_string(const char *s, int len)
struct data data_copy_file(FILE *f, size_t maxlen)
{
struct data d = empty_data;
+ d.type = STRING;
while (!feof(f) && (d.len < maxlen)) {
size_t chunksize, ret;
@@ -157,6 +159,7 @@ struct data data_merge(struct data d1, struct data d2)
struct marker *m2 = d2.markers;
d = data_append_markers(data_append_data(d1, d2.val, d2.len), m2);
+ d.type = d2.type ? d2.type : d1.type;
/* Adjust for the length of d1 */
for_each_marker(m2)
@@ -178,23 +181,30 @@ struct data data_append_integer(struct data d, uint64_t
value, int bits)
switch (bits) {
case 8:
value_8 = value;
- return data_append_data(d, &value_8, 1);
+ d = data_append_data(d, &value_8, 1);
+ break;
case 16:
value_16 = cpu_to_fdt16(value);
- return data_append_data(d, &value_16, 2);
+ d = data_append_data(d, &value_16, 2);
+ break;
case 32:
value_32 = cpu_to_fdt32(value);
- return data_append_data(d, &value_32, 4);
+ d = data_append_data(d, &value_32, 4);
+ break;
case 64:
value_64 = cpu_to_fdt64(value);
- return data_append_data(d, &value_64, 8);
+ d = data_append_data(d, &value_64, 8);
+ break;
default:
die("Invalid literal size (%d)\n", bits);
}
+
+ d.type = INTEGER;
+ return d;
}
struct data data_append_re(struct data d, const struct fdt_reserve_entry *re)
@@ -219,7 +229,9 @@ struct data data_append_addr(struct data d, uint64_t addr)
struct data data_append_byte(struct data d, uint8_t byte)
{
- return data_append_data(d, &byte, 1);
+ d = data_append_data(d, &byte, 1);
+ d.type = INTEGER;
+ return d;
}
struct data data_append_zeroes(struct data d, int len)
diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h
index e61dde7..a9b8602 100644
--- a/scripts/dtc/dtc.h
+++ b/scripts/dtc/dtc.h
@@ -82,10 +82,19 @@ struct marker {
struct marker *next;
};
+enum datatype {
+ UNDEFINED,
+ BOOLEAN,
+ INTEGER,
+ STRING,
+};
+
struct data {
int len;
char *val;
struct marker *markers;
+
+ enum datatype type;
};
diff --git a/scripts/dtc/schema-test.c b/scripts/dtc/schema-test.c
index 0eb2499..57c86d0 100644
--- a/scripts/dtc/schema-test.c
+++ b/scripts/dtc/schema-test.c
@@ -18,6 +18,11 @@ struct schema_test {
};
static struct schema_test tests[] = {
+ /* Types */
+ {"Types #1", "tests/test1.dts",
+ "tests/schemas/types-1.schema", 1},
+ {"Types #2", "tests/test1.dts",
+ "tests/schemas/types-2.schema", 0},
};
int main(void)
diff --git a/scripts/dtc/schema.c b/scripts/dtc/schema.c
index b190241..c01cdee 100644
--- a/scripts/dtc/schema.c
+++ b/scripts/dtc/schema.c
@@ -33,6 +33,7 @@ struct node_list {
struct prop_constraints {
const char *name;
+ char *type;
};
struct node_constraints {
@@ -202,9 +203,41 @@ load_property_constraints(struct node *schema)
if (p)
pc->name = p->val.val;
+ p = get_property(schema, "type");
+ if (p)
+ pc->type = p->val.val;
+
return pc;
}
+static int check_types(struct property *p, struct prop_constraints *pc)
+{
+ assert(p);
+ assert(pc);
+
+ if (!pc->type)
+ return 1;
+
+ switch (p->val.type) {
+ case BOOLEAN:
+ return !strcmp(pc->type, "bool");
+
+ case STRING:
+ return !strcmp(pc->type, "string");
+
+ case INTEGER:
+ return !strcmp(pc->type, "integer");
+
+ case UNDEFINED:
+ return 1;
+
+ default:
+ die("We shouldn't reach this point.");
+ };
+
+ return 0;
+}
+
static int validate_properties(struct node *n,
struct node *schema,
struct node_list *path);
@@ -222,6 +255,15 @@ static int validate_property(struct node *n,
assert(pc);
assert(path);
+ if (!p)
+ goto end;
+
+ if (!check_types(p, pc)) {
+ DT_ERROR(path, p, "Bad type for property, expecting a value of "
+ "the following type: '%s'\n", pc->type);
+ }
+
+end:
free_property_constraints(pc);
return ret;
}
@@ -319,6 +361,7 @@ static int for_each_compatible_validate(struct schema_db
*db,
assert(db);
assert(node);
assert(p);
+ assert(p->val.type == STRING);
while (offset >= 0 && offset < p->val.len) {
i = 0;
@@ -455,6 +498,7 @@ static void add_to_schema_db_from_property(struct schema_db
*db,
assert(db);
assert(file);
assert(p);
+ assert(p->val.type == STRING);
while (offset >= 0 && offset < p->val.len) {
add_compatible_to_schema_db(db, p->val.val + offset, file);
diff --git a/scripts/dtc/tests/schemas/types-1.schema
b/scripts/dtc/tests/schemas/types-1.schema
new file mode 100644
index 0000000..71d09e7
--- /dev/null
+++ b/scripts/dtc/tests/schemas/types-1.schema
@@ -0,0 +1,12 @@
+/dts-v1/;
+/ {
+ compatible = "compat1";
+
+ mypropint {
+ type = "integer";
+ };
+
+ mypropstr {
+ type = "string";
+ };
+};
diff --git a/scripts/dtc/tests/schemas/types-2.schema
b/scripts/dtc/tests/schemas/types-2.schema
new file mode 100644
index 0000000..f0779e1
--- /dev/null
+++ b/scripts/dtc/tests/schemas/types-2.schema
@@ -0,0 +1,7 @@
+/dts-v1/;
+/ {
+ compatible = "compat1";
+ mypropstr {
+ type = "integer";
+ };
+};
diff --git a/scripts/dtc/tests/test1.dts b/scripts/dtc/tests/test1.dts
new file mode 100644
index 0000000..9a950da
--- /dev/null
+++ b/scripts/dtc/tests/test1.dts
@@ -0,0 +1,10 @@
+/dts-v1/;
+/ {
+ compatible = "root", "node";
+
+ node1 {
+ compatible = "compat1";
+ mypropint = <0 2 4 6>;
+ mypropstr = "value0", "value1", "value2";
+ };
+};
--
1.8.1.2
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html