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

📄 prom.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	struct pci_intr_map *imp;	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) {			/* XXX assumes PCI addresses mapped 1-1 to physical */			adr[i].space = pci_addrs[i].addr.a_hi;			adr[i].address = 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;	/*	 * If the pci host bridge has an interrupt-map property,	 * look for our node in it.	 */	if (np->parent != 0 && pci_addrs != 0	    && (imp = (struct pci_intr_map *)		get_property(np->parent, "interrupt-map", &ml)) != 0	    && (ip = (int *) get_property(np, "interrupts", &l)) != 0) {		unsigned int devfn = pci_addrs[0].addr.a_hi & 0xff00;		unsigned int cell_size;		struct device_node* np2;		/* This is hackish, but is only used for BootX booting */		cell_size = sizeof(struct pci_intr_map);		np2 = np->parent;		while(np2) {			if (device_is_compatible(np2, "uni-north")) {				cell_size += 4;				break;			}			np2 = np2->parent;		}		np->n_intrs = 0;		np->intrs = (struct interrupt_info *) mem_start;		for (i = 0; (ml -= cell_size) >= 0; ++i) {			if (imp->addr.a_hi == devfn) {				np->intrs[np->n_intrs].line = imp->intr;				np->intrs[np->n_intrs].sense = 0; /* FIXME */				++np->n_intrs;			}			imp = (struct pci_intr_map *)(((unsigned int)imp)				+ cell_size);		}		if (np->n_intrs == 0)			np->intrs = 0;		mem_start += np->n_intrs * sizeof(struct interrupt_info);		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 = 0;		}	}	return mem_start;}__initstatic unsigned longinterpret_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 = 0;			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 = 0;		}	}	return mem_start;}__initstatic unsigned longinterpret_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, keylargo, *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;			keylargo = device_is_compatible(db, "Keylargo");			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 = 0;			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;		if (_machine == _MACH_Pmac) {			/* for the iMac */			np->n_intrs = l / sizeof(int);			/* Hack for BootX on Core99 */			if (keylargo)				np->n_intrs = np->n_intrs/2;			for (i = 0; i < np->n_intrs; ++i) {				np->intrs[i].line = *ip++;				if (keylargo)					np->intrs[i].sense = *ip++;				else					np->intrs[i].sense = 0;			}		} else {			/* CHRP machines */			np->n_intrs = l / (2 * sizeof(int));			for (i = 0; i < np->n_intrs; ++i) {				np->intrs[i].line = openpic_to_irq(*ip++);				np->intrs[i].sense = *ip++;			}		}		mem_start += np->n_intrs * sizeof(struct interrupt_info);	}	return mem_start;}__initstatic unsigned longinterpret_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;}__initstatic unsigned longinterpret_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 = 0;			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 = 0;		}	}	return mem_start;}/* * Construct and return a list of the device_nodes with a given name. */__openfirmwarestruct 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. */__openfirmwarestruct device_node *find_type_devices(const char *type){	struct device_node *head, **prevp, *np;	prevp = &head;	for (np = allnodes; np != 0; np = np->allnext) {		if (np->type != 0 && strcasecmp(np->type, type) == 0) {			*prevp = np;			prevp = &np->next;		}	}	*prevp = 0;	return head;}/* Finds a device node given its PCI bus number, device number * and function number */__openfirmwarestruct device_node *find_pci_device_OFnode(unsigned char bus, unsigned char dev_fn){	struct device_node* np;	unsigned int *reg;	int l;		for (np = allnodes; np != 0; np = np->allnext) {		int in_macio = 0;		struct device_node* parent = np->parent;		while(parent) {			char *pname = (char *)get_property(parent, "name", &l);			if (pname && strcmp(pname, "mac-io") == 0) {				in_macio = 1;				break;			}			parent = parent->parent;		}		if (in_macio)			continue;		reg = (unsigned int *) get_property(np, "reg", &l);		if (reg == 0 || l < sizeof(struct reg_property))			continue;		if (((reg[0] >> 8) & 0xff) == dev_fn && ((reg[0] >> 16) & 0xff) == bus)			break;	}	return np;}/* * Returns all nodes linked together */__openfirmwarestruct device_node *find_all_nodes(void){	struct device_node *head, **prevp, *np;	prevp = &head;	for (np = allnodes; np != 0; np = np->allnext) {		*prevp = np;		prevp = &np->next;	}	*prevp = 0;	return head;}/* Checks if the given "compat" string matches one of the strings in * the device's "compatible" property */__openfirmwareintdevice_is_compatible(struct device_node *device, const char *compat){	const char* cp;	int cplen, l;	cp = (char *) get_property(device, "compatible", &cplen);	if (cp == NULL)		return 0;	while (cplen > 0) {		if (strncasecmp(cp, compat, strlen(compat)) == 0)			return 1;		l = strlen(cp) + 1;		cp += l;		cplen -= l;	}	return 0;}/* * Indicates whether the root node has a given value in its * compatible property. */__openfirmwareintmachine_is_compatible(const char *compat){	struct device_node *root;		root = find_path_device("/");	if (root == 0)		return 0;	return device_is_compatible(root, compat);}/* * Construct and return a list of the device_nodes with a given type * and compatible property. */__openfirmwarestruct device_node *find_compatible_devices(const char *type, const char *compat){	struct device_node *head, **prevp, *np;	prevp = &head;	for (np = allnodes; np != 0; np = np->allnext) {		if (type != NULL		    && !(np->type != 0 && strcasecmp(np->type, type) == 0))			continue;		if (device_is_compatible(np, compat)) {			*prevp = np;			prevp = &np->next;		}	}	*prevp = 0;	return head;}/* * Find the device_node with a given full_name. */__openfirmwarestruct device_node *find_path_device(const char *path){	struct device_node *np;	for (np = allnodes; np != 0; np = np->allnext)		if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0)			return np;	return NULL;}/* * Find the device_node with a given phandle. */__openfirmwarestruct device_node *find_phandle(phandle ph){	struct device_node *np;	for (np = allnodes; np != 0; np = np->allnext)		if (np->node == ph)			return np;	return NULL;}/* * Find a property with a given name for a given node * and return the value. */__openfirmwareunsigned char *get_property(struct device_node *np, const char *name, int *lenp){	struct property *pp;	for (pp = np->properties; pp != 0; pp = pp->next)		if (strcmp(pp->name, name) == 0) {			if (lenp != 0)				*lenp = pp->length;			return pp->value;		}	return 0;}#if 0__openfirmwarevoidprint_properties(struct device_node *np){	struct property *pp;	char *cp;

⌨️ 快捷键说明

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