iseries_setup.c

来自「是关于linux2.5.1的完全源码」· C语言 代码 · 共 823 行 · 第 1/2 页

C
823
字号
			++thisChunk;		}		++currDword;		currChunk += 64;	}	// main store size (in chunks) is	//   totalChunks - hptSizeChunks	// which should be equal to	//   nextPhysChunk	totalLpChunks = nextPhysChunk;}/* * Set up the variables that describe the cache line sizes * for this machine. */static void __init setup_iSeries_cache_sizes(void){	unsigned i,n;	iSeries_icache_line_size = xIoHriProcessorVpd[0].xInstCacheOperandSize;	iSeries_dcache_line_size = xIoHriProcessorVpd[0].xDataCacheOperandSize;	iSeries_icache_lines_per_page = PAGE_SIZE / iSeries_icache_line_size;	iSeries_dcache_lines_per_page = PAGE_SIZE / iSeries_dcache_line_size;	i = iSeries_icache_line_size;	n = 0;	while ((i=(i/2))) ++n;	iSeries_log_icache_line_size = n;	i = iSeries_dcache_line_size;	n = 0;	while ((i=(i/2))) ++n;	iSeries_log_dcache_line_size = n;	printk( "D-cache line size = %d  (log = %d)\n",			(unsigned)iSeries_dcache_line_size,			(unsigned)iSeries_log_dcache_line_size );	printk( "I-cache line size = %d  (log = %d)\n",			(unsigned)iSeries_icache_line_size,			(unsigned)iSeries_log_icache_line_size );}int piranha_simulator = 0;/* * Document me. */void __initiSeries_setup_arch(void){	void *	eventStack;	u32	procFreq;	u32	tbFreq;//	u32	evStackContigReal;//	u64	evStackReal;	/* Setup the Lp Event Queue */	/* Associate Lp Event Queue 0 with processor 0 *///	HvCallEvent_setLpEventQueueInterruptProc( 0, 0 );	/* Allocate a page for the Event Stack	 * The hypervisor wants the absolute real address, so	 * we subtract out the KERNELBASE and add in the	 * absolute real address of the kernel load area	 */	eventStack = alloc_bootmem_pages( LpEventStackSize );	memset( eventStack, 0, LpEventStackSize );	/* Invoke the hypervisor to initialize the event stack */	HvCallEvent_setLpEventStack( 0, eventStack, LpEventStackSize );	/* Initialize fields in our Lp Event Queue */	xItLpQueue.xHSlicEventStackPtr = 0;	xItLpQueue.xSlicEventStackPtr = (char *)eventStack;	xItLpQueue.xHSlicCurEventPtr = 0;	xItLpQueue.xSlicCurEventPtr = (char *)eventStack;	xItLpQueue.xHSlicLastValidEventPtr = 0;	xItLpQueue.xSlicLastValidEventPtr = (char *)eventStack +					(LpEventStackSize - LpEventMaxSize);	xItLpQueue.xIndex = 0;	if ( itLpNaca.xPirEnvironMode == 0 ) {		printk("Running on Piranha simulator\n");		piranha_simulator = 1;	}	// Compute processor frequency	procFreq = ( 0x40000000 / (xIoHriProcessorVpd[0].xProcFreq / 1600) );	procFreqHz = procFreq * 10000;	procFreqMhz = procFreq / 100;	procFreqMhzHundreths = procFreq - (procFreqMhz * 100 );	// Compute time base frequency	tbFreq = ( 0x40000000 / (xIoHriProcessorVpd[0].xTimeBaseFreq / 400) );	tbFreqHz = tbFreq * 10000;	tbFreqMhz = tbFreq / 100;	tbFreqMhzHundreths = tbFreq - (tbFreqMhz * 100 );	printk("Max  logical processors = %d\n",			itVpdAreas.xSlicMaxLogicalProcs );	printk("Max physical processors = %d\n",			itVpdAreas.xSlicMaxPhysicalProcs );	printk("Processor frequency = %lu.%02lu\n",			procFreqMhz,			procFreqMhzHundreths );	printk("Time base frequency = %lu.%02lu\n",			tbFreqMhz,			tbFreqMhzHundreths );	printk("Processor version = %x\n",			xIoHriProcessorVpd[0].xPVR );#ifdef CONFIG_PCI	/* Initialize the flight recorder, global bus map and pci memory table */	iSeries_pci_Initialize();	/* Setup the PCI controller list */	iSeries_build_hose_list();#endif /* CONFIG_PCI         *//*	// copy the command line parameter from the primary VSP	HvCallEvent_dmaToSp( cmd_line,			     2*64*1024,			     256,			     HvLpDma_Direction_RemoteToLocal );	mf_init();	viopath_init();*/}/* * int iSeries_show_percpuinfo() * * Description: *   This routine pretty-prints CPU information gathered from the VPD *   for use in /proc/cpuinfo * * Input(s): *  *buffer - Buffer into which CPU data is to be printed. * * Output(s): *  *buffer - Buffer with CPU data. * * Returns: *   The number of bytes copied into 'buffer' if OK, otherwise zero or less *   on error. */static intiSeries_show_percpuinfo(struct seq_file *m, int i){	seq_printf(m, "clock\t\t: %lu.%02luMhz\n",		procFreqMhz, procFreqMhzHundreths );//	seq_printf(m, "  processor clock\t\t: %ldMHz\n",//		((unsigned long)xIoHriProcessorVpd[0].xProcFreq)/1000000);	seq_printf(m, "time base\t: %lu.%02luMHz\n",		tbFreqMhz, tbFreqMhzHundreths );//	seq_printf(m, "  time base freq\t\t: %ldMHz\n",//		((unsigned long)xIoHriProcessorVpd[0].xTimeBaseFreq)/1000000);	seq_printf(m, "i-cache\t\t: %d\n",		iSeries_icache_line_size);	seq_printf(m, "d-cache\t\t: %d\n",		iSeries_dcache_line_size);	return 0;}static int iSeries_show_cpuinfo(struct seq_file *m){	seq_printf(m, "machine\t\t: iSeries Logical Partition\n");	return 0;}#ifndef CONFIG_PCI/* * Document me. * and Implement me. * If no Native I/O, do nothing routine. */ void __initiSeries_init_IRQ(void){	return;}#endif/* * Document me. * and Implement me. */intiSeries_get_irq(struct pt_regs *regs){/*	return (ppc4xx_pic_get_irq(regs));*/	/* -2 means ignore this interrupt */	return -2;}/* * Document me. */voidiSeries_restart(char *cmd){	mf_reboot();}/* * Document me. */voidiSeries_power_off(void){	mf_powerOff();}/* * Document me. */voidiSeries_halt(void){	mf_powerOff();}/* * Nothing to do here. */void __initiSeries_time_init(void){	/* Nothing to do */}/* * Set the RTC in the virtual service processor * This requires flowing LpEvents to the primary partition */int iSeries_set_rtc_time(unsigned long time){    mf_setRtcTime(time);    return 0;}/* * Get the RTC from the virtual service processor * This requires flowing LpEvents to the primary partition */unsigned long iSeries_get_rtc_time(void){    /* XXX - Implement me */    unsigned long time;    mf_getRtcTime(&time);    return (time);}/* * void __init iSeries_calibrate_decr() * * Description: *   This routine retrieves the internal processor frequency from the VPD, *   and sets up the kernel timer decrementer based on that value. * */void __initiSeries_calibrate_decr(void){	u32	freq;	u32	tbf;	struct Paca * paca;	/* Compute decrementer (and TB) frequency	 * in cycles/sec	 */	tbf = xIoHriProcessorVpd[0].xTimeBaseFreq / 16;	freq = 0x010000000;	freq = freq / tbf;		/* cycles / usec */	freq = freq * 1000000;		/* now in cycles/sec */	/* Set the amount to refresh the decrementer by.  This	 * is the number of decrementer ticks it takes for	 * 1/HZ seconds.	 */	/* decrementer_count = freq / HZ;	 * count_period_num = 1;	 * count_period_den = freq; */	if ( decr_overclock_set && !decr_overclock_proc0_set )		decr_overclock_proc0 = decr_overclock;	tb_ticks_per_jiffy = freq / HZ;	paca = (struct Paca *)mfspr(SPRG1);	paca->default_decr = tb_ticks_per_jiffy / decr_overclock_proc0;	tb_to_us = mulhwu_scale_factor(freq, 1000000);}void __initiSeries_progress( char * st, unsigned short code ){	printk( "Progress: [%04x] - %s\n", (unsigned)code, st );	if (code != 0xffff)	    mf_displayProgress( code );	else	    mf_clearSrc();}#ifdef CONFIG_PCI/* * unsigned int __init iSeries_build_hose_list() * * Description: *   This routine builds a list of the PCI host bridges that *   connect PCI buses either partially or fully owned by *   this guest partition * */unsigned int __init iSeries_build_hose_list ( ) {    struct pci_controller* hose;    struct iSeries_hose_arch_data* hose_data;    u64 hvRc;    u16 hvbusnum;    int LxBusNumber = 0;		/* Linux Bus number for grins */    /* Check to make sure the device probing will work on this iSeries Release. */    if(hvReleaseData.xVrmIndex !=3) {	printk("PCI: iSeries Lpar and Linux native PCI I/O code is incompatible.\n");	printk("PCI: A newer version of the Linux kernel is need for this iSeries release.\n");	return 0;    }    for (hvbusnum = 0; hvbusnum < 256; hvbusnum++) {  /* All PCI buses which could be owned by this guest partition will be numbered by the hypervisor between 1 & 255 */	hvRc = HvCallXm_testBus (hvbusnum);  /* Call the system hypervisor to query guest partition ownership status of this bus */	if (hvRc == 0) {  /* This bus is partially/fully owned by this guest partition */	    hose = (struct pci_controller*)pcibios_alloc_controller();  // Create the hose for this PCI bus	    hose->first_busno = LxBusNumber;	/* This just for debug.   pcibios will */	    hose->last_busno  = 0xff;		/* assign the bus numbers.             */	    hose->ops = &iSeries_pci_ops;	    /* Create the iSeries_arch_data for the hose and cache the HV bus number in it so that pci bios can build the global bus map */	    hose_data = (struct iSeries_hose_arch_data *) alloc_bootmem(sizeof(struct iSeries_hose_arch_data));	    memset(hose_data, 0, sizeof(*hose_data));	    hose->arch_data = (void *) hose_data;	    ((struct iSeries_hose_arch_data *)(hose->arch_data))->hvBusNumber = hvbusnum;	    LxBusNumber += 1;			/* Keep track for debug */	}    }    pci_assign_all_busses = 1;          /* Let Linux assign the bus numbers in pcibios_init */    return 0;}#endif /* CONFIG_PCI         */int iSeries_spread_lpevents( char * str ){	/* The parameter is the number of processors to share in processing lp events */	unsigned long i;	unsigned long val = simple_strtoul(str, NULL, 0 );	if ( ( val > 0 ) && ( val <= maxPacas ) ) {		for( i=1; i<val; ++i )			xPaca[i].lpQueuePtr = xPaca[0].lpQueuePtr;	}	else		printk("invalid spread_lpevents %ld\n", val);	return 1;}int iSeries_decr_overclock_proc0( char * str ){	unsigned long val = simple_strtoul(str, NULL, 0 );	if ( ( val >= 1 ) && ( val <= 48 ) ) {		decr_overclock_proc0_set = 1;		decr_overclock_proc0 = val;		printk("proc 0 decrementer overclock factor of %ld\n", val);	}	else {		printk("invalid proc 0 decrementer overclock factor of %ld\n", val);	}	return 1;}int iSeries_decr_overclock( char * str ){	unsigned long val = simple_strtoul( str, NULL, 0 );	if ( ( val >= 1 ) && ( val <= 48 ) ) {		decr_overclock_set = 1;		decr_overclock = val;		printk("decrementer overclock factor of %ld\n", val);	}	else {		printk("invalid decrementer overclock factor of %ld\n", val);	}	return 1;}__setup("spread_lpevents=", iSeries_spread_lpevents );__setup("decr_overclock_proc0=", iSeries_decr_overclock_proc0 );__setup("decr_overclock=", iSeries_decr_overclock );

⌨️ 快捷键说明

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