mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
Merge branch 'x86/apic' into x86/x2apic
Conflicts: arch/x86/kernel/paravirt.c arch/x86/kernel/smpboot.c arch/x86/kernel/vmi_32.c arch/x86/lguest/boot.c arch/x86/xen/enlighten.c include/asm-x86/apic.h include/asm-x86/paravirt.h Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
commit
453c1404c5
@ -362,10 +362,6 @@ config X86_ALIGNMENT_16
|
||||
def_bool y
|
||||
depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
|
||||
|
||||
config X86_GOOD_APIC
|
||||
def_bool y
|
||||
depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8 || MEFFICEON || MCORE2 || MVIAC7 || X86_64
|
||||
|
||||
config X86_INTEL_USERCOPY
|
||||
def_bool y
|
||||
depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON || MCORE2
|
||||
|
@ -75,7 +75,7 @@ char system_vectors[NR_VECTORS] = { [0 ... NR_VECTORS-1] = SYS_VECTOR_FREE};
|
||||
/*
|
||||
* Debug level, exported for io_apic.c
|
||||
*/
|
||||
int apic_verbosity;
|
||||
unsigned int apic_verbosity;
|
||||
|
||||
int pic_mode;
|
||||
|
||||
@ -211,7 +211,7 @@ void __cpuinit enable_NMI_through_LVT0(void)
|
||||
/* Level triggered for 82489DX */
|
||||
if (!lapic_is_integrated())
|
||||
v |= APIC_LVT_LEVEL_TRIGGER;
|
||||
apic_write_around(APIC_LVT0, v);
|
||||
apic_write(APIC_LVT0, v);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -246,9 +246,6 @@ int lapic_get_maxlvt(void)
|
||||
* this function twice on the boot CPU, once with a bogus timeout
|
||||
* value, second time for real. The other (noncalibrating) CPUs
|
||||
* call this function only once, with the real, calibrated value.
|
||||
*
|
||||
* We do reads before writes even if unnecessary, to get around the
|
||||
* P5 APIC double write bug.
|
||||
*/
|
||||
static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen)
|
||||
{
|
||||
@ -263,18 +260,18 @@ static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen)
|
||||
if (!irqen)
|
||||
lvtt_value |= APIC_LVT_MASKED;
|
||||
|
||||
apic_write_around(APIC_LVTT, lvtt_value);
|
||||
apic_write(APIC_LVTT, lvtt_value);
|
||||
|
||||
/*
|
||||
* Divide PICLK by 16
|
||||
*/
|
||||
tmp_value = apic_read(APIC_TDCR);
|
||||
apic_write_around(APIC_TDCR, (tmp_value
|
||||
& ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE))
|
||||
| APIC_TDR_DIV_16);
|
||||
apic_write(APIC_TDCR,
|
||||
(tmp_value & ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE)) |
|
||||
APIC_TDR_DIV_16);
|
||||
|
||||
if (!oneshot)
|
||||
apic_write_around(APIC_TMICT, clocks/APIC_DIVISOR);
|
||||
apic_write(APIC_TMICT, clocks / APIC_DIVISOR);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -283,7 +280,7 @@ static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen)
|
||||
static int lapic_next_event(unsigned long delta,
|
||||
struct clock_event_device *evt)
|
||||
{
|
||||
apic_write_around(APIC_TMICT, delta);
|
||||
apic_write(APIC_TMICT, delta);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -312,7 +309,7 @@ static void lapic_timer_setup(enum clock_event_mode mode,
|
||||
case CLOCK_EVT_MODE_SHUTDOWN:
|
||||
v = apic_read(APIC_LVTT);
|
||||
v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
|
||||
apic_write_around(APIC_LVTT, v);
|
||||
apic_write(APIC_LVTT, v);
|
||||
break;
|
||||
case CLOCK_EVT_MODE_RESUME:
|
||||
/* Nothing to do here */
|
||||
@ -406,12 +403,7 @@ static void __init lapic_cal_handler(struct clock_event_device *dev)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the boot APIC
|
||||
*
|
||||
* Calibrate and verify the result.
|
||||
*/
|
||||
void __init setup_boot_APIC_clock(void)
|
||||
static int __init calibrate_APIC_clock(void)
|
||||
{
|
||||
struct clock_event_device *levt = &__get_cpu_var(lapic_events);
|
||||
const long pm_100ms = PMTMR_TICKS_PER_SEC/10;
|
||||
@ -421,24 +413,6 @@ void __init setup_boot_APIC_clock(void)
|
||||
long delta, deltapm;
|
||||
int pm_referenced = 0;
|
||||
|
||||
/*
|
||||
* The local apic timer can be disabled via the kernel
|
||||
* commandline or from the CPU detection code. Register the lapic
|
||||
* timer as a dummy clock event source on SMP systems, so the
|
||||
* broadcast mechanism is used. On UP systems simply ignore it.
|
||||
*/
|
||||
if (local_apic_timer_disabled) {
|
||||
/* No broadcast on UP ! */
|
||||
if (num_possible_cpus() > 1) {
|
||||
lapic_clockevent.mult = 1;
|
||||
setup_APIC_timer();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n"
|
||||
"calibrating APIC timer ...\n");
|
||||
|
||||
local_irq_disable();
|
||||
|
||||
/* Replace the global interrupt handler */
|
||||
@ -523,8 +497,6 @@ void __init setup_boot_APIC_clock(void)
|
||||
calibration_result / (1000000 / HZ),
|
||||
calibration_result % (1000000 / HZ));
|
||||
|
||||
local_apic_timer_verify_ok = 1;
|
||||
|
||||
/*
|
||||
* Do a sanity check on the APIC calibration result
|
||||
*/
|
||||
@ -532,12 +504,11 @@ void __init setup_boot_APIC_clock(void)
|
||||
local_irq_enable();
|
||||
printk(KERN_WARNING
|
||||
"APIC frequency too slow, disabling apic timer\n");
|
||||
/* No broadcast on UP ! */
|
||||
if (num_possible_cpus() > 1)
|
||||
setup_APIC_timer();
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
local_apic_timer_verify_ok = 1;
|
||||
|
||||
/* We trust the pm timer based calibration */
|
||||
if (!pm_referenced) {
|
||||
apic_printk(APIC_VERBOSE, "... verify APIC timer\n");
|
||||
@ -577,22 +548,55 @@ void __init setup_boot_APIC_clock(void)
|
||||
if (!local_apic_timer_verify_ok) {
|
||||
printk(KERN_WARNING
|
||||
"APIC timer disabled due to verification failure.\n");
|
||||
/* No broadcast on UP ! */
|
||||
if (num_possible_cpus() == 1)
|
||||
return;
|
||||
} else {
|
||||
/*
|
||||
* If nmi_watchdog is set to IO_APIC, we need the
|
||||
* PIT/HPET going. Otherwise register lapic as a dummy
|
||||
* device.
|
||||
*/
|
||||
if (nmi_watchdog != NMI_IO_APIC)
|
||||
lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY;
|
||||
else
|
||||
printk(KERN_WARNING "APIC timer registered as dummy,"
|
||||
" due to nmi_watchdog=%d!\n", nmi_watchdog);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the boot APIC
|
||||
*
|
||||
* Calibrate and verify the result.
|
||||
*/
|
||||
void __init setup_boot_APIC_clock(void)
|
||||
{
|
||||
/*
|
||||
* The local apic timer can be disabled via the kernel
|
||||
* commandline or from the CPU detection code. Register the lapic
|
||||
* timer as a dummy clock event source on SMP systems, so the
|
||||
* broadcast mechanism is used. On UP systems simply ignore it.
|
||||
*/
|
||||
if (local_apic_timer_disabled) {
|
||||
/* No broadcast on UP ! */
|
||||
if (num_possible_cpus() > 1) {
|
||||
lapic_clockevent.mult = 1;
|
||||
setup_APIC_timer();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n"
|
||||
"calibrating APIC timer ...\n");
|
||||
|
||||
if (calibrate_APIC_clock()) {
|
||||
/* No broadcast on UP ! */
|
||||
if (num_possible_cpus() > 1)
|
||||
setup_APIC_timer();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If nmi_watchdog is set to IO_APIC, we need the
|
||||
* PIT/HPET going. Otherwise register lapic as a dummy
|
||||
* device.
|
||||
*/
|
||||
if (nmi_watchdog != NMI_IO_APIC)
|
||||
lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY;
|
||||
else
|
||||
printk(KERN_WARNING "APIC timer registered as dummy,"
|
||||
" due to nmi_watchdog=%d!\n", nmi_watchdog);
|
||||
|
||||
/* Setup the lapic or request the broadcast */
|
||||
setup_APIC_timer();
|
||||
}
|
||||
@ -727,44 +731,44 @@ void clear_local_APIC(void)
|
||||
*/
|
||||
if (maxlvt >= 3) {
|
||||
v = ERROR_APIC_VECTOR; /* any non-zero vector will do */
|
||||
apic_write_around(APIC_LVTERR, v | APIC_LVT_MASKED);
|
||||
apic_write(APIC_LVTERR, v | APIC_LVT_MASKED);
|
||||
}
|
||||
/*
|
||||
* Careful: we have to set masks only first to deassert
|
||||
* any level-triggered sources.
|
||||
*/
|
||||
v = apic_read(APIC_LVTT);
|
||||
apic_write_around(APIC_LVTT, v | APIC_LVT_MASKED);
|
||||
apic_write(APIC_LVTT, v | APIC_LVT_MASKED);
|
||||
v = apic_read(APIC_LVT0);
|
||||
apic_write_around(APIC_LVT0, v | APIC_LVT_MASKED);
|
||||
apic_write(APIC_LVT0, v | APIC_LVT_MASKED);
|
||||
v = apic_read(APIC_LVT1);
|
||||
apic_write_around(APIC_LVT1, v | APIC_LVT_MASKED);
|
||||
apic_write(APIC_LVT1, v | APIC_LVT_MASKED);
|
||||
if (maxlvt >= 4) {
|
||||
v = apic_read(APIC_LVTPC);
|
||||
apic_write_around(APIC_LVTPC, v | APIC_LVT_MASKED);
|
||||
apic_write(APIC_LVTPC, v | APIC_LVT_MASKED);
|
||||
}
|
||||
|
||||
/* lets not touch this if we didn't frob it */
|
||||
#ifdef CONFIG_X86_MCE_P4THERMAL
|
||||
if (maxlvt >= 5) {
|
||||
v = apic_read(APIC_LVTTHMR);
|
||||
apic_write_around(APIC_LVTTHMR, v | APIC_LVT_MASKED);
|
||||
apic_write(APIC_LVTTHMR, v | APIC_LVT_MASKED);
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Clean APIC state for other OSs:
|
||||
*/
|
||||
apic_write_around(APIC_LVTT, APIC_LVT_MASKED);
|
||||
apic_write_around(APIC_LVT0, APIC_LVT_MASKED);
|
||||
apic_write_around(APIC_LVT1, APIC_LVT_MASKED);
|
||||
apic_write(APIC_LVTT, APIC_LVT_MASKED);
|
||||
apic_write(APIC_LVT0, APIC_LVT_MASKED);
|
||||
apic_write(APIC_LVT1, APIC_LVT_MASKED);
|
||||
if (maxlvt >= 3)
|
||||
apic_write_around(APIC_LVTERR, APIC_LVT_MASKED);
|
||||
apic_write(APIC_LVTERR, APIC_LVT_MASKED);
|
||||
if (maxlvt >= 4)
|
||||
apic_write_around(APIC_LVTPC, APIC_LVT_MASKED);
|
||||
apic_write(APIC_LVTPC, APIC_LVT_MASKED);
|
||||
|
||||
#ifdef CONFIG_X86_MCE_P4THERMAL
|
||||
if (maxlvt >= 5)
|
||||
apic_write_around(APIC_LVTTHMR, APIC_LVT_MASKED);
|
||||
apic_write(APIC_LVTTHMR, APIC_LVT_MASKED);
|
||||
#endif
|
||||
/* Integrated APIC (!82489DX) ? */
|
||||
if (lapic_is_integrated()) {
|
||||
@ -790,7 +794,7 @@ void disable_local_APIC(void)
|
||||
*/
|
||||
value = apic_read(APIC_SPIV);
|
||||
value &= ~APIC_SPIV_APIC_ENABLED;
|
||||
apic_write_around(APIC_SPIV, value);
|
||||
apic_write(APIC_SPIV, value);
|
||||
|
||||
/*
|
||||
* When LAPIC was disabled by the BIOS and enabled by the kernel,
|
||||
@ -899,8 +903,8 @@ void __init sync_Arb_IDs(void)
|
||||
apic_wait_icr_idle();
|
||||
|
||||
apic_printk(APIC_DEBUG, "Synchronizing Arb IDs.\n");
|
||||
apic_write_around(APIC_ICR, APIC_DEST_ALLINC | APIC_INT_LEVELTRIG
|
||||
| APIC_DM_INIT);
|
||||
apic_write(APIC_ICR,
|
||||
APIC_DEST_ALLINC | APIC_INT_LEVELTRIG | APIC_DM_INIT);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -936,16 +940,16 @@ void __init init_bsp_APIC(void)
|
||||
else
|
||||
value |= APIC_SPIV_FOCUS_DISABLED;
|
||||
value |= SPURIOUS_APIC_VECTOR;
|
||||
apic_write_around(APIC_SPIV, value);
|
||||
apic_write(APIC_SPIV, value);
|
||||
|
||||
/*
|
||||
* Set up the virtual wire mode.
|
||||
*/
|
||||
apic_write_around(APIC_LVT0, APIC_DM_EXTINT);
|
||||
apic_write(APIC_LVT0, APIC_DM_EXTINT);
|
||||
value = APIC_DM_NMI;
|
||||
if (!lapic_is_integrated()) /* 82489DX */
|
||||
value |= APIC_LVT_LEVEL_TRIGGER;
|
||||
apic_write_around(APIC_LVT1, value);
|
||||
apic_write(APIC_LVT1, value);
|
||||
}
|
||||
|
||||
static void __cpuinit lapic_setup_esr(void)
|
||||
@ -960,7 +964,7 @@ static void __cpuinit lapic_setup_esr(void)
|
||||
|
||||
/* enables sending errors */
|
||||
value = ERROR_APIC_VECTOR;
|
||||
apic_write_around(APIC_LVTERR, value);
|
||||
apic_write(APIC_LVTERR, value);
|
||||
/*
|
||||
* spec says clear errors after enabling vector.
|
||||
*/
|
||||
@ -1023,7 +1027,7 @@ void __cpuinit setup_local_APIC(void)
|
||||
*/
|
||||
value = apic_read(APIC_TASKPRI);
|
||||
value &= ~APIC_TPRI_MASK;
|
||||
apic_write_around(APIC_TASKPRI, value);
|
||||
apic_write(APIC_TASKPRI, value);
|
||||
|
||||
/*
|
||||
* After a crash, we no longer service the interrupts and a pending
|
||||
@ -1081,7 +1085,7 @@ void __cpuinit setup_local_APIC(void)
|
||||
* Set spurious IRQ vector
|
||||
*/
|
||||
value |= SPURIOUS_APIC_VECTOR;
|
||||
apic_write_around(APIC_SPIV, value);
|
||||
apic_write(APIC_SPIV, value);
|
||||
|
||||
/*
|
||||
* Set up LVT0, LVT1:
|
||||
@ -1103,7 +1107,7 @@ void __cpuinit setup_local_APIC(void)
|
||||
apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n",
|
||||
smp_processor_id());
|
||||
}
|
||||
apic_write_around(APIC_LVT0, value);
|
||||
apic_write(APIC_LVT0, value);
|
||||
|
||||
/*
|
||||
* only the BP should see the LINT1 NMI signal, obviously.
|
||||
@ -1114,7 +1118,7 @@ void __cpuinit setup_local_APIC(void)
|
||||
value = APIC_DM_NMI | APIC_LVT_MASKED;
|
||||
if (!integrated) /* 82489DX */
|
||||
value |= APIC_LVT_LEVEL_TRIGGER;
|
||||
apic_write_around(APIC_LVT1, value);
|
||||
apic_write(APIC_LVT1, value);
|
||||
}
|
||||
|
||||
void __cpuinit end_local_APIC_setup(void)
|
||||
@ -1125,7 +1129,7 @@ void __cpuinit end_local_APIC_setup(void)
|
||||
/* Disable the local apic timer */
|
||||
value = apic_read(APIC_LVTT);
|
||||
value |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
|
||||
apic_write_around(APIC_LVTT, value);
|
||||
apic_write(APIC_LVTT, value);
|
||||
|
||||
setup_apic_nmi_watchdog(NULL);
|
||||
apic_pm_activate();
|
||||
@ -1453,7 +1457,7 @@ void disconnect_bsp_APIC(int virt_wire_setup)
|
||||
value &= ~APIC_VECTOR_MASK;
|
||||
value |= APIC_SPIV_APIC_ENABLED;
|
||||
value |= 0xf;
|
||||
apic_write_around(APIC_SPIV, value);
|
||||
apic_write(APIC_SPIV, value);
|
||||
|
||||
if (!virt_wire_setup) {
|
||||
/*
|
||||
@ -1466,10 +1470,10 @@ void disconnect_bsp_APIC(int virt_wire_setup)
|
||||
APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED);
|
||||
value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
|
||||
value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT);
|
||||
apic_write_around(APIC_LVT0, value);
|
||||
apic_write(APIC_LVT0, value);
|
||||
} else {
|
||||
/* Disable LVT0 */
|
||||
apic_write_around(APIC_LVT0, APIC_LVT_MASKED);
|
||||
apic_write(APIC_LVT0, APIC_LVT_MASKED);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1483,7 +1487,7 @@ void disconnect_bsp_APIC(int virt_wire_setup)
|
||||
APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED);
|
||||
value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
|
||||
value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI);
|
||||
apic_write_around(APIC_LVT1, value);
|
||||
apic_write(APIC_LVT1, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok);
|
||||
/*
|
||||
* Debug level, exported for io_apic.c
|
||||
*/
|
||||
int apic_verbosity;
|
||||
unsigned int apic_verbosity;
|
||||
|
||||
/* Have we found an MP table */
|
||||
int smp_found_config;
|
||||
@ -386,7 +386,7 @@ static void setup_APIC_timer(void)
|
||||
|
||||
#define TICK_COUNT 100000000
|
||||
|
||||
static void __init calibrate_APIC_clock(void)
|
||||
static int __init calibrate_APIC_clock(void)
|
||||
{
|
||||
unsigned apic, apic_start;
|
||||
unsigned long tsc, tsc_start;
|
||||
@ -440,6 +440,17 @@ static void __init calibrate_APIC_clock(void)
|
||||
clockevent_delta2ns(0xF, &lapic_clockevent);
|
||||
|
||||
calibration_result = result / HZ;
|
||||
|
||||
/*
|
||||
* Do a sanity check on the APIC calibration result
|
||||
*/
|
||||
if (calibration_result < (1000000 / HZ)) {
|
||||
printk(KERN_WARNING
|
||||
"APIC frequency too slow, disabling apic timer\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -466,14 +477,7 @@ void __init setup_boot_APIC_clock(void)
|
||||
}
|
||||
|
||||
printk(KERN_INFO "Using local APIC timer interrupts.\n");
|
||||
calibrate_APIC_clock();
|
||||
|
||||
/*
|
||||
* Do a sanity check on the APIC calibration result
|
||||
*/
|
||||
if (calibration_result < (1000000 / HZ)) {
|
||||
printk(KERN_WARNING
|
||||
"APIC frequency too slow, disabling apic timer\n");
|
||||
if (calibrate_APIC_clock()) {
|
||||
/* No broadcast on UP ! */
|
||||
if (num_possible_cpus() > 1)
|
||||
setup_APIC_timer();
|
||||
|
@ -131,13 +131,7 @@ static void __init check_popad(void)
|
||||
* (for due to lack of "invlpg" and working WP on a i386)
|
||||
* - In order to run on anything without a TSC, we need to be
|
||||
* compiled for a i486.
|
||||
* - In order to support the local APIC on a buggy Pentium machine,
|
||||
* we need to be compiled with CONFIG_X86_GOOD_APIC disabled,
|
||||
* which happens implicitly if compiled for a Pentium or lower
|
||||
* (unless an advanced selection of CPU features is used) as an
|
||||
* otherwise config implies a properly working local APIC without
|
||||
* the need to do extra reads from the APIC.
|
||||
*/
|
||||
*/
|
||||
|
||||
static void __init check_config(void)
|
||||
{
|
||||
@ -151,21 +145,6 @@ static void __init check_config(void)
|
||||
if (boot_cpu_data.x86 == 3)
|
||||
panic("Kernel requires i486+ for 'invlpg' and other features");
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If we were told we had a good local APIC, check for buggy Pentia,
|
||||
* i.e. all B steppings and the C2 stepping of P54C when using their
|
||||
* integrated APIC (see 11AP erratum in "Pentium Processor
|
||||
* Specification Update").
|
||||
*/
|
||||
#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_GOOD_APIC)
|
||||
if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL
|
||||
&& cpu_has_apic
|
||||
&& boot_cpu_data.x86 == 5
|
||||
&& boot_cpu_data.x86_model == 2
|
||||
&& (boot_cpu_data.x86_mask < 6 || boot_cpu_data.x86_mask == 11))
|
||||
panic("Kernel compiled for PMMX+, assumes a local APIC without the read-before-write bug!");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -227,6 +227,16 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
|
||||
if (cpu_has_bts)
|
||||
ds_init_intel(c);
|
||||
|
||||
/*
|
||||
* See if we have a good local APIC by checking for buggy Pentia,
|
||||
* i.e. all B steppings and the C2 stepping of P54C when using their
|
||||
* integrated APIC (see 11AP erratum in "Pentium Processor
|
||||
* Specification Update").
|
||||
*/
|
||||
if (cpu_has_apic && (c->x86<<8 | c->x86_model<<4) == 0x520 &&
|
||||
(c->x86_mask < 0x6 || c->x86_mask == 0xb))
|
||||
set_cpu_cap(c, X86_FEATURE_11AP);
|
||||
|
||||
#ifdef CONFIG_X86_NUMAQ
|
||||
numaq_tsc_disable();
|
||||
#endif
|
||||
|
@ -102,7 +102,7 @@ static void intel_init_thermal(struct cpuinfo_x86 *c)
|
||||
/* The temperature transition interrupt handler setup */
|
||||
h = THERMAL_APIC_VECTOR; /* our delivery vector */
|
||||
h |= (APIC_DM_FIXED | APIC_LVT_MASKED); /* we'll mask till we're ready */
|
||||
apic_write_around(APIC_LVTTHMR, h);
|
||||
apic_write(APIC_LVTTHMR, h);
|
||||
|
||||
rdmsr(MSR_IA32_THERM_INTERRUPT, l, h);
|
||||
wrmsr(MSR_IA32_THERM_INTERRUPT, l | 0x03 , h);
|
||||
@ -114,7 +114,7 @@ static void intel_init_thermal(struct cpuinfo_x86 *c)
|
||||
wrmsr(MSR_IA32_MISC_ENABLE, l | (1<<3), h);
|
||||
|
||||
l = apic_read(APIC_LVTTHMR);
|
||||
apic_write_around(APIC_LVTTHMR, l & ~APIC_LVT_MASKED);
|
||||
apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED);
|
||||
printk(KERN_INFO "CPU%d: Thermal monitoring enabled\n", cpu);
|
||||
|
||||
/* enable thermal throttle processing */
|
||||
|
@ -756,7 +756,7 @@ void send_IPI_self(int vector)
|
||||
/*
|
||||
* Send the IPI. The write to APIC_ICR fires this off.
|
||||
*/
|
||||
apic_write_around(APIC_ICR, cfg);
|
||||
apic_write(APIC_ICR, cfg);
|
||||
}
|
||||
#endif /* !CONFIG_SMP */
|
||||
|
||||
@ -2029,7 +2029,7 @@ static void mask_lapic_irq(unsigned int irq)
|
||||
unsigned long v;
|
||||
|
||||
v = apic_read(APIC_LVT0);
|
||||
apic_write_around(APIC_LVT0, v | APIC_LVT_MASKED);
|
||||
apic_write(APIC_LVT0, v | APIC_LVT_MASKED);
|
||||
}
|
||||
|
||||
static void unmask_lapic_irq(unsigned int irq)
|
||||
@ -2037,7 +2037,7 @@ static void unmask_lapic_irq(unsigned int irq)
|
||||
unsigned long v;
|
||||
|
||||
v = apic_read(APIC_LVT0);
|
||||
apic_write_around(APIC_LVT0, v & ~APIC_LVT_MASKED);
|
||||
apic_write(APIC_LVT0, v & ~APIC_LVT_MASKED);
|
||||
}
|
||||
|
||||
static struct irq_chip lapic_chip __read_mostly = {
|
||||
@ -2167,7 +2167,7 @@ static inline void __init check_timer(void)
|
||||
* The AEOI mode will finish them in the 8259A
|
||||
* automatically.
|
||||
*/
|
||||
apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
|
||||
apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
|
||||
init_8259A(1);
|
||||
timer_ack = (nmi_watchdog == NMI_IO_APIC && !APIC_INTEGRATED(ver));
|
||||
|
||||
@ -2176,8 +2176,9 @@ static inline void __init check_timer(void)
|
||||
pin2 = ioapic_i8259.pin;
|
||||
apic2 = ioapic_i8259.apic;
|
||||
|
||||
printk(KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n",
|
||||
vector, apic1, pin1, apic2, pin2);
|
||||
apic_printk(APIC_QUIET, KERN_INFO "..TIMER: vector=0x%02X "
|
||||
"apic1=%d pin1=%d apic2=%d pin2=%d\n",
|
||||
vector, apic1, pin1, apic2, pin2);
|
||||
|
||||
/*
|
||||
* Some BIOS writers are clueless and report the ExtINTA
|
||||
@ -2215,12 +2216,13 @@ static inline void __init check_timer(void)
|
||||
}
|
||||
clear_IO_APIC_pin(apic1, pin1);
|
||||
if (!no_pin1)
|
||||
printk(KERN_ERR "..MP-BIOS bug: "
|
||||
"8254 timer not connected to IO-APIC\n");
|
||||
apic_printk(APIC_QUIET, KERN_ERR "..MP-BIOS bug: "
|
||||
"8254 timer not connected to IO-APIC\n");
|
||||
|
||||
printk(KERN_INFO "...trying to set up timer (IRQ0) "
|
||||
"through the 8259A ... ");
|
||||
printk("\n..... (found pin %d) ...", pin2);
|
||||
apic_printk(APIC_QUIET, KERN_INFO "...trying to set up timer "
|
||||
"(IRQ0) through the 8259A ...\n");
|
||||
apic_printk(APIC_QUIET, KERN_INFO
|
||||
"..... (found apic %d pin %d) ...\n", apic2, pin2);
|
||||
/*
|
||||
* legacy devices should be connected to IO APIC #0
|
||||
*/
|
||||
@ -2229,7 +2231,7 @@ static inline void __init check_timer(void)
|
||||
unmask_IO_APIC_irq(0);
|
||||
enable_8259A_irq(0);
|
||||
if (timer_irq_works()) {
|
||||
printk("works.\n");
|
||||
apic_printk(APIC_QUIET, KERN_INFO "....... works.\n");
|
||||
timer_through_8259 = 1;
|
||||
if (nmi_watchdog == NMI_IO_APIC) {
|
||||
disable_8259A_irq(0);
|
||||
@ -2243,44 +2245,47 @@ static inline void __init check_timer(void)
|
||||
*/
|
||||
disable_8259A_irq(0);
|
||||
clear_IO_APIC_pin(apic2, pin2);
|
||||
printk(" failed.\n");
|
||||
apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n");
|
||||
}
|
||||
|
||||
if (nmi_watchdog == NMI_IO_APIC) {
|
||||
printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n");
|
||||
apic_printk(APIC_QUIET, KERN_WARNING "timer doesn't work "
|
||||
"through the IO-APIC - disabling NMI Watchdog!\n");
|
||||
nmi_watchdog = NMI_NONE;
|
||||
}
|
||||
timer_ack = 0;
|
||||
|
||||
printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ...");
|
||||
apic_printk(APIC_QUIET, KERN_INFO
|
||||
"...trying to set up timer as Virtual Wire IRQ...\n");
|
||||
|
||||
lapic_register_intr(0, vector);
|
||||
apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */
|
||||
apic_write(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */
|
||||
enable_8259A_irq(0);
|
||||
|
||||
if (timer_irq_works()) {
|
||||
printk(" works.\n");
|
||||
apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
|
||||
goto out;
|
||||
}
|
||||
disable_8259A_irq(0);
|
||||
apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | vector);
|
||||
printk(" failed.\n");
|
||||
apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | vector);
|
||||
apic_printk(APIC_QUIET, KERN_INFO "..... failed.\n");
|
||||
|
||||
printk(KERN_INFO "...trying to set up timer as ExtINT IRQ...");
|
||||
apic_printk(APIC_QUIET, KERN_INFO
|
||||
"...trying to set up timer as ExtINT IRQ...\n");
|
||||
|
||||
init_8259A(0);
|
||||
make_8259A_irq(0);
|
||||
apic_write_around(APIC_LVT0, APIC_DM_EXTINT);
|
||||
apic_write(APIC_LVT0, APIC_DM_EXTINT);
|
||||
|
||||
unlock_ExtINT_logic();
|
||||
|
||||
if (timer_irq_works()) {
|
||||
printk(" works.\n");
|
||||
apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
|
||||
goto out;
|
||||
}
|
||||
printk(" failed :(.\n");
|
||||
apic_printk(APIC_QUIET, KERN_INFO "..... failed :(.\n");
|
||||
panic("IO-APIC + timer doesn't work! Boot with apic=debug and send a "
|
||||
"report. Then try booting with the 'noapic' option");
|
||||
"report. Then try booting with the 'noapic' option.\n");
|
||||
out:
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include <asm/proto.h>
|
||||
#include <asm/acpi.h>
|
||||
#include <asm/dma.h>
|
||||
#include <asm/i8259.h>
|
||||
#include <asm/nmi.h>
|
||||
#include <asm/msidef.h>
|
||||
#include <asm/hypertransport.h>
|
||||
@ -2010,8 +2011,9 @@ static inline void __init check_timer(void)
|
||||
pin2 = ioapic_i8259.pin;
|
||||
apic2 = ioapic_i8259.apic;
|
||||
|
||||
apic_printk(APIC_VERBOSE,KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n",
|
||||
cfg->vector, apic1, pin1, apic2, pin2);
|
||||
apic_printk(APIC_QUIET, KERN_INFO "..TIMER: vector=0x%02X "
|
||||
"apic1=%d pin1=%d apic2=%d pin2=%d\n",
|
||||
cfg->vector, apic1, pin1, apic2, pin2);
|
||||
|
||||
/*
|
||||
* Some BIOS writers are clueless and report the ExtINTA
|
||||
@ -2053,14 +2055,13 @@ static inline void __init check_timer(void)
|
||||
panic("timer doesn't work through Interrupt-remapped IO-APIC");
|
||||
clear_IO_APIC_pin(apic1, pin1);
|
||||
if (!no_pin1)
|
||||
apic_printk(APIC_QUIET,KERN_ERR "..MP-BIOS bug: "
|
||||
apic_printk(APIC_QUIET, KERN_ERR "..MP-BIOS bug: "
|
||||
"8254 timer not connected to IO-APIC\n");
|
||||
|
||||
apic_printk(APIC_VERBOSE,KERN_INFO
|
||||
"...trying to set up timer (IRQ0) "
|
||||
"through the 8259A ... ");
|
||||
apic_printk(APIC_VERBOSE,"\n..... (found apic %d pin %d) ...",
|
||||
apic2, pin2);
|
||||
apic_printk(APIC_QUIET, KERN_INFO "...trying to set up timer "
|
||||
"(IRQ0) through the 8259A ...\n");
|
||||
apic_printk(APIC_QUIET, KERN_INFO
|
||||
"..... (found apic %d pin %d) ...\n", apic2, pin2);
|
||||
/*
|
||||
* legacy devices should be connected to IO APIC #0
|
||||
*/
|
||||
@ -2069,7 +2070,7 @@ static inline void __init check_timer(void)
|
||||
unmask_IO_APIC_irq(0);
|
||||
enable_8259A_irq(0);
|
||||
if (timer_irq_works()) {
|
||||
apic_printk(APIC_VERBOSE," works.\n");
|
||||
apic_printk(APIC_QUIET, KERN_INFO "....... works.\n");
|
||||
timer_through_8259 = 1;
|
||||
if (nmi_watchdog == NMI_IO_APIC) {
|
||||
disable_8259A_irq(0);
|
||||
@ -2083,29 +2084,32 @@ static inline void __init check_timer(void)
|
||||
*/
|
||||
disable_8259A_irq(0);
|
||||
clear_IO_APIC_pin(apic2, pin2);
|
||||
apic_printk(APIC_VERBOSE," failed.\n");
|
||||
apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n");
|
||||
}
|
||||
|
||||
if (nmi_watchdog == NMI_IO_APIC) {
|
||||
printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n");
|
||||
apic_printk(APIC_QUIET, KERN_WARNING "timer doesn't work "
|
||||
"through the IO-APIC - disabling NMI Watchdog!\n");
|
||||
nmi_watchdog = NMI_NONE;
|
||||
}
|
||||
|
||||
apic_printk(APIC_VERBOSE, KERN_INFO "...trying to set up timer as Virtual Wire IRQ...");
|
||||
apic_printk(APIC_QUIET, KERN_INFO
|
||||
"...trying to set up timer as Virtual Wire IRQ...\n");
|
||||
|
||||
lapic_register_intr(0);
|
||||
apic_write(APIC_LVT0, APIC_DM_FIXED | cfg->vector); /* Fixed mode */
|
||||
enable_8259A_irq(0);
|
||||
|
||||
if (timer_irq_works()) {
|
||||
apic_printk(APIC_VERBOSE," works.\n");
|
||||
apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
|
||||
goto out;
|
||||
}
|
||||
disable_8259A_irq(0);
|
||||
apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | cfg->vector);
|
||||
apic_printk(APIC_VERBOSE," failed.\n");
|
||||
apic_printk(APIC_QUIET, KERN_INFO "..... failed.\n");
|
||||
|
||||
apic_printk(APIC_VERBOSE, KERN_INFO "...trying to set up timer as ExtINT IRQ...");
|
||||
apic_printk(APIC_QUIET, KERN_INFO
|
||||
"...trying to set up timer as ExtINT IRQ...\n");
|
||||
|
||||
init_8259A(0);
|
||||
make_8259A_irq(0);
|
||||
@ -2114,11 +2118,12 @@ static inline void __init check_timer(void)
|
||||
unlock_ExtINT_logic();
|
||||
|
||||
if (timer_irq_works()) {
|
||||
apic_printk(APIC_VERBOSE," works.\n");
|
||||
apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
|
||||
goto out;
|
||||
}
|
||||
apic_printk(APIC_VERBOSE," failed :(.\n");
|
||||
panic("IO-APIC + timer doesn't work! Try using the 'noapic' kernel parameter\n");
|
||||
apic_printk(APIC_QUIET, KERN_INFO "..... failed :(.\n");
|
||||
panic("IO-APIC + timer doesn't work! Boot with apic=debug and send a "
|
||||
"report. Then try booting with the 'noapic' option.\n");
|
||||
out:
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ void __send_IPI_shortcut(unsigned int shortcut, int vector)
|
||||
/*
|
||||
* Send the IPI. The write to APIC_ICR fires this off.
|
||||
*/
|
||||
apic_write_around(APIC_ICR, cfg);
|
||||
apic_write(APIC_ICR, cfg);
|
||||
}
|
||||
|
||||
void send_IPI_self(int vector)
|
||||
@ -98,7 +98,7 @@ static inline void __send_IPI_dest_field(unsigned long mask, int vector)
|
||||
* prepare target chip field
|
||||
*/
|
||||
cfg = __prepare_ICR2(mask);
|
||||
apic_write_around(APIC_ICR2, cfg);
|
||||
apic_write(APIC_ICR2, cfg);
|
||||
|
||||
/*
|
||||
* program the ICR
|
||||
@ -108,7 +108,7 @@ static inline void __send_IPI_dest_field(unsigned long mask, int vector)
|
||||
/*
|
||||
* Send the IPI. The write to APIC_ICR fires this off.
|
||||
*/
|
||||
apic_write_around(APIC_ICR, cfg);
|
||||
apic_write(APIC_ICR, cfg);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -263,7 +263,7 @@ late_initcall(init_lapic_nmi_sysfs);
|
||||
|
||||
static void __acpi_nmi_enable(void *__unused)
|
||||
{
|
||||
apic_write_around(APIC_LVT0, APIC_DM_NMI);
|
||||
apic_write(APIC_LVT0, APIC_DM_NMI);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -277,7 +277,7 @@ void acpi_nmi_enable(void)
|
||||
|
||||
static void __acpi_nmi_disable(void *__unused)
|
||||
{
|
||||
apic_write_around(APIC_LVT0, APIC_DM_NMI | APIC_LVT_MASKED);
|
||||
apic_write(APIC_LVT0, APIC_DM_NMI | APIC_LVT_MASKED);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -590,14 +590,9 @@ wakeup_secondary_cpu(int logical_apicid, unsigned long start_eip)
|
||||
* Give the other CPU some time to accept the IPI.
|
||||
*/
|
||||
udelay(200);
|
||||
/*
|
||||
* Due to the Pentium erratum 3AP.
|
||||
*/
|
||||
maxlvt = lapic_get_maxlvt();
|
||||
if (maxlvt > 3) {
|
||||
apic_read_around(APIC_SPIV);
|
||||
if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */
|
||||
apic_write(APIC_ESR, 0);
|
||||
}
|
||||
accept_status = (apic_read(APIC_ESR) & 0xEF);
|
||||
Dprintk("NMI sent.\n");
|
||||
|
||||
@ -623,12 +618,14 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip)
|
||||
return send_status;
|
||||
}
|
||||
|
||||
maxlvt = lapic_get_maxlvt();
|
||||
|
||||
/*
|
||||
* Be paranoid about clearing APIC errors.
|
||||
*/
|
||||
if (APIC_INTEGRATED(apic_version[phys_apicid])) {
|
||||
apic_read_around(APIC_SPIV);
|
||||
apic_write(APIC_ESR, 0);
|
||||
if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */
|
||||
apic_write(APIC_ESR, 0);
|
||||
apic_read(APIC_ESR);
|
||||
}
|
||||
|
||||
@ -683,12 +680,10 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip)
|
||||
*/
|
||||
Dprintk("#startup loops: %d.\n", num_starts);
|
||||
|
||||
maxlvt = lapic_get_maxlvt();
|
||||
|
||||
for (j = 1; j <= num_starts; j++) {
|
||||
Dprintk("Sending STARTUP #%d.\n", j);
|
||||
apic_read_around(APIC_SPIV);
|
||||
apic_write(APIC_ESR, 0);
|
||||
if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */
|
||||
apic_write(APIC_ESR, 0);
|
||||
apic_read(APIC_ESR);
|
||||
Dprintk("After apic_write.\n");
|
||||
|
||||
@ -716,13 +711,8 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip)
|
||||
* Give the other CPU some time to accept the IPI.
|
||||
*/
|
||||
udelay(200);
|
||||
/*
|
||||
* Due to the Pentium erratum 3AP.
|
||||
*/
|
||||
if (maxlvt > 3) {
|
||||
apic_read_around(APIC_SPIV);
|
||||
if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */
|
||||
apic_write(APIC_ESR, 0);
|
||||
}
|
||||
accept_status = (apic_read(APIC_ESR) & 0xEF);
|
||||
if (send_status || accept_status)
|
||||
break;
|
||||
|
@ -906,7 +906,6 @@ static inline int __init activate_vmi(void)
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
para_fill(apic_ops->read, APICRead);
|
||||
para_fill(apic_ops->write, APICWrite);
|
||||
para_fill(apic_ops->write_atomic, APICWrite);
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -816,7 +816,6 @@ static u32 lguest_apic_safe_wait_icr_idle(void)
|
||||
static struct apic_ops lguest_basic_apic_ops = {
|
||||
.read = lguest_apic_read,
|
||||
.write = lguest_apic_write,
|
||||
.write_atomic = lguest_apic_write,
|
||||
.icr_read = lguest_apic_icr_read,
|
||||
.icr_write = lguest_apic_icr_write,
|
||||
.wait_icr_idle = lguest_apic_wait_icr_idle,
|
||||
|
@ -583,7 +583,6 @@ static u32 xen_safe_apic_wait_icr_idle(void)
|
||||
static struct apic_ops xen_basic_apic_ops = {
|
||||
.read = xen_apic_read,
|
||||
.write = xen_apic_write,
|
||||
.write_atomic = xen_apic_write,
|
||||
.icr_read = xen_apic_icr_read,
|
||||
.icr_write = xen_apic_icr_write,
|
||||
.wait_icr_idle = xen_apic_wait_icr_idle,
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
#include <linux/pm.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <asm/alternative.h>
|
||||
#include <asm/fixmap.h>
|
||||
#include <asm/apicdef.h>
|
||||
#include <asm/processor.h>
|
||||
@ -12,7 +14,7 @@
|
||||
|
||||
#define ARCH_APICTIMER_STOPS_ON_C3 1
|
||||
|
||||
#define Dprintk(x...)
|
||||
#define Dprintk printk
|
||||
|
||||
/*
|
||||
* Debugging macros
|
||||
@ -37,7 +39,7 @@ extern void generic_apic_probe(void);
|
||||
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
|
||||
extern int apic_verbosity;
|
||||
extern unsigned int apic_verbosity;
|
||||
extern int local_apic_timer_c2_ok;
|
||||
|
||||
extern int ioapic_force;
|
||||
@ -57,12 +59,11 @@ extern int is_vsmp_box(void);
|
||||
|
||||
static inline void native_apic_mem_write(u32 reg, u32 v)
|
||||
{
|
||||
*((volatile u32 *)(APIC_BASE + reg)) = v;
|
||||
}
|
||||
volatile u32 *addr = (volatile u32 *)(APIC_BASE + reg);
|
||||
|
||||
static inline void native_apic_mem_write_atomic(u32 reg, u32 v)
|
||||
{
|
||||
(void)xchg((u32 *)(APIC_BASE + reg), v);
|
||||
alternative_io("movl %0, %1", "xchgl %0, %1", X86_FEATURE_11AP,
|
||||
ASM_OUTPUT2("=r" (v), "=m" (*addr)),
|
||||
ASM_OUTPUT2("0" (v), "m" (*addr)));
|
||||
}
|
||||
|
||||
static inline u32 native_apic_mem_read(u32 reg)
|
||||
@ -101,7 +102,6 @@ extern void x2apic_icr_write(u32 low, u32 id);
|
||||
struct apic_ops {
|
||||
u32 (*read)(u32 reg);
|
||||
void (*write)(u32 reg, u32 v);
|
||||
void (*write_atomic)(u32 reg, u32 v);
|
||||
u64 (*icr_read)(void);
|
||||
void (*icr_write)(u32 low, u32 high);
|
||||
void (*wait_icr_idle)(void);
|
||||
@ -112,7 +112,6 @@ extern struct apic_ops *apic_ops;
|
||||
|
||||
#define apic_read (apic_ops->read)
|
||||
#define apic_write (apic_ops->write)
|
||||
#define apic_write_atomic (apic_ops->write_atomic)
|
||||
#define apic_icr_read (apic_ops->icr_read)
|
||||
#define apic_icr_write (apic_ops->icr_write)
|
||||
#define apic_wait_icr_idle (apic_ops->wait_icr_idle)
|
||||
@ -120,16 +119,6 @@ extern struct apic_ops *apic_ops;
|
||||
|
||||
extern int get_physical_broadcast(void);
|
||||
|
||||
#ifdef CONFIG_X86_GOOD_APIC
|
||||
# define FORCE_READ_AROUND_WRITE 0
|
||||
# define apic_read_around(x)
|
||||
# define apic_write_around(x, y) apic_write((x), (y))
|
||||
#else
|
||||
# define FORCE_READ_AROUND_WRITE 1
|
||||
# define apic_read_around(x) apic_read(x)
|
||||
# define apic_write_around(x, y) apic_write_atomic((x), (y))
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
static inline void ack_x2APIC_irq(void)
|
||||
{
|
||||
@ -150,7 +139,7 @@ static inline void ack_APIC_irq(void)
|
||||
|
||||
/* Docs say use 0 for future compatibility */
|
||||
#ifdef CONFIG_X86_32
|
||||
apic_write_around(APIC_EOI, 0);
|
||||
apic_write(APIC_EOI, 0);
|
||||
#else
|
||||
native_apic_mem_write(APIC_EOI, 0);
|
||||
#endif
|
||||
|
@ -79,6 +79,7 @@
|
||||
#define X86_FEATURE_REP_GOOD (3*32+16) /* rep microcode works well on this CPU */
|
||||
#define X86_FEATURE_MFENCE_RDTSC (3*32+17) /* Mfence synchronizes RDTSC */
|
||||
#define X86_FEATURE_LFENCE_RDTSC (3*32+18) /* Lfence synchronizes RDTSC */
|
||||
#define X86_FEATURE_11AP (3*32+19) /* Bad local APIC aka 11AP */
|
||||
|
||||
/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
|
||||
#define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */
|
||||
|
@ -63,9 +63,9 @@ static inline void init_apic_ldr(void)
|
||||
unsigned long val;
|
||||
int cpu = smp_processor_id();
|
||||
|
||||
apic_write_around(APIC_DFR, APIC_DFR_VALUE);
|
||||
apic_write(APIC_DFR, APIC_DFR_VALUE);
|
||||
val = calculate_ldr(cpu);
|
||||
apic_write_around(APIC_LDR, val);
|
||||
apic_write(APIC_LDR, val);
|
||||
}
|
||||
|
||||
static inline void setup_apic_routing(void)
|
||||
|
@ -48,10 +48,10 @@ static inline void init_apic_ldr(void)
|
||||
{
|
||||
unsigned long val;
|
||||
|
||||
apic_write_around(APIC_DFR, APIC_DFR_VALUE);
|
||||
apic_write(APIC_DFR, APIC_DFR_VALUE);
|
||||
val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
|
||||
val |= SET_APIC_LOGICAL_ID(1UL << smp_processor_id());
|
||||
apic_write_around(APIC_LDR, val);
|
||||
apic_write(APIC_LDR, val);
|
||||
}
|
||||
|
||||
static inline int apic_id_registered(void)
|
||||
|
@ -66,9 +66,9 @@ static inline void init_apic_ldr(void)
|
||||
unsigned long val;
|
||||
int cpu = smp_processor_id();
|
||||
|
||||
apic_write_around(APIC_DFR, APIC_DFR_VALUE);
|
||||
apic_write(APIC_DFR, APIC_DFR_VALUE);
|
||||
val = calculate_ldr(cpu);
|
||||
apic_write_around(APIC_LDR, val);
|
||||
apic_write(APIC_LDR, val);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_X86_GENERICARCH
|
||||
|
@ -63,10 +63,10 @@ static inline void init_apic_ldr(void)
|
||||
* BIOS puts 5 CPUs in one APIC cluster, we're hosed. */
|
||||
BUG_ON(count >= XAPIC_DEST_CPUS_SHIFT);
|
||||
id = my_cluster | (1UL << count);
|
||||
apic_write_around(APIC_DFR, APIC_DFR_VALUE);
|
||||
apic_write(APIC_DFR, APIC_DFR_VALUE);
|
||||
val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
|
||||
val |= SET_APIC_LOGICAL_ID(id);
|
||||
apic_write_around(APIC_LDR, val);
|
||||
apic_write(APIC_LDR, val);
|
||||
}
|
||||
|
||||
static inline int multi_timer_check(int apic, int irq)
|
||||
|
Loading…
x
Reference in New Issue
Block a user