예제 #1
0
파일: mc.c 프로젝트: Xilinx/u-boot-xlnx
void fdt_fsl_mc_fixup_iommu_map_entry(void *blob)
{
	u32 *prop;
	u32 iommu_map[4];
	int offset;
	int lenp;

	/* find fsl-mc node */
	offset = fdt_path_offset(blob, "/soc/fsl-mc");
	if (offset < 0)
		offset = fdt_path_offset(blob, "/fsl-mc");
	if (offset < 0) {
		printf("%s: fsl-mc: ERR: fsl-mc node not found in DT, err %d\n",
		       __func__, offset);
		return;
	}

	prop = fdt_getprop_w(blob, offset, "iommu-map", &lenp);
	if (!prop) {
		debug("%s: fsl-mc: ERR: missing iommu-map in fsl-mc bus node\n",
		      __func__);
		return;
	}

	iommu_map[0] = cpu_to_fdt32(FSL_DPAA2_STREAM_ID_START);
	iommu_map[1] = *++prop;
	iommu_map[2] = cpu_to_fdt32(FSL_DPAA2_STREAM_ID_START);
	iommu_map[3] = cpu_to_fdt32(FSL_DPAA2_STREAM_ID_END -
		FSL_DPAA2_STREAM_ID_START + 1);

	fdt_setprop_inplace(blob, offset, "iommu-map",
			    iommu_map, sizeof(iommu_map));
}
예제 #2
0
static int ft_hs_fixup_sram(void *fdt, bd_t *bd)
{
	const char *path;
	int offs;
	int ret;
	u32 temp[2];

	/*
	 * Update SRAM reservations on secure devices. The OCMC RAM
	 * is always reserved for secure use from the start of that
	 * memory region
	 */
	path = "/ocp/ocmcram@40300000/sram-hs";
	offs = fdt_path_offset(fdt, path);
	if (offs < 0) {
		debug("Node %s not found.\n", path);
		return 0;
	}

	/* relative start offset */
	temp[0] = cpu_to_fdt32(0);
	/* reservation size */
	temp[1] = cpu_to_fdt32(max(CONFIG_SECURE_BOOT_SRAM,
				   CONFIG_SECURE_RUN_SRAM));
	fdt_delprop(fdt, offs, "reg");
	ret = fdt_setprop(fdt, offs, "reg", temp, 2 * sizeof(u32));
	if (ret < 0) {
		printf("Could not add reg property to node %s: %s\n",
		       path, fdt_strerror(ret));
		return ret;
	}

	return 0;
}
예제 #3
0
파일: fdt.c 프로젝트: 5kg/kvmtool
static void generate_irq_prop(void *fdt, u8 irq, enum irq_type irq_type)
{
	u32 irq_prop[] = {
		cpu_to_fdt32(GIC_FDT_IRQ_TYPE_SPI),
		cpu_to_fdt32(irq - GIC_SPI_IRQ_BASE),
		cpu_to_fdt32(irq_type)
	};

	_FDT(fdt_property(fdt, "interrupts", irq_prop, sizeof(irq_prop)));
}
예제 #4
0
static void generate_irq_prop(void *fdt, u8 irq)
{
	u32 irq_prop[] = {
		cpu_to_fdt32(GIC_FDT_IRQ_TYPE_SPI),
		cpu_to_fdt32(irq - GIC_SPI_IRQ_BASE),
		cpu_to_fdt32(GIC_FDT_IRQ_FLAGS_EDGE_LO_HI),
	};

	_FDT(fdt_property(fdt, "interrupts", irq_prop, sizeof(irq_prop)));
}
예제 #5
0
/*
 * Convert and fold provided ATAGs into the provided FDT.
 *
 * REturn values:
 *    = 0 -> pretend success
 *    = 1 -> bad ATAG (may retry with another possible ATAG pointer)
 *    < 0 -> error from libfdt
 */
