📄 smpboot.c
字号:
/* * 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 + -