Deleted Added
full compact
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 ---