int atags_to_fdt(void *atag_list, void *fdt, int total_space)
{
	struct tag *atag = atag_list;
	uint32_t mem_reg_property[16];
	int memcount = 0;
	int ret;

	/* make sure we've got an aligned pointer */
	if ((u32)atag_list & 0x3)
		return 1;

	/* if we get a DTB here we're done already */
	if (*(u32 *)atag_list == fdt32_to_cpu(FDT_MAGIC))
	       return 0;	

	/* validate the ATAG */
	if (atag->hdr.tag != ATAG_CORE ||
	    (atag->hdr.size != tag_size(tag_core) &&
	     atag->hdr.size != 2))
		return 1;

	/* let's give it all the room it could need */
	ret = fdt_open_into(fdt, fdt, total_space);
	if (ret < 0)
		return ret;

	for_each_tag(atag, atag_list) {
		if (atag->hdr.tag == ATAG_CMDLINE) {
			setprop_string(fdt, "/chosen", "bootargs",
					atag->u.cmdline.cmdline);
		} else if (atag->hdr.tag == ATAG_MEM) {
			if (memcount >= sizeof(mem_reg_property)/sizeof(uint32_t))
				continue;
			mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.start);
			mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.size);
		} else if (atag->hdr.tag == ATAG_INITRD2) {
			uint32_t initrd_start, initrd_size;
			initrd_start = atag->u.initrd.start;
			initrd_size = atag->u.initrd.size;
			setprop_cell(fdt, "/chosen", "linux,initrd-start",
					initrd_start);
			setprop_cell(fdt, "/chosen", "linux,initrd-end",
					initrd_start + initrd_size);
		}
	}

	if (memcount)
		setprop(fdt, "/memory", "reg", mem_reg_property, 4*memcount);

	return fdt_pack(fdt);
}
예제 #6
0
static void nop_region(void *start, int len)
{
	uint32_t *p;

	for (p = start; (void *)p < (start + len); p++)
		*p = cpu_to_fdt32(FDT_NOP);
}
예제 #7
0
struct data data_append_integer(struct data d, uint64_t value, int bits)
{
	uint8_t value_8;
	uint16_t value_16;
	uint32_t value_32;
	uint64_t value_64;

