]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/xen.git/commitdiff
cpuidle: Add support for Always Running APIC timer, CPUID_0x6_EAX_Bit2.
authorKeir Fraser <keir.fraser@citrix.com>
Fri, 17 Apr 2009 12:14:01 +0000 (13:14 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Fri, 17 Apr 2009 12:14:01 +0000 (13:14 +0100)
This bit means the APIC timer continues to run even when CPU is
in deep C-states.

The advantage is that we can use LAPIC timer on these CPUs
always, and there is no need for "slow to read and program"
external timers (HPET/PIT) and the timer broadcast logic
and related code in C-state entry and exit.

Refer to the latest Intel SDM Vol 2A
(http://www.intel.com/products/processor/manuals/index.htm)

Signed-off-by: Wei Gang <gang.wei@intel.com>
xen/arch/x86/acpi/cpu_idle.c
xen/arch/x86/cpu/intel.c
xen/arch/x86/time.c
xen/include/asm-x86/cpufeature.h

index b302f15a7c155afb63b9c387cb633d90df827a5d..068519402952fa21785da64c365c3ccad037c3ac 100644 (file)
@@ -51,6 +51,7 @@
 
 /*#define DEBUG_PM_CX*/
 
+static void lapic_timer_nop(void) { }
 static void (*lapic_timer_off)(void);
 static void (*lapic_timer_on)(void);
 
@@ -538,8 +539,12 @@ static int check_cx(struct acpi_processor_power *power, xen_processor_cx_t *cx)
         if ( local_apic_timer_c2_ok )
             break;
     case ACPI_STATE_C3:
-        /* We must be able to use HPET in place of LAPIC timers. */
-        if ( hpet_broadcast_is_available() )
+        if ( boot_cpu_has(X86_FEATURE_ARAT) )
+        {
+            lapic_timer_off = lapic_timer_nop;
+            lapic_timer_on = lapic_timer_nop;
+        }
+        else if ( hpet_broadcast_is_available() )
         {
             lapic_timer_off = hpet_broadcast_enter;
             lapic_timer_on = hpet_broadcast_exit;
index 1574004f6cb7e48db31977a03945f6135172224b..4715f3438c9869293b50f3900a6491d2173d3832 100644 (file)
@@ -222,6 +222,9 @@ static void __devinit init_intel(struct cpuinfo_x86 *c)
                set_bit(X86_FEATURE_CONSTANT_TSC, c->x86_capability);
                set_bit(X86_FEATURE_NOSTOP_TSC, c->x86_capability);
        }
+       if ((c->cpuid_level >= 0x00000006) &&
+           (cpuid_eax(0x00000006) & (1u<<2)))
+               set_bit(X86_FEATURE_ARAT, c->x86_capability);
 
        start_vmx();
 }
index b44871e13936e0d63d950df52635bfdd8e56ce12..9e9ff9b45602c7d3ce962cfda9c2f411360cdd1d 100644 (file)
@@ -1274,7 +1274,7 @@ static int disable_pit_irq(void)
      * XXX dom0 may rely on RTC interrupt delivery, so only enable
      * hpet_broadcast if FSB mode available or if force_hpet_broadcast.
      */
-    if ( xen_cpuidle )
+    if ( xen_cpuidle && !boot_cpu_has(X86_FEATURE_ARAT) )
     {
         hpet_broadcast_init();
         if ( !hpet_broadcast_is_available() )
index 4c6eeabc55dc1f4e46896ce584fed972fd7d1cc2..f36d7070c0cdb181f4192b2489c2b0579e47bdda 100644 (file)
@@ -75,6 +75,7 @@
 #define X86_FEATURE_P4         (3*32+ 7) /* P4 */
 #define X86_FEATURE_CONSTANT_TSC (3*32+ 8) /* TSC ticks at a constant rate */
 #define X86_FEATURE_NOSTOP_TSC (3*32+ 9) /* TSC does not stop in C states */
+#define X86_FEATURE_ARAT       (3*32+ 10) /* Always running APIC timer */
 
 /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
 #define X86_FEATURE_XMM3       (4*32+ 0) /* Streaming SIMD Extensions-3 */