static int ft_hs_add_tee(void *fdt, bd_t *bd) { const char *path, *subpath; int offs; extern int tee_loaded; if (!tee_loaded) return 0; path = "/"; offs = fdt_path_offset(fdt, path); subpath = "firmware"; offs = fdt_add_subnode(fdt, offs, subpath); if (offs < 0) { printf("Could not create %s node.\n", subpath); return 1; } subpath = "optee"; offs = fdt_add_subnode(fdt, offs, subpath); if (offs < 0) { printf("Could not create %s node.\n", subpath); return 1; } fdt_setprop_string(fdt, offs, "compatible", "linaro,optee-tz"); fdt_setprop_string(fdt, offs, "method", "smc"); return 0; }
static int add_optee_dt_node(void *fdt) { int offs; int ret; if (fdt_path_offset(fdt, "/firmware/optee") >= 0) { DMSG("OP-TEE Device Tree node already exists!\n"); return 0; } offs = fdt_path_offset(fdt, "/firmware"); if (offs < 0) { offs = fdt_path_offset(fdt, "/"); if (offs < 0) return -1; offs = fdt_add_subnode(fdt, offs, "firmware"); if (offs < 0) return -1; } offs = fdt_add_subnode(fdt, offs, "optee"); if (offs < 0) return -1; ret = fdt_setprop_string(fdt, offs, "compatible", "linaro,optee-tz"); if (ret < 0) return -1; ret = fdt_setprop_string(fdt, offs, "method", "smc"); if (ret < 0) return -1; return 0; }
void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr, enum fm_port port, int offset) { struct fixed_link f_link; if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_RGMII) { if (port == FM1_DTSEC3) { fdt_set_phy_handle(fdt, compat, addr, "rgmii_phy2"); fdt_setprop_string(fdt, offset, "phy-connection-type", "rgmii"); fdt_status_okay_by_alias(fdt, "emi1_rgmii1"); } } else if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_SGMII) { if (port == FM1_DTSEC1) { fdt_set_phy_handle(fdt, compat, addr, "sgmii_vsc8234_phy_s5"); } else if (port == FM1_DTSEC2) { fdt_set_phy_handle(fdt, compat, addr, "sgmii_vsc8234_phy_s4"); } } else if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_SGMII_2500) { if (port == FM1_DTSEC3) { fdt_set_phy_handle(fdt, compat, addr, "sgmii_aqr105_phy_s3"); } } else if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_QSGMII) { switch (port) { case FM1_DTSEC1: fdt_set_phy_handle(fdt, compat, addr, "qsgmii_phy_p1"); break; case FM1_DTSEC2: fdt_set_phy_handle(fdt, compat, addr, "qsgmii_phy_p2"); break; case FM1_DTSEC3: fdt_set_phy_handle(fdt, compat, addr, "qsgmii_phy_p3"); break; case FM1_DTSEC4: fdt_set_phy_handle(fdt, compat, addr, "qsgmii_phy_p4"); break; default: break; } fdt_delprop(fdt, offset, "phy-connection-type"); fdt_setprop_string(fdt, offset, "phy-connection-type", "qsgmii"); fdt_status_okay_by_alias(fdt, "emi1_slot2"); } else if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_XGMII) { /* XFI interface */ f_link.phy_id = port; f_link.duplex = 1; f_link.link_speed = 10000; f_link.pause = 0; f_link.asym_pause = 0; /* no PHY for XFI */ fdt_delprop(fdt, offset, "phy-handle"); fdt_setprop(fdt, offset, "fixed-link", &f_link, sizeof(f_link)); fdt_setprop_string(fdt, offset, "phy-connection-type", "xgmii"); } }
int main(int argc, char *argv[]) { void *fdt; int err; int offset, s1, s2; test_init(argc, argv); fdt = xmalloc(SPACE); /* First create empty tree with SW */ CHECK(fdt_create(fdt, SPACE)); CHECK(fdt_finish_reservemap(fdt)); CHECK(fdt_begin_node(fdt, "")); CHECK(fdt_end_node(fdt)); CHECK(fdt_finish(fdt)); verbose_printf("Built empty tree, totalsize = %d\n", fdt_totalsize(fdt)); CHECK(fdt_open_into(fdt, fdt, SPACE)); CHECK(fdt_add_mem_rsv(fdt, TEST_ADDR_1, TEST_SIZE_1)); CHECK(fdt_add_mem_rsv(fdt, TEST_ADDR_2, TEST_SIZE_2)); CHECK(fdt_setprop_string(fdt, 0, "compatible", "test_tree1")); CHECK(fdt_setprop_cell(fdt, 0, "prop-int", TEST_VALUE_1)); CHECK(fdt_setprop_string(fdt, 0, "prop-str", TEST_STRING_1)); OFF_CHECK(offset, fdt_add_subnode(fdt, 0, "subnode@1")); s1 = offset; CHECK(fdt_setprop_string(fdt, s1, "compatible", "subnode1")); CHECK(fdt_setprop_cell(fdt, s1, "prop-int", TEST_VALUE_1)); OFF_CHECK(offset, fdt_add_subnode(fdt, s1, "subsubnode")); CHECK(fdt_setprop(fdt, offset, "compatible", "subsubnode1\0subsubnode", 23)); CHECK(fdt_setprop_cell(fdt, offset, "prop-int", TEST_VALUE_1)); OFF_CHECK(offset, fdt_add_subnode(fdt, s1, "ss1")); OFF_CHECK(offset, fdt_add_subnode(fdt, 0, "subnode@2")); s2 = offset; CHECK(fdt_setprop_cell(fdt, s2, "linux,phandle", PHANDLE_1)); CHECK(fdt_setprop_cell(fdt, s2, "prop-int", TEST_VALUE_2)); OFF_CHECK(offset, fdt_add_subnode(fdt, s2, "subsubnode@0")); CHECK(fdt_setprop_cell(fdt, offset, "linux,phandle", PHANDLE_2)); CHECK(fdt_setprop(fdt, offset, "compatible", "subsubnode2\0subsubnode", 23)); CHECK(fdt_setprop_cell(fdt, offset, "prop-int", TEST_VALUE_2)); OFF_CHECK(offset, fdt_add_subnode(fdt, s2, "ss2")); CHECK(fdt_pack(fdt)); save_blob("rw_tree1.test.dtb", fdt); PASS(); }
static int ft_hs_fixup_dram(void *fdt, bd_t *bd) { const char *path, *subpath; int offs; u32 sec_mem_start = CONFIG_TI_SECURE_EMIF_REGION_START; u32 sec_mem_size = CONFIG_TI_SECURE_EMIF_TOTAL_REGION_SIZE; fdt64_t temp[2]; /* If start address is zero, place at end of DRAM */ if (0 == sec_mem_start) sec_mem_start = (CONFIG_SYS_SDRAM_BASE + (omap_sdram_size() - sec_mem_size)); /* Delete any original secure_reserved node */ path = "/reserved-memory/secure_reserved"; offs = fdt_path_offset(fdt, path); if (offs >= 0) fdt_del_node(fdt, offs); /* Add new secure_reserved node */ path = "/reserved-memory"; offs = fdt_path_offset(fdt, path); if (offs < 0) { debug("Node %s not found\n", path); path = "/"; subpath = "reserved-memory"; fdt_path_offset(fdt, path); offs = fdt_add_subnode(fdt, offs, subpath); if (offs < 0) { printf("Could not create %s%s node.\n", path, subpath); return 1; } path = "/reserved-memory"; offs = fdt_path_offset(fdt, path); } subpath = "secure_reserved"; offs = fdt_add_subnode(fdt, offs, subpath); if (offs < 0) { printf("Could not create %s%s node.\n", path, subpath); return 1; } temp[0] = cpu_to_fdt64(((u64)sec_mem_start)); temp[1] = cpu_to_fdt64(((u64)sec_mem_size)); fdt_setprop_string(fdt, offs, "compatible", "ti,dra7-secure-memory"); fdt_setprop_string(fdt, offs, "status", "okay"); fdt_setprop(fdt, offs, "no-map", NULL, 0); fdt_setprop(fdt, offs, "reg", temp, sizeof(temp)); return 0; }
static int dt_add_psci_node(void *fdt) { int offs; if (fdt_path_offset(fdt, "/psci") >= 0) { DMSG("PSCI Device Tree node already exists!\n"); return 0; } offs = fdt_path_offset(fdt, "/"); if (offs < 0) return -1; offs = fdt_add_subnode(fdt, offs, "psci"); if (offs < 0) return -1; if (append_psci_compatible(fdt, offs, "arm,psci-1.0")) return -1; if (append_psci_compatible(fdt, offs, "arm,psci-0.2")) return -1; if (append_psci_compatible(fdt, offs, "arm,psci")) return -1; if (fdt_setprop_string(fdt, offs, "method", "smc")) return -1; if (fdt_setprop_u32(fdt, offs, "cpu_suspend", PSCI_CPU_SUSPEND)) return -1; if (fdt_setprop_u32(fdt, offs, "cpu_off", PSCI_CPU_OFF)) return -1; if (fdt_setprop_u32(fdt, offs, "cpu_on", PSCI_CPU_ON)) return -1; if (fdt_setprop_u32(fdt, offs, "sys_poweroff", PSCI_SYSTEM_OFF)) return -1; if (fdt_setprop_u32(fdt, offs, "sys_reset", PSCI_SYSTEM_RESET)) return -1; return 0; }
STATIC VOID SetDeviceStatus ( IN VOID *Fdt, IN CONST CHAR8 *Device, IN BOOLEAN Enable ) { INT32 Node; INT32 SubNode; INT32 Rc; Node = fdt_subnode_offset (Fdt, 0, "smb"); if (Node >= 0) { SubNode = fdt_subnode_offset (Fdt, Node, Device); if (SubNode >= 0) { Rc = fdt_setprop_string (Fdt, SubNode, "status", Enable ? "okay" : "disabled"); if (Rc) { DEBUG ((DEBUG_ERROR, "%a: Could not set 'status' property for '%a' node\n", __FUNCTION__, Device)); } } } }
void ft_srio_setup(void *blob) { int srio1_used = 0, srio2_used = 0; int srio_off; /* search for srio node, if doesn't exist just return - nothing todo */ srio_off = fdt_node_offset_by_compatible(blob, -1, "fsl,srio"); if (srio_off < 0) return ; #ifdef CONFIG_SRIO1 if (is_serdes_configured(SRIO1)) srio1_used = 1; #endif #ifdef CONFIG_SRIO2 if (is_serdes_configured(SRIO2)) srio2_used = 1; #endif /* mark port1 disabled */ if (!srio1_used) ft_disable_srio_port(blob, srio_off, 1); /* mark port2 disabled */ if (!srio2_used) ft_disable_srio_port(blob, srio_off, 2); /* if both ports not used, disable controller, rmu and rman */ if (!srio1_used && !srio2_used) { fdt_setprop_string(blob, srio_off, "status", "disabled"); ft_disable_rman(blob); ft_disable_rmu(blob); } }
static void powernv_populate_serial(ISADevice *d, void *fdt, int lpc_off) { const char compatible[] = "ns16550\0pnpPNP,501"; uint32_t io_base = d->ioport_id; uint32_t io_regs[] = { cpu_to_be32(1), cpu_to_be32(io_base), cpu_to_be32(8) }; char *name; int node; name = g_strdup_printf("%s@i%x", qdev_fw_name(DEVICE(d)), io_base); node = fdt_add_subnode(fdt, lpc_off, name); _FDT(node); g_free(name); _FDT((fdt_setprop(fdt, node, "reg", io_regs, sizeof(io_regs)))); _FDT((fdt_setprop(fdt, node, "compatible", compatible, sizeof(compatible)))); _FDT((fdt_setprop_cell(fdt, node, "clock-frequency", 1843200))); _FDT((fdt_setprop_cell(fdt, node, "current-speed", 115200))); _FDT((fdt_setprop_cell(fdt, node, "interrupts", d->isairq[0]))); _FDT((fdt_setprop_cell(fdt, node, "interrupt-parent", fdt_get_phandle(fdt, lpc_off)))); /* This is needed by Linux */ _FDT((fdt_setprop_string(fdt, node, "device_type", "serial"))); }
static void ft_fixup_port(void *blob, struct fm_eth_info *info, char *prop) { int off, ph; phys_addr_t paddr = CONFIG_SYS_CCSRBAR_PHYS + info->compat_offset; u64 dtsec1_addr = (u64)CONFIG_SYS_CCSRBAR_PHYS + CONFIG_SYS_FSL_FM1_DTSEC1_OFFSET; off = fdt_node_offset_by_compat_reg(blob, prop, paddr); if (info->enabled) { fdt_fixup_phy_connection(blob, off, info->enet_if); board_ft_fman_fixup_port(blob, prop, paddr, info->port, off); return ; } /* board code might have caused offset to change */ off = fdt_node_offset_by_compat_reg(blob, prop, paddr); /* Don't disable FM1-DTSEC1 MAC as its used for MDIO */ if (paddr != dtsec1_addr) { /* disable the mac node */ fdt_setprop_string(blob, off, "status", "disabled"); } /* disable the node point to the mac */ ph = fdt_get_phandle(blob, off); do_fixup_by_prop(blob, "fsl,fman-mac", &ph, sizeof(ph), "status", "disabled", strlen("disabled") + 1, 1); }
static void powernv_populate_ipmi_bt(ISADevice *d, void *fdt, int lpc_off) { const char compatible[] = "bt\0ipmi-bt"; uint32_t io_base; uint32_t io_regs[] = { cpu_to_be32(1), 0, /* 'io_base' retrieved from the 'ioport' property of 'isa-ipmi-bt' */ cpu_to_be32(3) }; uint32_t irq; char *name; int node; io_base = object_property_get_int(OBJECT(d), "ioport", &error_fatal); io_regs[1] = cpu_to_be32(io_base); irq = object_property_get_int(OBJECT(d), "irq", &error_fatal); name = g_strdup_printf("%s@i%x", qdev_fw_name(DEVICE(d)), io_base); node = fdt_add_subnode(fdt, lpc_off, name); _FDT(node); g_free(name); _FDT((fdt_setprop(fdt, node, "reg", io_regs, sizeof(io_regs)))); _FDT((fdt_setprop(fdt, node, "compatible", compatible, sizeof(compatible)))); /* Mark it as reserved to avoid Linux trying to claim it */ _FDT((fdt_setprop_string(fdt, node, "status", "reserved"))); _FDT((fdt_setprop_cell(fdt, node, "interrupts", irq))); _FDT((fdt_setprop_cell(fdt, node, "interrupt-parent", fdt_get_phandle(fdt, lpc_off)))); }
static int setprop_string(void *fdt, const char *node_path, const char *property, const char *string) { int offset = node_offset(fdt, node_path); if (offset < 0) return offset; return fdt_setprop_string(fdt, offset, property, string); }
static inline void ft_disable_rmu(void *blob) { int off = fdt_node_offset_by_compatible(blob, -1, "fsl,srio-rmu"); if (off >= 0) { off = fdt_setprop_string(blob, off, "status", "disabled"); if (off > 0) printf("WARNING unable to set status for " "fsl,srio-rmu %s\n", fdt_strerror(off)); } }
int qemu_devtree_setprop_string(void *fdt, const char *node_path, const char *property, const char *string) { int offset; offset = fdt_path_offset(fdt, node_path); if (offset < 0) return offset; return fdt_setprop_string(fdt, offset, property, string); }
void spapr_dt_xics(int nr_servers, void *fdt, uint32_t phandle) { uint32_t interrupt_server_ranges_prop[] = { 0, cpu_to_be32(nr_servers), }; int node; _FDT(node = fdt_add_subnode(fdt, 0, "interrupt-controller")); _FDT(fdt_setprop_string(fdt, node, "device_type", "PowerPC-External-Interrupt-Presentation")); _FDT(fdt_setprop_string(fdt, node, "compatible", "IBM,ppc-xicp")); _FDT(fdt_setprop(fdt, node, "interrupt-controller", NULL, 0)); _FDT(fdt_setprop(fdt, node, "ibm,interrupt-server-ranges", interrupt_server_ranges_prop, sizeof(interrupt_server_ranges_prop))); _FDT(fdt_setprop_cell(fdt, node, "#interrupt-cells", 2)); _FDT(fdt_setprop_cell(fdt, node, "linux,phandle", phandle)); _FDT(fdt_setprop_cell(fdt, node, "phandle", phandle)); }
static inline void ft_disable_srio_port(void *blob, int srio_off, int port) { int off = fdt_node_offset_by_prop_value(blob, srio_off, "cell-index", &port, 4); if (off >= 0) { off = fdt_setprop_string(blob, off, "status", "disabled"); if (off > 0) printf("WARNING unable to set status for fsl,srio " "port %d: %s\n", port, fdt_strerror(off)); } }
/** * fit_image_write_sig() - write the signature to a FIT * * This writes the signature and signer data to the FIT. * * @fit: pointer to the FIT format image header * @noffset: hash node offset * @value: signature value to be set * @value_len: signature value length * @comment: Text comment to write (NULL for none) * * returns * 0, on success * -FDT_ERR_..., on failure */ static int fit_image_write_sig(void *fit, int noffset, uint8_t *value, int value_len, const char *comment, const char *region_prop, int region_proplen) { int string_size; int ret; /* * Get the current string size, before we update the FIT and add * more */ string_size = fdt_size_dt_strings(fit); ret = fdt_setprop(fit, noffset, FIT_VALUE_PROP, value, value_len); if (!ret) { ret = fdt_setprop_string(fit, noffset, "signer-name", "mkimage"); } if (!ret) { ret = fdt_setprop_string(fit, noffset, "signer-version", PLAIN_VERSION); } if (comment && !ret) ret = fdt_setprop_string(fit, noffset, "comment", comment); if (!ret) ret = fit_set_timestamp(fit, noffset, time(NULL)); if (region_prop && !ret) { uint32_t strdata[2]; ret = fdt_setprop(fit, noffset, "hashed-nodes", region_prop, region_proplen); strdata[0] = 0; strdata[1] = cpu_to_fdt32(string_size); if (!ret) { ret = fdt_setprop(fit, noffset, "hashed-strings", strdata, sizeof(strdata)); } } return ret; }
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; }
int qemu_fdt_setprop_string(void *fdt, const char *node_path, const char *property, const char *string) { int r; r = fdt_setprop_string(fdt, findnode_nofail(fdt, node_path), property, string); if (r < 0) { error_report("%s: Couldn't set %s/%s = %s: %s", __func__, node_path, property, string, fdt_strerror(r)); exit(1); } return r; }
void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr, enum fm_port port, int offset) { #if defined(CONFIG_T1024RDB) if (((fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_SGMII_2500) || (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_SGMII)) && (port == FM1_DTSEC3)) { fdt_set_phy_handle(fdt, compat, addr, "sg_2500_aqr105_phy4"); fdt_setprop_string(fdt, offset, "phy-connection-type", "sgmii-2500"); fdt_status_disabled_by_alias(fdt, "xg_aqr105_phy3"); } #endif }
/** * Add all bootstage timings to a device tree. * * @param blob Device tree blob * @return 0 on success, != 0 on failure. */ static int add_bootstages_devicetree(struct fdt_header *blob) { struct bootstage_data *data = gd->bootstage; int bootstage; char buf[20]; int recnum; int i; if (!blob) return 0; /* * Create the node for bootstage. * The address of flat device tree is set up by the command bootm. */ bootstage = fdt_add_subnode(blob, 0, "bootstage"); if (bootstage < 0) return -EINVAL; /* * Insert the timings to the device tree in the reverse order so * that they can be printed in the Linux kernel in the right order. */ for (recnum = data->rec_count - 1, i = 0; recnum >= 0; recnum--, i++) { struct bootstage_record *rec = &data->record[recnum]; int node; if (rec->id != BOOTSTAGE_ID_AWAKE && rec->time_us == 0) continue; node = fdt_add_subnode(blob, bootstage, simple_itoa(i)); if (node < 0) break; /* add properties to the node. */ if (fdt_setprop_string(blob, node, "name", get_record_name(buf, sizeof(buf), rec))) return -EINVAL; /* Check if this is a 'mark' or 'accum' record */ if (fdt_setprop_cell(blob, node, rec->start_us ? "accum" : "mark", rec->time_us)) return -EINVAL; } return 0; }
/*** * sandbox_write_state_node() - Write state associated with a driver * * This calls the write function to write out global state for that driver. * * TODO([email protected]): Support writing out state from multiple drivers * of the same time. We don't need this yet,and it will be much easier to * do when driver model is available. * * @state: Sandbox state * @io: Method to use for writing state * @return 0 if OK, -EIO if there is a fatal error (such as out of space * for adding the data), -EINVAL if the write function failed. */ int sandbox_write_state_node(struct sandbox_state *state, struct sandbox_state_io *io) { void *blob; int node; int ret; if (!io->write) return 0; ret = state_ensure_space(SANDBOX_STATE_MIN_SPACE); if (ret) { printf("Failed to add more space for state\n"); return -EIO; } /* The blob location can change when the size increases */ blob = state->state_fdt; node = fdt_node_offset_by_compatible(blob, -1, io->compat); if (node == -FDT_ERR_NOTFOUND) { node = fdt_add_subnode(blob, 0, io->name); if (node < 0) { printf("Cannot create node '%s': %s\n", io->name, fdt_strerror(node)); return -EIO; } if (fdt_setprop_string(blob, node, "compatible", io->compat)) { puts("Cannot set compatible\n"); return -EIO; } } else if (node < 0) { printf("Cannot access node '%s': %s\n", io->name, fdt_strerror(node)); return -EIO; } debug("Write state for '%s' to node %d\n", io->compat, node); ret = io->write(blob, node); if (ret) { printf("Unable to write state for '%s'\n", io->compat); return -EINVAL; } return 0; }
int ft_board_setup(void *fdt, bd_t *bd) { int offset, tmp, len; const struct fdt_property *prop; const char *cci_compatible = "arm,cci-400-ctrl-if"; #ifdef CONFIG_ARMV7_NONSEC if (!armv7_boot_nonsec()) return 0; #else return 0; #endif /* Booting in nonsec mode, disable CCI access */ offset = fdt_path_offset(fdt, "/cpus"); if (offset < 0) { printf("couldn't find /cpus\n"); return offset; } /* delete cci-control-port in each cpu node */ for (tmp = fdt_first_subnode(fdt, offset); tmp >= 0; tmp = fdt_next_subnode(fdt, tmp)) fdt_delprop(fdt, tmp, "cci-control-port"); /* disable all ace cci slave ports */ offset = fdt_node_offset_by_prop_value(fdt, offset, "compatible", cci_compatible, 20); while (offset > 0) { prop = fdt_get_property(fdt, offset, "interface-type", &len); if (!prop) continue; if (len < 4) continue; if (strcmp(prop->data, "ace")) continue; fdt_setprop_string(fdt, offset, "status", "disabled"); offset = fdt_node_offset_by_prop_value(fdt, offset, "compatible", cci_compatible, 20); } return 0; }
/* * Memory nodes are created by hostboot, one for each range of memory * that has a different "affinity". In practice, it means one range * per chip. */ static void pnv_dt_memory(void *fdt, int chip_id, hwaddr start, hwaddr size) { char *mem_name; uint64_t mem_reg_property[2]; int off; mem_reg_property[0] = cpu_to_be64(start); mem_reg_property[1] = cpu_to_be64(size); mem_name = g_strdup_printf("memory@%"HWADDR_PRIx, start); off = fdt_add_subnode(fdt, 0, mem_name); g_free(mem_name); _FDT((fdt_setprop_string(fdt, off, "device_type", "memory"))); _FDT((fdt_setprop(fdt, off, "reg", mem_reg_property, sizeof(mem_reg_property)))); _FDT((fdt_setprop_cell(fdt, off, "ibm,chip-id", chip_id))); }
void ft_fixup_cpu(void *blob) { int off; __maybe_unused u64 spin_tbl_addr = (u64)get_spin_tbl_addr(); fdt32_t *reg; int addr_cells; u64 val, core_id; size_t *boot_code_size = &(__secondary_boot_code_size); off = fdt_path_offset(blob, "/cpus"); if (off < 0) { puts("couldn't find /cpus node\n"); return; } of_bus_default_count_cells(blob, off, &addr_cells, NULL); off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpu", 4); while (off != -FDT_ERR_NOTFOUND) { reg = (fdt32_t *)fdt_getprop(blob, off, "reg", 0); core_id = of_read_number(reg, addr_cells); if (reg) { if (core_id == 0 || (is_core_online(core_id))) { val = spin_tbl_addr; val += id_to_core(core_id) * SPIN_TABLE_ELEM_SIZE; val = cpu_to_fdt64(val); fdt_setprop_string(blob, off, "enable-method", "spin-table"); fdt_setprop(blob, off, "cpu-release-addr", &val, sizeof(val)); } else { debug("skipping offline core\n"); } } else { puts("Warning: found cpu node without reg property\n"); } off = fdt_node_offset_by_prop_value(blob, off, "device_type", "cpu", 4); } fdt_add_mem_rsv(blob, (uintptr_t)&secondary_boot_code, *boot_code_size); }
static void powernv_populate_rtc(ISADevice *d, void *fdt, int lpc_off) { uint32_t io_base = d->ioport_id; uint32_t io_regs[] = { cpu_to_be32(1), cpu_to_be32(io_base), cpu_to_be32(2) }; char *name; int node; name = g_strdup_printf("%s@i%x", qdev_fw_name(DEVICE(d)), io_base); node = fdt_add_subnode(fdt, lpc_off, name); _FDT(node); g_free(name); _FDT((fdt_setprop(fdt, node, "reg", io_regs, sizeof(io_regs)))); _FDT((fdt_setprop_string(fdt, node, "compatible", "pnpPNP,b00"))); }
void fdt_fixup_dmamem(void *fdt) { /* * By default assume param values specified in U-Boot config */ u32 mem_adr = CONFIG_DMAMEM_BASE; u32 mem_sz = CONFIG_DMAMEM_SZ_ALL; u32 fb_sz = CONFIG_DMAMEM_SZ_FB; const u32 *val; int node; node = fdt_path_offset(fdt, "/dmamem"); if (node < 0) { /* * The device-tree file does not include 'dmamem' node. * Create it, and fill with U-Boot params */ node = fdt_add_subnode(fdt, 0, "dmamem"); if (node < 0) goto out; fdt_setprop_string(fdt, node, "compatible", "dmamem"); fdt_setprop_cell(fdt, node, "base-addr", mem_adr); fdt_setprop_cell(fdt, node, "full-size", mem_sz); fdt_setprop_cell(fdt, node, "fb-size", fb_sz); goto out; } /* * Get params from device-tree */ val = fdt_getprop(fdt, node, "base-addr", NULL); if (val) mem_adr = fdt32_to_cpu(*val); val = fdt_getprop(fdt, node, "full-size", NULL); if (val) mem_sz = fdt32_to_cpu(*val); out: /* * Configure the dmamem area if it's not empty */ if (mem_sz) dmamem_init(mem_adr, mem_sz); }
static int dt_add_psci_cpu_enable_methods(void *fdt) { int offs = 0; while (1) { offs = fdt_next_node(fdt, offs, NULL); if (offs < 0) break; if (fdt_getprop(fdt, offs, "enable-method", NULL)) continue; /* already set */ if (check_node_compat_prefix(fdt, offs, "arm,cortex-a")) continue; /* no compatible */ if (fdt_setprop_string(fdt, offs, "enable-method", "psci")) return -1; /* Need to restart scanning as offsets may have changed */ offs = 0; } return 0; }
int dev_tree_setprop_string(void *fdt, char *node, const char *property, const char *value) { int ret = 0; int offset; offset = fdt_path_offset(fdt, node); if (offset < 0) { dprintf(CRITICAL, "Could not found %s node.\n" , node); return ret; } ret = fdt_setprop_string(fdt, offset, property, value); if (ret < 0) { dprintf(CRITICAL, "Could not set %s value to %s property in %s node.\n", value, property, node); return ret; } return ret; }
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; }