⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flatdevtree.c

📁 xen 3.2.2 源码
💻 C
📖 第 1 页 / 共 2 页
字号:
static int is_printable_string(const void *data, int len){	const char *s = data;	const char *ss;	/* zero length is not */	if (len == 0)		return 0;	/* must terminate with zero */	if (s[len - 1] != '\0')		return 0;	ss = s;	while (*s && isprint(*s))		s++;	/* not zero, or not done yet */	if (*s != '\0' || (s + 1 - ss) < len)		return 0;	return 1;}static void print_data(const void *data, int len){	int i;	const char *s;	/* no data, don't print */	if (len == 0)		return;	if (is_printable_string(data, len)) {		printf(" = \"%s\"", (char *)data);		return;	}	switch (len) {	case 1:		/* byte */		printf(" = <0x%02x>", (*(char *) data) & 0xff);		break;	case 2:		/* half-word */		printf(" = <0x%04x>", be16_to_cpu(*(u16 *) data) & 0xffff);		break;	case 4:		/* word */		printf(" = <0x%08x>", be32_to_cpu(*(u32 *) data) & 0xffffffffU);		break;	case 8:		/* double-word */		printf(" = <0x%16llx>", be64_to_cpu(*(u64 *) data));		break;	default:		/* anything else... hexdump */		printf(" = [");		for (i = 0, s = data; i < len; i++)			printf("%02x%s", s[i], i < len - 1 ? " " : "");		printf("]");		break;	}}void ft_dump_blob(const void *bphp){	const struct boot_param_header *bph = bphp;	const u64 *p_rsvmap = (const u64 *)		((const char *)bph + be32_to_cpu(bph->off_mem_rsvmap));	const u32 *p_struct = (const u32 *)		((const char *)bph + be32_to_cpu(bph->off_dt_struct));	const u32 *p_strings = (const u32 *)		((const char *)bph + be32_to_cpu(bph->off_dt_strings));	const u32 version = be32_to_cpu(bph->version);	u32 i, *p, *tagp, *sizep;	char *namep, *datap;	int depth, shift;	u64 addr, size;	if (be32_to_cpu(bph->magic) != OF_DT_HEADER) {		/* not valid tree */		return;	}	depth = 0;	shift = 4;	for (i = 0;; i++) {		addr = be64_to_cpu(p_rsvmap[i * 2]);		size = be64_to_cpu(p_rsvmap[i * 2 + 1]);		if (addr == 0 && size == 0)			break;		printf("/memreserve/ 0x%llx 0x%llx;\n", addr, size);	}	p = (u32 *)p_struct;	while ((p = ft_next(p, p_strings, version, &tagp, &namep, &datap,					&sizep)) != NULL)		switch (be32_to_cpu(*tagp)) {		case OF_DT_BEGIN_NODE:			printf("%*s%s {\n", depth * shift, "", namep);			depth++;			break;		case OF_DT_END_NODE:			depth--;			printf("%*s};\n", depth * shift, "");			break;		case OF_DT_NOP:			printf("%*s[NOP]\n", depth * shift, "");			break;		case OF_DT_END:			break;		case OF_DT_PROP:			printf("%*s%s", depth * shift, "", namep);			print_data(datap, *sizep);			printf(";\n");			break;		default:			fprintf(stderr, "%*s ** Unknown tag 0x%08x\n",				depth * shift, "", *tagp);			return;		}}void ft_backtrack_node(struct ft_cxt *cxt){	if (be32_to_cpu(*(u32 *) (cxt->p - 4)) != OF_DT_END_NODE)		return;		/* XXX only for node */	cxt->p -= 4;}/* note that the root node of the blob is "peeled" off */void ft_merge_blob(struct ft_cxt *cxt, void *blob){	struct boot_param_header *bph = (struct boot_param_header *)blob;	u32 *p_struct = (u32 *) ((char *)bph + be32_to_cpu(bph->off_dt_struct));	u32 *p_strings =		(u32 *) ((char *)bph + be32_to_cpu(bph->off_dt_strings));	const u32 version = be32_to_cpu(bph->version);	u32 *p, *tagp, *sizep;	char *namep, *datap;	int depth;	if (be32_to_cpu(*(u32 *) (cxt->p - 4)) != OF_DT_END_NODE)		return;		/* XXX only for node */	cxt->p -= 4;	depth = 0;	p = p_struct;	while ((p = ft_next(p, p_strings, version, &tagp, &namep, &datap,					&sizep)) != NULL)		switch (be32_to_cpu(*tagp)) {		case OF_DT_BEGIN_NODE:			if (depth++ > 0)				ft_begin_node(cxt, namep);			break;		case OF_DT_END_NODE:			ft_end_node(cxt);			if (--depth == 0)				return;			break;		case OF_DT_PROP:			ft_prop(cxt, namep, datap, *sizep);			break;		}}/**********************************************************************/void *ft_find_node(const void *bphp, const char *srch_path){	const struct boot_param_header *bph = bphp;	u32 *p_struct = (u32 *)((char *)bph + be32_to_cpu(bph->off_dt_struct));	u32 *p_strings= (u32 *)((char *)bph + be32_to_cpu(bph->off_dt_strings));	u32 version = be32_to_cpu(bph->version);	u32 *p, *tagp, *sizep;	char *namep, *datap;	static char path[MAX_PATH_LEN];	path[0] = '\0';	p = p_struct;	while ((p = ft_next(p, p_strings, version, &tagp, &namep, &datap,					&sizep)) != NULL)		switch (be32_to_cpu(*tagp)) {		case OF_DT_BEGIN_NODE:			strcat(path, namep);			if (!strcmp(path, srch_path))				return tagp;			strcat(path, "/");			break;		case OF_DT_END_NODE:			ft_parentize(path, 1);			break;		}	return NULL;}int ft_get_prop(const void *bphp, const void *node, const char *propname,		void *buf, const unsigned int buflen){	const struct boot_param_header *bph = bphp;	u32 *p_strings= (u32 *)((char *)bph + be32_to_cpu(bph->off_dt_strings));	u32 version = be32_to_cpu(bph->version);	u32 *p, *tagp, *sizep, size;	char *namep, *datap;	int depth;	depth = 0;	p = (u32 *)node;	while ((p = ft_next(p, p_strings, version, &tagp, &namep, &datap,					&sizep)) != NULL)		switch (be32_to_cpu(*tagp)) {		case OF_DT_BEGIN_NODE:			depth++;			break;		case OF_DT_PROP:			if ((depth == 1) && !strcmp(namep, propname)) {				size = min(be32_to_cpu(*sizep), (u32)buflen);				memcpy(buf, datap, size);				return size;			}			break;		case OF_DT_END_NODE:			if (--depth <= 0)				return -1;			break;		}	return -1;}static void ft_modify_prop(void **bphpp, char *datap, u32 *old_prop_sizep,		const char *buf, const unsigned int buflen){	u32 old_prop_data_len, new_prop_data_len;	old_prop_data_len = _ALIGN(be32_to_cpu(*old_prop_sizep), 4);	new_prop_data_len = _ALIGN(buflen, 4);	/* Check if new prop data fits in old prop data area */	if (new_prop_data_len == old_prop_data_len) {		memcpy(datap, buf, buflen);		*old_prop_sizep = cpu_to_be32(buflen);	} else {		/* Need to alloc new area to put larger or smaller ft */		struct boot_param_header *old_bph = *bphpp, *new_bph;		u32 *old_tailp, *new_tailp, *new_datap;		u32 old_total_size, new_total_size, head_len, tail_len, diff, v;		old_total_size = be32_to_cpu(old_bph->totalsize);		head_len = (u32)(datap - (char *)old_bph);		tail_len = old_total_size - (head_len + old_prop_data_len);		old_tailp = (u32 *)(datap + old_prop_data_len);		new_total_size = head_len + new_prop_data_len + tail_len;		if (!(new_bph = malloc(new_total_size))) {			printf("Can't alloc space for new ft\n");			ft_exit(-ENOSPC);		}		new_datap = (u32 *)((char *)new_bph + head_len);		new_tailp = (u32 *)((char *)new_datap + new_prop_data_len);		memcpy(new_bph, *bphpp, head_len);		memcpy(new_datap, buf, buflen);		memcpy(new_tailp, old_tailp, tail_len);		*(new_datap - 2) = cpu_to_be32(buflen); /* Set prop size */		new_bph->totalsize = cpu_to_be32(new_total_size);		diff = new_prop_data_len - old_prop_data_len;		if (be32_to_cpu(old_bph->off_dt_strings)				> be32_to_cpu(old_bph->off_dt_struct)) {			v = be32_to_cpu(new_bph->off_dt_strings);			new_bph->off_dt_strings = cpu_to_be32(v + diff);		}		if (be32_to_cpu(old_bph->off_mem_rsvmap)				> be32_to_cpu(old_bph->off_dt_struct)) {			v = be32_to_cpu(new_bph->off_mem_rsvmap);			new_bph->off_mem_rsvmap = cpu_to_be32(v + diff);		}		ft_free(*bphpp, old_total_size);		*bphpp = new_bph;	}}/* * - Only modifies existing properties. * - The dev tree passed in may be freed and a new one allocated *   (and *bphpp set to location of new dev tree). */int ft_set_prop(void **bphpp, const void *node, const char *propname,		const void *buf, const unsigned int buflen){	struct boot_param_header *bph = *bphpp;	u32 *p_strings= (u32 *)((char *)bph + be32_to_cpu(bph->off_dt_strings));	u32 version = be32_to_cpu(bph->version);	u32 *p, *tagp, *sizep;	char *namep, *datap;	int depth;	depth = 0;	p = (u32 *)node;	while ((p = ft_next(p, p_strings, version, &tagp, &namep, &datap,					&sizep)) != NULL)		switch (be32_to_cpu(*tagp)) {		case OF_DT_BEGIN_NODE:			depth++;			break;		case OF_DT_PROP:			if ((depth == 1) && !strcmp(namep, propname)) {				ft_modify_prop(bphpp, datap, sizep, buf,						buflen);				return be32_to_cpu(*sizep);			}			break;		case OF_DT_END_NODE:			if (--depth <= 0)				return -1;			break;		}	return -1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -