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

📄 prom.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 3 页
字号:
		 * On a CHRP we have an 8259 which is subordinate to		 * the openpic in the interrupt tree, but we want the		 * openpic's interrupt numbers offsetted, not the 8259's.		 * So we apply the offset if the controller is at the		 * root of the interrupt tree, i.e. has no interrupt-parent.		 * This doesn't cope with the general case of multiple		 * cascaded interrupt controllers, but then neither will		 * irq.c at the moment either.  -- paulus		 */		if (num_interrupt_controllers > 1 && ic != NULL		    && get_property(ic, "interrupt-parent", NULL) == NULL)			offset = 16;		np->intrs[i].line = irq[0] + offset;		if (n > 1)			np->intrs[i].sense = irq[1];		if (n > 2) {			printk("hmmm, got %d intr cells for %s:", n,			       np->full_name);			for (j = 0; j < n; ++j)				printk(" %d", irq[j]);			printk("\n");		}		ints += intrcells;	}	return mem_start;}/* * When BootX makes a copy of the device tree from the MacOS * Name Registry, it is in the format we use but all of the pointers * are offsets from the start of the tree. * This procedure updates the pointers. */void __initrelocate_nodes(void){	unsigned long base;	struct device_node *np;	struct property *pp;#define ADDBASE(x)	(x = (x)? ((typeof (x))((unsigned long)(x) + base)): 0)	base = (unsigned long) boot_infos + boot_infos->deviceTreeOffset;	allnodes = (struct device_node *)(base + 4);	for (np = allnodes; np != 0; np = np->allnext) {		ADDBASE(np->full_name);		ADDBASE(np->properties);		ADDBASE(np->parent);		ADDBASE(np->child);		ADDBASE(np->sibling);		ADDBASE(np->allnext);		for (pp = np->properties; pp != 0; pp = pp->next) {			ADDBASE(pp->name);			ADDBASE(pp->value);			ADDBASE(pp->next);		}	}}intprom_n_addr_cells(struct device_node* np){	int* ip;	do {		if (np->parent)			np = np->parent;		ip = (int *) get_property(np, "#address-cells", 0);		if (ip != NULL)			return *ip;	} while (np->parent);	/* No #address-cells property for the root node, default to 1 */	return 1;}intprom_n_size_cells(struct device_node* np){	int* ip;	do {		if (np->parent)			np = np->parent;		ip = (int *) get_property(np, "#size-cells", 0);		if (ip != NULL)			return *ip;	} while (np->parent);	/* No #size-cells property for the root node, default to 1 */	return 1;}static unsigned long __initmap_addr(struct device_node *np, unsigned long space, unsigned long addr){	int na;	unsigned int *ranges;	int rlen = 0;	unsigned int type;	type = (space >> 24) & 3;	if (type == 0)		return addr;	while ((np = np->parent) != NULL) {		if (strcmp(np->type, "pci") != 0)			continue;		/* PCI bridge: map the address through the ranges property */		na = prom_n_addr_cells(np);		ranges = (unsigned int *) get_property(np, "ranges", &rlen);		while ((rlen -= (na + 5) * sizeof(unsigned int)) >= 0) {			if (((ranges[0] >> 24) & 3) == type			    && ranges[2] <= addr			    && addr - ranges[2] < ranges[na+4]) {				/* ok, this matches, translate it */				addr += ranges[na+2] - ranges[2];				break;			}			ranges += na + 5;		}	}	return addr;}static unsigned long __initinterpret_pci_props(struct device_node *np, unsigned long mem_start,		    int naddrc, int nsizec){	struct address_range *adr;	struct pci_reg_property *pci_addrs;	int i, l, *ip;	pci_addrs = (struct pci_reg_property *)		get_property(np, "assigned-addresses", &l);	if (pci_addrs != 0 && l >= sizeof(struct pci_reg_property)) {		i = 0;		adr = (struct address_range *) mem_start;		while ((l -= sizeof(struct pci_reg_property)) >= 0) {			adr[i].space = pci_addrs[i].addr.a_hi;			adr[i].address = map_addr(np, pci_addrs[i].addr.a_hi,						  pci_addrs[i].addr.a_lo);			adr[i].size = pci_addrs[i].size_lo;			++i;		}		np->addrs = adr;		np->n_addrs = i;		mem_start += i * sizeof(struct address_range);	}	if (use_of_interrupt_tree)		return mem_start;	ip = (int *) get_property(np, "AAPL,interrupts", &l);	if (ip == 0 && np->parent)		ip = (int *) get_property(np->parent, "AAPL,interrupts", &l);	if (ip == 0)		ip = (int *) get_property(np, "interrupts", &l);	if (ip != 0) {		np->intrs = (struct interrupt_info *) mem_start;		np->n_intrs = l / sizeof(int);		mem_start += np->n_intrs * sizeof(struct interrupt_info);		for (i = 0; i < np->n_intrs; ++i) {			np->intrs[i].line = *ip++;			np->intrs[i].sense = 1;		}	}	return mem_start;}static unsigned long __initinterpret_dbdma_props(struct device_node *np, unsigned long mem_start,		      int naddrc, int nsizec){	struct reg_property *rp;	struct address_range *adr;	unsigned long base_address;	int i, l, *ip;	struct device_node *db;	base_address = 0;	for (db = np->parent; db != NULL; db = db->parent) {		if (!strcmp(db->type, "dbdma") && db->n_addrs != 0) {			base_address = db->addrs[0].address;			break;		}	}	rp = (struct reg_property *) get_property(np, "reg", &l);	if (rp != 0 && l >= sizeof(struct reg_property)) {		i = 0;		adr = (struct address_range *) mem_start;		while ((l -= sizeof(struct reg_property)) >= 0) {			adr[i].space = 2;			adr[i].address = rp[i].address + base_address;			adr[i].size = rp[i].size;			++i;		}		np->addrs = adr;		np->n_addrs = i;		mem_start += i * sizeof(struct address_range);	}	if (use_of_interrupt_tree)		return mem_start;	ip = (int *) get_property(np, "AAPL,interrupts", &l);	if (ip == 0)		ip = (int *) get_property(np, "interrupts", &l);	if (ip != 0) {		np->intrs = (struct interrupt_info *) mem_start;		np->n_intrs = l / sizeof(int);		mem_start += np->n_intrs * sizeof(struct interrupt_info);		for (i = 0; i < np->n_intrs; ++i) {			np->intrs[i].line = *ip++;			np->intrs[i].sense = 1;		}	}	return mem_start;}static unsigned long __initinterpret_macio_props(struct device_node *np, unsigned long mem_start,		      int naddrc, int nsizec){	struct reg_property *rp;	struct address_range *adr;	unsigned long base_address;	int i, l, *ip;	struct device_node *db;	base_address = 0;	for (db = np->parent; db != NULL; db = db->parent) {		if (!strcmp(db->type, "mac-io") && db->n_addrs != 0) {			base_address = db->addrs[0].address;			break;		}	}	rp = (struct reg_property *) get_property(np, "reg", &l);	if (rp != 0 && l >= sizeof(struct reg_property)) {		i = 0;		adr = (struct address_range *) mem_start;		while ((l -= sizeof(struct reg_property)) >= 0) {			adr[i].space = 2;			adr[i].address = rp[i].address + base_address;			adr[i].size = rp[i].size;			++i;		}		np->addrs = adr;		np->n_addrs = i;		mem_start += i * sizeof(struct address_range);	}	if (use_of_interrupt_tree)		return mem_start;	ip = (int *) get_property(np, "interrupts", &l);	if (ip == 0)		ip = (int *) get_property(np, "AAPL,interrupts", &l);	if (ip != 0) {		np->intrs = (struct interrupt_info *) mem_start;		np->n_intrs = l / sizeof(int);		for (i = 0; i < np->n_intrs; ++i) {			np->intrs[i].line = *ip++;			np->intrs[i].sense = 1;		}		mem_start += np->n_intrs * sizeof(struct interrupt_info);	}	return mem_start;}static unsigned long __initinterpret_isa_props(struct device_node *np, unsigned long mem_start,		    int naddrc, int nsizec){	struct isa_reg_property *rp;	struct address_range *adr;	int i, l, *ip;	rp = (struct isa_reg_property *) get_property(np, "reg", &l);	if (rp != 0 && l >= sizeof(struct isa_reg_property)) {		i = 0;		adr = (struct address_range *) mem_start;		while ((l -= sizeof(struct reg_property)) >= 0) {			adr[i].space = rp[i].space;			adr[i].address = rp[i].address				+ (adr[i].space? 0: _ISA_MEM_BASE);			adr[i].size = rp[i].size;			++i;		}		np->addrs = adr;		np->n_addrs = i;		mem_start += i * sizeof(struct address_range);	}	if (use_of_interrupt_tree)		return mem_start;	ip = (int *) get_property(np, "interrupts", &l);	if (ip != 0) {		np->intrs = (struct interrupt_info *) mem_start;		np->n_intrs = l / (2 * sizeof(int));		mem_start += np->n_intrs * sizeof(struct interrupt_info);		for (i = 0; i < np->n_intrs; ++i) {			np->intrs[i].line = *ip++;			np->intrs[i].sense = *ip++;		}	}	return mem_start;}static unsigned long __initinterpret_root_props(struct device_node *np, unsigned long mem_start,		     int naddrc, int nsizec){	struct address_range *adr;	int i, l, *ip;	unsigned int *rp;	int rpsize = (naddrc + nsizec) * sizeof(unsigned int);	rp = (unsigned int *) get_property(np, "reg", &l);	if (rp != 0 && l >= rpsize) {		i = 0;		adr = (struct address_range *) mem_start;		while ((l -= rpsize) >= 0) {			adr[i].space = (naddrc >= 2? rp[naddrc-2]: 2);			adr[i].address = rp[naddrc - 1];			adr[i].size = rp[naddrc + nsizec - 1];			++i;			rp += naddrc + nsizec;		}		np->addrs = adr;		np->n_addrs = i;		mem_start += i * sizeof(struct address_range);	}	if (use_of_interrupt_tree)		return mem_start;	ip = (int *) get_property(np, "AAPL,interrupts", &l);	if (ip == 0)		ip = (int *) get_property(np, "interrupts", &l);	if (ip != 0) {		np->intrs = (struct interrupt_info *) mem_start;		np->n_intrs = l / sizeof(int);		mem_start += np->n_intrs * sizeof(struct interrupt_info);		for (i = 0; i < np->n_intrs; ++i) {			np->intrs[i].line = *ip++;			np->intrs[i].sense = 1;		}	}	return mem_start;}/* * Work out the sense (active-low level / active-high edge) * of each interrupt from the device tree. */void __initprom_get_irq_senses(unsigned char *senses, int off, int max){	struct device_node *np;	int i, j;	/* default to level-triggered */	memset(senses, 1, max - off);	if (!use_of_interrupt_tree)		return;	for (np = allnodes; np != 0; np = np->allnext) {		for (j = 0; j < np->n_intrs; j++) {			i = np->intrs[j].line;			if (i >= off && i < max) {				if (np->intrs[j].sense == 1) {					senses[i-off] = (IRQ_SENSE_LEVEL |							IRQ_POLARITY_NEGATIVE);				} else {					senses[i-off] = (IRQ_SENSE_EDGE |							IRQ_POLARITY_POSITIVE);				}			}		}	}}/* * Construct and return a list of the device_nodes with a given name. */struct device_node *find_devices(const char *name){	struct device_node *head, **prevp, *np;	prevp = &head;	for (np = allnodes; np != 0; np = np->allnext) {		if (np->name != 0 && strcasecmp(np->name, name) == 0) {			*prevp = np;			prevp = &np->next;		}	}	*prevp = 0;	return head;}/* * Construct and return a list of the device_nodes with a given type. */struct device_node *find_type_devices(const char *type){	struct device_node *head, **prevp, *np;	prevp = &head;	for (np = allnodes; np != 0; np = np->allnext) {

⌨️ 快捷键说明

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