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

📄 smpboot.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
		/*		 * allow APs to start initializing.		 */		Dprintk("Before Callout %d.\n", cpu_id);		cpu_set(cpu_id, cpu_callout_map);		Dprintk("After Callout %d.\n", cpu_id);		/*		 * Wait 5s total for a response		 */		for (timeout = 0; timeout < 5000; timeout++) {			if (cpu_isset(cpu_id, cpu_callin_map))				break;	/* It has booted */			udelay(1000);		}		if (cpu_isset(cpu_id, cpu_callin_map)) {			/* number CPUs logically, starting from 1 (BSP is 0) */			Dprintk("OK.\n");		} else {			boot_status = 1;			printk("Not responding.\n");		}	} else		printk("IPI never delivered???\n");	if (send_status || boot_status) {		unmap_cpu_to_physid(cpu_id, phys_id);		cpu_clear(cpu_id, cpu_callout_map);		cpu_clear(cpu_id, cpu_callin_map);		cpu_clear(cpu_id, cpu_initialized);		cpucount--;	}}int __devinit __cpu_up(unsigned int cpu_id){	int timeout;	cpu_set(cpu_id, smp_commenced_mask);	/*	 * Wait 5s total for a response	 */	for (timeout = 0; timeout < 5000; timeout++) {		if (cpu_isset(cpu_id, cpu_online_map))			break;		udelay(1000);	}	if (!cpu_isset(cpu_id, cpu_online_map))		BUG();	return 0;}void __init smp_cpus_done(unsigned int max_cpus){	int cpu_id, timeout;	unsigned long bogosum = 0;	for (timeout = 0; timeout < 5000; timeout++) {		if (cpus_equal(cpu_callin_map, cpu_online_map))			break;		udelay(1000);	}	if (!cpus_equal(cpu_callin_map, cpu_online_map))		BUG();	for (cpu_id = 0 ; cpu_id < num_online_cpus() ; cpu_id++)		show_cpu_info(cpu_id);	/*	 * Allow the user to impress friends.	 */	Dprintk("Before bogomips.\n");	if (cpucount) {		for_each_cpu_mask(cpu_id, cpu_online_map)			bogosum += cpu_data[cpu_id].loops_per_jiffy;		printk(KERN_INFO "Total of %d processors activated " \			"(%lu.%02lu BogoMIPS).\n", cpucount + 1,			bogosum / (500000 / HZ),			(bogosum / (5000 / HZ)) % 100);		Dprintk("Before bogocount - setting activated=1.\n");	}}/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*//* Activate a secondary processor Routins                                    *//*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*//*==========================================================================* * Name:         start_secondary * * Description:  This routine activate a secondary processor. * * Born on Date: 2002.02.05 * * Arguments:    *unused - currently unused. * * Returns:      void (cannot fail) * * Modification log: * Date       Who Description * ---------- --- -------------------------------------------------------- * 2003-06-24 hy  modify for linux-2.5.69 * *==========================================================================*/int __init start_secondary(void *unused){	cpu_init();	preempt_disable();	smp_callin();	while (!cpu_isset(smp_processor_id(), smp_commenced_mask))		cpu_relax();	smp_online();	/*	 * low-memory mappings have been cleared, flush them from	 * the local TLBs too.	 */	local_flush_tlb_all();	cpu_idle();	return 0;}/*==========================================================================* * Name:         smp_callin * * Description:  This routine activate a secondary processor. * * Born on Date: 2002.02.05 * * Arguments:    NONE * * Returns:      void (cannot fail) * * Modification log: * Date       Who Description * ---------- --- -------------------------------------------------------- * 2003-06-24 hy  modify for linux-2.5.69 * *==========================================================================*/static void __init smp_callin(void){	int phys_id = hard_smp_processor_id();	int cpu_id = smp_processor_id();	unsigned long timeout;	if (cpu_isset(cpu_id, cpu_callin_map)) {		printk("huh, phys CPU#%d, CPU#%d already present??\n",			phys_id, cpu_id);		BUG();	}	Dprintk("CPU#%d (phys ID: %d) waiting for CALLOUT\n", cpu_id, phys_id);	/* Waiting 2s total for startup (udelay is not yet working) */	timeout = jiffies + (2 * HZ);	while (time_before(jiffies, timeout)) {		/* Has the boot CPU finished it's STARTUP sequence ? */		if (cpu_isset(cpu_id, cpu_callout_map))			break;		cpu_relax();	}	if (!time_before(jiffies, timeout)) {		printk("BUG: CPU#%d started up but did not get a callout!\n",			cpu_id);		BUG();	}	/* Allow the master to continue. */	cpu_set(cpu_id, cpu_callin_map);}static void __init smp_online(void){	int cpu_id = smp_processor_id();	local_irq_enable();	/* Get our bogomips. */	calibrate_delay();	/* Save our processor parameters */ 	smp_store_cpu_info(cpu_id);	cpu_set(cpu_id, cpu_online_map);}/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*//* Boot up CPUs common Routins                                               *//*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/static void __init show_mp_info(int nr_cpu){	int i;	char cpu_model0[17], cpu_model1[17], cpu_ver[9];	strncpy(cpu_model0, (char *)M32R_FPGA_CPU_NAME_ADDR, 16);	strncpy(cpu_model1, (char *)M32R_FPGA_MODEL_ID_ADDR, 16);	strncpy(cpu_ver, (char *)M32R_FPGA_VERSION_ADDR, 8);	cpu_model0[16] = '\0';	for (i = 15 ; i >= 0 ; i--) {		if (cpu_model0[i] != ' ')			break;		cpu_model0[i] = '\0';	}	cpu_model1[16] = '\0';	for (i = 15 ; i >= 0 ; i--) {		if (cpu_model1[i] != ' ')			break;		cpu_model1[i] = '\0';	}	cpu_ver[8] = '\0';	for (i = 7 ; i >= 0 ; i--) {		if (cpu_ver[i] != ' ')			break;		cpu_ver[i] = '\0';	}	printk(KERN_INFO "M32R-mp information\n");	printk(KERN_INFO "  On-chip CPUs : %d\n", nr_cpu);	printk(KERN_INFO "  CPU model : %s/%s(%s)\n", cpu_model0,		cpu_model1, cpu_ver);}/* * The bootstrap kernel entry code has set these up. Save them for * a given CPU */static void __init smp_store_cpu_info(int cpu_id){	struct cpuinfo_m32r *ci = cpu_data + cpu_id;	*ci = boot_cpu_data;	ci->loops_per_jiffy = loops_per_jiffy;}static void __init show_cpu_info(int cpu_id){	struct cpuinfo_m32r *ci = &cpu_data[cpu_id];	printk("CPU#%d : ", cpu_id);#define PRINT_CLOCK(name, value) \	printk(name " clock %d.%02dMHz", \		((value) / 1000000), ((value) % 1000000) / 10000)	PRINT_CLOCK("CPU", (int)ci->cpu_clock);	PRINT_CLOCK(", Bus", (int)ci->bus_clock);	printk(", loops_per_jiffy[%ld]\n", ci->loops_per_jiffy);}/* * the frequency of the profiling timer can be changed * by writing a multiplier value into /proc/profile. */int setup_profiling_timer(unsigned int multiplier){	int i;	/*	 * Sanity check. [at least 500 APIC cycles should be	 * between APIC interrupts as a rule of thumb, to avoid	 * irqs flooding us]	 */	if ( (!multiplier) || (calibration_result / multiplier < 500))		return -EINVAL;	/*	 * Set the new multiplier for each CPU. CPUs don't start using the	 * new values until the next timer interrupt in which they do process	 * accounting. At that time they also adjust their APIC timers	 * accordingly.	 */	for (i = 0; i < NR_CPUS; ++i)		per_cpu(prof_multiplier, i) = multiplier;	return 0;}/* Initialize all maps between cpu number and apicids */static void __init init_cpu_to_physid(void){	int  i;	for (i = 0 ; i < NR_CPUS ; i++) {		cpu_2_physid[i] = -1;		physid_2_cpu[i] = -1;	}}/* * set up a mapping between cpu and apicid. Uses logical apicids for multiquad, * else physical apic ids */static void __init map_cpu_to_physid(int cpu_id, int phys_id){	physid_2_cpu[phys_id] = cpu_id;	cpu_2_physid[cpu_id] = phys_id;}/* * undo a mapping between cpu and apicid. Uses logical apicids for multiquad, * else physical apic ids */static void __init unmap_cpu_to_physid(int cpu_id, int phys_id){	physid_2_cpu[phys_id] = -1;	cpu_2_physid[cpu_id] = -1;}

⌨️ 快捷键说明

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