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

📄 smpboot.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  linux/arch/m32r/kernel/smpboot.c *    orig : i386 2.4.10 * *  M32R SMP booting functions * *  Copyright (c) 2001, 2002, 2003  Hitoshi Yamamoto * *  Taken from i386 version. *	  (c) 1995 Alan Cox, Building #3 <alan@redhat.com> *	  (c) 1998, 1999, 2000 Ingo Molnar <mingo@redhat.com> * *	Much of the core SMP work is based on previous work by Thomas Radke, to *	whom a great many thanks are extended. * *	Thanks to Intel for making available several different Pentium, *	Pentium Pro and Pentium-II/Xeon MP machines. *	Original development of Linux SMP code supported by Caldera. * *	This code is released under the GNU General Public License version 2 or *	later. * *	Fixes *		Felix Koop	:	NR_CPUS used properly *		Jose Renau	:	Handle single CPU case. *		Alan Cox	:	By repeated request *					8) - Total BogoMIP report. *		Greg Wright	:	Fix for kernel stacks panic. *		Erich Boleyn	:	MP v1.4 and additional changes. *	Matthias Sattler	:	Changes for 2.1 kernel map. *	Michel Lespinasse	:	Changes for 2.1 kernel map. *	Michael Chastain	:	Change trampoline.S to gnu as. *		Alan Cox	:	Dumb bug: 'B' step PPro's are fine *		Ingo Molnar	:	Added APIC timers, based on code *					from Jose Renau *		Ingo Molnar	:	various cleanups and rewrites *		Tigran Aivazian	:	fixed "0.00 in /proc/uptime on SMP" bug. *	Maciej W. Rozycki	:	Bits for genuine 82489DX APICs *		Martin J. Bligh	: 	Added support for multi-quad systems */#include <linux/config.h>#include <linux/init.h>#include <linux/mm.h>#include <linux/smp_lock.h>#include <linux/irq.h>#include <linux/bootmem.h>#include <linux/delay.h>#include <asm/io.h>#include <asm/pgalloc.h>#include <asm/tlbflush.h>#define DEBUG_SMP#ifdef DEBUG_SMP#define Dprintk(x...) printk(x)#else#define Dprintk(x...)#endifextern cpumask_t cpu_initialized;/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*//* Data structures and variables                                             *//*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*//* Processor that is doing the boot up */static unsigned int bsp_phys_id = -1;/* Bitmask of physically existing CPUs */physid_mask_t phys_cpu_present_map;/* Bitmask of currently online CPUs */cpumask_t cpu_online_map;cpumask_t cpu_bootout_map;cpumask_t cpu_bootin_map;cpumask_t cpu_callout_map;static cpumask_t cpu_callin_map;/* Per CPU bogomips and other parameters */struct cpuinfo_m32r cpu_data[NR_CPUS] __cacheline_aligned;static int cpucount;static cpumask_t smp_commenced_mask;extern struct {	void * spi;	unsigned short ss;} stack_start;/* which physical physical ID maps to which logical CPU number */static volatile int physid_2_cpu[NR_CPUS];#define physid_to_cpu(physid)	physid_2_cpu[physid]/* which logical CPU number maps to which physical ID */volatile int cpu_2_physid[NR_CPUS];DEFINE_PER_CPU(int, prof_multiplier) = 1;DEFINE_PER_CPU(int, prof_old_multiplier) = 1;DEFINE_PER_CPU(int, prof_counter) = 1;spinlock_t ipi_lock[NR_IPIS];static unsigned int calibration_result;/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*//* Function Prototypes                                                       *//*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/void smp_prepare_boot_cpu(void);void smp_prepare_cpus(unsigned int);static void smp_tune_scheduling(void);static void init_ipi_lock(void);static void do_boot_cpu(int);int __cpu_up(unsigned int);void smp_cpus_done(unsigned int);int start_secondary(void *);static void smp_callin(void);static void smp_online(void);static void show_mp_info(int);static void smp_store_cpu_info(int);static void show_cpu_info(int);int setup_profiling_timer(unsigned int);static void init_cpu_to_physid(void);static void map_cpu_to_physid(int, int);static void unmap_cpu_to_physid(int, int);/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*//* Boot up APs Routins : BSP                                                 *//*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/void __devinit smp_prepare_boot_cpu(void){	bsp_phys_id = hard_smp_processor_id();	physid_set(bsp_phys_id, phys_cpu_present_map);	cpu_set(0, cpu_online_map);	/* BSP's cpu_id == 0 */	cpu_set(0, cpu_callout_map);	cpu_set(0, cpu_callin_map);	/*	 * Initialize the logical to physical CPU number mapping	 */	init_cpu_to_physid();	map_cpu_to_physid(0, bsp_phys_id);	current_thread_info()->cpu = 0;}/*==========================================================================* * Name:         smp_prepare_cpus (old smp_boot_cpus) * * Description:  This routine boot up APs. * * 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 * *==========================================================================*/void __init smp_prepare_cpus(unsigned int max_cpus){	int phys_id;	unsigned long nr_cpu;	nr_cpu = inl(M32R_FPGA_NUM_OF_CPUS_PORTL);	if (nr_cpu > NR_CPUS) {		printk(KERN_INFO "NUM_OF_CPUS reg. value [%ld] > NR_CPU [%d]",			nr_cpu, NR_CPUS);		goto smp_done;	}	for (phys_id = 0 ; phys_id < nr_cpu ; phys_id++)		physid_set(phys_id, phys_cpu_present_map);	show_mp_info(nr_cpu);	init_ipi_lock();	/*	 * Setup boot CPU information	 */	smp_store_cpu_info(0); /* Final full version of the data */	smp_tune_scheduling();	/*	 * If SMP should be disabled, then really disable it!	 */	if (!max_cpus) {		printk(KERN_INFO "SMP mode deactivated by commandline.\n");		goto smp_done;	}	/*	 * Now scan the CPU present map and fire up the other CPUs.	 */	Dprintk("CPU present map : %lx\n", physids_coerce(phys_cpu_present_map));	for (phys_id = 0 ; phys_id < NR_CPUS ; phys_id++) {		/*		 * Don't even attempt to start the boot CPU!		 */		if (phys_id == bsp_phys_id)			continue;		if (!physid_isset(phys_id, phys_cpu_present_map))			continue;		if ((max_cpus >= 0) && (max_cpus <= cpucount + 1))			continue;		do_boot_cpu(phys_id);		/*		 * Make sure we unmap all failed CPUs		 */		if (physid_to_cpu(phys_id) == -1) {			physid_clear(phys_id, phys_cpu_present_map);			printk("phys CPU#%d not responding - " \				"cannot use it.\n", phys_id);		}	}smp_done:	Dprintk("Boot done.\n");}static void __init smp_tune_scheduling(void){	/* Nothing to do. */}/* * init_ipi_lock : Initialize IPI locks. */static void __init init_ipi_lock(void){	int ipi;	for (ipi = 0 ; ipi < NR_IPIS ; ipi++)		spin_lock_init(&ipi_lock[ipi]);}/*==========================================================================* * Name:         do_boot_cpu * * Description:  This routine boot up one AP. * * Born on Date: 2002.02.05 * * Arguments:    phys_id - Target CPU physical ID * * Returns:      void (cannot fail) * * Modification log: * Date       Who Description * ---------- --- -------------------------------------------------------- * 2003-06-24 hy  modify for linux-2.5.69 * *==========================================================================*/static void __init do_boot_cpu(int phys_id){	struct task_struct *idle;	unsigned long send_status, boot_status;	int timeout, cpu_id;	cpu_id = ++cpucount;	/*	 * We can't use kernel_thread since we must avoid to	 * reschedule the child.	 */	idle = fork_idle(cpu_id);	if (IS_ERR(idle))		panic("failed fork for CPU#%d.", cpu_id);	idle->thread.lr = (unsigned long)start_secondary;	map_cpu_to_physid(cpu_id, phys_id);	/* So we see what's up   */	printk("Booting processor %d/%d\n", phys_id, cpu_id);	stack_start.spi = (void *)idle->thread.sp;	idle->thread_info->cpu = cpu_id;	/*	 * Send Startup IPI	 *   1.IPI received by CPU#(phys_id).	 *   2.CPU#(phys_id) enter startup_AP (arch/m32r/kernel/head.S)	 *   3.CPU#(phys_id) enter start_secondary()	 */	send_status = 0;	boot_status = 0;	cpu_set(phys_id, cpu_bootout_map);	/* Send Startup IPI */	send_IPI_mask_phys(cpumask_of_cpu(phys_id), CPU_BOOT_IPI, 0);	Dprintk("Waiting for send to finish...\n");	timeout = 0;	/* Wait 100[ms] */	do {		Dprintk("+");		udelay(1000);		send_status = !cpu_isset(phys_id, cpu_bootin_map);	} while (send_status && (timeout++ < 100));	Dprintk("After Startup.\n");	if (!send_status) {

⌨️ 快捷键说明

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