dtb_set.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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. static off_t dtb_node_find_and_add_subnode(void *fdt, char* name)
  9. {
  10. off_t chosen_offset = 0;
  11. chosen_offset = fdt_subnode_offset(fdt, 0, name);
  12. if (chosen_offset == -FDT_ERR_NOTFOUND)
  13. {
  14. chosen_offset = fdt_add_subnode(fdt, 0, name);
  15. }
  16. return chosen_offset;
  17. }
  18. size_t dtb_node_set_linux_cmdline(void *fdt, char *cmdline)
  19. {
  20. off_t chosen_offset;
  21. size_t cmdline_size;
  22. if (cmdline == NULL || fdt == NULL)
  23. {
  24. goto end;
  25. }
  26. chosen_offset = dtb_node_find_and_add_subnode(fdt, "chosen");
  27. cmdline_size = strlen(cmdline);
  28. /* install bootargs */
  29. if (chosen_offset >= 0 || chosen_offset == -FDT_ERR_EXISTS)
  30. {
  31. if (fdt_setprop(fdt, chosen_offset, "bootargs", cmdline, cmdline_size) < 0)
  32. {
  33. fdt_open_into(fdt, fdt, fdt_totalsize(fdt) + FDT_DTB_PAD_SIZE);
  34. fdt_setprop(fdt, chosen_offset, "bootargs", cmdline, cmdline_size);
  35. }
  36. }
  37. end:
  38. return fdt_totalsize(fdt);
  39. }
  40. size_t dtb_node_set_linux_initrd(void *fdt, uint64_t initrd_addr, size_t initrd_size)
  41. {
  42. uint64_t addr, size_ptr;
  43. off_t chosen_offset;
  44. int i;
  45. if (fdt == NULL)
  46. {
  47. goto end;
  48. }
  49. chosen_offset = dtb_node_find_and_add_subnode(fdt, "chosen");
  50. /* update the entry */
  51. for (i = fdt_num_mem_rsv(fdt) - 1; i >= 0; --i)
  52. {
  53. fdt_get_mem_rsv(fdt, i, &addr, &size_ptr);
  54. if (addr == initrd_addr)
  55. {
  56. fdt_del_mem_rsv(fdt, i);
  57. break;
  58. }
  59. }
  60. /* add the memory */
  61. if (fdt_add_mem_rsv(fdt, initrd_addr, initrd_size) < 0)
  62. {
  63. /* move the memory */
  64. fdt_open_into(fdt, fdt, fdt_totalsize(fdt) + FDT_DTB_PAD_SIZE);
  65. if (fdt_add_mem_rsv(fdt, initrd_addr, initrd_size) < 0)
  66. {
  67. goto end;
  68. }
  69. }
  70. /* install initrd */
  71. if (chosen_offset >= 0 || chosen_offset == -FDT_ERR_EXISTS)
  72. {
  73. chosen_offset = fdt_path_offset(fdt, "/chosen");
  74. if (IN_64BITS_MODE)
  75. {
  76. fdt_setprop_u64(fdt, chosen_offset, "linux,initrd-start", initrd_addr);
  77. fdt_setprop_u64(fdt, chosen_offset, "linux,initrd-end", initrd_addr + initrd_size);
  78. }
  79. else
  80. {
  81. fdt_setprop_u32(fdt, chosen_offset, "linux,initrd-start", initrd_addr);
  82. fdt_setprop_u32(fdt, chosen_offset, "linux,initrd-end", initrd_addr + initrd_size);
  83. }
  84. }
  85. end:
  86. return fdt_totalsize(fdt);
  87. }
  88. size_t dtb_node_set_dtb_property(void *fdt, char *pathname, char *property_name, uint32_t *cells, size_t cells_size)
  89. {
  90. int node_off;
  91. if (fdt == NULL)
  92. {
  93. goto end;
  94. }
  95. node_off = fdt_path_offset(fdt, pathname);
  96. if (node_off >= 0 && cells_size != 0)
  97. {
  98. fdt_setprop(fdt, node_off, property_name, cells, cells_size);
  99. }
  100. end:
  101. return fdt_totalsize(fdt);
  102. }
  103. size_t dtb_node_add_dtb_memreserve(void *fdt, uint64_t address, uint64_t size)
  104. {
  105. if (fdt == NULL)
  106. {
  107. goto end;
  108. }
  109. fdt_add_mem_rsv(fdt, address, size);
  110. end:
  111. return fdt_totalsize(fdt);
  112. }
  113. size_t dtb_node_del_dtb_memreserve(void *fdt, uint64_t address)
  114. {
  115. int i;
  116. int num_mem_rsvmap;
  117. uint32_t off_mem_rsvmap;
  118. struct fdt_reserve_entry *rsvmap;
  119. if (fdt == NULL)
  120. {
  121. goto end;
  122. }
  123. num_mem_rsvmap = fdt_num_mem_rsv(fdt);
  124. off_mem_rsvmap = fdt_off_mem_rsvmap(fdt);
  125. rsvmap = (struct fdt_reserve_entry *)((char *)fdt + off_mem_rsvmap);
  126. for (i = 0; i < num_mem_rsvmap; ++i)
  127. {
  128. if (address == fdt64_to_cpu(rsvmap[i].address))
  129. {
  130. fdt_del_mem_rsv(fdt, i);
  131. break;
  132. }
  133. }
  134. end:
  135. return fdt_totalsize(fdt);
  136. }