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