subr_smp.c (71525) | subr_smp.c (71576) |
---|---|
1/* 2 * Copyright (c) 1996, by Steve Passe 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 8 unchanged lines hidden (view full) --- 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 * | 1/* 2 * Copyright (c) 1996, by Steve Passe 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 8 unchanged lines hidden (view full) --- 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 * |
25 * $FreeBSD: head/sys/kern/subr_smp.c 71525 2001-01-24 09:48:52Z jhb $ | 25 * $FreeBSD: head/sys/kern/subr_smp.c 71576 2001-01-24 12:35:55Z jasone $ |
26 */ 27 28#include "opt_cpu.h" 29#include "opt_user_ldt.h" 30 31#ifdef SMP 32#include <machine/smptests.h> 33#else --- 199 unchanged lines hidden (view full) --- 233 234#define START_ALL_APS_POST 0x16 235#define INSTALL_AP_TRAMP_POST 0x17 236#define START_AP_POST 0x18 237 238#define MP_ANNOUNCE_POST 0x19 239 240/* used to hold the AP's until we are ready to release them */ | 26 */ 27 28#include "opt_cpu.h" 29#include "opt_user_ldt.h" 30 31#ifdef SMP 32#include <machine/smptests.h> 33#else --- 199 unchanged lines hidden (view full) --- 233 234#define START_ALL_APS_POST 0x16 235#define INSTALL_AP_TRAMP_POST 0x17 236#define START_AP_POST 0x18 237 238#define MP_ANNOUNCE_POST 0x19 239 240/* used to hold the AP's until we are ready to release them */ |
241struct simplelock ap_boot_lock; | 241struct mtx ap_boot_mtx; |
242 243/** XXX FIXME: where does this really belong, isa.h/isa.c perhaps? */ 244int current_postcode; 245 246/** XXX FIXME: what system files declare these??? */ 247extern struct region_descriptor r_gdt, r_idt; 248 249int bsp_apic_ready = 0; /* flags useability of BSP apic */ --- 63 unchanged lines hidden (view full) --- 313SYSCTL_INT(_machdep, OID_AUTO, forward_roundrobin_enabled, CTLFLAG_RW, 314 &forward_roundrobin_enabled, 0, ""); 315 316 317/* 318 * Local data and functions. 319 */ 320 | 242 243/** XXX FIXME: where does this really belong, isa.h/isa.c perhaps? */ 244int current_postcode; 245 246/** XXX FIXME: what system files declare these??? */ 247extern struct region_descriptor r_gdt, r_idt; 248 249int bsp_apic_ready = 0; /* flags useability of BSP apic */ --- 63 unchanged lines hidden (view full) --- 313SYSCTL_INT(_machdep, OID_AUTO, forward_roundrobin_enabled, CTLFLAG_RW, 314 &forward_roundrobin_enabled, 0, ""); 315 316 317/* 318 * Local data and functions. 319 */ 320 |
321/* Set to 1 once we're ready to let the APs out of the pen. */ 322static volatile int aps_ready = 0; 323 |
|
321static int mp_capable; 322static u_int boot_address; 323static u_int base_memory; 324 325static int picmode; /* 0: virtual wire mode, 1: PIC mode */ 326static mpfps_t mpfps; 327static int search_for_sig(u_int32_t target, int count); 328static void mp_enable(u_int boot_addr); --- 11 unchanged lines hidden (view full) --- 340static int apic_int_is_bus_type(int intr, int bus_type); 341static void release_aps(void *dummy); 342 343/* 344 * initialize all the SMP locks 345 */ 346 347/* critical region around IO APIC, apic_imen */ | 324static int mp_capable; 325static u_int boot_address; 326static u_int base_memory; 327 328static int picmode; /* 0: virtual wire mode, 1: PIC mode */ 329static mpfps_t mpfps; 330static int search_for_sig(u_int32_t target, int count); 331static void mp_enable(u_int boot_addr); --- 11 unchanged lines hidden (view full) --- 343static int apic_int_is_bus_type(int intr, int bus_type); 344static void release_aps(void *dummy); 345 346/* 347 * initialize all the SMP locks 348 */ 349 350/* critical region around IO APIC, apic_imen */ |
348struct simplelock imen_lock; | 351struct mtx imen_mtx; |
349 350/* lock region used by kernel profiling */ | 352 353/* lock region used by kernel profiling */ |
351struct simplelock mcount_lock; | 354struct mtx mcount_mtx; |
352 353#ifdef USE_COMLOCK 354/* locks com (tty) data/hardware accesses: a FASTINTR() */ | 355 356#ifdef USE_COMLOCK 357/* locks com (tty) data/hardware accesses: a FASTINTR() */ |
355struct simplelock com_lock; | 358struct mtx com_mtx; |
356#endif /* USE_COMLOCK */ 357 358/* lock around the MP rendezvous */ | 359#endif /* USE_COMLOCK */ 360 361/* lock around the MP rendezvous */ |
359static struct simplelock smp_rv_lock; | 362static struct mtx smp_rv_mtx; |
360 361/* only 1 CPU can panic at a time :) */ | 363 364/* only 1 CPU can panic at a time :) */ |
362struct simplelock panic_lock; | 365struct mtx panic_mtx; |
363 364static void 365init_locks(void) 366{ | 366 367static void 368init_locks(void) 369{ |
367 s_lock_init(&mcount_lock); | 370 /* 371 * XXX The mcount mutex probably needs to be statically initialized, 372 * since it will be used even in the function calls that get us to this 373 * point. 374 */ 375 mtx_init(&mcount_mtx, "mcount", MTX_DEF); |
368 | 376 |
369 s_lock_init(&imen_lock); 370 s_lock_init(&smp_rv_lock); 371 s_lock_init(&panic_lock); | 377 mtx_init(&smp_rv_mtx, "smp rendezvous", MTX_SPIN); 378 mtx_init(&panic_mtx, "panic", MTX_DEF); |
372 373#ifdef USE_COMLOCK | 379 380#ifdef USE_COMLOCK |
374 s_lock_init(&com_lock); | 381 mtx_init(&com_mtx, "com", MTX_SPIN); |
375#endif /* USE_COMLOCK */ 376 | 382#endif /* USE_COMLOCK */ 383 |
377 s_lock_init(&ap_boot_lock); | 384 mtx_init(&ap_boot_mtx, "ap boot", MTX_SPIN); |
378} 379 380/* 381 * Calculate usable address in base memory for AP trampoline code. 382 */ 383u_int 384mp_bootaddress(u_int basemem) 385{ --- 264 unchanged lines hidden (view full) --- 650 SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); 651#endif /** TEST_TEST1 */ 652 653#endif /* APIC_IO */ 654 655 /* initialize all SMP locks */ 656 init_locks(); 657 | 385} 386 387/* 388 * Calculate usable address in base memory for AP trampoline code. 389 */ 390u_int 391mp_bootaddress(u_int basemem) 392{ --- 264 unchanged lines hidden (view full) --- 657 SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); 658#endif /** TEST_TEST1 */ 659 660#endif /* APIC_IO */ 661 662 /* initialize all SMP locks */ 663 init_locks(); 664 |
658 /* obtain the ap_boot_lock */ 659 s_lock(&ap_boot_lock); 660 | |
661 /* start each Application Processor */ 662 start_all_aps(boot_addr); 663} 664 665 666/* 667 * look for the MP spec signature 668 */ --- 1573 unchanged lines hidden (view full) --- 2242 * This is called once the rest of the system is up and running and we're 2243 * ready to let the AP's out of the pen. 2244 */ 2245void 2246ap_init(void) 2247{ 2248 u_int apic_id; 2249 | 665 /* start each Application Processor */ 666 start_all_aps(boot_addr); 667} 668 669 670/* 671 * look for the MP spec signature 672 */ --- 1573 unchanged lines hidden (view full) --- 2246 * This is called once the rest of the system is up and running and we're 2247 * ready to let the AP's out of the pen. 2248 */ 2249void 2250ap_init(void) 2251{ 2252 u_int apic_id; 2253 |
2254 /* spin until all the AP's are ready */ 2255 while (!aps_ready) 2256 /* spin */ ; 2257 |
|
2250 /* lock against other AP's that are waking up */ | 2258 /* lock against other AP's that are waking up */ |
2251 s_lock(&ap_boot_lock); | 2259 mtx_enter(&ap_boot_mtx, MTX_SPIN); |
2252 2253 /* BSP may have changed PTD while we're waiting for the lock */ 2254 cpu_invltlb(); 2255 2256 smp_cpus++; 2257 2258#if defined(I586_CPU) && !defined(NO_F00F_HACK) 2259 lidt(&r_idt); --- 32 unchanged lines hidden (view full) --- 2292 */ 2293 if (smp_cpus == mp_ncpus) { 2294 invltlb_ok = 1; 2295 smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */ 2296 smp_active = 1; /* historic */ 2297 } 2298 2299 /* let other AP's wake up now */ | 2260 2261 /* BSP may have changed PTD while we're waiting for the lock */ 2262 cpu_invltlb(); 2263 2264 smp_cpus++; 2265 2266#if defined(I586_CPU) && !defined(NO_F00F_HACK) 2267 lidt(&r_idt); --- 32 unchanged lines hidden (view full) --- 2300 */ 2301 if (smp_cpus == mp_ncpus) { 2302 invltlb_ok = 1; 2303 smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */ 2304 smp_active = 1; /* historic */ 2305 } 2306 2307 /* let other AP's wake up now */ |
2300 s_unlock(&ap_boot_lock); | 2308 mtx_exit(&ap_boot_mtx, MTX_SPIN); |
2301 2302 /* wait until all the AP's are up */ 2303 while (smp_started == 0) 2304 ; /* nothing */ 2305 2306 /* 2307 * Set curproc to our per-cpu idleproc so that mutexes have 2308 * something unique to lock with. --- 537 unchanged lines hidden (view full) --- 2846} 2847 2848void 2849smp_rendezvous(void (* setup_func)(void *), 2850 void (* action_func)(void *), 2851 void (* teardown_func)(void *), 2852 void *arg) 2853{ | 2309 2310 /* wait until all the AP's are up */ 2311 while (smp_started == 0) 2312 ; /* nothing */ 2313 2314 /* 2315 * Set curproc to our per-cpu idleproc so that mutexes have 2316 * something unique to lock with. --- 537 unchanged lines hidden (view full) --- 2854} 2855 2856void 2857smp_rendezvous(void (* setup_func)(void *), 2858 void (* action_func)(void *), 2859 void (* teardown_func)(void *), 2860 void *arg) 2861{ |
2854 u_int efl; 2855 | 2862 |
2856 /* obtain rendezvous lock */ | 2863 /* obtain rendezvous lock */ |
2857 s_lock(&smp_rv_lock); /* XXX sleep here? NOWAIT flag? */ | 2864 mtx_enter(&smp_rv_mtx, MTX_SPIN); |
2858 2859 /* set static function pointers */ 2860 smp_rv_setup_func = setup_func; 2861 smp_rv_action_func = action_func; 2862 smp_rv_teardown_func = teardown_func; 2863 smp_rv_func_arg = arg; 2864 smp_rv_waiters[0] = 0; 2865 smp_rv_waiters[1] = 0; 2866 | 2865 2866 /* set static function pointers */ 2867 smp_rv_setup_func = setup_func; 2868 smp_rv_action_func = action_func; 2869 smp_rv_teardown_func = teardown_func; 2870 smp_rv_func_arg = arg; 2871 smp_rv_waiters[0] = 0; 2872 smp_rv_waiters[1] = 0; 2873 |
2867 /* disable interrupts on this CPU, save interrupt status */ 2868 efl = read_eflags(); 2869 write_eflags(efl & ~PSL_I); 2870 2871 /* signal other processors, which will enter the IPI with interrupts off */ | 2874 /* 2875 * signal other processors, which will enter the IPI with interrupts off 2876 */ |
2872 all_but_self_ipi(XRENDEZVOUS_OFFSET); 2873 2874 /* call executor function */ 2875 smp_rendezvous_action(); 2876 | 2877 all_but_self_ipi(XRENDEZVOUS_OFFSET); 2878 2879 /* call executor function */ 2880 smp_rendezvous_action(); 2881 |
2877 /* restore interrupt flag */ 2878 write_eflags(efl); 2879 | |
2880 /* release lock */ | 2882 /* release lock */ |
2881 s_unlock(&smp_rv_lock); | 2883 mtx_exit(&smp_rv_mtx, MTX_SPIN); |
2882} 2883 2884void 2885release_aps(void *dummy __unused) 2886{ | 2884} 2885 2886void 2887release_aps(void *dummy __unused) 2888{ |
2887 s_unlock(&ap_boot_lock); | 2889 atomic_store_rel_int(&aps_ready, 1); |
2888} 2889 2890SYSINIT(start_aps, SI_SUB_SMP, SI_ORDER_FIRST, release_aps, NULL); | 2890} 2891 2892SYSINIT(start_aps, SI_SUB_SMP, SI_ORDER_FIRST, release_aps, NULL); |