	switch (bits) {
	case 8:
		value_8 = value;
		return data_append_data(d, &value_8, 1);

	case 16:
		value_16 = cpu_to_fdt16(value);
		return data_append_data(d, &value_16, 2);

	case 32:
		value_32 = cpu_to_fdt32(value);
		return data_append_data(d, &value_32, 4);

	case 64:
		value_64 = cpu_to_fdt64(value);
		return data_append_data(d, &value_64, 8);

	default:
		die("Invalid literal size (%d)\n", bits);
	}
}
예제 #8
0
파일: fdt_wip.c 프로젝트: 020gzh/linux
static void _fdt_nop_region(void *start, int len)
{
	fdt32_t *p;

	for (p = start; (char *)p < ((char *)start + len); p++)
		*p = cpu_to_fdt32(FDT_NOP);
}
예제 #9
0
void do_fixup_by_prop_u32(void *fdt,
			  const char *pname, const void *pval, int plen,
			  const char *prop, u32 val, int create)
{
	val = cpu_to_fdt32(val);
	do_fixup_by_prop(fdt, pname, pval, plen, prop, &val, 4, create);
}
예제 #10
0
파일: nexus.c 프로젝트: ChristosKa/freebsd
static int
nexus_ofw_map_intr(device_t dev, device_t child, phandle_t iparent, int icells,
    pcell_t *intr)
{
	fdt_pic_decode_t intr_decode;
	phandle_t intr_offset;
	int i, rv, interrupt, trig, pol;

	intr_offset = OF_xref_phandle(iparent);
	for (i = 0; i < icells; i++)
		intr[i] = cpu_to_fdt32(intr[i]);

	for (i = 0; fdt_pic_table[i] != NULL; i++) {
		intr_decode = fdt_pic_table[i];
		rv = intr_decode(intr_offset, intr, &interrupt, &trig, &pol);

		if (rv == 0) {
			/* This was recognized as our PIC and decoded. */
			interrupt = FDT_MAP_IRQ(intr_parent, interrupt);
			return (interrupt);
		}
	}

	/* Not in table, so guess */
	interrupt = FDT_MAP_IRQ(intr_parent, fdt32_to_cpu(intr[0]));

	return (interrupt);
}
예제 #11
0
int
intr_fdt_map_irq(phandle_t iparent, pcell_t *intr, int icells)
{
	fdt_pic_decode_t intr_decode;
	phandle_t intr_parent;
	int i, rv, interrupt, trig, pol;

	intr_parent = OF_node_from_xref(iparent);
	for (i = 0; i < icells; i++)
		intr[i] = cpu_to_fdt32(intr[i]);

	for (i = 0; fdt_pic_table[i] != NULL; i++) {
		intr_decode = fdt_pic_table[i];
		rv = intr_decode(intr_parent, intr, &interrupt, &trig, &pol);

		if (rv == 0) {
			/* This was recognized as our PIC and decoded. */
			interrupt = FDT_MAP_IRQ(intr_parent, interrupt);
			return (interrupt);
		}
	}

	/* Not in table, so guess */
	interrupt = FDT_MAP_IRQ(intr_parent, fdt32_to_cpu(intr[0]));

	return (interrupt);
}
예제 #12
0
파일: fdt_sw.c 프로젝트: 274914765/C
int fdt_finish(void *fdt)
{
    int err = check_header_sw(fdt);
    char *p = (char *)fdt;
    uint32_t *end;
    int oldstroffset, newstroffset;
    uint32_t tag;
    int offset, nextoffset;

    if (err)
        return err;

    /* Add terminator */
    end = grab_space(fdt, sizeof(*end));
    if (! end)
        return -FDT_ERR_NOSPACE;
    *end = cpu_to_fdt32(FDT_END);

    /* Relocate the string table */
    oldstroffset = fdt_totalsize(fdt) - fdt_size_dt_strings(fdt);
    newstroffset = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
    memmove(p + newstroffset, p + oldstroffset, fdt_size_dt_strings(fdt));
    fdt_set_off_dt_strings(fdt, newstroffset);

    /* Walk the structure, correcting string offsets */
    offset = 0;
    while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) {
        if (tag == FDT_PROP) {
            struct fdt_property *prop =
                fdt_offset_ptr_w(fdt, offset, sizeof(*prop));
            int nameoff;

            if (! prop)
                return -FDT_ERR_BADSTRUCTURE;

            nameoff = fdt32_to_cpu(prop->nameoff);
            nameoff += fdt_size_dt_strings(fdt);
            prop->nameoff = cpu_to_fdt32(nameoff);
        }
        offset = nextoffset;
    }

    /* Finally, adjust the header */
    fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt));
    fdt_set_magic(fdt, FDT_MAGIC);
    return 0;
}
예제 #13
0
파일: fdt_ro.c 프로젝트: ForayJones/iods
int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
{
	if ((phandle == 0) || (phandle == -1))
		return -FDT_ERR_BADPHANDLE;
	phandle = cpu_to_fdt32(phandle);
	return fdt_node_offset_by_prop_value(fdt, -1, "linux,phandle",
					     &phandle, sizeof(phandle));
}
예제 #14
0
/*
 * Increase u32 value at pos by offset
 */
