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

📄 prom_init.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
			/* Primary Thread of non-boot cpu */			prom_printf("%x : starting cpu hw idx %x... ", cpuid, reg);			call_prom("start-cpu", 3, 0, node,				  secondary_hold, reg);			for (i = 0; (i < 100000000) && 			     (*acknowledge == ((unsigned long)-1)); i++ )				mb();			if (*acknowledge == reg)				prom_printf("done\n");			else				prom_printf("failed: %x\n", *acknowledge);		}#ifdef CONFIG_SMP		else			prom_printf("%x : boot cpu     %x\n", cpuid, reg);#endif /* CONFIG_SMP */		/* Reserve cpu #s for secondary threads.   They start later. */		cpuid += cpu_threads;	}	if (cpuid > NR_CPUS)		prom_printf("WARNING: maximum CPUs (" __stringify(NR_CPUS)			    ") exceeded: ignoring extras\n");	prom_debug("prom_hold_cpus: end...\n");}static void __init prom_init_client_services(unsigned long pp){	struct prom_t *_prom = &RELOC(prom);	/* Get a handle to the prom entry point before anything else */	RELOC(prom_entry) = pp;	/* get a handle for the stdout device */	_prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen"));	if (!PHANDLE_VALID(_prom->chosen))		prom_panic("cannot find chosen"); /* msg won't be printed :( */	/* get device tree root */	_prom->root = call_prom("finddevice", 1, 1, ADDR("/"));	if (!PHANDLE_VALID(_prom->root))		prom_panic("cannot find device tree root"); /* msg won't be printed :( */	_prom->mmumap = 0;}#ifdef CONFIG_PPC32/* * For really old powermacs, we need to map things we claim. * For that, we need the ihandle of the mmu. * Also, on the longtrail, we need to work around other bugs. */static void __init prom_find_mmu(void){	struct prom_t *_prom = &RELOC(prom);	phandle oprom;	char version[64];	oprom = call_prom("finddevice", 1, 1, ADDR("/openprom"));	if (!PHANDLE_VALID(oprom))		return;	if (prom_getprop(oprom, "model", version, sizeof(version)) <= 0)		return;	version[sizeof(version) - 1] = 0;	/* XXX might need to add other versions here */	if (strcmp(version, "Open Firmware, 1.0.5") == 0)		of_workarounds = OF_WA_CLAIM;	else if (strncmp(version, "FirmWorks,3.", 12) == 0) {		of_workarounds = OF_WA_CLAIM | OF_WA_LONGTRAIL;		call_prom("interpret", 1, 1, "dev /memory 0 to allow-reclaim");	} else		return;	_prom->memory = call_prom("open", 1, 1, ADDR("/memory"));	prom_getprop(_prom->chosen, "mmu", &_prom->mmumap,		     sizeof(_prom->mmumap));	if (!IHANDLE_VALID(_prom->memory) || !IHANDLE_VALID(_prom->mmumap))		of_workarounds &= ~OF_WA_CLAIM;		/* hmmm */}#else#define prom_find_mmu()#endifstatic void __init prom_init_stdout(void){	struct prom_t *_prom = &RELOC(prom);	char *path = RELOC(of_stdout_device);	char type[16];	u32 val;	if (prom_getprop(_prom->chosen, "stdout", &val, sizeof(val)) <= 0)		prom_panic("cannot find stdout");	_prom->stdout = val;	/* Get the full OF pathname of the stdout device */	memset(path, 0, 256);	call_prom("instance-to-path", 3, 1, _prom->stdout, path, 255);	val = call_prom("instance-to-package", 1, 1, _prom->stdout);	prom_setprop(_prom->chosen, "/chosen", "linux,stdout-package",		     &val, sizeof(val));	prom_printf("OF stdout device is: %s\n", RELOC(of_stdout_device));	prom_setprop(_prom->chosen, "/chosen", "linux,stdout-path",		     path, strlen(path) + 1);	/* If it's a display, note it */	memset(type, 0, sizeof(type));	prom_getprop(val, "device_type", type, sizeof(type));	if (strcmp(type, RELOC("display")) == 0)		prom_setprop(val, path, "linux,boot-display", NULL, 0);}static void __init prom_close_stdin(void){	struct prom_t *_prom = &RELOC(prom);	ihandle val;	if (prom_getprop(_prom->chosen, "stdin", &val, sizeof(val)) > 0)		call_prom("close", 1, 0, val);}static int __init prom_find_machine_type(void){	struct prom_t *_prom = &RELOC(prom);	char compat[256];	int len, i = 0;#ifdef CONFIG_PPC64	phandle rtas;	int x;#endif	/* Look for a PowerMac */	len = prom_getprop(_prom->root, "compatible",			   compat, sizeof(compat)-1);	if (len > 0) {		compat[len] = 0;		while (i < len) {			char *p = &compat[i];			int sl = strlen(p);			if (sl == 0)				break;			if (strstr(p, RELOC("Power Macintosh")) ||			    strstr(p, RELOC("MacRISC")))				return PLATFORM_POWERMAC;#ifdef CONFIG_PPC64			/* We must make sure we don't detect the IBM Cell			 * blades as pSeries due to some firmware issues,			 * so we do it here.			 */			if (strstr(p, RELOC("IBM,CBEA")) ||			    strstr(p, RELOC("IBM,CPBW-1.0")))				return PLATFORM_GENERIC;#endif /* CONFIG_PPC64 */			i += sl + 1;		}	}#ifdef CONFIG_PPC64	/* If not a mac, try to figure out if it's an IBM pSeries or any other	 * PAPR compliant platform. We assume it is if :	 *  - /device_type is "chrp" (please, do NOT use that for future	 *    non-IBM designs !	 *  - it has /rtas	 */	len = prom_getprop(_prom->root, "device_type",			   compat, sizeof(compat)-1);	if (len <= 0)		return PLATFORM_GENERIC;	if (strcmp(compat, RELOC("chrp")))		return PLATFORM_GENERIC;	/* Default to pSeries. We need to know if we are running LPAR */	rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));	if (!PHANDLE_VALID(rtas))		return PLATFORM_GENERIC;	x = prom_getproplen(rtas, "ibm,hypertas-functions");	if (x != PROM_ERROR) {		prom_printf("Hypertas detected, assuming LPAR !\n");		return PLATFORM_PSERIES_LPAR;	}	return PLATFORM_PSERIES;#else	return PLATFORM_GENERIC;#endif}static int __init prom_set_color(ihandle ih, int i, int r, int g, int b){	return call_prom("call-method", 6, 1, ADDR("color!"), ih, i, b, g, 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 void __init prom_check_displays(void){	char type[16], *path;	phandle node;	ihandle ih;	int i;	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	};	const unsigned char *clut;	prom_printf("Looking for displays\n");	for (node = 0; prom_next_node(&node); ) {		memset(type, 0, sizeof(type));		prom_getprop(node, "device_type", type, sizeof(type));		if (strcmp(type, RELOC("display")) != 0)			continue;		/* It seems OF doesn't null-terminate the path :-( */		path = RELOC(prom_scratch);		memset(path, 0, PROM_SCRATCH_SIZE);		/*		 * leave some room at the end of the path for appending extra		 * arguments		 */		if (call_prom("package-to-path", 3, 1, node, path,			      PROM_SCRATCH_SIZE-10) == PROM_ERROR)			continue;		prom_printf("found display   : %s, opening ... ", path);				ih = call_prom("open", 1, 1, path);		if (ih == 0) {			prom_printf("failed\n");			continue;		}		/* Success */		prom_printf("done\n");		prom_setprop(node, path, "linux,opened", NULL, 0);		/* Setup a usable color table when the appropriate		 * method is available. Should update this to set-colors */		clut = RELOC(default_colors);		for (i = 0; i < 32; i++, clut += 3)			if (prom_set_color(ih, i, clut[0], clut[1],					   clut[2]) != 0)				break;#ifdef CONFIG_LOGO_LINUX_CLUT224		clut = PTRRELOC(RELOC(logo_linux_clut224.clut));		for (i = 0; i < RELOC(logo_linux_clut224.clutsize); i++, clut += 3)			if (prom_set_color(ih, i + 32, clut[0], clut[1],					   clut[2]) != 0)				break;#endif /* CONFIG_LOGO_LINUX_CLUT224 */	}}/* Return (relocated) pointer to this much memory: moves initrd if reqd. */static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end,			      unsigned long needed, unsigned long align){	void *ret;	*mem_start = _ALIGN(*mem_start, align);	while ((*mem_start + needed) > *mem_end) {		unsigned long room, chunk;		prom_debug("Chunk exhausted, claiming more at %x...\n",			   RELOC(alloc_bottom));		room = RELOC(alloc_top) - RELOC(alloc_bottom);		if (room > DEVTREE_CHUNK_SIZE)			room = DEVTREE_CHUNK_SIZE;		if (room < PAGE_SIZE)			prom_panic("No memory for flatten_device_tree (no room)");		chunk = alloc_up(room, 0);		if (chunk == 0)			prom_panic("No memory for flatten_device_tree (claim failed)");		*mem_end = RELOC(alloc_top);	}	ret = (void *)*mem_start;	*mem_start += needed;	return ret;}#define dt_push_token(token, mem_start, mem_end) \	do { *((u32 *)make_room(mem_start, mem_end, 4, 4)) = token; } while(0)static unsigned long __init dt_find_string(char *str){	char *s, *os;	s = os = (char *)RELOC(dt_string_start);	s += 4;	while (s <  (char *)RELOC(dt_string_end)) {		if (strcmp(s, str) == 0)			return s - os;		s += strlen(s) + 1;	}	return 0;}/* * The Open Firmware 1275 specification states properties must be 31 bytes or * less, however not all firmwares obey this. Make it 64 bytes to be safe. */#define MAX_PROPERTY_NAME 64static void __init scan_dt_build_strings(phandle node,					 unsigned long *mem_start,					 unsigned long *mem_end){	char *prev_name, *namep, *sstart;	unsigned long soff;	phandle child;	sstart =  (char *)RELOC(dt_string_start);	/* get and store all property names */	prev_name = RELOC("");	for (;;) {		/* 64 is max len of name including nul. */		namep = make_room(mem_start, mem_end, MAX_PROPERTY_NAME, 1);		if (call_prom("nextprop", 3, 1, node, prev_name, namep) != 1) {			/* No more nodes: unwind alloc */			*mem_start = (unsigned long)namep;			break;		} 		/* skip "name" */ 		if (strcmp(namep, RELOC("name")) == 0) { 			*mem_start = (unsigned long)namep; 			prev_name = RELOC("name"); 			continue; 		}		/* get/create string entry */		soff = dt_find_string(namep);		if (soff != 0) {			*mem_start = (unsigned long)namep;			namep = sstart + soff;		} else {			/* Trim off some if we can */			*mem_start = (unsigned long)namep + strlen(namep) + 1;			RELOC(dt_string_end) = *mem_start;		}		prev_name = namep;	}	/* do all our children */	child = call_prom("child", 1, 1, node);	while (child != 0) {		scan_dt_build_strings(child, mem_start, mem_end);		child = call_prom("peer", 1, 1, child);	}}static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,					unsigned long *mem_end){	phandle child;	char *namep, *prev_name, *sstart, *p, *ep, *lp, *path;	unsigned long soff;	unsigned char *valp;	static char pname[MAX_PROPERTY_NAME];	int l, room;	dt_push_token(OF_DT_BEGIN_NODE, mem_start, mem_end);	/* get the node's full name */	namep = (char *)*mem_start;	room = *mem_end - *mem_start;	if (room > 255)		room = 255;	l = call_prom("package-to-path", 3, 1, node, namep, room);	if (l >= 0) {		/* Didn't fit?  Get more room. */		if (l >= room) {			if (l >= *mem_end - *mem_start)				namep = make_room(mem_start, mem_end, l+1, 1);			call_prom("package-to-path", 3, 1, node, namep, l);		}		namep[l] = '\0';		/* Fixup an Apple bug where they have bogus \0 chars in the		 * middle of the path in some properties, and extract		 * the unit name (everything after the last '/').		 */		for (lp = p = namep, ep = namep + l; p < ep; p++) {			if (*p == '/')				lp = namep;			else if (*p != 0)				*lp++ = *p;		}		*lp = 0;		*mem_start = _ALIGN((unsigned long)lp + 1, 4);	}	/* get it again for debugging */	path = RELOC(prom_scratch);	memset(path, 0, PROM_SCRATCH_SIZE);	call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);	/* get and store all properties */	prev_name = RELOC("");	sstart = (char *)RELOC(dt_string_start);	for (;;) {		if (call_prom("nextprop", 3, 1, node, prev_name,			      RELOC(pname)) != 1)			break; 		/* skip "name" */ 		if (strcmp(RELOC(pname), RELOC("name")) == 0) { 			prev_name = RELOC("name"); 			continue; 		}		/* find string offset */		soff = dt_find_string(RELOC(pname));		if (soff == 0) {			prom_printf("WARNING: Can't find string index for"				    " <%s>, node %s\n", RELOC(pname), path);			break;		}		prev_name = sstart + soff;		/* get length */		l = call_prom("getproplen", 2, 1, node, RELOC(pname));		/* sanity checks */		if (l == PROM_ERROR)			continue;		if (l > MAX_PROPERTY_LENGTH) {			prom_printf("WARNING: ignoring large property ");			/* It seems OF doesn't null-terminate the path :-( */			prom_printf("[%s] ", path);			prom_printf("%s length 0x%x\n", RELOC(pname), l);			continue;		}		/* push property head */		dt_push_token(OF_DT_PROP, mem_start, mem_end);		dt_push_token(l, mem_start, mem_end);		dt_push_token(soff, mem_start, mem_end);		/* push property content */		valp = make_room(mem_start, mem_end, l, 4);		call_prom("getprop", 4, 1, node, RELOC(pname), valp, l);

⌨️ 快捷键说明

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