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

📄 prom.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
 * and each option may be preceeded by a + or - to force on or off state. * The special option "all" may also be used.  They are processed strictly * left to right.  Multiple ppcdbg= options are the command line are treated * as a single option list. * * Examples:  ppcdbg=phb_init,buswalk *            ppcdbg=all,-mm,-tce * * ToDo: add "group" names that map to common combinations of flags. */void parse_ppcdbg_cmd_line(const char *line){	unsigned long offset = reloc_offset();	const char *ppcdbgopt = RELOC("ppcdbg=");	struct naca_struct *_naca = RELOC(naca);	const char *cmd, *end;	_naca->debug_switch = PPC_DEBUG_DEFAULT; /* | PPCDBG_BUSWALK | PPCDBG_PHBINIT | PPCDBG_MM | PPCDBG_MMINIT | PPCDBG_TCEINIT | PPCDBG_TCE */	cmd = line;	while (cmd && (cmd = strstr(cmd, ppcdbgopt)) != NULL) {		cmd += 7;	/* skip ppcdbg= */		for (end = cmd;		     *end != '\0' && *end != '\t' && *end != ' ';		     end++)			; /* scan to whitespace or end */		parse_ppcdbg_optionlist(cmd, end);	}}#endif /* CONFIG_PPCDBG *//* * Do minimal cmd_line parsing for early boot options. */static void __initprom_parse_cmd_line(char *line){#ifdef CONFIG_PPCDBG	parse_ppcdbg_cmd_line(line);#endif}/* * We enter here early on, when the Open Firmware prom is still * handling exceptions and the MMU hash table for us. */unsigned long __initprom_init(unsigned long r3, unsigned long r4, unsigned long pp,	  unsigned long r6, unsigned long r7, yaboot_debug_t *yaboot){	int chrp = 0;	unsigned long mem;	ihandle prom_mmu, prom_op, prom_root, prom_cpu;	phandle cpu_pkg;	unsigned long offset = reloc_offset();	long l, sz;	char *p, *d; 	unsigned long phys;        u32 getprop_rval;        struct systemcfg *_systemcfg = RELOC(systemcfg);	struct paca_struct *_xPaca = PTRRELOC(&paca[0]);	struct prom_t *_prom = PTRRELOC(&prom);	char *_cmd_line = PTRRELOC(&cmd_line[0]);	/* Default machine type. */	_systemcfg->platform = PLATFORM_PSERIES;	/* Get a handle to the prom entry point before anything else */	_prom->entry = pp;	_prom->bi_recs = prom_bi_rec_verify((struct bi_record *)r6);	if ( _prom->bi_recs != NULL ) {		RELOC(klimit) = PTRUNRELOC((unsigned long)_prom->bi_recs + _prom->bi_recs->data[1]);	}#ifdef DEBUG_YABOOT	call_yaboot(yaboot->dummy,offset>>32,offset&0xffffffff);	call_yaboot(yaboot->printf, RELOC("offset = 0x%08x%08x\n"), LONG_MSW(offset), LONG_LSW(offset));#endif 	/* Default */ 	phys = KERNELBASE - offset;#ifdef DEBUG_YABOOT	call_yaboot(yaboot->printf, RELOC("phys = 0x%08x%08x\n"), LONG_MSW(phys), LONG_LSW(phys));#endif#ifdef DEBUG_YABOOT	_prom->yaboot = yaboot;	call_yaboot(yaboot->printf, RELOC("pp = 0x%08x%08x\n"), LONG_MSW(pp), LONG_LSW(pp));	call_yaboot(yaboot->printf, RELOC("prom = 0x%08x%08x\n"), LONG_MSW(_prom->entry), LONG_LSW(_prom->entry));#endif	/* First get a handle for the stdout device */	_prom->chosen = (ihandle)call_prom(RELOC("finddevice"), 1, 1,				       RELOC("/chosen"));#ifdef DEBUG_YABOOT	call_yaboot(yaboot->printf, RELOC("prom->chosen = 0x%08x%08x\n"), LONG_MSW(_prom->chosen), LONG_LSW(_prom->chosen));#endif	if ((long)_prom->chosen <= 0)		prom_exit();        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';        if (sz <=1 )                strcpy(_cmd_line,RELOC(CONFIG_CMDLINE));	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);	mem = check_display(mem);	prom_instantiate_rtas();                /* Initialize some system info into the Naca early... */        mem = prom_initialize_naca(mem);	smt_setup();        /* If we are on an SMP machine, then we *MUST* do the         * following, regardless of whether we have an SMP         * kernel or not.         */	prom_hold_cpus(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 (_systemcfg->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 */	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);}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 (;;) {

⌨️ 快捷键说明

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