/* * This initializes the IO-APIC and APIC hardware if this is * a UP kernel. */ int __init APIC_init_uniprocessor (void) { if (disable_apic) { printk(KERN_INFO "Apic disabled\n"); return -1; } if (!cpu_has_apic) { disable_apic = 1; printk(KERN_INFO "Apic disabled by BIOS\n"); return -1; } verify_local_APIC(); connect_bsp_APIC(); phys_cpu_present_map = physid_mask_of_physid(boot_cpu_id); apic_write(APIC_ID, SET_APIC_ID(boot_cpu_id)); setup_local_APIC(); #ifdef CONFIG_X86_IO_APIC if (smp_found_config && !skip_ioapic_setup && nr_ioapics) setup_IO_APIC(); else nr_ioapics = 0; #endif setup_boot_APIC_clock(); check_nmi_watchdog(); return 0; }
/* * This initializes the IO-APIC and APIC hardware if this is * a UP kernel. */ int __init APIC_init_uniprocessor (void) { if (enable_local_apic < 0) clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); if (!smp_found_config && !cpu_has_apic) return -1; /* * Complain if the BIOS pretends there is one. */ if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) { printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n", boot_cpu_physical_apicid); clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); return -1; } verify_local_APIC(); connect_bsp_APIC(); phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid); setup_local_APIC(); #ifdef CONFIG_X86_IO_APIC if (smp_found_config) if (!skip_ioapic_setup && nr_ioapics) setup_IO_APIC(); #endif setup_boot_APIC_clock(); return 0; }
/* * This initializes the IO-APIC and APIC hardware if this is * a UP kernel. */ int __init APIC_init_uniprocessor (void) { if (!smp_found_config && !cpu_has_apic) return -1; /* * Complain if the BIOS pretends there is one. */ if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) { printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n", boot_cpu_physical_apicid); return -1; } verify_local_APIC(); connect_bsp_APIC(); phys_cpu_present_map = 1 << boot_cpu_physical_apicid; apic_pm_init2(); setup_local_APIC(); if (nmi_watchdog == NMI_LOCAL_APIC) check_nmi_watchdog(); #ifdef CONFIG_X86_IO_APIC if (smp_found_config) if (!skip_ioapic_setup && nr_ioapics) setup_IO_APIC(); #endif setup_APIC_clocks(); return 0; }
/* * This initializes the IO-APIC and APIC hardware if this is * a UP kernel. */ int __init APIC_init_uniprocessor (void) { if (enable_local_apic < 0) clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); if (!smp_found_config && !cpu_has_apic) { skip_ioapic_setup = 1; return -1; } /* * Complain if the BIOS pretends there is one. */ if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) { printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n", boot_cpu_physical_apicid); clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); skip_ioapic_setup = 1; return -1; } verify_local_APIC(); connect_bsp_APIC(); /* * Hack: In case of kdump, after a crash, kernel might be booting * on a cpu with non-zero lapic id. But boot_cpu_physical_apicid * might be zero if read from MP tables. Get it from LAPIC. */ #ifdef CONFIG_CRASH_DUMP boot_cpu_physical_apicid = get_apic_id(); #endif physids_clear(phys_cpu_present_map); physid_set(boot_cpu_physical_apicid, phys_cpu_present_map); setup_local_APIC(); if (nmi_watchdog == NMI_LOCAL_APIC) check_nmi_watchdog(); #ifdef CONFIG_X86_IO_APIC if (smp_found_config) if (!skip_ioapic_setup && nr_ioapics) setup_IO_APIC(); #endif setup_boot_APIC_clock(); return 0; }
/** @brief prepare goto the smp mode */ static void x86_prepare_smp() { /* Find and Analyze the table from BIOS AND ACPI*/ mptable_find_smp_config(); mptable_get_smp_config(); /* This is called in init_IRQ */ init_bsp_APIC(); /* Connect apic */ connect_bsp_APIC(); setup_local_APIC(); bsp_end_local_APIC_setup(); printk("\n%s->%s->%d.",__FILE__,__FUNCTION__,__LINE__); }
/* * This initializes the IO-APIC and APIC hardware if this is * a UP kernel. */ int __init APIC_init_uniprocessor (void) { if (apic_disabled) clear_bit(X86_FEATURE_APIC, &boot_cpu_data.x86_capability); if (!cpu_has_apic) { printk("No APIC available.\n"); apic_disabled = 1; return -1; } /* * Complain if the BIOS pretends there is one. */ if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_id])) { printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n", boot_cpu_id); apic_disabled = 1; return -1; } verify_local_APIC(); connect_bsp_APIC(); phys_cpu_present_map = 1; apic_write_around(APIC_ID, boot_cpu_id); apic_pm_init2(); setup_local_APIC(); if (nmi_watchdog == NMI_LOCAL_APIC) check_nmi_watchdog(); #ifdef CONFIG_X86_IO_APIC if (smp_found_config && !skip_ioapic_setup && nr_ioapics) setup_IO_APIC(); else nr_ioapics = 0; #endif setup_APIC_clocks(); return 0; }
/* * This initializes the IO-APIC and APIC hardware if this is * a UP kernel. */ int __init APIC_init_uniprocessor(void) { if (disable_apic) { printk(KERN_INFO "Apic disabled\n"); return -1; } if (!cpu_has_apic) { disable_apic = 1; printk(KERN_INFO "Apic disabled by BIOS\n"); return -1; } verify_local_APIC(); connect_bsp_APIC(); physid_set_mask_of_physid(boot_cpu_physical_apicid, &phys_cpu_present_map); apic_write(APIC_ID, SET_APIC_ID(boot_cpu_physical_apicid)); setup_local_APIC(); /* * Now enable IO-APICs, actually call clear_IO_APIC * We need clear_IO_APIC before enabling vector on BP */ if (!skip_ioapic_setup && nr_ioapics) enable_IO_APIC(); if (!smp_found_config || skip_ioapic_setup || !nr_ioapics) localise_nmi_watchdog(); end_local_APIC_setup(); if (smp_found_config && !skip_ioapic_setup && nr_ioapics) setup_IO_APIC(); else nr_ioapics = 0; setup_boot_APIC_clock(); check_nmi_watchdog(); return 0; }
static void __init smp_boot_cpus(unsigned int max_cpus) { int apicid, cpu, bit, kicked; unsigned long bogosum = 0; /* * Setup boot CPU information */ smp_store_cpu_info(0); /* Final full version of the data */ printk("CPU%d: ", 0); print_cpu_info(&cpu_data[0]); boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID)); boot_cpu_logical_apicid = logical_smp_processor_id(); x86_cpu_to_apicid[0] = boot_cpu_physical_apicid; current_thread_info()->cpu = 0; smp_tune_scheduling(); cpus_clear(cpu_sibling_map[0]); cpu_set(0, cpu_sibling_map[0]); /* * If we couldn't find an SMP configuration at boot time, * get out of here now! */ if (!smp_found_config && !acpi_lapic) { printk(KERN_NOTICE "SMP motherboard not detected.\n"); smpboot_clear_io_apic_irqs(); phys_cpu_present_map = physid_mask_of_physid(0); if (APIC_init_uniprocessor()) printk(KERN_NOTICE "Local APIC not detected." " Using dummy APIC emulation.\n"); map_cpu_to_logical_apicid(); return; } /* * Should not be necessary because the MP table should list the boot * CPU too, but we do it for the sake of robustness anyway. * Makes no sense to do this check in clustered apic mode, so skip it */ if (!check_phys_apicid_present(boot_cpu_physical_apicid)) { printk("weird, boot CPU (#%d) not listed by the BIOS.\n", boot_cpu_physical_apicid); physid_set(hard_smp_processor_id(), phys_cpu_present_map); } /* * If we couldn't find a local APIC, then get out of here now! */ if (APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid]) && !cpu_has_apic) { printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n", boot_cpu_physical_apicid); printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n"); smpboot_clear_io_apic_irqs(); phys_cpu_present_map = physid_mask_of_physid(0); return; } verify_local_APIC(); /* * If SMP should be disabled, then really disable it! */ if (!max_cpus) { smp_found_config = 0; printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n"); smpboot_clear_io_apic_irqs(); phys_cpu_present_map = physid_mask_of_physid(0); return; } connect_bsp_APIC(); setup_local_APIC(); map_cpu_to_logical_apicid(); setup_portio_remap(); /* * Scan the CPU present map and fire up the other CPUs via do_boot_cpu * * In clustered apic mode, phys_cpu_present_map is a constructed thus: * bits 0-3 are quad0, 4-7 are quad1, etc. A perverse twist on the * clustered apic ID. */ Dprintk("CPU present map: %lx\n", physids_coerce(phys_cpu_present_map)); kicked = 1; for (bit = 0; kicked < NR_CPUS && bit < MAX_APICS; bit++) { apicid = cpu_present_to_apicid(bit); /* * Don't even attempt to start the boot CPU! */ if ((apicid == boot_cpu_apicid) || (apicid == BAD_APICID)) continue; if (!check_apicid_present(bit)) continue; if (max_cpus <= cpucount+1) continue; if (do_boot_cpu(apicid)) printk("CPU #%d not responding - cannot use it.\n", apicid); else ++kicked; } /* * Cleanup possible dangling ends... */ smpboot_restore_warm_reset_vector(); /* * Allow the user to impress friends. */ Dprintk("Before bogomips.\n"); for (cpu = 0; cpu < NR_CPUS; cpu++) if (cpu_isset(cpu, cpu_callout_map)) bogosum += cpu_data[cpu].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"); if (smp_b_stepping) printk(KERN_WARNING "WARNING: SMP operation may be unreliable with B stepping processors.\n"); /* * Don't taint if we are running SMP kernel on a single non-MP * approved Athlon */ if (tainted & TAINT_UNSAFE_SMP) { if (cpucount) printk (KERN_INFO "WARNING: This combination of AMD processors is not suitable for SMP.\n"); else tainted &= ~TAINT_UNSAFE_SMP; } Dprintk("Boot done.\n"); /* * construct cpu_sibling_map[], so that we can tell sibling CPUs * efficiently. */ for (cpu = 0; cpu < NR_CPUS; cpu++) cpus_clear(cpu_sibling_map[cpu]); for (cpu = 0; cpu < NR_CPUS; cpu++) { int siblings = 0; int i; if (!cpu_isset(cpu, cpu_callout_map)) continue; if (smp_num_siblings > 1) { for (i = 0; i < NR_CPUS; i++) { if (!cpu_isset(i, cpu_callout_map)) continue; if (phys_proc_id[cpu] == phys_proc_id[i]) { siblings++; cpu_set(i, cpu_sibling_map[cpu]); } } } else { siblings++; cpu_set(cpu, cpu_sibling_map[cpu]); } if (siblings != smp_num_siblings) printk(KERN_WARNING "WARNING: %d siblings found for CPU%d, should be %d\n", siblings, cpu, smp_num_siblings); } if (nmi_watchdog == NMI_LOCAL_APIC) check_nmi_watchdog(); smpboot_setup_io_apic(); setup_boot_APIC_clock(); /* * Synchronize the TSC with the AP */ if (cpu_has_tsc && cpucount && cpu_khz) synchronize_tsc_bp(); }
int __init APIC_init_uniprocessor(void) { if (disable_apic) { pr_info("Apic disabled\n"); return -1; } #ifdef CONFIG_X86_64 if (!cpu_has_apic) { disable_apic = 1; pr_info("Apic disabled by BIOS\n"); return -1; } #else if (!smp_found_config && !cpu_has_apic) return -1; if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) { pr_err("BIOS bug, local APIC 0x%x not detected!...\n", boot_cpu_physical_apicid); return -1; } #endif enable_IR_x2apic(); #ifdef CONFIG_X86_64 default_setup_apic_routing(); #endif verify_local_APIC(); connect_bsp_APIC(); #ifdef CONFIG_X86_64 apic_write(APIC_ID, SET_APIC_ID(boot_cpu_physical_apicid)); #else # ifdef CONFIG_CRASH_DUMP boot_cpu_physical_apicid = read_apic_id(); # endif #endif physid_set_mask_of_physid(boot_cpu_physical_apicid, &phys_cpu_present_map); setup_local_APIC(); #ifdef CONFIG_X86_IO_APIC if (!skip_ioapic_setup && nr_ioapics) enable_IO_APIC(); #endif end_local_APIC_setup(); #ifdef CONFIG_X86_IO_APIC if (smp_found_config && !skip_ioapic_setup && nr_ioapics) setup_IO_APIC(); else { nr_ioapics = 0; localise_nmi_watchdog(); } #else localise_nmi_watchdog(); #endif x86_init.timers.setup_percpu_clockev(); #ifdef CONFIG_X86_64 check_nmi_watchdog(); #endif return 0; }
static void __init smp_boot_cpus(unsigned int max_cpus) { unsigned apicid, cpu, bit, kicked; nmi_watchdog_default(); /* * Setup boot CPU information */ smp_store_cpu_info(0); /* Final full version of the data */ printk(KERN_INFO "CPU%d: ", 0); print_cpu_info(&cpu_data[0]); current_thread_info()->cpu = 0; smp_tune_scheduling(); if (!physid_isset(hard_smp_processor_id(), phys_cpu_present_map)) { printk("weird, boot CPU (#%d) not listed by the BIOS.\n", hard_smp_processor_id()); physid_set(hard_smp_processor_id(), phys_cpu_present_map); } /* * If we couldn't find an SMP configuration at boot time, * get out of here now! */ if (!smp_found_config) { printk(KERN_NOTICE "SMP motherboard not detected.\n"); io_apic_irqs = 0; cpu_online_map = cpumask_of_cpu(0); cpu_set(0, cpu_sibling_map[0]); phys_cpu_present_map = physid_mask_of_physid(0); if (APIC_init_uniprocessor()) printk(KERN_NOTICE "Local APIC not detected." " Using dummy APIC emulation.\n"); goto smp_done; } /* * Should not be necessary because the MP table should list the boot * CPU too, but we do it for the sake of robustness anyway. */ if (!physid_isset(boot_cpu_id, phys_cpu_present_map)) { printk(KERN_NOTICE "weird, boot CPU (#%d) not listed by the BIOS.\n", boot_cpu_id); physid_set(hard_smp_processor_id(), phys_cpu_present_map); } /* * If we couldn't find a local APIC, then get out of here now! */ if (APIC_INTEGRATED(apic_version[boot_cpu_id]) && !cpu_has_apic) { printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n", boot_cpu_id); printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n"); io_apic_irqs = 0; cpu_online_map = cpumask_of_cpu(0); cpu_set(0, cpu_sibling_map[0]); phys_cpu_present_map = physid_mask_of_physid(0); disable_apic = 1; goto smp_done; } verify_local_APIC(); /* * If SMP should be disabled, then really disable it! */ if (!max_cpus) { smp_found_config = 0; printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n"); io_apic_irqs = 0; cpu_online_map = cpumask_of_cpu(0); cpu_set(0, cpu_sibling_map[0]); phys_cpu_present_map = physid_mask_of_physid(0); disable_apic = 1; goto smp_done; } connect_bsp_APIC(); setup_local_APIC(); if (GET_APIC_ID(apic_read(APIC_ID)) != boot_cpu_id) BUG(); x86_cpu_to_apicid[0] = boot_cpu_id; /* * Now scan the CPU present map and fire up the other CPUs. */ Dprintk("CPU present map: %lx\n", physids_coerce(phys_cpu_present_map)); kicked = 1; for (bit = 0; kicked < NR_CPUS && bit < MAX_APICS; bit++) { apicid = cpu_present_to_apicid(bit); /* * Don't even attempt to start the boot CPU! */ if (apicid == boot_cpu_id || (apicid == BAD_APICID)) continue; if (!physid_isset(apicid, phys_cpu_present_map)) continue; if ((max_cpus >= 0) && (max_cpus <= cpucount+1)) continue; do_boot_cpu(apicid); ++kicked; } /* * Cleanup possible dangling ends... */ { /* * Install writable page 0 entry to set BIOS data area. */ local_flush_tlb(); /* * Paranoid: Set warm reset code and vector here back * to default values. */ CMOS_WRITE(0, 0xf); *((volatile int *) phys_to_virt(0x467)) = 0; } /* * Allow the user to impress friends. */ Dprintk("Before bogomips.\n"); if (!cpucount) { printk(KERN_INFO "Only one processor found.\n"); } else { unsigned long bogosum = 0; for (cpu = 0; cpu < NR_CPUS; cpu++) if (cpu_isset(cpu, cpu_callout_map)) bogosum += cpu_data[cpu].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"); } /* * Construct cpu_sibling_map[], so that we can tell the * sibling CPU efficiently. */ for (cpu = 0; cpu < NR_CPUS; cpu++) cpus_clear(cpu_sibling_map[cpu]); for (cpu = 0; cpu < NR_CPUS; cpu++) { int siblings = 0; int i; if (!cpu_isset(cpu, cpu_callout_map)) continue; if (smp_num_siblings > 1) { for (i = 0; i < NR_CPUS; i++) { if (!cpu_isset(i, cpu_callout_map)) continue; if (phys_proc_id[cpu] == phys_proc_id[i]) { siblings++; cpu_set(i, cpu_sibling_map[cpu]); } } } else { siblings++; cpu_set(cpu, cpu_sibling_map[cpu]); } if (siblings != smp_num_siblings) { printk(KERN_WARNING "WARNING: %d siblings found for CPU%d, should be %d\n", siblings, cpu, smp_num_siblings); smp_num_siblings = siblings; } } Dprintk("Boot done.\n"); /* * Here we can be sure that there is an IO-APIC in the system. Let's * go and set it up: */ if (!skip_ioapic_setup && nr_ioapics) setup_IO_APIC(); else nr_ioapics = 0; setup_boot_APIC_clock(); /* * Synchronize the TSC with the AP */ if (cpu_has_tsc && cpucount) synchronize_tsc_bp(); smp_done: time_init_smp(); }