xref: /rk3399_ARM-atf/common/fdt_wrappers.c (revision ff2743e544f0f82381ebb9dff8f14eacb837d2e0)
1 /*
2  * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 /* Helper functions to offer easier navigation of Device Tree Blob */
8 
9 #include <assert.h>
10 #include <debug.h>
11 #include <fdt_wrappers.h>
12 #include <libfdt.h>
13 
14 /*
15  * Read cells from a given property of the given node. At most 2 cells of the
16  * property are read, and pointer is updated. Returns 0 on success, and -1 upon
17  * error
18  */
19 int fdtw_read_cells(const void *dtb, int node, const char *prop,
20 		unsigned int cells, void *value)
21 {
22 	const uint32_t *value_ptr;
23 	uint32_t hi = 0, lo;
24 	int value_len;
25 
26 	assert(dtb != NULL);
27 	assert(prop != NULL);
28 	assert(value != NULL);
29 	assert(node >= 0);
30 
31 	/* We expect either 1 or 2 cell property */
32 	assert(cells <= 2U);
33 
34 	/* Access property and obtain its length (in bytes) */
35 	value_ptr = fdt_getprop_namelen(dtb, node, prop, (int)strlen(prop),
36 			&value_len);
37 	if (value_ptr == NULL) {
38 		WARN("Couldn't find property %s in dtb\n", prop);
39 		return -1;
40 	}
41 
42 
43 	/* Verify that property length accords with cell length */
44 	if (NCELLS((unsigned int)value_len) != cells) {
45 		WARN("Property length mismatch\n");
46 		return -1;
47 	}
48 
49 	if (cells == 2U) {
50 		hi = fdt32_to_cpu(*value_ptr);
51 		value_ptr++;
52 	}
53 
54 	lo = fdt32_to_cpu(*value_ptr);
55 
56 	if (cells == 2U)
57 		*((uint64_t *) value) = ((uint64_t) hi << 32) | lo;
58 	else
59 		*((uint32_t *) value) = lo;
60 
61 	return 0;
62 }
63 
64 /*
65  * Write cells in place to a given property of the given node. At most 2 cells
66  * of the property are written. Returns 0 on success, and -1 upon error.
67  */
68 int fdtw_write_inplace_cells(void *dtb, int node, const char *prop,
69 		unsigned int cells, void *value)
70 {
71 	int err, len;
72 
73 	assert(dtb != NULL);
74 	assert(prop != NULL);
75 	assert(value != NULL);
76 	assert(node >= 0);
77 
78 	/* We expect either 1 or 2 cell property */
79 	assert(cells <= 2U);
80 
81 	if (cells == 2U)
82 		*(uint64_t *)value = cpu_to_fdt64(*(uint64_t *)value);
83 	else
84 		*(uint32_t *)value = cpu_to_fdt32(*(uint32_t *)value);
85 
86 	len = (int)cells * 4;
87 
88 	/* Set property value in place */
89 	err = fdt_setprop_inplace(dtb, node, prop, value, len);
90 	if (err != 0) {
91 		WARN("Modify property %s failed with error %d\n", prop, err);
92 		return -1;
93 	}
94 
95 	return 0;
96 }
97