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

📄 prom.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 5 页
字号:
		if (call_prom(RELOC("getprop"), 4, 1, node, 			     RELOC("tce-table-minsize"), &minsize, 			     sizeof(minsize)) < 0) {			minsize = 4UL << 20;		}		/* Even though we read what OF wants, we just set the table		 * size to 4 MB.  This is enough to map 2GB of PCI DMA space.		 * By doing this, we avoid the pitfalls of trying to DMA to		 * MMIO space and the DMA alias hole.		 */		minsize = 4UL << 20;		/* Align to the greater of the align or size */		align = (minalign < minsize) ? minsize : minalign;		/* Carve out storage for the TCE table. */		base = lmb_alloc(minsize, align);		if ( !base ) {			prom_print(RELOC("ERROR, cannot find space for TCE table.\n"));			prom_exit();		}		vbase = absolute_to_virt(base);		/* Save away the TCE table attributes for later use. */		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_struct *_naca = RELOC(naca);	struct paca_struct *_xPaca = PTRRELOC(&paca[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}#ifdef CONFIG_PPCDBGextern char *trace_names[];	/* defined in udbg.c -- need a better interface */static void parse_ppcdbg_optionlist(const char *cmd,				    const char *cmdend){	unsigned long offset = reloc_offset();	char **_trace_names = PTRRELOC(&trace_names[0]);	const char *all = RELOC("all");        struct naca_struct *_naca = RELOC(naca);	const char *p, *pend;	int onoff, i, cmdidx;	unsigned long mask;	char cmdbuf[30];	for (p = cmd, pend = strchr(p, ',');	     p < cmdend;	     pend = strchr(p, ',')) {		if (pend == NULL || pend > cmdend)			pend = cmdend;		onoff = 1;	/* default */		if (*p == '+' || *p == '-') {			/* explicit on or off */			onoff = (*p == '+');			p++;		}		/* parse out p..pend here */		if (pend - p < sizeof(cmdbuf)) {			strncpy(cmdbuf, p, pend - p);			cmdbuf[pend - p] = '\0';			for (cmdidx = -1, i = 0; i < PPCDBG_NUM_FLAGS; i++) {				if (_trace_names[i] &&				    (strcmp(PTRRELOC(_trace_names[i]), cmdbuf) == 0)) {					cmdidx = i;					break;				}			}			mask = 0;			if (cmdidx >= 0) {				mask = (1 << cmdidx);			} else if (strcmp(cmdbuf, all) == 0) {				mask = PPCDBG_ALL;			} else {				prom_print(RELOC("ppcdbg: unknown debug: "));				prom_print(cmdbuf);				prom_print_nl();			}			if (mask) {				if (onoff)					_naca->debug_switch |= mask;				else					_naca->debug_switch &= ~mask;			}		}		p = pend+1;	}}/* * Parse ppcdbg= cmdline option. * * Option names are listed in <asm/ppcdebug.h> in the trace_names * table.  Multiple names may be listed separated by commas (no whitespace), * 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 naca_struct   *_naca = RELOC(naca);	struct paca_struct *_xPaca = PTRRELOC(&paca[0]);	struct prom_t *_prom = PTRRELOC(&prom);	char *_cmd_line = PTRRELOC(&cmd_line[0]);	/* Default machine type. */	_naca->platform = PLATFORM_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();

⌨️ 快捷键说明

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