int fdt_fixup_memory_banks(void *blob, u64 start[], u64 size[], int banks) { int err, nodeoffset; int addr_cell_len, size_cell_len, len; u8 tmp[MEMORY_BANKS_MAX * 16]; /* Up to 64-bit address + 64-bit size */ int bank; if (banks > MEMORY_BANKS_MAX) { printf("%s: num banks %d exceeds hardcoded limit %d." " Recompile with higher MEMORY_BANKS_MAX?\n", __FUNCTION__, banks, MEMORY_BANKS_MAX); return -1; } err = fdt_check_header(blob); if (err < 0) { printf("%s: %s\n", __FUNCTION__, fdt_strerror(err)); return err; } /* update, or add and update /memory node */ nodeoffset = fdt_path_offset(blob, "/memory"); if (nodeoffset < 0) { nodeoffset = fdt_add_subnode(blob, 0, "memory"); if (nodeoffset < 0) { printf("WARNING: could not create /memory: %s.\n", fdt_strerror(nodeoffset)); return nodeoffset; } } err = fdt_setprop(blob, nodeoffset, "device_type", "memory", sizeof("memory")); if (err < 0) { printf("WARNING: could not set %s %s.\n", "device_type", fdt_strerror(err)); return err; } addr_cell_len = get_cells_len(blob, "#address-cells"); size_cell_len = get_cells_len(blob, "#size-cells"); for (bank = 0, len = 0; bank < banks; bank++) { write_cell(tmp + len, start[bank], addr_cell_len); len += addr_cell_len; write_cell(tmp + len, size[bank], size_cell_len); len += size_cell_len; } err = fdt_setprop(blob, nodeoffset, "reg", tmp, len); if (err < 0) { printf("WARNING: could not set %s %s.\n", "reg", fdt_strerror(err)); return err; } return 0; }
int fdt_fixup_memory_banks(void *blob, u64 start[], u64 size[], int banks) { int err, nodeoffset; int addr_cell_len, size_cell_len, len; u8 tmp[banks * 8]; int bank; err = fdt_check_header(blob); if (err < 0) { printf("%s: %s\n", __FUNCTION__, fdt_strerror(err)); return err; } /* update, or add and update /memory node */ nodeoffset = fdt_path_offset(blob, "/memory"); if (nodeoffset < 0) { nodeoffset = fdt_add_subnode(blob, 0, "memory"); if (nodeoffset < 0) printf("WARNING: could not create /memory: %s.\n", fdt_strerror(nodeoffset)); return nodeoffset; } err = fdt_setprop(blob, nodeoffset, "device_type", "memory", sizeof("memory")); if (err < 0) { printf("WARNING: could not set %s %s.\n", "device_type", fdt_strerror(err)); return err; } addr_cell_len = get_cells_len(blob, "#address-cells"); size_cell_len = get_cells_len(blob, "#size-cells"); for (bank = 0, len = 0; bank < banks; bank++) { write_cell(tmp + len, start[bank], addr_cell_len); len += addr_cell_len; write_cell(tmp + len, size[bank], size_cell_len); len += size_cell_len; } err = fdt_setprop(blob, nodeoffset, "reg", tmp, len); if (err < 0) { printf("WARNING: could not set %s %s.\n", "reg", fdt_strerror(err)); return err; } return 0; }
int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end, int force) { int nodeoffset, addr_cell_len; int err, j, total; fdt64_t tmp; const char *path; uint64_t addr, size; /* Find the "chosen" node. */ nodeoffset = fdt_path_offset (fdt, "/chosen"); /* If there is no "chosen" node in the blob return */ if (nodeoffset < 0) { printf("fdt_initrd: %s\n", fdt_strerror(nodeoffset)); return nodeoffset; } /* just return if initrd_start/end aren't valid */ if ((initrd_start == 0) || (initrd_end == 0)) return 0; total = fdt_num_mem_rsv(fdt); /* * Look for an existing entry and update it. If we don't find * the entry, we will j be the next available slot. */ for (j = 0; j < total; j++) { err = fdt_get_mem_rsv(fdt, j, &addr, &size); if (addr == initrd_start) { fdt_del_mem_rsv(fdt, j); break; } } err = fdt_add_mem_rsv(fdt, initrd_start, initrd_end - initrd_start); if (err < 0) { printf("fdt_initrd: %s\n", fdt_strerror(err)); return err; } addr_cell_len = get_cells_len(fdt, "#address-cells"); path = fdt_getprop(fdt, nodeoffset, "linux,initrd-start", NULL); if ((path == NULL) || force) { write_cell((u8 *)&tmp, initrd_start, addr_cell_len); err = fdt_setprop(fdt, nodeoffset, "linux,initrd-start", &tmp, addr_cell_len); if (err < 0) { printf("WARNING: " "could not set linux,initrd-start %s.\n", fdt_strerror(err)); return err; } write_cell((u8 *)&tmp, initrd_end, addr_cell_len); err = fdt_setprop(fdt, nodeoffset, "linux,initrd-end", &tmp, addr_cell_len); if (err < 0) { printf("WARNING: could not set linux,initrd-end %s.\n", fdt_strerror(err)); return err; } } return 0; }