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

📄 prom.c

📁 是关于linux2.5.1的完全源码
💻 C
📖 第 1 页 / 共 5 页
字号:
		prom_tce_table[table].node = node;		prom_tce_table[table].base = vbase;		prom_tce_table[table].size = minsize;#ifdef DEBUG_PROM		prom_print(RELOC("TCE table: 0x"));		prom_print_hex(table);		prom_print_nl();		prom_print(RELOC("\tnode = 0x"));		prom_print_hex(node);		prom_print_nl();		prom_print(RELOC("\tbase = 0x"));		prom_print_hex(vbase);		prom_print_nl();		prom_print(RELOC("\tsize = 0x"));		prom_print_hex(minsize);		prom_print_nl();#endif		/* Initialize the table to have a one-to-one mapping		 * over the allocated size.		 */		tce_entryp = (unsigned long *)base;		for (i = 0; i < (minsize >> 3) ;tce_entryp++, i++) {			tce_entry = (i << PAGE_SHIFT);			tce_entry |= 0x3;			*tce_entryp = tce_entry;		}		/* Call OF to setup the TCE hardware */		if (call_prom(RELOC("package-to-path"), 3, 1, node,                             path, 255) <= 0) {                        prom_print(RELOC("package-to-path failed\n"));                } else {                        prom_print(RELOC("opened "));                        prom_print(path);                        prom_print_nl();                }                phb_node = (ihandle)call_prom(RELOC("open"), 1, 1, path);                if ( (long)phb_node <= 0) {                        prom_print(RELOC("open failed\n"));                } else {                        prom_print(RELOC("open success\n"));                }                call_prom(RELOC("call-method"), 6, 0,                             RELOC("set-64-bit-addressing"),			     phb_node,			     -1,                             minsize,                              base & 0xffffffff,                             (base >> 32) & 0xffffffff);                call_prom(RELOC("close"), 1, 0, phb_node);		table++;	}	/* Flag the first invalid entry */	prom_tce_table[table].node = 0;#ifdef DEBUG_PROM	prom_print(RELOC("ending prom_initialize_tce_table\n"));#endif}/* * With CHRP SMP we need to use the OF to start the other * processors so we can't wait until smp_boot_cpus (the OF is * trashed by then) so we have to put the processors into * a holding pattern controlled by the kernel (not OF) before * we destroy the OF. * * This uses a chunk of low memory, puts some holding pattern * code there and sends the other processors off to there until * smp_boot_cpus tells them to do something.  The holding pattern * checks that address until its cpu # is there, when it is that * cpu jumps to __secondary_start().  smp_boot_cpus() takes care * of setting those values. * * We also use physical address 0x4 here to tell when a cpu * is in its holding pattern code. * * Fixup comment... DRENG / PPPBBB - Peter * * -- Cort */static voidprom_hold_cpus(unsigned long mem){	unsigned long i;	unsigned int reg;	phandle node;	unsigned long offset = reloc_offset();	char type[64], *path;	int cpuid = 0;	extern void __secondary_hold(void);        extern unsigned long __secondary_hold_spinloop;        extern unsigned long __secondary_hold_acknowledge;        unsigned long *spinloop     = __v2a(&__secondary_hold_spinloop);        unsigned long *acknowledge  = __v2a(&__secondary_hold_acknowledge);        unsigned long secondary_hold = (unsigned long)__v2a(*PTRRELOC((unsigned long *)__secondary_hold));        struct Naca *_naca = RELOC(naca);	struct Paca *_xPaca = PTRRELOC(&xPaca[0]);	struct prom_t *_prom = PTRRELOC(&prom);	/* Initially, we must have one active CPU. */	_naca->processorCount = 1;#ifdef DEBUG_PROM	prom_print(RELOC("prom_hold_cpus: start...\n"));	prom_print(RELOC("    1) spinloop       = 0x"));	prom_print_hex(spinloop);	prom_print_nl();	prom_print(RELOC("    1) *spinloop      = 0x"));	prom_print_hex(*spinloop);	prom_print_nl();	prom_print(RELOC("    1) acknowledge    = 0x"));	prom_print_hex(acknowledge);	prom_print_nl();	prom_print(RELOC("    1) *acknowledge   = 0x"));	prom_print_hex(*acknowledge);	prom_print_nl();	prom_print(RELOC("    1) secondary_hold = 0x"));	prom_print_hex(secondary_hold);	prom_print_nl();#endif        /* Set the common spinloop variable, so all of the secondary cpus	 * will block when they are awakened from their OF spinloop.	 * This must occur for both SMP and non SMP kernels, since OF will	 * be trashed when we move the kernel.         */        *spinloop = 0;#ifdef CONFIG_HMT	for (i=0; i < NR_CPUS; i++) {		RELOC(hmt_thread_data)[i].pir = 0xdeadbeef;	}#endif	/* look for cpus */	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("cpu")) != 0)			continue;		/* Skip non-configured cpus. */		call_prom(RELOC("getprop"), 4, 1, node, RELOC("status"),			  type, sizeof(type));		if (strcmp(type, RELOC("okay")) != 0)			continue;                reg = -1;		call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"),			  &reg, sizeof(reg));		/* Only need to start secondary procs, not ourself. */		if ( reg == _prom->cpu )			continue;		path = (char *) mem;		memset(path, 0, 256);		if ((long) call_prom(RELOC("package-to-path"), 3, 1,				     node, path, 255) < 0)			continue;		cpuid++;#ifdef DEBUG_PROM		prom_print_nl();		prom_print(RELOC("cpuid        = 0x"));		prom_print_hex(cpuid);		prom_print_nl();		prom_print(RELOC("cpu hw idx   = 0x"));		prom_print_hex(reg);		prom_print_nl();#endif		_xPaca[cpuid].xHwProcNum = reg;		prom_print(RELOC("starting cpu "));		prom_print(path);		/* Init the acknowledge var which will be reset by		 * the secondary cpu when it awakens from its OF		 * spinloop.		 */		*acknowledge = (unsigned long)-1;#ifdef DEBUG_PROM		prom_print(RELOC("    3) spinloop       = 0x"));		prom_print_hex(spinloop);		prom_print_nl();		prom_print(RELOC("    3) *spinloop      = 0x"));		prom_print_hex(*spinloop);		prom_print_nl();		prom_print(RELOC("    3) acknowledge    = 0x"));		prom_print_hex(acknowledge);		prom_print_nl();		prom_print(RELOC("    3) *acknowledge   = 0x"));		prom_print_hex(*acknowledge);		prom_print_nl();		prom_print(RELOC("    3) secondary_hold = 0x"));		prom_print_hex(secondary_hold);		prom_print_nl();		prom_print(RELOC("    3) cpuid = 0x"));		prom_print_hex(cpuid);		prom_print_nl();#endif		call_prom(RELOC("start-cpu"), 3, 0, node, secondary_hold, cpuid);		prom_print(RELOC("..."));		for ( i = 0 ; (i < 100000000) && 			      (*acknowledge == ((unsigned long)-1)); i++ ) ;#ifdef DEBUG_PROM		{			unsigned long *p = 0x0;			prom_print(RELOC("    4) 0x0 = 0x"));			prom_print_hex(*p);			prom_print_nl();		}#endif		if (*acknowledge == cpuid) {			prom_print(RELOC("ok\n"));			/* Set the number of active processors. */			_naca->processorCount++;		} else {			prom_print(RELOC("failed: "));			prom_print_hex(*acknowledge);			prom_print_nl();		}	}#ifdef CONFIG_HMT	/* Only enable HMT on processors that provide support. */	if (__is_processor(PV_PULSAR) || 	    __is_processor(PV_ICESTAR) ||	    __is_processor(PV_SSTAR)) {		prom_print(RELOC("    starting secondary threads\n"));		for (i=0; i < _naca->processorCount ;i++) {			unsigned long threadid = _naca->processorCount*2-1-i;						if (i == 0) {				unsigned long pir = _get_PIR();				if (__is_processor(PV_PULSAR)) {					RELOC(hmt_thread_data)[i].pir = 						pir & 0x1f;				} else {					RELOC(hmt_thread_data)[i].pir = 						pir & 0x3ff;				}			}						RELOC(hmt_thread_data)[i].threadid = threadid;#ifdef DEBUG_PROM			prom_print(RELOC("        cpuid 0x"));			prom_print_hex(i);			prom_print(RELOC(" maps to threadid 0x"));			prom_print_hex(threadid);			prom_print_nl();			prom_print(RELOC(" pir 0x"));			prom_print_hex(RELOC(hmt_thread_data)[i].pir);			prom_print_nl();#endif			_xPaca[threadid].xHwProcNum = _xPaca[i].xHwProcNum+1;		}		_naca->processorCount *= 2;	} else {		prom_print(RELOC("Processor is not HMT capable\n"));	}#endif	#ifdef DEBUG_PROM	prom_print(RELOC("prom_hold_cpus: end...\n"));#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;	char *p, *d; 	unsigned long phys;        u32 getprop_rval;        struct Naca   *_naca = RELOC(naca);	struct Paca *_xPaca = PTRRELOC(&xPaca[0]);	struct prom_t *_prom = PTRRELOC(&prom);	/* Default machine type. */	RELOC(_machine) = _MACH_pSeries;	/* Reset klimit to take into account the embedded system map */	if (RELOC(embedded_sysmap_end))		RELOC(klimit) = __va(PAGE_ALIGN(RELOC(embedded_sysmap_end)));	/* 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;#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];		long sz;		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 = prom_instantiate_rtas(mem);                /* 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;

⌨️ 快捷键说明

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