static void
fdt_increase_u32(void *pos, uint32_t offset)
{
	uint32_t val;

	memcpy(&val, pos,  sizeof(val));
	val = cpu_to_fdt32(fdt32_to_cpu(val) + offset);
	memcpy(pos, &val, sizeof(val));
}
예제 #15
0
int fdt_finish(void *fdt)
{
	char *p = (char *)fdt;
	uint32_t *end;
	int oldstroffset, newstroffset;
	uint32_t tag;
	int offset, nextoffset;

	FDT_SW_CHECK_HEADER(fdt);

	
	end = _fdt_grab_space(fdt, sizeof(*end));
	if (! end)
		return -FDT_ERR_NOSPACE;
	*end = cpu_to_fdt32(FDT_END);

	
	oldstroffset = fdt_totalsize(fdt) - fdt_size_dt_strings(fdt);
	newstroffset = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
	memmove(p + newstroffset, p + oldstroffset, fdt_size_dt_strings(fdt));
	fdt_set_off_dt_strings(fdt, newstroffset);

	
	offset = 0;
	while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) {
		if (tag == FDT_PROP) {
			struct fdt_property *prop =
				_fdt_offset_ptr_w(fdt, offset);
			int nameoff;

			nameoff = fdt32_to_cpu(prop->nameoff);
			nameoff += fdt_size_dt_strings(fdt);
			prop->nameoff = cpu_to_fdt32(nameoff);
		}
		offset = nextoffset;
	}
	if (nextoffset < 0)
		return nextoffset;

	
	fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt));
	fdt_set_magic(fdt, FDT_MAGIC);
	return 0;
}
예제 #16
0
static int fdt_add_bignum(void *blob, int noffset, const char *prop_name,
			  BIGNUM *num, int num_bits)
{
	int nwords = num_bits / 32;
	int size;
	uint32_t *buf, *ptr;
	BIGNUM *tmp, *big2, *big32, *big2_32;
	BN_CTX *ctx;
	int ret;

	tmp = BN_new();
	big2 = BN_new();
	big32 = BN_new();
	big2_32 = BN_new();
	if (!tmp || !big2 || !big32 || !big2_32) {
		fprintf(stderr, "Out of memory (bignum)\n");
		return -ENOMEM;
	}
	ctx = BN_CTX_new();
	if (!tmp) {
		fprintf(stderr, "Out of memory (bignum context)\n");
		return -ENOMEM;
	}
	BN_set_word(big2, 2L);
	BN_set_word(big32, 32L);
	BN_exp(big2_32, big2, big32, ctx); /* B = 2^32 */

	size = nwords * sizeof(uint32_t);
	buf = malloc(size);
	if (!buf) {
		fprintf(stderr, "Out of memory (%d bytes)\n", size);
		return -ENOMEM;
	}

	/* Write out modulus as big endian array of integers */
	for (ptr = buf + nwords - 1; ptr >= buf; ptr--) {
		BN_mod(tmp, num, big2_32, ctx); /* n = N mod B */
		*ptr = cpu_to_fdt32(BN_get_word(tmp));
		BN_rshift(num, num, 32); /*  N = N/B */
	}

	/*
	 * We try signing with successively increasing size values, so this
	 * might fail several times
	 */
	ret = fdt_setprop(blob, noffset, prop_name, buf, size);
	if (ret)
		return -FDT_ERR_NOSPACE;
	free(buf);
	BN_free(tmp);
	BN_free(big2);
	BN_free(big32);
	BN_free(big2_32);

	return ret;
}
예제 #17
0
static int fdt_add_bignum(void *blob, int noffset, const char *prop_name,
			  BIGNUM *num, int num_bits)
{
	int nwords = num_bits / 32;
	int size;
	uint32_t *buf, *ptr;
	BIGNUM *tmp, *big2, *big32, *big2_32;
	BN_CTX *ctx;
	int ret;

	tmp = BN_new();
	big2 = BN_new();
	big32 = BN_new();
	big2_32 = BN_new();
	if (!tmp || !big2 || !big32 || !big2_32) {
		fprintf(stderr, "Out of memory (bignum)\n");
		return -ENOMEM;
	}
	ctx = BN_CTX_new();
	if (!tmp) {
		fprintf(stderr, "Out of memory (bignum context)\n");
		return -ENOMEM;
	}
	BN_set_word(big2, 2L);
	BN_set_word(big32, 32L);
	BN_exp(big2_32, big2, big32, ctx); /* B = 2^32 */

	size = nwords * sizeof(uint32_t);
	buf = malloc(size);
	if (!buf) {
		fprintf(stderr, "Out of memory (%d bytes)\n", size);
		return -ENOMEM;
	}

	/* Write out modulus as big endian array of integers */
	for (ptr = buf + nwords - 1; ptr >= buf; ptr--) {
		BN_mod(tmp, num, big2_32, ctx); /* n = N mod B */
		*ptr = cpu_to_fdt32(BN_get_word(tmp));
		BN_rshift(num, num, 32); /*  N = N/B */
	}

	ret = fdt_setprop(blob, noffset, prop_name, buf, size);
	if (ret) {
		fprintf(stderr, "Failed to write public key to FIT\n");
		return -ENOSPC;
	}
	free(buf);
	BN_free(tmp);
	BN_free(big2);
	BN_free(big32);
	BN_free(big2_32);

	return ret;
}
예제 #18
0
파일: fdt_address.c 프로젝트: 19Dan01/linux
static int __init fdt_bus_default_translate(__be32 *addr, u64 offset, int na)
{
	u64 a = of_read_number(addr, na);
	memset(addr, 0, na * 4);
	a += offset;
	if (na > 1)
		addr[na - 2] = cpu_to_fdt32(a >> 32);
	addr[na - 1] = cpu_to_fdt32(a & 0xffffffffu);

	return 0;
}
예제 #19
0
int fdt_property(void *fdt, const char *name, const void *val, int len)
{
	struct fdt_property *prop;
	int nameoff;

	FDT_SW_CHECK_HEADER(fdt);

	nameoff = _fdt_find_add_string(fdt, name);
	if (nameoff == 0)
		return -FDT_ERR_NOSPACE;

	prop = _fdt_grab_space(fdt, sizeof(*prop) + FDT_TAGALIGN(len));
	if (! prop)
		return -FDT_ERR_NOSPACE;

	prop->tag = cpu_to_fdt32(FDT_PROP);
	prop->nameoff = cpu_to_fdt32(nameoff);
	prop->len = cpu_to_fdt32(len);
	memcpy(prop->data, val, len);
	return 0;
}
예제 #20
0
파일: fdt.c 프로젝트: garyvan/openwrt-1.6
static void generate_virtio_mmio_node(void *fdt, struct virtio_mmio *vmmio)
{
	char dev_name[DEVICE_NAME_MAX_LEN];
	u64 addr = vmmio->addr;
	u64 reg_prop[] = {
		cpu_to_fdt64(addr),
		cpu_to_fdt64(VIRTIO_MMIO_IO_SIZE)
	};
	u32 irq_prop[] = {
		cpu_to_fdt32(GIC_FDT_IRQ_TYPE_SPI),
		cpu_to_fdt32(vmmio->irq - GIC_SPI_IRQ_BASE),
		cpu_to_fdt32(GIC_FDT_IRQ_FLAGS_EDGE_LO_HI),
	};

	snprintf(dev_name, DEVICE_NAME_MAX_LEN, "virtio@%llx", addr);

	_FDT(fdt_begin_node(fdt, dev_name));
	_FDT(fdt_property_string(fdt, "compatible", "virtio,mmio"));
	_FDT(fdt_property(fdt, "reg", reg_prop, sizeof(reg_prop)));
	_FDT(fdt_property(fdt, "interrupts", irq_prop, sizeof(irq_prop)));
	_FDT(fdt_end_node(fdt));
}
예제 #21
0
int fdt_end_node(void *fdt)
{
	uint32_t *en;

	FDT_SW_CHECK_HEADER(fdt);

	en = _fdt_grab_space(fdt, FDT_TAGSIZE);
	if (! en)
		return -FDT_ERR_NOSPACE;

	*en = cpu_to_fdt32(FDT_END_NODE);
	return 0;
}
예제 #22
0
파일: fdt_sw.c 프로젝트: 274914765/C
int fdt_property(void *fdt, const char *name, const void *val, int len)
{
    struct fdt_property *prop;
    int err = check_header_sw(fdt);
    int nameoff;

    if (err)
        return err;

    nameoff = find_add_string(fdt, name);
    if (nameoff == 0)
        return -FDT_ERR_NOSPACE;

    prop = grab_space(fdt, sizeof(*prop) + ALIGN(len, FDT_TAGSIZE));
    if (! prop)
        return -FDT_ERR_NOSPACE;

    prop->tag = cpu_to_fdt32(FDT_PROP);
    prop->nameoff = cpu_to_fdt32(nameoff);
    prop->len = cpu_to_fdt32(len);
    memcpy(prop->data, val, len);
    return 0;
}
예제 #23
0
파일: mc.c 프로젝트: Xilinx/u-boot-xlnx
static int mc_fixup_mac_addr(void *blob, int nodeoffset,
			     const char *propname, struct eth_device *eth_dev,
			     enum mc_fixup_type type)
{
	int err = 0, len = 0, size, i;
	unsigned char env_enetaddr[ARP_HLEN];
	unsigned int enetaddr_32[ARP_HLEN];
	void *val = NULL;

