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

📄 prom.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 5 页
字号:
        if ((long)call_prom(RELOC("getprop"), 4, 1, _prom->chosen,			    RELOC("stdout"), &getprop_rval,			    sizeof(getprop_rval)) <= 0)                prom_exit();        _prom->stdout = (ihandle)(unsigned long)getprop_rval;#ifdef DEBUG_YABOOT        if (_prom->stdout == 0) {	    call_yaboot(yaboot->printf, RELOC("prom->stdout = 0x%08x%08x\n"), LONG_MSW(_prom->stdout), LONG_LSW(_prom->stdout));        }	call_yaboot(yaboot->printf, RELOC("prom->stdout = 0x%08x%08x\n"), LONG_MSW(_prom->stdout), LONG_LSW(_prom->stdout));#endif#ifdef DEBUG_YABOOT	call_yaboot(yaboot->printf, RELOC("Location: 0x11\n"));#endif	mem = RELOC(klimit) - offset; #ifdef DEBUG_YABOOT	call_yaboot(yaboot->printf, RELOC("Location: 0x11b\n"));#endif	/* Get the full OF pathname of the stdout device */	p = (char *) mem;	memset(p, 0, 256);	call_prom(RELOC("instance-to-path"), 3, 1, _prom->stdout, p, 255);	RELOC(of_stdout_device) = PTRUNRELOC(p);	mem += strlen(p) + 1;	getprop_rval = 1;	prom_root = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/"));	if (prom_root != (ihandle)-1) {                call_prom(RELOC("getprop"), 4, 1,                    prom_root, RELOC("#size-cells"),		    &getprop_rval, sizeof(getprop_rval));	}	_prom->encode_phys_size = (getprop_rval==1) ? 32 : 64;	/* Fetch the cmd_line */	sz = (long)call_prom(RELOC("getprop"), 4, 1, _prom->chosen,			    RELOC("bootargs"), _cmd_line,			    sizeof(cmd_line)-1);	if (sz > 0)		_cmd_line[sz] = '\0';	prom_parse_cmd_line(_cmd_line);#ifdef DEBUG_PROM	prom_print(RELOC("DRENG:    Detect OF version...\n"));#endif	/* Find the OF version */	prom_op = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/openprom"));	if (prom_op != (ihandle)-1) {		char model[64];		sz = (long)call_prom(RELOC("getprop"), 4, 1, prom_op,				    RELOC("model"), model, 64);		if (sz > 0) {			char *c;			/* hack to skip the ibm chrp firmware # */			if ( strncmp(model,RELOC("IBM"),3) ) {				for (c = model; *c; c++)					if (*c >= '0' && *c <= '9') {						_prom->version = *c - '0';						break;					}			}			else				chrp = 1;		}	}	if (_prom->version >= 3)		prom_print(RELOC("OF Version 3 detected.\n"));	/* Determine which cpu is actually running right _now_ */        if ((long)call_prom(RELOC("getprop"), 4, 1, _prom->chosen,			    RELOC("cpu"), &getprop_rval,			    sizeof(getprop_rval)) <= 0)                prom_exit();	prom_cpu = (ihandle)(unsigned long)getprop_rval;	cpu_pkg = call_prom(RELOC("instance-to-package"), 1, 1, prom_cpu);	call_prom(RELOC("getprop"), 4, 1,		cpu_pkg, RELOC("reg"),		&getprop_rval, sizeof(getprop_rval));	_prom->cpu = (int)(unsigned long)getprop_rval;	_xPaca[0].xHwProcNum = _prom->cpu;#ifdef DEBUG_PROM  	prom_print(RELOC("Booting CPU hw index = 0x"));  	prom_print_hex(_prom->cpu);  	prom_print_nl();#endif	/* Get the boot device and translate it to a full OF pathname. */	p = (char *) mem;	l = (long) call_prom(RELOC("getprop"), 4, 1, _prom->chosen,			    RELOC("bootpath"), p, 1<<20);	if (l > 0) {		p[l] = 0;	/* should already be null-terminated */		RELOC(bootpath) = PTRUNRELOC(p);		mem += l + 1;		d = (char *) mem;		*d = 0;		call_prom(RELOC("canon"), 3, 1, p, d, 1<<20);		RELOC(bootdevice) = PTRUNRELOC(d);		mem = DOUBLEWORD_ALIGN(mem + strlen(d) + 1);	}	mem = prom_initialize_lmb(mem);	mem = prom_bi_rec_reserve(mem);	prom_instantiate_rtas();                /* Initialize some system info into the Naca early... */        mem = prom_initialize_naca(mem);        /* If we are on an SMP machine, then we *MUST* do the         * following, regardless of whether we have an SMP         * kernel or not.         */        if ( _naca->processorCount > 1 )	        prom_hold_cpus(mem);	mem = check_display(mem);#ifdef DEBUG_PROM	prom_print(RELOC("copying OF device tree...\n"));#endif	mem = copy_device_tree(mem);	RELOC(klimit) = mem + offset;	lmb_reserve(0, __pa(RELOC(klimit)));	if (_naca->platform == PLATFORM_PSERIES)		prom_initialize_tce_table(); 	if ((long) call_prom(RELOC("getprop"), 4, 1,				_prom->chosen,				RELOC("mmu"),				&getprop_rval,				sizeof(getprop_rval)) <= 0) {			prom_print(RELOC(" no MMU found\n"));                prom_exit();	}	/* We assume the phys. address size is 3 cells */	RELOC(prom_mmu) = (ihandle)(unsigned long)getprop_rval;	if ((long)call_prom(RELOC("call-method"), 4, 4,				RELOC("translate"),				prom_mmu,				(void *)(KERNELBASE - offset),				(void *)1) != 0) {		prom_print(RELOC(" (translate failed) "));	} else {		prom_print(RELOC(" (translate ok) "));		phys = (unsigned long)_prom->args.rets[3];	}	/* If OpenFirmware version >= 3, then use quiesce call */	if (_prom->version >= 3) {		prom_print(RELOC("Calling quiesce ...\n"));		call_prom(RELOC("quiesce"), 0, 0);		phys = KERNELBASE - offset;	}	prom_print(RELOC("returning from prom_init\n"));	return phys;}static intprom_set_color(ihandle ih, int i, int r, int g, int b){	unsigned long offset = reloc_offset();	return (int)(long)call_prom(RELOC("call-method"), 6, 1,		                    RELOC("color!"),                                    ih,                                    (void *)(long) i,                                    (void *)(long) b,                                    (void *)(long) g,                                    (void *)(long) r );}/* * If we have a display that we don't know how to drive, * we will want to try to execute OF's open method for it * later.  However, OF will probably fall over if we do that * we've taken over the MMU. * So we check whether we will need to open the display, * and if so, open it now. */static unsigned long __initcheck_display(unsigned long mem){	phandle node;	ihandle ih;	int i;	unsigned long offset = reloc_offset();        struct prom_t *_prom = PTRRELOC(&prom);	char type[64], *path;	static unsigned char default_colors[] = {		0x00, 0x00, 0x00,		0x00, 0x00, 0xaa,		0x00, 0xaa, 0x00,		0x00, 0xaa, 0xaa,		0xaa, 0x00, 0x00,		0xaa, 0x00, 0xaa,		0xaa, 0xaa, 0x00,		0xaa, 0xaa, 0xaa,		0x55, 0x55, 0x55,		0x55, 0x55, 0xff,		0x55, 0xff, 0x55,		0x55, 0xff, 0xff,		0xff, 0x55, 0x55,		0xff, 0x55, 0xff,		0xff, 0xff, 0x55,		0xff, 0xff, 0xff	};	_prom->disp_node = 0;	for (node = 0; prom_next_node(&node); ) {		type[0] = 0;		call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"),			  type, sizeof(type));		if (strcmp(type, RELOC("display")) != 0)			continue;		/* It seems OF doesn't null-terminate the path :-( */		path = (char *) mem;		memset(path, 0, 256);		if ((long) call_prom(RELOC("package-to-path"), 3, 1,				    node, path, 255) < 0)			continue;		prom_print(RELOC("opening display "));		prom_print(path);		ih = (ihandle)call_prom(RELOC("open"), 1, 1, path);		if (ih == (ihandle)0 || ih == (ihandle)-1) {			prom_print(RELOC("... failed\n"));			continue;		}		prom_print(RELOC("... ok\n"));		if (_prom->disp_node == 0)			_prom->disp_node = (ihandle)(unsigned long)node;		/* Setup a useable color table when the appropriate		 * method is available. Should update this to set-colors */		for (i = 0; i < 32; i++)			if (prom_set_color(ih, i, RELOC(default_colors)[i*3],					   RELOC(default_colors)[i*3+1],					   RELOC(default_colors)[i*3+2]) != 0)				break;#ifdef CONFIG_FB		for (i = 0; i < LINUX_LOGO_COLORS; i++)			if (prom_set_color(ih, i + 32,					   RELOC(linux_logo_red)[i],					   RELOC(linux_logo_green)[i],					   RELOC(linux_logo_blue)[i]) != 0)				break;#endif /* CONFIG_FB */		/*		 * If this display is the device that OF is using for stdout,		 * move it to the front of the list.		 */		mem += strlen(path) + 1;		i = RELOC(prom_num_displays)++;		if (RELOC(of_stdout_device) != 0 && i > 0		    && strcmp(PTRRELOC(RELOC(of_stdout_device)), path) == 0) {			for (; i > 0; --i)				RELOC(prom_display_paths[i]) = RELOC(prom_display_paths[i-1]);		}		RELOC(prom_display_paths[i]) = PTRUNRELOC(path);		if (RELOC(prom_num_displays) >= FB_MAX)			break;	}	return DOUBLEWORD_ALIGN(mem);}voidvirt_irq_init(void){	int i;	for (i = 0; i < NR_IRQS; i++)		virt_irq_to_real_map[i] = UNDEFINED_IRQ;	for (i = 0; i < NR_HW_IRQS; i++)		real_irq_to_virt_map[i] = UNDEFINED_IRQ;}/* Create a mapping for a real_irq if it doesn't already exist. * Return the virtual irq as a convenience. */unsigned longvirt_irq_create_mapping(unsigned long real_irq){	unsigned long virq;	if (naca->interrupt_controller == IC_OPEN_PIC)		return real_irq;	/* no mapping for openpic (for now) */	virq = real_irq_to_virt(real_irq);	if (virq == UNDEFINED_IRQ) {		/* Assign a virtual IRQ number */		if (real_irq < NR_IRQS && virt_irq_to_real(real_irq) == UNDEFINED_IRQ) {			/* A 1-1 mapping will work. */			virq = real_irq;		} else {			while (last_virt_irq < NR_IRQS &&			       virt_irq_to_real(++last_virt_irq) != UNDEFINED_IRQ)				/* skip irq's in use */;			if (last_virt_irq >= NR_IRQS)				panic("Too many IRQs are required on this system.  NR_IRQS=%d\n", NR_IRQS);			virq = last_virt_irq;		}		virt_irq_to_real_map[virq] = real_irq;		real_irq_to_virt_map[real_irq] = virq;	}	return virq;}static int __initprom_next_node(phandle *nodep){	phandle node;	unsigned long offset = reloc_offset();	if ((node = *nodep) != 0	    && (*nodep = call_prom(RELOC("child"), 1, 1, node)) != 0)		return 1;	if ((*nodep = call_prom(RELOC("peer"), 1, 1, node)) != 0)		return 1;	for (;;) {		if ((node = call_prom(RELOC("parent"), 1, 1, node)) == 0)			return 0;		if ((*nodep = call_prom(RELOC("peer"), 1, 1, node)) != 0)			return 1;	}}/* * Make a copy of the device tree from the PROM. */static unsigned long __initcopy_device_tree(unsigned long mem_start){	phandle root;	unsigned long new_start;	struct device_node **allnextp;	unsigned long offset = reloc_offset();	unsigned long mem_end = mem_start + (8<<20);	root = call_prom(RELOC("peer"), 1, 1, (phandle)0);	if (root == (phandle)0) {		prom_print(RELOC("couldn't get device tree root\n"));		prom_exit();	}	allnextp = &RELOC(allnodes);	mem_start = DOUBLEWORD_ALIGN(mem_start);	new_start = inspect_node(root, 0, mem_start, mem_end, &allnextp);	*allnextp = 0;	return new_start;}__initstatic unsigned longinspect_node(phandle node, struct device_node *dad,	     unsigned long mem_start, unsigned long mem_end,	     struct device_node ***allnextpp){	int l;	phandle child;	struct device_node *np;	struct property *pp, **prev_propp;	char *prev_name, *namep;	unsigned char *valp;	unsigned long offset = reloc_offset();	np = (struct device_node *) mem_start;	mem_start += sizeof(struct device_node);	memset(np, 0, sizeof(*np));	np->node = node;	**allnextpp = PTRUNRELOC(np);	*allnextpp = &np->allnext;	if (dad != 0) {		np->parent = PTRUNRELOC(dad);		/* we temporarily use the `next' field as `last_child'. */		if (dad->next == 0)			dad->child = PTRUNRELOC(np);		else			dad->next->sibling = PTRUNRELOC(np);		dad->next = np;	}	/* get and store all properties */	prev_propp = &np->properties;	prev_name = RELOC("");	for (;;) {		pp = (struct property *) mem_start;		namep = (char *) (pp + 1);		pp->name = PTRUNRELOC(namep);		if ((long) call_prom(RELOC("nextprop"), 3, 1, node, prev_name,				    namep) <= 0)			break;		mem_start = DOUBLEWORD_ALIGN((unsigned long)namep + strlen(namep) + 1);		prev_name = namep;		valp = (unsigned char *) mem_start;		pp->value = PTRUNRELOC(valp);		pp->length = (int)(long)			call_prom(RELOC("getprop"), 4, 1, node, namep,				  valp, mem_end - mem_start);		if (pp->length < 0)			continue;		mem_start = DOUBLEWORD_ALIGN(mem_start + pp->length);		*prev_propp = PTRUNRELOC(pp);		prev_propp = &pp->next;	}	*prev_propp = 0;	/* get the node's full name */	l = (long) call_prom(RELOC("package-to-path"), 3, 1, node,			    (char *) mem_start, mem_end - mem_start);	if (l >= 0) {		np->full_name = PTRUNRELOC((char *) mem_start);		*(char *)(mem_start + l) = 0;		mem_start = DOUBLEWORD_ALIGN(mem_start + l + 1);	}	/* do all our children */	child = call_prom(RELOC("child"), 1, 1, node);	while (child != (phandle)0) {		mem_start = inspect_node(child, np, mem_start, mem_end,					 allnextpp);		child = call_prom(RELOC("peer"), 1, 1, child);	}	return mem_start;}/* * finish_device_tree is called once things are running normally * (i.e. with text and data mapped to the address they were linked at). * It traverses the device tree and fills in the name, type, * {n_}addrs and {n_}intrs fields of each node. */void __initfinish_device_tree(void){	unsigned long mem = klimit;	virt_irq_init();	mem = finish_node(allnodes, mem, NULL, 0, 0);	dev_tree_size = mem - (unsigned long) allnodes;	mem = _ALIGN(mem, PAGE_SIZE);	lmb_reserve(__pa(klimit), mem-klimit);	klimit = mem;	rtas.dev = find_devices("rtas");}static unsigned long __initfinish_node(struct device_node *np, unsigned long mem_start,	    interpret_func *ifunc, int naddrc, int nsizec){	struct device_node *child;	int *ip;	np->name = get_property(np, "name", 0);

⌨️ 快捷键说明

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