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 + -
显示快捷键?