1 /*
2 * Copyright (c) 2006-2023, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include "libfdt.h"
7 #include "dtb_node.h"
8
9 /* Max address size we deal with */
10 #define FDT_MAX_ADDR_CELLS 4
11 #define FDT_CHECK_ADDR_COUNT(na) ((na) > 0 && (na) <= FDT_MAX_ADDR_CELLS)
12 #define FDT_CHECK_COUNTS(na, ns) (FDT_CHECK_ADDR_COUNT(na) && (ns) > 0)
13
dtb_node_default_count_cells(const struct dtb_node * dn,int * addrc,int * sizec)14 static void dtb_node_default_count_cells(const struct dtb_node *dn,
15 int *addrc, int *sizec)
16 {
17 if (addrc)
18 *addrc = dtb_node_n_addr_cells(dn);
19 if (sizec)
20 *sizec = dtb_node_n_size_cells(dn);
21 }
22
dtb_node_get_address(const struct dtb_node * dev,int index,uint64_t * size,unsigned int * flags)23 const uint32_t *dtb_node_get_address(const struct dtb_node *dev, int index,
24 uint64_t *size, unsigned int *flags)
25 {
26 const uint32_t *prop;
27 int psize;
28 struct dtb_node *parent;
29 int onesize, i, na, ns;
30
31 /* Get parent */
32 parent = dtb_node_get_parent(dev);
33 if (parent == NULL)
34 return NULL;
35
36 dtb_node_default_count_cells(dev, &na, &ns);
37 if (!FDT_CHECK_ADDR_COUNT(na))
38 return NULL;
39
40 /* Get "reg" or "assigned-addresses" property */
41 prop = dtb_node_get_dtb_node_property_value(dev, "reg", &psize);
42 if (prop == NULL)
43 return NULL;
44 psize /= 4;
45
46 onesize = na + ns;
47 for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
48 if (i == index)
49 {
50 if (size)
51 *size = dtb_node_read_number(prop + na, ns);
52 if (flags)
53 *flags = 0x200;
54 return prop;
55 }
56 return NULL;
57 }
58