	switch (type) {
	case MC_FIXUP_DPL:
	/* DPL likes its addresses on 32 * ARP_HLEN bits */
	for (i = 0; i < ARP_HLEN; i++)
		enetaddr_32[i] = cpu_to_fdt32(eth_dev->enetaddr[i]);
	val = enetaddr_32;
	len = sizeof(enetaddr_32);
	break;

	case MC_FIXUP_DPC:
	val = eth_dev->enetaddr;
	len = ARP_HLEN;
	break;
	}

	/* MAC address property present */
	if (fdt_get_property(blob, nodeoffset, propname, NULL)) {
		/* u-boot MAC addr randomly assigned - leave the present one */
		if (!eth_env_get_enetaddr_by_index("eth", eth_dev->index,
						   env_enetaddr))
			return err;
	} else {
		size = MC_DT_INCREASE_SIZE + strlen(propname) + len;
		/* make room for mac address property */
		err = fdt_increase_size(blob, size);
		if (err) {
			printf("fdt_increase_size: err=%s\n",
			       fdt_strerror(err));
			return err;
		}
	}

	err = fdt_setprop(blob, nodeoffset, propname, val, len);
	if (err) {
		printf("fdt_setprop: err=%s\n", fdt_strerror(err));
		return err;
	}

	return err;
}
예제 #24
0
int fdt_begin_node(void *fdt, const char *name)
{
	struct fdt_node_header *nh;
	int namelen = strlen(name) + 1;

	FDT_SW_CHECK_HEADER(fdt);

	nh = _fdt_grab_space(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen));
	if (! nh)
		return -FDT_ERR_NOSPACE;

	nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
	memcpy(nh->name, name, namelen);
	return 0;
}
예제 #25
0
/*
 * fdt_pack_reg - pack address and size array into the "reg"-suitable stream
 */
