diff options
Diffstat (limited to 'arch/x86/machine')
-rw-r--r-- | arch/x86/machine/boot.c | 4 | ||||
-rw-r--r-- | arch/x86/machine/cpu.c | 71 | ||||
-rw-r--r-- | arch/x86/machine/cpu.h | 13 | ||||
-rw-r--r-- | arch/x86/machine/pmap.c | 12 | ||||
-rw-r--r-- | arch/x86/machine/pmap.h | 9 |
5 files changed, 48 insertions, 61 deletions
diff --git a/arch/x86/machine/boot.c b/arch/x86/machine/boot.c index 02a4050f..5e8b735f 100644 --- a/arch/x86/machine/boot.c +++ b/arch/x86/machine/boot.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012, 2013 Richard Braun. + * Copyright (c) 2010-2014 Richard Braun. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -281,7 +281,7 @@ boot_main(void) vm_page_info(); pic_setup(); pit_setup(); - cpu_mp_setup(); + cpu_mp_probe(); kernel_main(); /* Never reached */ diff --git a/arch/x86/machine/cpu.c b/arch/x86/machine/cpu.c index 5cdd85ff..5e18eb54 100644 --- a/arch/x86/machine/cpu.c +++ b/arch/x86/machine/cpu.c @@ -71,20 +71,10 @@ static struct cpu cpu_array[MAX_CPUS]; /* * Number of configured processors. - * - * The boot version is used until all processors are configured, since some - * modules depend on cpu_count() to adjust their behaviour when several - * processors are present. */ -static unsigned int cpu_boot_array_size __initdata; unsigned int cpu_array_size __read_mostly; /* - * Barrier for processor synchronization on kernel entry. - */ -static unsigned int cpu_mp_synced __initdata; - -/* * Interrupt descriptor table. */ static struct cpu_gate_desc cpu_idt[CPU_IDT_SIZE] __aligned(8) __read_mostly; @@ -418,7 +408,6 @@ cpu_setup(void) cpu_array[i].state = CPU_STATE_OFF; } - cpu_boot_array_size = 1; cpu_array_size = 1; cpu_array[0].double_fault_stack = (unsigned long)cpu_double_fault_stack; cpu_init(&cpu_array[0]); @@ -459,6 +448,8 @@ cpu_info(const struct cpu *cpu) void __init cpu_mp_register_lapic(unsigned int apic_id, int is_bsp) { + static int skip_warning __initdata; + if (is_bsp) { if (cpu_array[0].apic_id != CPU_INVALID_APIC_ID) panic("cpu: another processor pretends to be the BSP"); @@ -467,17 +458,28 @@ cpu_mp_register_lapic(unsigned int apic_id, int is_bsp) return; } - if (cpu_boot_array_size == ARRAY_SIZE(cpu_array)) { - printk("cpu: ignoring processor beyond id %u\n", MAX_CPUS - 1); + if (cpu_array_size == ARRAY_SIZE(cpu_array)) { + if (!skip_warning) { + printk("cpu: ignoring processor beyond id %u\n", MAX_CPUS - 1); + skip_warning = 1; + } + return; } - cpu_array[cpu_boot_array_size].apic_id = apic_id; - cpu_boot_array_size++; + cpu_array[cpu_array_size].apic_id = apic_id; + cpu_array_size++; } -static void __init -cpu_mp_start_aps(void) +void __init +cpu_mp_probe(void) +{ + acpimp_setup(); + printk("cpu: %u processor(s) configured\n", cpu_array_size); +} + +void __init +cpu_mp_setup(void) { uint16_t reset_vector[2]; struct cpu *cpu; @@ -486,7 +488,7 @@ cpu_mp_start_aps(void) size_t map_size; unsigned int i; - if (cpu_boot_array_size == 1) + if (cpu_array_size == 1) return; assert(BOOT_MP_TRAMPOLINE_ADDR < BIOSMEM_BASE); @@ -522,7 +524,7 @@ cpu_mp_start_aps(void) * Preallocate stacks now, as the kernel mappings shouldn't change while * the APs are starting. */ - for (i = 1; i < cpu_boot_array_size; i++) { + for (i = 1; i < cpu_array_size; i++) { cpu = &cpu_array[i]; cpu->double_fault_stack = vm_kmem_alloc(STACK_SIZE); @@ -530,7 +532,7 @@ cpu_mp_start_aps(void) panic("cpu: unable to allocate double fault stack for cpu%u", i); } - for (i = 1; i < cpu_boot_array_size; i++) { + for (i = 1; i < cpu_array_size; i++) { cpu = &cpu_array[i]; boot_ap_id = i; @@ -548,27 +550,7 @@ cpu_mp_start_aps(void) cpu_pause(); } - cpu_array_size = cpu_boot_array_size; -} - -static void __init -cpu_mp_info(void) -{ - printk("cpu: %u processor(s) configured\n", cpu_array_size); -} - -void __init -cpu_mp_setup(void) -{ - acpimp_setup(); - cpu_mp_start_aps(); - cpu_mp_info(); -} - -void __init -cpu_mp_sync(void) -{ - cpu_mp_synced = 1; + pmap_mp_setup(); } void __init @@ -579,13 +561,6 @@ cpu_ap_setup(void) lapic_ap_setup(); } -void __init -cpu_ap_sync(void) -{ - while (!cpu_mp_synced) - cpu_pause(); -} - void cpu_halt_broadcast(void) { diff --git a/arch/x86/machine/cpu.h b/arch/x86/machine/cpu.h index 3c13911b..0147c357 100644 --- a/arch/x86/machine/cpu.h +++ b/arch/x86/machine/cpu.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2011, 2012, 2013 Richard Braun. + * Copyright (c) 2010-2014 Richard Braun. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -603,12 +603,12 @@ void cpu_mp_register_lapic(unsigned int apic_id, int is_bsp); * * On return, cpu_count() gives the actual number of managed processors. */ -void cpu_mp_setup(void); +void cpu_mp_probe(void); /* - * Synchronize with APs on kernel entry. + * Start application processors. */ -void cpu_mp_sync(void); +void cpu_mp_setup(void); /* * CPU initialization on APs. @@ -616,11 +616,6 @@ void cpu_mp_sync(void); void cpu_ap_setup(void); /* - * Synchronize with BSP on kernel entry. - */ -void cpu_ap_sync(void); - -/* * Send a scheduling interrupt to a remote processor. */ static inline void diff --git a/arch/x86/machine/pmap.c b/arch/x86/machine/pmap.c index 4a8c437a..673c6794 100644 --- a/arch/x86/machine/pmap.c +++ b/arch/x86/machine/pmap.c @@ -195,6 +195,7 @@ struct pmap_update_data { } __aligned(CPU_L1_SIZE); static struct pmap_update_data pmap_update_data[MAX_CPUS]; +static int pmap_allow_remote_updates __read_mostly; /* * Global list of physical maps. @@ -707,7 +708,7 @@ pmap_update(struct pmap *pmap, unsigned long start, unsigned long end) pmap_assert_range(pmap, start, end); - if (cpu_count() == 1) { + if (!pmap_allow_remote_updates) { pmap_update_local(pmap, start, end); return; } @@ -875,6 +876,15 @@ pmap_setup(void) pmap_ready = 1; } +void __init +pmap_mp_setup(void) +{ + if (cpu_count() == 1) + return; + + pmap_allow_remote_updates = 1; +} + int pmap_create(struct pmap **pmapp) { diff --git a/arch/x86/machine/pmap.h b/arch/x86/machine/pmap.h index ea5692d7..2a34a8f5 100644 --- a/arch/x86/machine/pmap.h +++ b/arch/x86/machine/pmap.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2011, 2012, 2013 Richard Braun. + * Copyright (c) 2010-2014 Richard Braun. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -222,6 +222,13 @@ void pmap_update_intr(struct trap_frame *frame); void pmap_setup(void); /* + * Set up the pmap module for multiprocessor operations. + * + * This function basically enables pmap updates across processors. + */ +void pmap_mp_setup(void); + +/* * Create a pmap for a user task. */ int pmap_create(struct pmap **pmapp); |