コード例 #1
0
ファイル: irq.c プロジェクト: doniexun/bitthunder
BT_ERROR bt_of_irq_map_raw(struct bt_device_node *parent, const BT_be32 *intspec, BT_u32 ointsize,
						   const BT_be32 *addr, struct bt_of_irq *out_irq) {

	struct bt_device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
	const BT_be32 *tmp, *imap, *imask;
	BT_u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
	BT_u32 imaplen, match, i;

	ipar = bt_of_node_get(parent);

	do {
		tmp = bt_of_get_property(ipar, "#interrupt-cells", NULL);
		if(tmp) {
			intsize = bt_be32_to_cpu(*tmp);
			break;
		}
		tnode = ipar;
		ipar = bt_of_irq_find_parent(ipar);
		bt_of_node_put(tnode);
	} while(ipar);

	if(!ipar) {
		goto fail;
	}

	if(ointsize != intsize) {
		return BT_ERR_GENERIC;
	}

	old = bt_of_node_get(ipar);
	do {
		tmp = bt_of_get_property(old, "#address-cells", NULL);
		tnode = bt_of_get_parent(old);
		bt_of_node_put(old);
		old = tnode;
	} while(old && !tmp);

	bt_of_node_put(old);

	old = NULL;

	addrsize = (!tmp) ? 2 : bt_be32_to_cpu(*tmp);

	while(ipar) {
		if(bt_of_get_property(ipar, "interrupt-controller", NULL)) {
			for(i = 0; i < intsize; i++) {
				out_irq->specifier[i] = bt_of_read_number(intspec + i, 1);
				out_irq->size = intsize;
				out_irq->controller = ipar;
				bt_of_node_put(old);
				return BT_ERR_NONE;
			}
		}

		// look for interrupt map and parse.

		imap = bt_of_get_property(ipar, "interrupt-map", &imaplen);
		if(!imap) {
			newpar = bt_of_irq_find_parent(ipar);
			goto skiplevel;
		}

		imaplen /= sizeof(BT_u32);

		imask = bt_of_get_property(ipar, "interrupt-map-mask", NULL);

		if(!addr && addrsize != 0) {
			goto fail;
		}

		match = 0;
		while(imaplen > (addrsize + intsize + 1) && !match) {
			match = 1;
			for(i = 0; i < addrsize && match; ++i) {
				BT_be32 mask = imask ? imask[i] : bt_cpu_to_be32(0xffffffffu);
				match = ((addr[i] ^ imap[i]) & mask) == 0;
			}

			for(; i < (addrsize + intsize) && match; ++i) {
				BT_be32 mask = imask ? imask[i] : bt_cpu_to_be32(0xffffffffu);
				match = ((intspec[i-addrsize] ^ imap[i]) & mask) == 0;
			}

			imap += addrsize + intsize;
			imaplen -= addrsize + intsize;

			// Get the int parent.
			newpar = bt_of_find_node_by_phandle(bt_be32_to_cpu(*imap));
			imap++;
			--imaplen;

			if(!newpar) {
				goto fail;
			}

			tmp = bt_of_get_property(newpar, "#interrupt-cells", NULL);
			if(!tmp) {
				goto fail;
			}

			newintsize = bt_be32_to_cpu(*tmp);
			tmp = bt_of_get_property(newpar, "#address-cells", NULL);
			newaddrsize = (!tmp) ? 0 : bt_be32_to_cpu(*tmp);

			if(imaplen < (newaddrsize + newintsize)) {
				goto fail;
			}

			imap += newaddrsize + newintsize;
			imaplen -= newaddrsize + newintsize;
		}

		if(!match) {
			goto fail;
		}

		bt_of_node_put(old);
		old = bt_of_node_get(newpar);
		addrsize = newaddrsize;
		intsize = newintsize;
		intspec = imap - intsize;
		addr = intspec - addrsize;

	skiplevel:
		bt_of_node_put(ipar);
		ipar = newpar;
		newpar = NULL;
	}


fail:
	bt_of_node_put(ipar);
	bt_of_node_put(old);
	bt_of_node_put(newpar);

	return BT_ERR_GENERIC;
}
コード例 #2
0
ファイル: cmd_fdt.c プロジェクト: BitThunder/bootthunder
static int fdt_parse_property(BT_HANDLE hStdout, char **values, int count, char **data, int *len, int *bAllocated) {

	char *valp = values[0];
	int stridx = 0;
	*len = 0;
	*bAllocated = 0;

	if(values[0][0] == '<') {
		// Array of cells dec/hex
		// Assume data required == (count - 2) * 4 bytes + 8 for good measure.
		*data = BT_kMalloc((sizeof(BT_u32) * (count - 2)) + 8);
		*bAllocated = 1;

		char *dat = *data;

		valp++;
		while((stridx < count) && (*valp != '>')) {
			if(!*valp) {
				valp = values[++stridx];
				continue;
			}

			char *copy = valp;
			BT_u32 val = strtoul(valp, &valp, 0);
			*(BT_be32 *) dat = bt_cpu_to_be32(val);
			dat += 4;
			*len += 4;

			if((valp - copy) <= 0) {
				bt_fprintf(hStdout, "Could not convert \"%s\"\n", copy);
				return -1;
			}
		}

		if(*valp != '>') {
			bt_fprintf(hStdout, "Unexpected character %c\n", *valp);
			return -1;
		}
	} else if(values[0][0] == '[') {
		// Byte stream, (just hex)
		// Assume data required == (count - 2) * 1bytes, + 4 bytes for good measure
		*data = BT_kMalloc((sizeof(char) * (count - 2)) + 4);
		*bAllocated = 1;

		char *dat = *data;

		valp++;
		while((stridx < count) && (*valp != ']')) {
			if(!*valp) {
				valp = values[++stridx];
				continue;
			}

			if(!isxdigit((int)*valp)) {
				break;
			}

			int temp = strtoul(valp, &valp, 16);
			*dat++ = (char) (temp & 0xFF);
			*len    = *len + 1;
		}

		if(*valp != ']') {
			bt_fprintf(hStdout, "Unexpected character '%c'\n", *valp);
			return -1;
		}

	} else {
		// Assume a string to be copied directly to data!
		*data = values[0];
		*bAllocated = 0;
		*len += strlen(values[0]) + 1;
	}

	return 0;
}