local_apic.c (122690) | local_apic.c (123133) |
---|---|
1/*- 2 * Copyright (c) 2003 John Baldwin <jhb@FreeBSD.org> 3 * Copyright (c) 1996, by Steve Passe 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 18 unchanged lines hidden (view full) --- 27 * SUCH DAMAGE. 28 */ 29 30/* 31 * Local APIC support on Pentium and later processors. 32 */ 33 34#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2003 John Baldwin <jhb@FreeBSD.org> 3 * Copyright (c) 1996, by Steve Passe 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 18 unchanged lines hidden (view full) --- 27 * SUCH DAMAGE. 28 */ 29 30/* 31 * Local APIC support on Pentium and later processors. 32 */ 33 34#include <sys/cdefs.h> |
35__FBSDID("$FreeBSD: head/sys/i386/i386/local_apic.c 122690 2003-11-14 19:10:13Z jhb $"); | 35__FBSDID("$FreeBSD: head/sys/i386/i386/local_apic.c 123133 2003-12-03 20:33:18Z jhb $"); |
36 37#include <sys/param.h> 38#include <sys/systm.h> 39#include <sys/bus.h> 40#include <sys/kernel.h> 41#include <sys/pcpu.h> 42 43#include <vm/vm.h> --- 488 unchanged lines hidden (view full) --- 532 panic("%s: Duplicate register of %s", __func__, 533 enumerator->apic_name); 534 } 535#endif 536 SLIST_INSERT_HEAD(&enumerators, enumerator, apic_next); 537} 538 539/* | 36 37#include <sys/param.h> 38#include <sys/systm.h> 39#include <sys/bus.h> 40#include <sys/kernel.h> 41#include <sys/pcpu.h> 42 43#include <vm/vm.h> --- 488 unchanged lines hidden (view full) --- 532 panic("%s: Duplicate register of %s", __func__, 533 enumerator->apic_name); 534 } 535#endif 536 SLIST_INSERT_HEAD(&enumerators, enumerator, apic_next); 537} 538 539/* |
540 * We have to look for CPU's very, very early because certain subsystems 541 * want to know how many CPU's we have extremely early on in the boot 542 * process. | 540 * Probe the APIC enumerators, enumerate CPUs, and initialize the 541 * local APIC. |
543 */ 544static void 545apic_init(void *dummy __unused) 546{ 547 struct apic_enumerator *enumerator; | 542 */ 543static void 544apic_init(void *dummy __unused) 545{ 546 struct apic_enumerator *enumerator; |
547 uint64_t apic_base; |
|
548 int retval, best; 549 550 /* We only support built in local APICs. */ 551 if (!(cpu_feature & CPUID_APIC)) 552 return; 553 | 548 int retval, best; 549 550 /* We only support built in local APICs. */ 551 if (!(cpu_feature & CPUID_APIC)) 552 return; 553 |
554 /* Don't probe if APIC mode is disabled. */ 555 if (resource_disabled("apic", 0)) 556 return; 557 |
|
554 /* First, probe all the enumerators to find the best match. */ 555 best_enum = NULL; 556 best = 0; 557 SLIST_FOREACH(enumerator, &enumerators, apic_next) { 558 retval = enumerator->apic_probe(); 559 if (retval > 0) 560 continue; 561 if (best_enum == NULL || best < retval) { --- 6 unchanged lines hidden (view full) --- 568 printf("APIC: Could not find any APICs.\n"); 569 return; 570 } 571 572 if (bootverbose) 573 printf("APIC: Using the %s enumerator.\n", 574 best_enum->apic_name); 575 | 558 /* First, probe all the enumerators to find the best match. */ 559 best_enum = NULL; 560 best = 0; 561 SLIST_FOREACH(enumerator, &enumerators, apic_next) { 562 retval = enumerator->apic_probe(); 563 if (retval > 0) 564 continue; 565 if (best_enum == NULL || best < retval) { --- 6 unchanged lines hidden (view full) --- 572 printf("APIC: Could not find any APICs.\n"); 573 return; 574 } 575 576 if (bootverbose) 577 printf("APIC: Using the %s enumerator.\n", 578 best_enum->apic_name); 579 |
576 /* Second, probe the CPU's in the system. */ 577 retval = best_enum->apic_probe_cpus(); 578 if (retval != 0) 579 printf("%s: Failed to probe CPUs: returned %d\n", 580 best_enum->apic_name, retval); 581} 582SYSINIT(apic_init, SI_SUB_TUNABLES - 1, SI_ORDER_SECOND, apic_init, NULL) 583 584/* 585 * Setup the local APIC. We have to do this prior to starting up the APs 586 * in the SMP case. 587 */ 588static void 589apic_setup_local(void *dummy __unused) 590{ 591 int retval; 592 uint64_t apic_base; 593 594 if (best_enum == NULL) 595 return; | |
596 /* 597 * To work around an errata, we disable the local APIC on some 598 * CPUs during early startup. We need to turn the local APIC back 599 * on on such CPUs now. 600 */ 601 if (cpu == CPU_686 && strcmp(cpu_vendor, "GenuineIntel") == 0 && 602 (cpu_id & 0xff0) == 0x610) { 603 apic_base = rdmsr(MSR_APICBASE); 604 apic_base |= APICBASE_ENABLED; 605 wrmsr(MSR_APICBASE, apic_base); 606 } | 580 /* 581 * To work around an errata, we disable the local APIC on some 582 * CPUs during early startup. We need to turn the local APIC back 583 * on on such CPUs now. 584 */ 585 if (cpu == CPU_686 && strcmp(cpu_vendor, "GenuineIntel") == 0 && 586 (cpu_id & 0xff0) == 0x610) { 587 apic_base = rdmsr(MSR_APICBASE); 588 apic_base |= APICBASE_ENABLED; 589 wrmsr(MSR_APICBASE, apic_base); 590 } |
591 592 /* Second, probe the CPU's in the system. */ 593 retval = best_enum->apic_probe_cpus(); 594 if (retval != 0) 595 printf("%s: Failed to probe CPUs: returned %d\n", 596 best_enum->apic_name, retval); 597 598 /* Third, initialize the local APIC. */ |
|
607 retval = best_enum->apic_setup_local(); 608 if (retval != 0) 609 printf("%s: Failed to setup the local APIC: returned %d\n", 610 best_enum->apic_name, retval); 611} | 599 retval = best_enum->apic_setup_local(); 600 if (retval != 0) 601 printf("%s: Failed to setup the local APIC: returned %d\n", 602 best_enum->apic_name, retval); 603} |
612SYSINIT(apic_setup_local, SI_SUB_CPU, SI_ORDER_FIRST, apic_setup_local, NULL) | 604SYSINIT(apic_init, SI_SUB_CPU, SI_ORDER_FIRST, apic_init, NULL) |
613 614/* 615 * Setup the I/O APICs. 616 */ 617static void 618apic_setup_io(void *dummy __unused) 619{ 620 int retval; --- 147 unchanged lines hidden --- | 605 606/* 607 * Setup the I/O APICs. 608 */ 609static void 610apic_setup_io(void *dummy __unused) 611{ 612 int retval; --- 147 unchanged lines hidden --- |