mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
No C1-Clock Ramp disabling on AMD processors. The tiny drift
caused by the ramping changes should not cause TSCs to become noticeably out of sync on Xen systems. Signed-off-by: Keir Fraser <keir@xensource.com>
This commit is contained in:
1 parent
326db4216a
commit
695affde7f
3 files changed
-114
No files matched your search
@@ -3,20 +3,13 @@
|
||||
#include <xen/bitops.h>
|
||||
#include <xen/mm.h>
|
||||
#include <xen/smp.h>
|
||||
#include <xen/sched.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/hvm/vcpu.h>
|
||||
#include <asm/hvm/support.h>
|
||||
|
||||
|
||||
#include "cpu.h"
|
||||
|
||||
|
||||
#define AMD_C1_CLOCK_RAMP 0x80000084
|
||||
#define AMD_ADVPM_TSC_INVARIANT 0x80000007
|
||||
|
||||
/*
|
||||
* amd_flush_filter={on,off}. Forcibly Enable or disable the TLB flush
|
||||
* filter on AMD 64-bit processors.
|
||||
@@ -49,99 +42,6 @@ custom_param("amd_flush_filter", flush_filter);
|
||||
extern void vide(void);
|
||||
__asm__(".text\n.align 4\nvide: ret");
|
||||
|
||||
|
||||
/*
|
||||
* Check if C1-Clock ramping enabled in PMM7.CpuLowPwrEnh
|
||||
* On 8th-Generation cores only. Assume BIOS has setup
|
||||
* all Northbridges equivalently.
|
||||
*/
|
||||
|
||||
static int c1_ramp_8gen(void)
|
||||
{
|
||||
u32 l;
|
||||
|
||||
/* Read dev=0x18, function = 3, offset=0x87 */
|
||||
l = AMD_C1_CLOCK_RAMP;
|
||||
/* fill in dev (18) + function (3) */
|
||||
/* direct cfc/cf8 should be safe here */
|
||||
l += (((0x18) << 3) + 0x3) << 8;
|
||||
outl(l, 0xcf8);
|
||||
return (1 & (inl(0xcfc) >> 24));
|
||||
}
|
||||
|
||||
/*
|
||||
* returns TRUE if ok to use TSC
|
||||
*/
|
||||
|
||||
static int use_amd_tsc(struct cpuinfo_x86 *c)
|
||||
{
|
||||
if (c->x86 < 0xf) {
|
||||
/*
|
||||
* TSC drift doesn't exist on 7th Gen or less
|
||||
* However, OS still needs to consider effects
|
||||
* of P-state changes on TSC
|
||||
*/
|
||||
return 1;
|
||||
} else if ( cpuid_edx(AMD_ADVPM_TSC_INVARIANT) & 0x100 ) {
|
||||
/*
|
||||
* CPUID.AdvPowerMgmtInfo.TscInvariant
|
||||
* EDX bit 8, 8000_0007
|
||||
* Invariant TSC on 8th Gen or newer, use it
|
||||
* (assume all cores have invariant TSC)
|
||||
*/
|
||||
return 1;
|
||||
} else if ((mp_get_num_processors() == 1) && (c->x86_num_cores == 1)) {
|
||||
/*
|
||||
* OK to use TSC on uni-processor-uni-core
|
||||
* However, OS still needs to consider effects
|
||||
* of P-state changes on TSC
|
||||
*/
|
||||
return 1;
|
||||
} else if ( (mp_get_num_processors() == 1) && (c->x86 == 0x0f)
|
||||
&& !c1_ramp_8gen()) {
|
||||
/*
|
||||
* Use TSC on 8th Gen uni-proc with C1_ramp off
|
||||
* However, OS still needs to consider effects
|
||||
* of P-state changes on TSC
|
||||
*/
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable C1-Clock ramping if enabled in PMM7.CpuLowPwrEnh
|
||||
* On 8th-Generation cores only. Assume BIOS has setup
|
||||
* all Northbridges equivalently.
|
||||
*/
|
||||
|
||||
static void amd_disable_c1_ramping(void)
|
||||
{
|
||||
u32 l, h;
|
||||
int i;
|
||||
|
||||
for (i=0; i < NR_CPUS;i++) {
|
||||
/* Read from the Northbridge for Node x. until we get invalid data */
|
||||
/* fill in dev (18 + cpu#) + function (3) */
|
||||
l = AMD_C1_CLOCK_RAMP + ((((0x18 + i) << 3) + 0x3) << 8);
|
||||
/* direct cfc/cf8 should be safe here */
|
||||
outl(l, 0xcf8);
|
||||
h = inl(0xcfc);
|
||||
if (h != 0xFFFFFFFF) {
|
||||
h &= 0xFCFFFFFF; /* clears pmm7[1:0] */
|
||||
outl(l, 0xcf8);
|
||||
outl(h, 0xcfc);
|
||||
printk ("AMD: Disabling C1 Clock Ramping Node #%x\n",i);
|
||||
}
|
||||
else {
|
||||
i = NR_CPUS;
|
||||
}
|
||||
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void __init init_amd(struct cpuinfo_x86 *c)
|
||||
{
|
||||
u32 l, h;
|
||||
@@ -347,14 +247,6 @@ static void __init init_amd(struct cpuinfo_x86 *c)
|
||||
cpu, c->x86_num_cores, cpu_core_id[cpu]);
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Prevent TSC drift in non single-processor, single-core platforms
|
||||
*/
|
||||
if ( !use_amd_tsc(c) && (c->x86 == 0x0f) && c1_ramp_8gen() &&
|
||||
(smp_processor_id() == 0)) {
|
||||
/* Disable c1 Clock Ramping on all cores */
|
||||
amd_disable_c1_ramping();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SVM
|
||||
start_svm();
|
||||
|
||||
@@ -730,11 +730,6 @@ void __init get_smp_config (void)
|
||||
*/
|
||||
}
|
||||
|
||||
int __init mp_get_num_processors(void)
|
||||
{
|
||||
return num_processors;
|
||||
}
|
||||
|
||||
static int __init smp_scan_config (unsigned long base, unsigned long length)
|
||||
{
|
||||
unsigned int *bp = maddr_to_virt(base);
|
||||
|
||||
@@ -35,7 +35,6 @@ extern void mp_register_ioapic (u8 id, u32 address, u32 gsi_base);
|
||||
extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, u32 gsi);
|
||||
extern void mp_config_acpi_legacy_irqs (void);
|
||||
extern int mp_register_gsi (u32 gsi, int edge_level, int active_high_low);
|
||||
extern int mp_get_num_processors(void);
|
||||
#endif /*CONFIG_ACPI_BOOT*/
|
||||
|
||||
#define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_APICS)
|
||||
|
||||