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

📄 setup.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
	moreChunks = totalChunks;	while (moreChunks) {		map = HvCallSm_get64BitsOfAccessMap(itLpNaca.xLpIndex,				currDword);		thisChunk = currChunk;		while (map) {			chunkBit = map >> 63;			map <<= 1;			if (chunkBit) {				--moreChunks;				while (thisChunk >= mb[curBlock].logicalEnd) {					++curBlock;					if (curBlock >= numMemoryBlocks)						panic("out of memory blocks");				}				if (thisChunk < mb[curBlock].logicalStart)					panic("memory block error");				absChunk = mb[curBlock].absStart +					(thisChunk - mb[curBlock].logicalStart);				if (((absChunk < hptFirstChunk) ||				     (absChunk > hptLastChunk)) &&				    ((absChunk < loadAreaFirstChunk) ||				     (absChunk > loadAreaLastChunk))) {					mschunks_map.mapping[nextPhysChunk] =						absChunk;					++nextPhysChunk;				}			}			++thisChunk;		}		++currDword;		currChunk += 64;	}	/*	 * main store size (in chunks) is	 *   totalChunks - hptSizeChunks	 * which should be equal to	 *   nextPhysChunk	 */	return chunk_to_addr(nextPhysChunk);}/* * Document me. */static void __init iSeries_setup_arch(void){	if (get_paca()->lppaca.shared_proc) {		ppc_md.idle_loop = iseries_shared_idle;		printk(KERN_INFO "Using shared processor idle loop\n");	} else {		ppc_md.idle_loop = iseries_dedicated_idle;		printk(KERN_INFO "Using dedicated idle loop\n");	}	/* Setup the Lp Event Queue */	setup_hvlpevent_queue();	printk("Max  logical processors = %d\n",			itVpdAreas.xSlicMaxLogicalProcs);	printk("Max physical processors = %d\n",			itVpdAreas.xSlicMaxPhysicalProcs);}static void iSeries_show_cpuinfo(struct seq_file *m){	seq_printf(m, "machine\t\t: 64-bit iSeries Logical Partition\n");}/* * Document me. * and Implement me. */static int iSeries_get_irq(struct pt_regs *regs){	/* -2 means ignore this interrupt */	return -2;}/* * Document me. */static void iSeries_restart(char *cmd){	mf_reboot();}/* * Document me. */static void iSeries_power_off(void){	mf_power_off();}/* * Document me. */static void iSeries_halt(void){	mf_power_off();}static void __init iSeries_progress(char * st, unsigned short code){	printk("Progress: [%04x] - %s\n", (unsigned)code, st);	if (!piranha_simulator && mf_initialized) {		if (code != 0xffff)			mf_display_progress(code);		else			mf_clear_src();	}}static void __init iSeries_fixup_klimit(void){	/*	 * Change klimit to take into account any ram disk	 * that may be included	 */	if (naca.xRamDisk)		klimit = KERNELBASE + (u64)naca.xRamDisk +			(naca.xRamDiskSize * HW_PAGE_SIZE);	else {		/*		 * No ram disk was included - check and see if there		 * was an embedded system map.  Change klimit to take		 * into account any embedded system map		 */		if (embedded_sysmap_end)			klimit = KERNELBASE + ((embedded_sysmap_end + 4095) &					0xfffffffffffff000);	}}static int __init iSeries_src_init(void){        /* clear the progress line */        ppc_md.progress(" ", 0xffff);        return 0;}late_initcall(iSeries_src_init);static inline void process_iSeries_events(void){	asm volatile ("li 0,0x5555; sc" : : : "r0", "r3");}static void yield_shared_processor(void){	unsigned long tb;	HvCall_setEnabledInterrupts(HvCall_MaskIPI |				    HvCall_MaskLpEvent |				    HvCall_MaskLpProd |				    HvCall_MaskTimeout);	tb = get_tb();	/* Compute future tb value when yield should expire */	HvCall_yieldProcessor(HvCall_YieldTimed, tb+tb_ticks_per_jiffy);	/*	 * The decrementer stops during the yield.  Force a fake decrementer	 * here and let the timer_interrupt code sort out the actual time.	 */	get_paca()->lppaca.int_dword.fields.decr_int = 1;	process_iSeries_events();}static void iseries_shared_idle(void){	while (1) {		while (!need_resched() && !hvlpevent_is_pending()) {			local_irq_disable();			ppc64_runlatch_off();			/* Recheck with irqs off */			if (!need_resched() && !hvlpevent_is_pending())				yield_shared_processor();			HMT_medium();			local_irq_enable();		}		ppc64_runlatch_on();		if (hvlpevent_is_pending())			process_iSeries_events();		preempt_enable_no_resched();		schedule();		preempt_disable();	}}static void iseries_dedicated_idle(void){	set_thread_flag(TIF_POLLING_NRFLAG);	while (1) {		if (!need_resched()) {			while (!need_resched()) {				ppc64_runlatch_off();				HMT_low();				if (hvlpevent_is_pending()) {					HMT_medium();					ppc64_runlatch_on();					process_iSeries_events();				}			}			HMT_medium();		}		ppc64_runlatch_on();		preempt_enable_no_resched();		schedule();		preempt_disable();	}}#ifndef CONFIG_PCIvoid __init iSeries_init_IRQ(void) { }#endifstatic int __init iseries_probe(int platform){	return PLATFORM_ISERIES_LPAR == platform;}struct machdep_calls __initdata iseries_md = {	.setup_arch	= iSeries_setup_arch,	.show_cpuinfo	= iSeries_show_cpuinfo,	.init_IRQ	= iSeries_init_IRQ,	.get_irq	= iSeries_get_irq,	.init_early	= iSeries_init_early,	.pcibios_fixup	= iSeries_pci_final_fixup,	.restart	= iSeries_restart,	.power_off	= iSeries_power_off,	.halt		= iSeries_halt,	.get_boot_time	= iSeries_get_boot_time,	.set_rtc_time	= iSeries_set_rtc_time,	.get_rtc_time	= iSeries_get_rtc_time,	.calibrate_decr	= generic_calibrate_decr,	.progress	= iSeries_progress,	.probe		= iseries_probe,	/* XXX Implement enable_pmcs for iSeries */};struct blob {	unsigned char data[PAGE_SIZE];	unsigned long next;};struct iseries_flat_dt {	struct boot_param_header header;	u64 reserve_map[2];	struct blob dt;	struct blob strings;};struct iseries_flat_dt iseries_dt;void dt_init(struct iseries_flat_dt *dt){	dt->header.off_mem_rsvmap =		offsetof(struct iseries_flat_dt, reserve_map);	dt->header.off_dt_struct = offsetof(struct iseries_flat_dt, dt);	dt->header.off_dt_strings = offsetof(struct iseries_flat_dt, strings);	dt->header.totalsize = sizeof(struct iseries_flat_dt);	dt->header.dt_strings_size = sizeof(struct blob);	/* There is no notion of hardware cpu id on iSeries */	dt->header.boot_cpuid_phys = smp_processor_id();	dt->dt.next = (unsigned long)&dt->dt.data;	dt->strings.next = (unsigned long)&dt->strings.data;	dt->header.magic = OF_DT_HEADER;	dt->header.version = 0x10;	dt->header.last_comp_version = 0x10;	dt->reserve_map[0] = 0;	dt->reserve_map[1] = 0;}void dt_check_blob(struct blob *b){	if (b->next >= (unsigned long)&b->next) {		DBG("Ran out of space in flat device tree blob!\n");		BUG();	}}void dt_push_u32(struct iseries_flat_dt *dt, u32 value){	*((u32*)dt->dt.next) = value;	dt->dt.next += sizeof(u32);	dt_check_blob(&dt->dt);}void dt_push_u64(struct iseries_flat_dt *dt, u64 value){	*((u64*)dt->dt.next) = value;	dt->dt.next += sizeof(u64);	dt_check_blob(&dt->dt);}unsigned long dt_push_bytes(struct blob *blob, char *data, int len){	unsigned long start = blob->next - (unsigned long)blob->data;	memcpy((char *)blob->next, data, len);	blob->next = _ALIGN(blob->next + len, 4);	dt_check_blob(blob);	return start;}void dt_start_node(struct iseries_flat_dt *dt, char *name){	dt_push_u32(dt, OF_DT_BEGIN_NODE);	dt_push_bytes(&dt->dt, name, strlen(name) + 1);}#define dt_end_node(dt) dt_push_u32(dt, OF_DT_END_NODE)void dt_prop(struct iseries_flat_dt *dt, char *name, char *data, int len){	unsigned long offset;	dt_push_u32(dt, OF_DT_PROP);	/* Length of the data */	dt_push_u32(dt, len);	/* Put the property name in the string blob. */	offset = dt_push_bytes(&dt->strings, name, strlen(name) + 1);	/* The offset of the properties name in the string blob. */	dt_push_u32(dt, (u32)offset);	/* The actual data. */	dt_push_bytes(&dt->dt, data, len);}void dt_prop_str(struct iseries_flat_dt *dt, char *name, char *data){	dt_prop(dt, name, data, strlen(data) + 1); /* + 1 for NULL */}void dt_prop_u32(struct iseries_flat_dt *dt, char *name, u32 data){	dt_prop(dt, name, (char *)&data, sizeof(u32));}void dt_prop_u64(struct iseries_flat_dt *dt, char *name, u64 data){	dt_prop(dt, name, (char *)&data, sizeof(u64));}void dt_prop_u64_list(struct iseries_flat_dt *dt, char *name, u64 *data, int n){	dt_prop(dt, name, (char *)data, sizeof(u64) * n);}void dt_prop_empty(struct iseries_flat_dt *dt, char *name){	dt_prop(dt, name, NULL, 0);}void dt_cpus(struct iseries_flat_dt *dt){	unsigned char buf[32];	unsigned char *p;	unsigned int i, index;	struct IoHriProcessorVpd *d;	/* yuck */	snprintf(buf, 32, "PowerPC,%s", cur_cpu_spec->cpu_name);	p = strchr(buf, ' ');	if (!p) p = buf + strlen(buf);	dt_start_node(dt, "cpus");	dt_prop_u32(dt, "#address-cells", 1);	dt_prop_u32(dt, "#size-cells", 0);	for (i = 0; i < NR_CPUS; i++) {		if (paca[i].lppaca.dyn_proc_status >= 2)			continue;		snprintf(p, 32 - (p - buf), "@%d", i);		dt_start_node(dt, buf);		dt_prop_str(dt, "device_type", "cpu");		index = paca[i].lppaca.dyn_hv_phys_proc_index;		d = &xIoHriProcessorVpd[index];		dt_prop_u32(dt, "i-cache-size", d->xInstCacheSize * 1024);		dt_prop_u32(dt, "i-cache-line-size", d->xInstCacheOperandSize);		dt_prop_u32(dt, "d-cache-size", d->xDataL1CacheSizeKB * 1024);		dt_prop_u32(dt, "d-cache-line-size", d->xDataCacheOperandSize);		/* magic conversions to Hz copied from old code */		dt_prop_u32(dt, "clock-frequency",			((1UL << 34) * 1000000) / d->xProcFreq);		dt_prop_u32(dt, "timebase-frequency",			((1UL << 32) * 1000000) / d->xTimeBaseFreq);		dt_prop_u32(dt, "reg", i);		dt_end_node(dt);	}	dt_end_node(dt);}void build_flat_dt(struct iseries_flat_dt *dt, unsigned long phys_mem_size){	u64 tmp[2];	dt_init(dt);	dt_start_node(dt, "");	dt_prop_u32(dt, "#address-cells", 2);	dt_prop_u32(dt, "#size-cells", 2);	/* /memory */	dt_start_node(dt, "memory@0");	dt_prop_str(dt, "name", "memory");	dt_prop_str(dt, "device_type", "memory");	tmp[0] = 0;	tmp[1] = phys_mem_size;	dt_prop_u64_list(dt, "reg", tmp, 2);	dt_end_node(dt);	/* /chosen */	dt_start_node(dt, "chosen");	dt_prop_u32(dt, "linux,platform", PLATFORM_ISERIES_LPAR);	if (cmd_mem_limit)		dt_prop_u64(dt, "linux,memory-limit", cmd_mem_limit);	dt_end_node(dt);	dt_cpus(dt);	dt_end_node(dt);	dt_push_u32(dt, OF_DT_END);}void * __init iSeries_early_setup(void){	unsigned long phys_mem_size;	iSeries_fixup_klimit();	/*	 * Initialize the table which translate Linux physical addresses to	 * AS/400 absolute addresses	 */	phys_mem_size = build_iSeries_Memory_Map();	iSeries_get_cmdline();	/* Save unparsed command line copy for /proc/cmdline */	strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);	/* Parse early parameters, in particular mem=x */	parse_early_param();	build_flat_dt(&iseries_dt, phys_mem_size);	return (void *) __pa(&iseries_dt);}/* * On iSeries we just parse the mem=X option from the command line. * On pSeries it's a bit more complicated, see prom_init_mem() */static int __init early_parsemem(char *p){	if (p)		cmd_mem_limit = ALIGN(memparse(p, &p), PAGE_SIZE);	return 0;}early_param("mem", early_parsemem);

⌨️ 快捷键说明

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