| 304 | } |
| 305 | |
| 306 | static rt_err_t fdt_scan_memory(void) |
| 307 | { |
| 308 | int nodeoffset, no; |
| 309 | rt_uint64_t base, size; |
| 310 | rt_err_t err = -RT_EEMPTY; |
| 311 | |
| 312 | /* Process header /memreserve/ fields */ |
| 313 | for (no = 0; ; ++no) |
| 314 | { |
| 315 | fdt_get_mem_rsv(_fdt, no, &base, &size); |
| 316 | |
| 317 | if (!size) |
| 318 | { |
| 319 | break; |
| 320 | } |
| 321 | |
| 322 | rt_memblock_reserve_memory("memreserve", base, base + size, MEMBLOCK_NONE); |
| 323 | } |
| 324 | |
| 325 | fdt_for_each_subnode(nodeoffset, _fdt, 0) |
| 326 | { |
| 327 | int len; |
| 328 | const fdt32_t *reg, *endptr; |
| 329 | const char *name = fdt_get_name(_fdt, nodeoffset, RT_NULL); |
| 330 | const char *type = fdt_getprop(_fdt, nodeoffset, "device_type", RT_NULL); |
| 331 | |
| 332 | if (!type || rt_strcmp(type, "memory")) |
| 333 | { |
| 334 | continue; |
| 335 | } |
| 336 | |
| 337 | if (!rt_fdt_device_is_available(_fdt, nodeoffset)) |
| 338 | { |
| 339 | continue; |
| 340 | } |
| 341 | |
| 342 | reg = fdt_getprop(_fdt, nodeoffset, "reg", &len); |
| 343 | |
| 344 | if (!reg) |
| 345 | { |
| 346 | continue; |
| 347 | } |
| 348 | |
| 349 | endptr = reg + (len / sizeof(fdt32_t)); |
| 350 | name = name ? name : "memory"; |
| 351 | |
| 352 | while ((endptr - reg) >= (_root_addr_cells + _root_size_cells)) |
| 353 | { |
| 354 | base = rt_fdt_next_cell(®, _root_addr_cells); |
| 355 | size = rt_fdt_next_cell(®, _root_size_cells); |
| 356 | |
| 357 | if (!size) |
| 358 | { |
| 359 | continue; |
| 360 | } |
| 361 | |
| 362 | bool is_hotpluggable = fdt_getprop(_fdt, nodeoffset, "hotpluggable", RT_NULL) ? RT_TRUE : RT_FALSE; |
| 363 | err = rt_memblock_add_memory(name, base, base + size, is_hotpluggable); |
no test coverage detected