dtb_addr.c 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  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. /* Max address size we deal with */
  9. #define FDT_MAX_ADDR_CELLS 4
  10. #define FDT_CHECK_ADDR_COUNT(na) ((na) > 0 && (na) <= FDT_MAX_ADDR_CELLS)
  11. #define FDT_CHECK_COUNTS(na, ns) (FDT_CHECK_ADDR_COUNT(na) && (ns) > 0)
  12. static void dtb_node_default_count_cells(const struct dtb_node *dn,
  13. int *addrc, int *sizec)
  14. {
  15. if (addrc)
  16. *addrc = dtb_node_n_addr_cells(dn);
  17. if (sizec)
  18. *sizec = dtb_node_n_size_cells(dn);
  19. }
  20. const uint32_t *dtb_node_get_address(const struct dtb_node *dev, int index,
  21. uint64_t *size, unsigned int *flags)
  22. {
  23. const uint32_t *prop;
  24. int psize;
  25. struct dtb_node *parent;
  26. int onesize, i, na, ns;
  27. /* Get parent */
  28. parent = dtb_node_get_parent(dev);
  29. if (parent == NULL)
  30. return NULL;
  31. dtb_node_default_count_cells(dev, &na, &ns);
  32. if (!FDT_CHECK_ADDR_COUNT(na))
  33. return NULL;
  34. /* Get "reg" or "assigned-addresses" property */
  35. prop = dtb_node_get_dtb_node_property_value(dev, "reg", &psize);
  36. if (prop == NULL)
  37. return NULL;
  38. psize /= 4;
  39. onesize = na + ns;
  40. for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
  41. if (i == index)
  42. {
  43. if (size)
  44. *size = dtb_node_read_number(prop + na, ns);
  45. if (flags)
  46. *flags = 0x200;
  47. return prop;
  48. }
  49. return NULL;
  50. }