static int fdt_pack_reg(const void *fdt, void *buf, u64 *address, u64 *size,
			int n)
{
	int i;
	int address_cells = fdt_address_cells(fdt, 0);
	int size_cells = fdt_size_cells(fdt, 0);
	char *p = buf;

	for (i = 0; i < n; i++) {
		if (address_cells == 2)
			*(fdt64_t *)p = cpu_to_fdt64(address[i]);
		else
			*(fdt32_t *)p = cpu_to_fdt32(address[i]);
		p += 4 * address_cells;

		if (size_cells == 2)
			*(fdt64_t *)p = cpu_to_fdt64(size[i]);
		else
			*(fdt32_t *)p = cpu_to_fdt32(size[i]);
		p += 4 * size_cells;
	}

	return p - (char *)buf;
}
예제 #26
0
파일: fdt_sw.c 프로젝트: 274914765/C
int fdt_end_node(void *fdt)
{
    uint32_t *en;
    int err = check_header_sw(fdt);

    if (err)
        return err;

    en = grab_space(fdt, FDT_TAGSIZE);
    if (! en)
        return -FDT_ERR_NOSPACE;

    *en = cpu_to_fdt32(FDT_END_NODE);
    return 0;
}
예제 #27
0
파일: fdt_sw.c 프로젝트: 274914765/C
int fdt_begin_node(void *fdt, const char *name)
{
    struct fdt_node_header *nh;
    int err = check_header_sw(fdt);
    int namelen = strlen(name) + 1;

    if (err)
        return err;

    nh = grab_space(fdt, sizeof(*nh) + ALIGN(namelen, FDT_TAGSIZE));
    if (! nh)
        return -FDT_ERR_NOSPACE;

    nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
    memcpy(nh->name, name, namelen);
    return 0;
}
static void __ft_tsec_fixup(void *blob, bd_t *bd, const char *alias,
			    int phy_addr)
{
	const char *phy_type = "sgmii";
	const u32 *ph;
	int off;
	int err;

	off = fdt_path_offset(blob, alias);
	if (off < 0) {
		printf("WARNING: could not find %s alias: %s.\n", alias,
			fdt_strerror(off));
		return;
	}

	err = fdt_setprop(blob, off, "phy-connection-type", phy_type,
			  strlen(phy_type) + 1);
	if (err) {
		printf("WARNING: could not set phy-connection-type for %s: "
			"%s.\n", alias, fdt_strerror(err));
		return;
	}

	ph = (u32 *)fdt_getprop(blob, off, "phy-handle", 0);
	if (!ph) {
		printf("WARNING: could not get phy-handle for %s.\n",
			alias);
		return;
	}

	off = fdt_node_offset_by_phandle(blob, *ph);
	if (off < 0) {
		printf("WARNING: could not get phy node for %s: %s\n", alias,
			fdt_strerror(off));
		return;
	}

	phy_addr = cpu_to_fdt32(phy_addr);
	err = fdt_setprop(blob, off, "reg", &phy_addr, sizeof(phy_addr));
	if (err < 0) {
		printf("WARNING: could not set phy node's reg for %s: "
			"%s.\n", alias, fdt_strerror(err));
		return;
	}
}
예제 #29
0
/* Get the value of a property of a package. */
static ssize_t
ofw_fdt_getprop(ofw_t ofw, phandle_t package, const char *propname, void *buf,
    size_t buflen)
{
	const void *prop;
	const char *name;
	int len, offset;
	uint32_t cpuid;

	offset = fdt_phandle_offset(package);
	if (offset < 0)
		return (-1);

	prop = fdt_getprop(fdtp, offset, propname, &len);

	if (prop == NULL && strcmp(propname, "name") == 0) {
		/* Emulate the 'name' property */
		name = fdt_get_name(fdtp, offset, &len);
		strncpy(buf, name, buflen);
		if (len + 1 > buflen)
			len = buflen;
		return (len + 1);
	}

	if (prop == NULL && offset == fdt_path_offset(fdtp, "/chosen")) {
		if (strcmp(propname, "fdtbootcpu") == 0) {
			cpuid = cpu_to_fdt32(fdt_boot_cpuid_phys(fdtp));
			len = sizeof(cpuid);
			prop = &cpuid;
		}
		if (strcmp(propname, "fdtmemreserv") == 0) {
			prop = (char *)fdtp + fdt_off_mem_rsvmap(fdtp);
			len = sizeof(uint64_t)*2*fdt_num_mem_rsv(fdtp);
		}
	}

	if (prop == NULL)
		return (-1);

	if (len > buflen)
		len = buflen;
	bcopy(prop, buf, len);
	return (len);
}
예제 #30
0
/*
 * Process one entry in __fixups__ { } node
 * @fixups is property value, array of NUL-terminated strings
 *   with fixup locations
 * @fixups_len length of the fixups array in bytes
 * @phandle is value for these locations
 */
static int
fdt_do_one_fixup(void *fdtp, const char *fixups, int fixups_len, int phandle)
{
	void *fixup_pos;
	uint32_t val;

	val = cpu_to_fdt32(phandle);

	while (fixups_len > 0) {
		fixup_pos = fdt_get_fixup_location(fdtp, fixups);
		if (fixup_pos != NULL)
			memcpy(fixup_pos, &val, sizeof(val));

		fixups_len -= strlen(fixups) + 1;
		fixups += strlen(fixups) + 1;
	}

	return (0);
}