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

📄 setup.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
 */static unsigned long __init build_iSeries_Memory_Map(void){	u32 loadAreaFirstChunk, loadAreaLastChunk, loadAreaSize;	u32 nextPhysChunk;	u32 hptFirstChunk, hptLastChunk, hptSizeChunks, hptSizePages;	u32 totalChunks,moreChunks;	u32 currChunk, thisChunk, absChunk;	u32 currDword;	u32 chunkBit;	u64 map;	struct MemoryBlock mb[32];	unsigned long numMemoryBlocks, curBlock;	/* Chunk size on iSeries is 256K bytes */	totalChunks = (u32)HvLpConfig_getMsChunks();	mschunks_alloc(totalChunks);	/*	 * Get absolute address of our load area	 * and map it to physical address 0	 * This guarantees that the loadarea ends up at physical 0	 * otherwise, it might not be returned by PLIC as the first	 * chunks	 */	loadAreaFirstChunk = (u32)addr_to_chunk(itLpNaca.xLoadAreaAddr);	loadAreaSize =  itLpNaca.xLoadAreaChunks;	/*	 * Only add the pages already mapped here.	 * Otherwise we might add the hpt pages	 * The rest of the pages of the load area	 * aren't in the HPT yet and can still	 * be assigned an arbitrary physical address	 */	if ((loadAreaSize * 64) > HvPagesToMap)		loadAreaSize = HvPagesToMap / 64;	loadAreaLastChunk = loadAreaFirstChunk + loadAreaSize - 1;	/*	 * TODO Do we need to do something if the HPT is in the 64MB load area?	 * This would be required if the itLpNaca.xLoadAreaChunks includes	 * the HPT size	 */	printk("Mapping load area - physical addr = 0000000000000000\n"		"                    absolute addr = %016lx\n",		chunk_to_addr(loadAreaFirstChunk));	printk("Load area size %dK\n", loadAreaSize * 256);	for (nextPhysChunk = 0; nextPhysChunk < loadAreaSize; ++nextPhysChunk)		mschunks_map.mapping[nextPhysChunk] =			loadAreaFirstChunk + nextPhysChunk;	/*	 * Get absolute address of our HPT and remember it so	 * we won't map it to any physical address	 */	hptFirstChunk = (u32)addr_to_chunk(HvCallHpt_getHptAddress());	hptSizePages = (u32)HvCallHpt_getHptPages();	hptSizeChunks = hptSizePages >>		(MSCHUNKS_CHUNK_SHIFT - HW_PAGE_SHIFT);	hptLastChunk = hptFirstChunk + hptSizeChunks - 1;	printk("HPT absolute addr = %016lx, size = %dK\n",			chunk_to_addr(hptFirstChunk), hptSizeChunks * 256);	/*	 * Determine if absolute memory has any	 * holes so that we can interpret the	 * access map we get back from the hypervisor	 * correctly.	 */	numMemoryBlocks = iSeries_process_mainstore_vpd(mb, 32);	/*	 * Process the main store access map from the hypervisor	 * to build up our physical -> absolute translation table	 */	curBlock = 0;	currChunk = 0;	currDword = 0;	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_lppaca()->shared_proc) {		ppc_md.idle_loop = iseries_shared_idle;		printk(KERN_DEBUG "Using shared processor idle loop\n");	} else {		ppc_md.idle_loop = iseries_dedicated_idle;		printk(KERN_DEBUG "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");}static void __init iSeries_progress(char * st, unsigned short code){	printk("Progress: [%04x] - %s\n", (unsigned)code, st);	mf_display_progress(code);}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);}static int __init iSeries_src_init(void){        /* clear the progress line */	if (firmware_has_feature(FW_FEATURE_ISERIES))		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_lppaca()->int_dword.fields.decr_int = 1;	ppc64_runlatch_on();	process_iSeries_events();}static void iseries_shared_idle(void){	while (1) {		tick_nohz_stop_sched_tick();		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();		tick_nohz_restart_sched_tick();		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) {		tick_nohz_stop_sched_tick();		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();		tick_nohz_restart_sched_tick();		preempt_enable_no_resched();		schedule();		preempt_disable();	}}static void __iomem *iseries_ioremap(phys_addr_t address, unsigned long size,				     unsigned long flags){	return (void __iomem *)address;}static void iseries_iounmap(volatile void __iomem *token){}static int __init iseries_probe(void){	unsigned long root = of_get_flat_dt_root();	if (!of_flat_dt_is_compatible(root, "IBM,iSeries"))		return 0;	hpte_init_iSeries();	/* iSeries does not support 16M pages */	cur_cpu_spec->cpu_features &= ~CPU_FTR_16M_PAGE;	return 1;}define_machine(iseries) {	.name		= "iSeries",	.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	= mf_reboot,	.power_off	= mf_power_off,	.halt		= mf_power_off,	.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,	.ioremap	= iseries_ioremap,	.iounmap	= iseries_iounmap,	/* XXX Implement enable_pmcs for iSeries */};void * __init iSeries_early_setup(void){	unsigned long phys_mem_size;	/* Identify CPU type. This is done again by the common code later	 * on but calling this function multiple times is fine.	 */	identify_cpu(0, mfspr(SPRN_PVR));	powerpc_firmware_features |= FW_FEATURE_ISERIES;	powerpc_firmware_features |= FW_FEATURE_LPAR;	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();	return (void *) __pa(build_flat_dt(phys_mem_size));}static void hvputc(char c){	if (c == '\n')		hvputc('\r');	HvCall_writeLogBuffer(&c, 1);}void __init udbg_init_iseries(void){	udbg_putc = hvputc;}

⌨️ 快捷键说明

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