void __ft_board_setup(void *blob, bd_t *bd) { int rc; int i; u32 bxcr; u32 ranges[EBC_NUM_BANKS * 4]; u32 *p = ranges; char ebc_path[] = "/plb/opb/ebc"; ft_cpu_setup(blob, bd); /* * Read 4xx EBC bus bridge registers to get mappings of the * peripheral banks into the OPB/PLB address space */ for (i = 0; i < EBC_NUM_BANKS; i++) { mtdcr(EBC0_CFGADDR, EBC_BXCR(i)); bxcr = mfdcr(EBC0_CFGDATA); if ((bxcr & EBC_BXCR_BU_MASK) != EBC_BXCR_BU_NONE) { *p++ = i; *p++ = 0; *p++ = bxcr & EBC_BXCR_BAS_MASK; *p++ = EBC_BXCR_BANK_SIZE(bxcr); } } #ifdef CONFIG_FDT_FIXUP_NOR_FLASH_SIZE /* Update reg property in all nor flash nodes too */ fdt_fixup_nor_flash_size(blob); #endif /* Some 405 PPC's have EBC as direct PLB child in the dts */ if (fdt_path_offset(blob, ebc_path) < 0) strcpy(ebc_path, "/plb/ebc"); rc = fdt_find_and_setprop(blob, ebc_path, "ranges", ranges, (p - ranges) * sizeof(u32), 1); if (rc) { printf("Unable to update property EBC mappings, err=%s\n", fdt_strerror(rc)); } }
void ft_board_setup(void *blob, bd_t *bd) { int rc; __ft_board_setup(blob, bd); /* * Disable PCI in adapter mode. */ if (!cpci405_host()) { rc = fdt_find_and_setprop(blob, "/plb/pci@ec000000", "status", "disabled", sizeof("disabled"), 1); if (rc) { printf("Unable to update property status in PCI node, " "err=%s\n", fdt_strerror(rc)); } } }
static void check_path_offset_namelen(void *fdt, char *path, int namelen, int offset) { int rc; verbose_printf("Checking offset of \"%s\" [first %d characters]" " is %d...\n", path, namelen, offset); rc = fdt_path_offset_namelen(fdt, path, namelen); if (rc == offset) return; if (rc < 0) FAIL("fdt_path_offset_namelen(\"%s\", %d) failed: %s", path, namelen, fdt_strerror(rc)); else FAIL("fdt_path_offset_namelen(\"%s\", %d) returned incorrect" " offset %d instead of %d", path, namelen, rc, offset); }
static int fdt_load_dtb(vm_offset_t va) { struct fdt_header header; int err; debugf("fdt_load_dtb(0x%08jx)\n", (uintmax_t)va); COPYOUT(va, &header, sizeof(header)); err = fdt_check_header(&header); if (err < 0) { if (err == -FDT_ERR_BADVERSION) sprintf(command_errbuf, "incompatible blob version: %d, should be: %d", fdt_version(fdtp), FDT_LAST_SUPPORTED_VERSION); else sprintf(command_errbuf, "error validating blob: %s", fdt_strerror(err)); return (1); } /* * Release previous blob */ if (fdtp) free(fdtp); fdtp_size = fdt_totalsize(&header); fdtp = malloc(fdtp_size); if (fdtp == NULL) { command_errmsg = "can't allocate memory for device tree copy"; return (1); } fdtp_va = va; COPYOUT(va, fdtp, fdtp_size); debugf("DTB blob found at 0x%jx, size: 0x%jx\n", (uintmax_t)va, (uintmax_t)fdtp_size); return (0); }
void ft_cpu_setup(void *blob, bd_t *bd) { #ifdef CONFIG_MP int off; u32 bootpg = determine_mp_bootpg(); #endif do_fixup_by_prop_u32(blob, "device_type", "cpu", 4, "timebase-frequency", bd->bi_busfreq / 4, 1); do_fixup_by_prop_u32(blob, "device_type", "cpu", 4, "bus-frequency", bd->bi_busfreq, 1); do_fixup_by_prop_u32(blob, "device_type", "cpu", 4, "clock-frequency", bd->bi_intfreq, 1); do_fixup_by_prop_u32(blob, "device_type", "soc", 4, "bus-frequency", bd->bi_busfreq, 1); #if defined(CONFIG_MPC8641) do_fixup_by_compat_u32(blob, "fsl,mpc8641-localbus", "bus-frequency", gd->lbc_clk, 1); #endif do_fixup_by_compat_u32(blob, "fsl,elbc", "bus-frequency", gd->lbc_clk, 1); fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize); #if defined(CONFIG_HAS_ETH0) || defined(CONFIG_HAS_ETH1) \ || defined(CONFIG_HAS_ETH2) || defined(CONFIG_HAS_ETH3) fdt_fixup_ethernet(blob); #endif #ifdef CONFIG_SYS_NS16550 do_fixup_by_compat_u32(blob, "ns16550", "clock-frequency", CONFIG_SYS_NS16550_CLK, 1); #endif #ifdef CONFIG_MP /* Reserve the boot page so OSes dont use it */ off = fdt_add_mem_rsv(blob, bootpg, (u64)4096); if (off < 0) printf("%s: %s\n", __FUNCTION__, fdt_strerror(off)); #endif }
static int dt_sysinfo_check_root_property( fwts_framework *fw, const char *name, bool print_flag) { int node, len; const char *buf; if (!fw->fdt) { fwts_failed(fw, LOG_LEVEL_CRITICAL, "DTMissing", "Device Tree is missing, aborting"); return FWTS_ABORTED; } node = fdt_path_offset(fw->fdt, "/"); if (node < 0) { fwts_failed(fw, LOG_LEVEL_CRITICAL, "DTRootNodeMissing", "root device tree node is missing"); return FWTS_ERROR; } buf = fdt_getprop(fw->fdt, node, name, &len); if (buf == NULL) { fwts_failed(fw, LOG_LEVEL_CRITICAL, "DTSysinfoPropertyMissing", "Cannot read property %s: %s", name, fdt_strerror(len)); return FWTS_ERROR; } if (print_flag) { if (check_property_printable(fw, name, buf, len)) return FWTS_ERROR; /* failures logged prior */ } fwts_passed(fw, "sysinfo property \"%s\" is valid", name); return FWTS_OK; }
int ft_board_setup(void *blob, bd_t *bd) { int rc; __ft_board_setup(blob, bd); /* * Disable PCI in non-monarch mode. */ if (!is_monarch()) { rc = fdt_find_and_setprop(blob, "/plb/pci@ec000000", "status", "disabled", sizeof("disabled"), 1); if (rc) { printf("Unable to update property status in PCI node, " "err=%s\n", fdt_strerror(rc)); } } return 0; }
static int fdt_valid(void) { int err; if (working_fdt == NULL) { printf ("The address of the fdt is invalid (NULL).\n"); return 0; } err = fdt_check_header(working_fdt); if (err == 0) return 1; /* valid */ if (err < 0) { printf("libfdt fdt_check_header(): %s", fdt_strerror(err)); /* * Be more informative on bad version. */ if (err == -FDT_ERR_BADVERSION) { if (fdt_version(working_fdt) < FDT_FIRST_SUPPORTED_VERSION) { printf (" - too old, fdt %d < %d", fdt_version(working_fdt), FDT_FIRST_SUPPORTED_VERSION); working_fdt = NULL; } if (fdt_last_comp_version(working_fdt) > FDT_LAST_SUPPORTED_VERSION) { printf (" - too new, fdt %d > %d", fdt_version(working_fdt), FDT_LAST_SUPPORTED_VERSION); working_fdt = NULL; } return 0; } printf("\n"); return 0; } return 1; }
int fit_image_verify_required_sigs(const void *fit, int image_noffset, const char *data, size_t size, const void *sig_blob, int *no_sigsp) { int verify_count = 0; int noffset; int sig_node; /* Work out what we need to verify */ *no_sigsp = 1; sig_node = fdt_subnode_offset(sig_blob, 0, FIT_SIG_NODENAME); if (sig_node < 0) { debug("%s: No signature node found: %s\n", __func__, fdt_strerror(sig_node)); return 0; } fdt_for_each_subnode(noffset, sig_blob, sig_node) { const char *required; int ret; required = fdt_getprop(sig_blob, noffset, "required", NULL); if (!required || strcmp(required, "image")) continue; ret = fit_image_verify_sig(fit, image_noffset, data, size, sig_blob, noffset); if (ret) { printf("Failed to verify required signature '%s'\n", fit_get_name(sig_blob, noffset, NULL)); return ret; } verify_count++; } if (verify_count) *no_sigsp = 0; return 0; }
static dt_node_t add_device_fdt(dt_node_t parent, void *fdt, int fdt_node, int depth) { const char *name = fdt_get_name(fdt, fdt_node, NULL); printf("%*cEnumerating \"%s\"\n", depth, ' ', name); dt_node_t n = dt_node_alloc(parent, name); if (!n) panic("Out of memory enumerating node \"%s\"\n", name); for (int propoff = fdt_first_property_offset(fdt, fdt_node); propoff >= 0; propoff = fdt_next_property_offset(fdt, propoff)) { int len; const struct fdt_property *fdt_prop = fdt_get_property_by_offset(fdt, propoff, &len); if (!fdt_prop) { panic("Error getting property of \"%s\": %s\n", name, fdt_strerror(len)); } const char *prop_name = fdt_string(fdt, fdt32_to_cpu(fdt_prop->nameoff)); printf("%*c \"%s\" = \"", depth, ' ', prop_name); print_dtval(fdt_prop->data, len); printf("\"\n"); if (!dt_node_set_property(n, prop_name, fdt_prop->data, len)) panic("Out of memory allocating \"%s\":\"%s\"", name, prop_name); } for (int suboff = fdt_first_subnode(fdt, fdt_node); suboff != -FDT_ERR_NOTFOUND; suboff = fdt_next_subnode(fdt, suboff)) { add_device_fdt(n, fdt, suboff, depth + 2); } return n; }
static int ft_hs_disable_rng(void *fdt, bd_t *bd) { const char *path; int offs; int ret; /* Make HW RNG reserved for secure world use */ path = "/ocp/rng"; offs = fdt_path_offset(fdt, path); if (offs < 0) { debug("Node %s not found.\n", path); return 0; } ret = fdt_setprop_string(fdt, offs, "status", "disabled"); if (ret < 0) { printf("Could not add status property to node %s: %s\n", path, fdt_strerror(ret)); return ret; } return 0; }
int sandbox_read_fdt_from_file(void) { struct sandbox_state *state = state_get_current(); const char *fname = state->fdt_fname; void *blob; loff_t size; int err; int fd; blob = map_sysmem(CONFIG_SYS_FDT_LOAD_ADDR, 0); if (!state->fdt_fname) { err = fdt_create_empty_tree(blob, 256); if (!err) goto done; printf("Unable to create empty FDT: %s\n", fdt_strerror(err)); return -EINVAL; } err = os_get_filesize(fname, &size); if (err < 0) { printf("Failed to file FDT file '%s'\n", fname); return err; } fd = os_open(fname, OS_O_RDONLY); if (fd < 0) { printf("Failed to open FDT file '%s'\n", fname); return -EACCES; } if (os_read(fd, blob, size) != size) { os_close(fd); return -EIO; } os_close(fd); done: gd->fdt_blob = blob; return 0; }
void *create_device_tree(int *sizep) { void *fdt; int ret; *sizep = FDT_MAX_SIZE; fdt = g_malloc0(FDT_MAX_SIZE); ret = fdt_create(fdt, FDT_MAX_SIZE); if (ret < 0) { goto fail; } ret = fdt_finish_reservemap(fdt); if (ret < 0) { goto fail; } ret = fdt_begin_node(fdt, ""); if (ret < 0) { goto fail; } ret = fdt_end_node(fdt); if (ret < 0) { goto fail; } ret = fdt_finish(fdt); if (ret < 0) { goto fail; } ret = fdt_open_into(fdt, fdt, *sizep); if (ret) { error_report("Unable to copy device tree in memory"); exit(1); } return fdt; fail: error_report("%s Couldn't create dt: %s", __func__, fdt_strerror(ret)); exit(1); }
int fdt_record_loadable(void *blob, u32 index, const char *name, uintptr_t load_addr, u32 size, uintptr_t entry_point, const char *type, const char *os) { int err, node; err = fdt_check_header(blob); if (err < 0) { printf("%s: %s\n", __func__, fdt_strerror(err)); return err; } /* find or create "/fit-images" node */ node = fdt_find_or_add_subnode(blob, 0, "fit-images"); if (node < 0) return node; /* find or create "/fit-images/<name>" node */ node = fdt_find_or_add_subnode(blob, node, name); if (node < 0) return node; /* * We record these as 32bit entities, possibly truncating addresses. * However, spl_fit.c is not 64bit safe either: i.e. we should not * have an issue here. */ fdt_setprop_u32(blob, node, "load-addr", load_addr); if (entry_point != -1) fdt_setprop_u32(blob, node, "entry-point", entry_point); fdt_setprop_u32(blob, node, "size", size); if (type) fdt_setprop_string(blob, node, "type", type); if (os) fdt_setprop_string(blob, node, "os", os); return node; }
/** * fit_all_image_verify - verify data intergity for all images * @fit: pointer to the FIT format image header * * fit_all_image_verify() goes over all images in the FIT and * for every images checks if all it's hashes are valid. * * returns: * 1, if all hashes of all images are valid * 0, otherwise (or on error) */ int fit_all_image_verify(const void *fit) { int images_noffset; int noffset; int ndepth; int count; /* Find images parent node offset */ images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); if (images_noffset < 0) { printf("Can't find images parent node '%s' (%s)\n", FIT_IMAGES_PATH, fdt_strerror(images_noffset)); return 0; } /* Process all image subnodes, check hashes for each */ printf("## Checking hash(es) for FIT Image at %08lx ...\n", (ulong)fit); for (ndepth = 0, count = 0, noffset = fdt_next_node(fit, images_noffset, &ndepth); (noffset >= 0) && (ndepth > 0); noffset = fdt_next_node(fit, noffset, &ndepth)) { if (ndepth == 1) { /* * Direct child node of the images parent node, * i.e. component image node. */ printf(" Hash(es) for Image %u (%s): ", count, fit_get_name(fit, noffset, NULL)); count++; if (!fit_image_verify(fit, noffset)) return 0; printf("\n"); } } return 1; }
/* * This is called from the context of an open /rtas node, in order to add * properties for the rtas call tokens. */ int spapr_rtas_fdt_setup(struct kvm *kvm, void *fdt) { int ret; int i; for (i = 0; i < TOKEN_MAX; i++) { struct rtas_call *call = &rtas_table[i]; if (!call->fn) { continue; } ret = fdt_property_cell(fdt, call->name, i + TOKEN_BASE); if (ret < 0) { pr_warning("Couldn't add rtas token for %s: %s\n", call->name, fdt_strerror(ret)); return ret; } } return 0; }
static int decode_sromc(const void *blob, struct fdt_sromc *config) { int err; int node; node = fdtdec_next_compatible(blob, 0, COMPAT_SAMSUNG_EXYNOS5_SROMC); if (node < 0) { debug("Could not find SROMC node\n"); return node; } config->bank = fdtdec_get_int(blob, node, "bank", 0); config->width = fdtdec_get_int(blob, node, "width", 2); err = fdtdec_get_int_array(blob, node, "srom-timing", config->timing, FDT_SROM_TIMING_COUNT); if (err < 0) { debug("Could not decode SROMC configuration Error: %s\n", fdt_strerror(err)); return -FDT_ERR_NOTFOUND; } return 0; }
static int fdt_setup_fdtp() { struct preloaded_file *bfp; int err; /* * Find the device tree blob. */ bfp = file_findfile(NULL, "dtb"); if (bfp == NULL) { if ((fdtp = (struct fdt_header *)fdt_find_static_dtb()) == 0) { command_errmsg = "no device tree blob found!"; return (CMD_ERROR); } } else { /* Dynamic blob has precedence over static. */ fdtp = (struct fdt_header *)bfp->f_addr; } /* * Validate the blob. */ err = fdt_check_header(fdtp); if (err < 0) { if (err == -FDT_ERR_BADVERSION) sprintf(command_errbuf, "incompatible blob version: %d, should be: %d", fdt_version(fdtp), FDT_LAST_SUPPORTED_VERSION); else sprintf(command_errbuf, "error validating blob: %s", fdt_strerror(err)); return (CMD_ERROR); } return (CMD_OK); }
/** ** Relocate the FDT blob to a more appropriate location for the Linux kernel. ** This function will allocate memory for the relocated FDT blob. ** ** @retval EFI_SUCCESS on success. ** @retval EFI_OUT_OF_RESOURCES or EFI_INVALID_PARAMETER on failure. */ STATIC EFI_STATUS RelocateFdt ( EFI_PHYSICAL_ADDRESS OriginalFdt, UINTN OriginalFdtSize, EFI_PHYSICAL_ADDRESS *RelocatedFdt, UINTN *RelocatedFdtSize, EFI_PHYSICAL_ADDRESS *RelocatedFdtAlloc ) { EFI_STATUS Status; INTN Error; *RelocatedFdtSize = OriginalFdtSize + FDT_ADDITIONAL_ENTRIES_SIZE; // XXXX This needs fixing ! The FDT could be overwriten by the kernel // relocating itself. See comments in LinuxStarter.c Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData, EFI_SIZE_TO_PAGES (*RelocatedFdtSize), RelocatedFdt); if (EFI_ERROR (Status)) { Print (L"ERROR: Failed to allocate pages for FDT\n"); return Status; } *RelocatedFdtAlloc = *RelocatedFdt; // Load the Original FDT tree into the new region Error = fdt_open_into ((VOID*)(UINTN) OriginalFdt, (VOID*)(UINTN)(*RelocatedFdt), *RelocatedFdtSize); if (Error) { DEBUG ((EFI_D_ERROR, "fdt_open_into(): %a\n", fdt_strerror (Error))); gBS->FreePages (*RelocatedFdtAlloc, EFI_SIZE_TO_PAGES (*RelocatedFdtSize)); return EFI_INVALID_PARAMETER; } return EFI_SUCCESS; }
int fdt_load_dtb_addr(struct fdt_header *header) { int err; debugf("fdt_load_dtb_addr(%p)\n", header); fdtp_size = fdt_totalsize(header); err = fdt_check_header(header); if (err < 0) { sprintf(command_errbuf, "error validating blob: %s", fdt_strerror(err)); return (err); } free(fdtp); if ((fdtp = malloc(fdtp_size)) == NULL) { command_errmsg = "can't allocate memory for device tree copy"; return (1); } fdtp_va = 0; // Don't write this back into module or kernel. bcopy(header, fdtp, fdtp_size); return (0); }
static int fdt_fixup_stdout(void *fdt, int chosenoff) { int err = 0; #ifdef CONFIG_CONS_INDEX int node; char sername[9] = { 0 }; const char *path; fdt_fill_multisername(sername, sizeof(sername) - 1); if (!sername[0]) sprintf(sername, "serial%d", CONFIG_CONS_INDEX - 1); err = node = fdt_path_offset(fdt, "/aliases"); if (node >= 0) { int len; path = fdt_getprop(fdt, node, sername, &len); if (path) { char *p = malloc(len); err = -FDT_ERR_NOSPACE; if (p) { memcpy(p, path, len); err = fdt_setprop(fdt, chosenoff, "linux,stdout-path", p, len); free(p); } } else { err = len; } } #endif if (err < 0) printf("WARNING: could not set linux,stdout-path %s.\n", fdt_strerror(err)); return err; }
static int fdt_fixup_stdout(void *fdt, int chosenoff) { int err; int aliasoff; char sername[9] = { 0 }; const void *path; int len; char tmp[256]; /* long enough */ fdt_fill_multisername(sername, sizeof(sername) - 1); if (!sername[0]) sprintf(sername, "serial%d", CONFIG_CONS_INDEX - 1); aliasoff = fdt_path_offset(fdt, "/aliases"); if (aliasoff < 0) { err = aliasoff; goto error; } path = fdt_getprop(fdt, aliasoff, sername, &len); if (!path) { err = len; goto error; } /* fdt_setprop may break "path" so we copy it to tmp buffer */ memcpy(tmp, path, len); err = fdt_setprop(fdt, chosenoff, "linux,stdout-path", tmp, len); error: if (err < 0) printf("WARNING: could not set linux,stdout-path %s.\n", fdt_strerror(err)); return err; }
static void compare_subnodes(const void *fdt1, int offset1, const void *fdt2, int offset2, int recurse) { int coffset1, coffset2, depth; for (depth = 0, coffset1 = offset1; (coffset1 >= 0) && (depth >= 0); coffset1 = fdt_next_node(fdt1, coffset1, &depth)) if (depth == 1) { const char *name = fdt_get_name(fdt1, coffset1, NULL); verbose_printf("Subnode %s\n", name); coffset2 = fdt_subnode_offset(fdt2, offset2, name); if (coffset2 == -FDT_ERR_NOTFOUND) MISMATCH("Subnode %s missing\n", name); else if (coffset2 < 0) FAIL("fdt_subnode_offset(): %s\n", fdt_strerror(coffset2)); if (recurse) compare_node(fdt1, coffset1, fdt2, coffset2); } }
int main(int argc, char *argv[]) { const struct fdt_property *prop; void *fdt; int offset; int subnode1_offset; const void *val; int lenerr; test_init(argc, argv); fdt = load_blob_arg(argc, argv); prop = fdt_get_property(fdt, 0, "nonexistant-property", &lenerr); check_error("fdt_get_property(\"nonexistant-property\")", lenerr); val = fdt_getprop(fdt, 0, "nonexistant-property", &lenerr); check_error("fdt_getprop(\"nonexistant-property\"", lenerr); subnode1_offset = fdt_subnode_offset(fdt, 0, "subnode@1"); if (subnode1_offset < 0) FAIL("Couldn't find subnode1: %s", fdt_strerror(subnode1_offset)); val = fdt_getprop(fdt, subnode1_offset, "prop-str", &lenerr); check_error("fdt_getprop(\"prop-str\")", lenerr); offset = fdt_subnode_offset(fdt, 0, "nonexistant-subnode"); check_error("fdt_subnode_offset(\"nonexistant-subnode\")", offset); offset = fdt_subnode_offset(fdt, 0, "subsubnode"); check_error("fdt_subnode_offset(\"subsubnode\")", offset); offset = fdt_path_offset(fdt, "/nonexistant-subnode"); check_error("fdt_path_offset(\"/nonexistant-subnode\")", offset); PASS(); }
/** * fit_print_contents - prints out the contents of the FIT format image * @fit: pointer to the FIT format image header * @p: pointer to prefix string * * fit_print_contents() formats a multi line FIT image contents description. * The routine prints out FIT image properties (root node level) follwed by * the details of each component image. * * returns: * no returned results */ void fit_print_contents(const void *fit) { char *desc; char *uname; int images_noffset; int confs_noffset; int noffset; int ndepth; int count = 0; int ret; const char *p; time_t timestamp; /* Indent string is defined in header image.h */ p = IMAGE_INDENT_STRING; /* Root node properties */ ret = fit_get_desc(fit, 0, &desc); printf("%sFIT description: ", p); if (ret) printf("unavailable\n"); else printf("%s\n", desc); if (IMAGE_ENABLE_TIMESTAMP) { ret = fit_get_timestamp(fit, 0, ×tamp); printf("%sCreated: ", p); if (ret) printf("unavailable\n"); else genimg_print_time(timestamp); } /* Find images parent node offset */ images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); if (images_noffset < 0) { printf("Can't find images parent node '%s' (%s)\n", FIT_IMAGES_PATH, fdt_strerror(images_noffset)); return; } /* Process its subnodes, print out component images details */ for (ndepth = 0, count = 0, noffset = fdt_next_node(fit, images_noffset, &ndepth); (noffset >= 0) && (ndepth > 0); noffset = fdt_next_node(fit, noffset, &ndepth)) { if (ndepth == 1) { /* * Direct child node of the images parent node, * i.e. component image node. */ printf("%s Image %u (%s)\n", p, count++, fit_get_name(fit, noffset, NULL)); fit_image_print(fit, noffset, p); } } /* Find configurations parent node offset */ confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH); if (confs_noffset < 0) { debug("Can't get configurations parent node '%s' (%s)\n", FIT_CONFS_PATH, fdt_strerror(confs_noffset)); return; } /* get default configuration unit name from default property */ uname = (char *)fdt_getprop(fit, noffset, FIT_DEFAULT_PROP, NULL); if (uname) printf("%s Default Configuration: '%s'\n", p, uname); /* Process its subnodes, print out configurations details */ for (ndepth = 0, count = 0, noffset = fdt_next_node(fit, confs_noffset, &ndepth); (noffset >= 0) && (ndepth > 0); noffset = fdt_next_node(fit, noffset, &ndepth)) { if (ndepth == 1) { /* * Direct child node of the configurations parent node, * i.e. configuration node. */ printf("%s Configuration %u (%s)\n", p, count++, fit_get_name(fit, noffset, NULL)); fit_conf_print(fit, noffset, p); } } }
static int _fdt_fixup_msi_node(void *blob, const char *name, int irq_0, int irq_1, int rev) { int err, offset, len; u32 tmp[4][3]; void *p; offset = fdt_path_offset(blob, name); if (offset < 0) { printf("WARNING: fdt_path_offset can't find path %s: %s\n", name, fdt_strerror(offset)); return 0; } /*fixup the property of interrupts*/ tmp[0][0] = cpu_to_fdt32(0x0); tmp[0][1] = cpu_to_fdt32(irq_0); tmp[0][2] = cpu_to_fdt32(0x4); if (rev > REV1_0) { tmp[1][0] = cpu_to_fdt32(0x0); tmp[1][1] = cpu_to_fdt32(irq_1); tmp[1][2] = cpu_to_fdt32(0x4); tmp[2][0] = cpu_to_fdt32(0x0); tmp[2][1] = cpu_to_fdt32(irq_1 + 1); tmp[2][2] = cpu_to_fdt32(0x4); tmp[3][0] = cpu_to_fdt32(0x0); tmp[3][1] = cpu_to_fdt32(irq_1 + 2); tmp[3][2] = cpu_to_fdt32(0x4); len = sizeof(tmp); } else { len = sizeof(tmp[0]); } err = fdt_setprop(blob, offset, "interrupts", tmp, len); if (err < 0) { printf("WARNING: fdt_setprop can't set %s from node %s: %s\n", "interrupts", name, fdt_strerror(err)); return 0; } /*fixup the property of reg*/ p = (char *)fdt_getprop(blob, offset, "reg", &len); if (!p) { printf("WARNING: fdt_getprop can't get %s from node %s\n", "reg", name); return 0; } memcpy((char *)tmp, p, len); if (rev > REV1_0) *((u32 *)tmp + 3) = cpu_to_fdt32(0x1000); else *((u32 *)tmp + 3) = cpu_to_fdt32(0x8); err = fdt_setprop(blob, offset, "reg", tmp, len); if (err < 0) { printf("WARNING: fdt_setprop can't set %s from node %s: %s\n", "reg", name, fdt_strerror(err)); return 0; } /*fixup the property of compatible*/ if (rev > REV1_0) err = fdt_setprop_string(blob, offset, "compatible", "fsl,ls1043a-v1.1-msi"); else err = fdt_setprop_string(blob, offset, "compatible", "fsl,ls1043a-msi"); if (err < 0) { printf("WARNING: fdt_setprop can't set %s from node %s: %s\n", "compatible", name, fdt_strerror(err)); return 0; } return 1; }
/* * Flattened Device Tree command, see the help for parameter definitions. */ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { if (argc < 2) return CMD_RET_USAGE; /* * Set the address of the fdt */ if (strncmp(argv[1], "ad", 2) == 0) { unsigned long addr; int control = 0; struct fdt_header *blob; /* * Set the address [and length] of the fdt. */ argc -= 2; argv += 2; /* Temporary #ifdef - some archs don't have fdt_blob yet */ #ifdef CONFIG_OF_CONTROL if (argc && !strcmp(*argv, "-c")) { control = 1; argc--; argv++; } #endif if (argc == 0) { if (control) blob = (struct fdt_header *)gd->fdt_blob; else blob = working_fdt; if (!blob || !fdt_valid(&blob)) return 1; printf("The address of the fdt is %#08lx\n", control ? (ulong)map_to_sysmem(blob) : getenv_hex("fdtaddr", 0)); return 0; } addr = simple_strtoul(argv[0], NULL, 16); blob = map_sysmem(addr, 0); if (!fdt_valid(&blob)) return 1; if (control) gd->fdt_blob = blob; else set_working_fdt_addr(addr); if (argc >= 2) { int len; int err; /* * Optional new length */ len = simple_strtoul(argv[1], NULL, 16); if (len < fdt_totalsize(blob)) { printf ("New length %d < existing length %d, " "ignoring.\n", len, fdt_totalsize(blob)); } else { /* * Open in place with a new length. */ err = fdt_open_into(blob, blob, len); if (err != 0) { printf ("libfdt fdt_open_into(): %s\n", fdt_strerror(err)); } } } return CMD_RET_SUCCESS; } if (!working_fdt) { puts( "No FDT memory address configured. Please configure\n" "the FDT address via \"fdt addr <address>\" command.\n" "Aborting!\n"); return CMD_RET_FAILURE; } /* * Move the working_fdt */ if (strncmp(argv[1], "mo", 2) == 0) { struct fdt_header *newaddr; int len; int err; if (argc < 4) return CMD_RET_USAGE; /* * Set the address and length of the fdt. */ working_fdt = (struct fdt_header *)simple_strtoul(argv[2], NULL, 16); if (!fdt_valid(&working_fdt)) return 1; newaddr = (struct fdt_header *)simple_strtoul(argv[3],NULL,16); /* * If the user specifies a length, use that. Otherwise use the * current length. */ if (argc <= 4) { len = fdt_totalsize(working_fdt); } else { len = simple_strtoul(argv[4], NULL, 16); if (len < fdt_totalsize(working_fdt)) { printf ("New length 0x%X < existing length " "0x%X, aborting.\n", len, fdt_totalsize(working_fdt)); return 1; } } /* * Copy to the new location. */ err = fdt_open_into(working_fdt, newaddr, len); if (err != 0) { printf ("libfdt fdt_open_into(): %s\n", fdt_strerror(err)); return 1; } working_fdt = newaddr; /* * Make a new node */ } else if (strncmp(argv[1], "mk", 2) == 0) { char *pathp; /* path */ char *nodep; /* new node to add */ int nodeoffset; /* node offset from libfdt */ int err; /* * Parameters: Node path, new node to be appended to the path. */ if (argc < 4) return CMD_RET_USAGE; pathp = argv[2]; nodep = argv[3]; nodeoffset = fdt_path_offset (working_fdt, pathp); if (nodeoffset < 0) { /* * Not found or something else bad happened. */ printf ("libfdt fdt_path_offset() returned %s\n", fdt_strerror(nodeoffset)); return 1; } err = fdt_add_subnode(working_fdt, nodeoffset, nodep); if (err < 0) { printf ("libfdt fdt_add_subnode(): %s\n", fdt_strerror(err)); return 1; } /* * Set the value of a property in the working_fdt. */ } else if (argv[1][0] == 's') { char *pathp; /* path */ char *prop; /* property */ int nodeoffset; /* node offset from libfdt */ static char data[SCRATCHPAD]; /* storage for the property */ int len; /* new length of the property */ int ret; /* return value */ /* * Parameters: Node path, property, optional value. */ if (argc < 4) return CMD_RET_USAGE; pathp = argv[2]; prop = argv[3]; if (argc == 4) { len = 0; } else { ret = fdt_parse_prop(&argv[4], argc - 4, data, &len); if (ret != 0) return ret; } nodeoffset = fdt_path_offset (working_fdt, pathp); if (nodeoffset < 0) { /* * Not found or something else bad happened. */ printf ("libfdt fdt_path_offset() returned %s\n", fdt_strerror(nodeoffset)); return 1; } ret = fdt_setprop(working_fdt, nodeoffset, prop, data, len); if (ret < 0) { printf ("libfdt fdt_setprop(): %s\n", fdt_strerror(ret)); return 1; } /******************************************************************** * Get the value of a property in the working_fdt. ********************************************************************/ } else if (argv[1][0] == 'g') { char *subcmd; /* sub-command */ char *pathp; /* path */ char *prop; /* property */ char *var; /* variable to store result */ int nodeoffset; /* node offset from libfdt */ const void *nodep; /* property node pointer */ int len = 0; /* new length of the property */ /* * Parameters: Node path, property, optional value. */ if (argc < 5) return CMD_RET_USAGE; subcmd = argv[2]; if (argc < 6 && subcmd[0] != 's') return CMD_RET_USAGE; var = argv[3]; pathp = argv[4]; prop = argv[5]; nodeoffset = fdt_path_offset(working_fdt, pathp); if (nodeoffset < 0) { /* * Not found or something else bad happened. */ printf("libfdt fdt_path_offset() returned %s\n", fdt_strerror(nodeoffset)); return 1; } if (subcmd[0] == 'n' || (subcmd[0] == 's' && argc == 5)) { int reqIndex = -1; int startDepth = fdt_node_depth( working_fdt, nodeoffset); int curDepth = startDepth; int curIndex = -1; int nextNodeOffset = fdt_next_node( working_fdt, nodeoffset, &curDepth); if (subcmd[0] == 'n') reqIndex = simple_strtoul(argv[5], NULL, 16); while (curDepth > startDepth) { if (curDepth == startDepth + 1) curIndex++; if (subcmd[0] == 'n' && curIndex == reqIndex) { const char *nodeName = fdt_get_name( working_fdt, nextNodeOffset, NULL); setenv(var, (char *)nodeName); return 0; } nextNodeOffset = fdt_next_node( working_fdt, nextNodeOffset, &curDepth); if (nextNodeOffset < 0) break; } if (subcmd[0] == 's') { /* get the num nodes at this level */ setenv_ulong(var, curIndex + 1); } else { /* node index not found */ printf("libfdt node not found\n"); return 1; } } else { nodep = fdt_getprop( working_fdt, nodeoffset, prop, &len); if (len == 0) { /* no property value */ setenv(var, ""); return 0; } else if (len > 0) { if (subcmd[0] == 'v') { int ret; ret = fdt_value_setenv(nodep, len, var); if (ret != 0) return ret; } else if (subcmd[0] == 'a') { /* Get address */ char buf[11]; sprintf(buf, "0x%p", nodep); setenv(var, buf); } else if (subcmd[0] == 's') { /* Get size */ char buf[11]; sprintf(buf, "0x%08X", len); setenv(var, buf); } else return CMD_RET_USAGE; return 0; } else { printf("libfdt fdt_getprop(): %s\n", fdt_strerror(len)); return 1; } } /* * Print (recursive) / List (single level) */ } else if ((argv[1][0] == 'p') || (argv[1][0] == 'l')) { int depth = MAX_LEVEL; /* how deep to print */ char *pathp; /* path */ char *prop; /* property */ int ret; /* return value */ static char root[2] = "/"; /* * list is an alias for print, but limited to 1 level */ if (argv[1][0] == 'l') { depth = 1; } /* * Get the starting path. The root node is an oddball, * the offset is zero and has no name. */ if (argc == 2) pathp = root; else pathp = argv[2]; if (argc > 3) prop = argv[3]; else prop = NULL; ret = fdt_print(pathp, prop, depth); if (ret != 0) return ret; /* * Remove a property/node */ } else if (strncmp(argv[1], "rm", 2) == 0) { int nodeoffset; /* node offset from libfdt */ int err; /* * Get the path. The root node is an oddball, the offset * is zero and has no name. */ nodeoffset = fdt_path_offset (working_fdt, argv[2]); if (nodeoffset < 0) { /* * Not found or something else bad happened. */ printf ("libfdt fdt_path_offset() returned %s\n", fdt_strerror(nodeoffset)); return 1; } /* * Do the delete. A fourth parameter means delete a property, * otherwise delete the node. */ if (argc > 3) { err = fdt_delprop(working_fdt, nodeoffset, argv[3]); if (err < 0) { printf("libfdt fdt_delprop(): %s\n", fdt_strerror(err)); return err; } } else { err = fdt_del_node(working_fdt, nodeoffset); if (err < 0) { printf("libfdt fdt_del_node(): %s\n", fdt_strerror(err)); return err; } } /* * Display header info */ } else if (argv[1][0] == 'h') { u32 version = fdt_version(working_fdt); printf("magic:\t\t\t0x%x\n", fdt_magic(working_fdt)); printf("totalsize:\t\t0x%x (%d)\n", fdt_totalsize(working_fdt), fdt_totalsize(working_fdt)); printf("off_dt_struct:\t\t0x%x\n", fdt_off_dt_struct(working_fdt)); printf("off_dt_strings:\t\t0x%x\n", fdt_off_dt_strings(working_fdt)); printf("off_mem_rsvmap:\t\t0x%x\n", fdt_off_mem_rsvmap(working_fdt)); printf("version:\t\t%d\n", version); printf("last_comp_version:\t%d\n", fdt_last_comp_version(working_fdt)); if (version >= 2) printf("boot_cpuid_phys:\t0x%x\n", fdt_boot_cpuid_phys(working_fdt)); if (version >= 3) printf("size_dt_strings:\t0x%x\n", fdt_size_dt_strings(working_fdt)); if (version >= 17) printf("size_dt_struct:\t\t0x%x\n", fdt_size_dt_struct(working_fdt)); printf("number mem_rsv:\t\t0x%x\n", fdt_num_mem_rsv(working_fdt)); printf("\n"); /* * Set boot cpu id */ } else if (strncmp(argv[1], "boo", 3) == 0) { unsigned long tmp = simple_strtoul(argv[2], NULL, 16); fdt_set_boot_cpuid_phys(working_fdt, tmp); /* * memory command */ } else if (strncmp(argv[1], "me", 2) == 0) { uint64_t addr, size; int err; addr = simple_strtoull(argv[2], NULL, 16); size = simple_strtoull(argv[3], NULL, 16); err = fdt_fixup_memory(working_fdt, addr, size); if (err < 0) return err; /* * mem reserve commands */ } else if (strncmp(argv[1], "rs", 2) == 0) { if (argv[2][0] == 'p') { uint64_t addr, size; int total = fdt_num_mem_rsv(working_fdt); int j, err; printf("index\t\t start\t\t size\n"); printf("-------------------------------" "-----------------\n"); for (j = 0; j < total; j++) { err = fdt_get_mem_rsv(working_fdt, j, &addr, &size); if (err < 0) { printf("libfdt fdt_get_mem_rsv(): %s\n", fdt_strerror(err)); return err; } printf(" %x\t%08x%08x\t%08x%08x\n", j, (u32)(addr >> 32), (u32)(addr & 0xffffffff), (u32)(size >> 32), (u32)(size & 0xffffffff)); } } else if (argv[2][0] == 'a') {
static int ait_menu_check_image(void) { char *s; unsigned long fit_addr; void *addr; int format; char *desc; char *subtype; int images_noffset; int noffset; int ndepth; int count = 0; int ret; int i; int found_uboot = -1; int found_ramdisk = -1; memset(imgs, 0, sizeof(imgs)); s = getenv("fit_addr_r"); fit_addr = s ? (unsigned long)simple_strtol(s, NULL, 16) : \ CONFIG_BOARD_IMG_ADDR_R; addr = (void *)fit_addr; /* check if it is a FIT image */ format = genimg_get_format(addr); if (format != IMAGE_FORMAT_FIT) return -EINVAL; if (!fit_check_format(addr)) return -EINVAL; /* print the FIT description */ ret = fit_get_desc(addr, 0, &desc); printf("FIT description: "); if (ret) printf("unavailable\n"); else printf("%s\n", desc); /* find images */ images_noffset = fdt_path_offset(addr, FIT_IMAGES_PATH); if (images_noffset < 0) { printf("Can't find images parent node '%s' (%s)\n", FIT_IMAGES_PATH, fdt_strerror(images_noffset)); return -EINVAL; } /* Process its subnodes, print out component images details */ for (ndepth = 0, count = 0, noffset = fdt_next_node(addr, images_noffset, &ndepth); (noffset >= 0) && (ndepth > 0); noffset = fdt_next_node(addr, noffset, &ndepth)) { if (ndepth == 1) { /* * Direct child node of the images parent node, * i.e. component image node. */ printf("Image %u (%s)\n", count, fit_get_name(addr, noffset, NULL)); fit_image_print(addr, noffset, ""); fit_image_get_type(addr, noffset, &imgs[count].type); /* Mandatory properties */ ret = fit_get_desc(addr, noffset, &desc); printf("Description: "); if (ret) printf("unavailable\n"); else printf("%s\n", desc); ret = fit_get_subtype(addr, noffset, &subtype); printf("Subtype: "); if (ret) { printf("unavailable\n"); } else { imgs[count].subtype = ait_subtype_nr(subtype); printf("%s %d\n", subtype, imgs[count].subtype); } sprintf(imgs[count].desc, "%s", desc); ret = fit_image_get_data(addr, noffset, &imgs[count].data, &imgs[count].size); printf("Data Size: "); if (ret) printf("unavailable\n"); else genimg_print_size(imgs[count].size); printf("Data @ %p\n", imgs[count].data); count++; } } for (i = 0; i < count; i++) { if (imgs[i].subtype == FIT_SUBTYPE_UBOOT_IMAGE) found_uboot = i; if (imgs[i].type == IH_TYPE_RAMDISK) { found_ramdisk = i; imgs[i].subtype = FIT_SUBTYPE_RAMDISK_IMAGE; } } /* dvn_* env var update, if the FIT descriptors are different */ if (found_uboot >= 0) { s = getenv("dvn_boot_vers"); if (s) { ret = strcmp(s, imgs[found_uboot].desc); if (ret != 0) { setenv("x_dvn_boot_vers", imgs[found_uboot].desc); } else { found_uboot = -1; printf("no new uboot version\n"); } } else { setenv("dvn_boot_vers", imgs[found_uboot].desc); } } if (found_ramdisk >= 0) { s = getenv("dvn_app_vers"); if (s) { ret = strcmp(s, imgs[found_ramdisk].desc); if (ret != 0) { setenv("x_dvn_app_vers", imgs[found_ramdisk].desc); } else { found_ramdisk = -1; printf("no new ramdisk version\n"); } } else { setenv("dvn_app_vers", imgs[found_ramdisk].desc); } } if ((found_uboot == -1) && (found_ramdisk == -1)) return -EINVAL; return 0; }
/* * Flattened Device Tree command, see the help for parameter definitions. */ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { if (argc < 2) { printf ("Usage:\n%s\n", cmdtp->usage); return 1; } /******************************************************************** * Set the address of the fdt ********************************************************************/ if (argv[1][0] == 'a') { /* * Set the address [and length] of the fdt. */ if (argc == 2) { if (!fdt_valid()) { return 1; } printf("The address of the fdt is %p\n", working_fdt); return 0; } working_fdt = (struct fdt_header *)simple_strtoul(argv[2], NULL, 16); if (!fdt_valid()) { return 1; } if (argc >= 4) { int len; int err; /* * Optional new length */ len = simple_strtoul(argv[3], NULL, 16); if (len < fdt_totalsize(working_fdt)) { printf ("New length %d < existing length %d, " "ignoring.\n", len, fdt_totalsize(working_fdt)); } else { /* * Open in place with a new length. */ err = fdt_open_into(working_fdt, working_fdt, len); if (err != 0) { printf ("libfdt fdt_open_into(): %s\n", fdt_strerror(err)); } } } /******************************************************************** * Move the working_fdt ********************************************************************/ } else if (strncmp(argv[1], "mo", 2) == 0) { struct fdt_header *newaddr; int len; int err; if (argc < 4) { printf ("Usage:\n%s\n", cmdtp->usage); return 1; } /* * Set the address and length of the fdt. */ working_fdt = (struct fdt_header *)simple_strtoul(argv[2], NULL, 16); if (!fdt_valid()) { return 1; } newaddr = (struct fdt_header *)simple_strtoul(argv[3],NULL,16); /* * If the user specifies a length, use that. Otherwise use the * current length. */ if (argc <= 4) { len = fdt_totalsize(working_fdt); } else { len = simple_strtoul(argv[4], NULL, 16); if (len < fdt_totalsize(working_fdt)) { printf ("New length 0x%X < existing length " "0x%X, aborting.\n", len, fdt_totalsize(working_fdt)); return 1; } } /* * Copy to the new location. */ err = fdt_open_into(working_fdt, newaddr, len); if (err != 0) { printf ("libfdt fdt_open_into(): %s\n", fdt_strerror(err)); return 1; } working_fdt = newaddr; /******************************************************************** * Make a new node ********************************************************************/ } else if (strncmp(argv[1], "mk", 2) == 0) { char *pathp; /* path */ char *nodep; /* new node to add */ int nodeoffset; /* node offset from libfdt */ int err; /* * Parameters: Node path, new node to be appended to the path. */ if (argc < 4) { printf ("Usage:\n%s\n", cmdtp->usage); return 1; } pathp = argv[2]; nodep = argv[3]; nodeoffset = fdt_path_offset (working_fdt, pathp); if (nodeoffset < 0) { /* * Not found or something else bad happened. */ printf ("libfdt fdt_path_offset() returned %s\n", fdt_strerror(nodeoffset)); return 1; } err = fdt_add_subnode(working_fdt, nodeoffset, nodep); if (err < 0) { printf ("libfdt fdt_add_subnode(): %s\n", fdt_strerror(err)); return 1; } /******************************************************************** * Set the value of a property in the working_fdt. ********************************************************************/ } else if (argv[1][0] == 's') { char *pathp; /* path */ char *prop; /* property */ int nodeoffset; /* node offset from libfdt */ static char data[SCRATCHPAD]; /* storage for the property */ int len; /* new length of the property */ int ret; /* return value */ /* * Parameters: Node path, property, optional value. */ if (argc < 4) { printf ("Usage:\n%s\n", cmdtp->usage); return 1; } pathp = argv[2]; prop = argv[3]; if (argc == 4) { len = 0; } else { ret = fdt_parse_prop(&argv[4], argc - 4, data, &len); if (ret != 0) return ret; } nodeoffset = fdt_path_offset (working_fdt, pathp); if (nodeoffset < 0) { /* * Not found or something else bad happened. */ printf ("libfdt fdt_path_offset() returned %s\n", fdt_strerror(nodeoffset)); return 1; } ret = fdt_setprop(working_fdt, nodeoffset, prop, data, len); if (ret < 0) { printf ("libfdt fdt_setprop(): %s\n", fdt_strerror(ret)); return 1; } /******************************************************************** * Print (recursive) / List (single level) ********************************************************************/ } else if ((argv[1][0] == 'p') || (argv[1][0] == 'l')) { int depth = MAX_LEVEL; /* how deep to print */ char *pathp; /* path */ char *prop; /* property */ int ret; /* return value */ static char root[2] = "/"; /* * list is an alias for print, but limited to 1 level */ if (argv[1][0] == 'l') { depth = 1; } /* * Get the starting path. The root node is an oddball, * the offset is zero and has no name. */ if (argc == 2) pathp = root; else pathp = argv[2]; if (argc > 3) prop = argv[3]; else prop = NULL; ret = fdt_print(pathp, prop, depth); if (ret != 0) return ret; /******************************************************************** * Remove a property/node ********************************************************************/ } else if (strncmp(argv[1], "rm", 2) == 0) { int nodeoffset; /* node offset from libfdt */ int err; /* * Get the path. The root node is an oddball, the offset * is zero and has no name. */ nodeoffset = fdt_path_offset (working_fdt, argv[2]); if (nodeoffset < 0) { /* * Not found or something else bad happened. */ printf ("libfdt fdt_path_offset() returned %s\n", fdt_strerror(nodeoffset)); return 1; } /* * Do the delete. A fourth parameter means delete a property, * otherwise delete the node. */ if (argc > 3) { err = fdt_delprop(working_fdt, nodeoffset, argv[3]); if (err < 0) { printf("libfdt fdt_delprop(): %s\n", fdt_strerror(err)); return err; } } else { err = fdt_del_node(working_fdt, nodeoffset); if (err < 0) { printf("libfdt fdt_del_node(): %s\n", fdt_strerror(err)); return err; } } /******************************************************************** * Display header info ********************************************************************/ } else if (argv[1][0] == 'h') { u32 version = fdt_version(working_fdt); printf("magic:\t\t\t0x%x\n", fdt_magic(working_fdt)); printf("totalsize:\t\t0x%x (%d)\n", fdt_totalsize(working_fdt), fdt_totalsize(working_fdt)); printf("off_dt_struct:\t\t0x%x\n", fdt_off_dt_struct(working_fdt)); printf("off_dt_strings:\t\t0x%x\n", fdt_off_dt_strings(working_fdt)); printf("off_mem_rsvmap:\t\t0x%x\n", fdt_off_mem_rsvmap(working_fdt)); printf("version:\t\t%d\n", version); printf("last_comp_version:\t%d\n", fdt_last_comp_version(working_fdt)); if (version >= 2) printf("boot_cpuid_phys:\t0x%x\n", fdt_boot_cpuid_phys(working_fdt)); if (version >= 3) printf("size_dt_strings:\t0x%x\n", fdt_size_dt_strings(working_fdt)); if (version >= 17) printf("size_dt_struct:\t\t0x%x\n", fdt_size_dt_struct(working_fdt)); printf("number mem_rsv:\t\t0x%x\n", fdt_num_mem_rsv(working_fdt)); printf("\n"); /******************************************************************** * Set boot cpu id ********************************************************************/ } else if (strncmp(argv[1], "boo", 3) == 0) { unsigned long tmp = simple_strtoul(argv[2], NULL, 16); fdt_set_boot_cpuid_phys(working_fdt, tmp); /******************************************************************** * memory command ********************************************************************/ } else if (strncmp(argv[1], "me", 2) == 0) { uint64_t addr, size; int err; #ifdef CFG_64BIT_STRTOUL addr = simple_strtoull(argv[2], NULL, 16); size = simple_strtoull(argv[3], NULL, 16); #else addr = simple_strtoul(argv[2], NULL, 16); size = simple_strtoul(argv[3], NULL, 16); #endif err = fdt_fixup_memory(working_fdt, addr, size); if (err < 0) return err; /******************************************************************** * mem reserve commands ********************************************************************/ } else if (strncmp(argv[1], "rs", 2) == 0) { if (argv[2][0] == 'p') { uint64_t addr, size; int total = fdt_num_mem_rsv(working_fdt); int j, err; printf("index\t\t start\t\t size\n"); printf("-------------------------------" "-----------------\n"); for (j = 0; j < total; j++) { err = fdt_get_mem_rsv(working_fdt, j, &addr, &size); if (err < 0) { printf("libfdt fdt_get_mem_rsv(): %s\n", fdt_strerror(err)); return err; } printf(" %x\t%08x%08x\t%08x%08x\n", j, (u32)(addr >> 32), (u32)(addr & 0xffffffff), (u32)(size >> 32), (u32)(size & 0xffffffff)); } } else if (argv[2][0] == 'a') {
static int fit_config_process_sig(const char *keydir, void *keydest, void *fit, const char *conf_name, int conf_noffset, int noffset, const char *comment, int require_keys) { struct image_sign_info info; const char *node_name; struct image_region *region; char *region_prop; int region_proplen; int region_count; uint8_t *value; uint value_len; int ret; node_name = fit_get_name(fit, noffset, NULL); if (fit_config_get_data(fit, conf_noffset, noffset, ®ion, ®ion_count, ®ion_prop, ®ion_proplen)) return -1; if (fit_image_setup_sig(&info, keydir, fit, conf_name, noffset, require_keys ? "conf" : NULL)) return -1; ret = info.algo->sign(&info, region, region_count, &value, &value_len); free(region); if (ret) { printf("Failed to sign '%s' signature node in '%s' conf node\n", node_name, conf_name); /* We allow keys to be missing */ if (ret == -ENOENT) return 0; return -1; } ret = fit_image_write_sig(fit, noffset, value, value_len, comment, region_prop, region_proplen); if (ret) { if (ret == -FDT_ERR_NOSPACE) return -ENOSPC; printf("Can't write signature for '%s' signature node in '%s' conf node: %s\n", node_name, conf_name, fdt_strerror(ret)); return -1; } free(value); free(region_prop); /* Get keyname again, as FDT has changed and invalidated our pointer */ info.keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL); /* Write the public key into the supplied FDT file */ if (keydest) { ret = info.algo->add_verify_data(&info, keydest); if (ret == -ENOSPC) return -ENOSPC; if (ret) { printf("Failed to add verification data for '%s' signature node in '%s' image node\n", node_name, conf_name); } return ret; } return 0; }