[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v4 01/11] x86/acpi: add a common interface for x86 cpu matching
Add a common interface for matching the current cpu against an array of x86_cpu_ids. Also change mwait-idle.c to use it. v4 changes: None. Signed-off-by: Wei Wang <wei.w.wang@xxxxxxxxx> --- xen/arch/x86/cpu/common.c | 38 ++++++++++++++++++++++++++++++++++++++ xen/arch/x86/cpu/mwait-idle.c | 28 +++++++++++----------------- xen/include/asm-x86/processor.h | 10 ++++++++++ 3 files changed, 59 insertions(+), 17 deletions(-) diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c index 53dbd84..e105aeb 100644 --- a/xen/arch/x86/cpu/common.c +++ b/xen/arch/x86/cpu/common.c @@ -637,3 +637,41 @@ void cpu_uninit(unsigned int cpu) { cpumask_clear_cpu(cpu, &cpu_initialized); } + +/* + * x86_match_cpu - match the current CPU against an array of + * x86_cpu_ids + * @match: Pointer to array of x86_cpu_ids. Last entry terminated with + * {}. + * Return the entry if the current CPU matches the entries in the + * passed x86_cpu_id match table. Otherwise NULL. The match table + * contains vendor (X86_VENDOR_*), family, model and feature bits or + * respective wildcard entries. + * + * A typical table entry would be to match a specific CPU + * { X86_VENDOR_INTEL, 6, 0x12 } + * or to match a specific CPU feature + * { X86_FEATURE_MATCH(X86_FEATURE_FOOBAR) } + * + * This always matches against the boot cpu, assuming models and +features are + * consistent over all CPUs. + */ +const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id table[]) +{ + const struct x86_cpu_id *m; + const struct cpuinfo_x86 *c = &boot_cpu_data; + + for (m = table; m->vendor | m->family | m->model | m->feature; m++) { + if (c->x86_vendor != m->vendor) + continue; + if (c->x86 != m->family) + continue; + if (c->x86_model != m->model) + continue; + if (!cpu_has(c, m->feature)) + continue; + return m; + } + return NULL; +} diff --git a/xen/arch/x86/cpu/mwait-idle.c b/xen/arch/x86/cpu/mwait-idle.c index 91b76ec..30cfc4c 100644 --- a/xen/arch/x86/cpu/mwait-idle.c +++ b/xen/arch/x86/cpu/mwait-idle.c @@ -689,12 +689,11 @@ static const struct idle_cpu idle_cpu_avn = { .disable_promotion_to_c1e = 1, }; -#define ICPU(model, cpu) { 6, model, &idle_cpu_##cpu } +#define ICPU(model, cpu) \ + { X86_VENDOR_INTEL, 6, model, X86_FEATURE_MWAIT, \ + &idle_cpu_##cpu} -static struct intel_idle_id { - unsigned int family, model; - const struct idle_cpu *data; -} intel_idle_ids[] __initdata = { +static const struct x86_cpu_id intel_idle_ids[] __initconst = { ICPU(0x1a, nehalem), ICPU(0x1e, nehalem), ICPU(0x1f, nehalem), @@ -757,23 +756,18 @@ static void __init mwait_idle_state_table_update(void) static int __init mwait_idle_probe(void) { unsigned int eax, ebx, ecx; - const struct intel_idle_id *id; + const struct x86_cpu_id *id; - if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL || - !boot_cpu_has(X86_FEATURE_MWAIT) || - boot_cpu_data.cpuid_level < CPUID_MWAIT_LEAF) - return -ENODEV; - - for (id = intel_idle_ids; id->family; ++id) - if (id->family == boot_cpu_data.x86 && - id->model == boot_cpu_data.x86_model) - break; - if (!id->family) { + id = x86_match_cpu(intel_idle_ids); + if (!id) { pr_debug(PREFIX "does not run on family %d model %d\n", boot_cpu_data.x86, boot_cpu_data.x86_model); return -ENODEV; } + if (boot_cpu_data.cpuid_level < CPUID_MWAIT_LEAF) + return -ENODEV; + cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &mwait_substates); if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) || @@ -788,7 +782,7 @@ static int __init mwait_idle_probe(void) pr_debug(PREFIX "MWAIT substates: %#x\n", mwait_substates); - icpu = id->data; + icpu = (const struct idle_cpu *)id->driver_data; cpuidle_state_table = icpu->state_table; if (boot_cpu_has(X86_FEATURE_ARAT)) diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h index fb2c2fc..68cd92b 100644 --- a/xen/include/asm-x86/processor.h +++ b/xen/include/asm-x86/processor.h @@ -163,6 +163,14 @@ struct vcpu; pc; \ }) +struct x86_cpu_id { + uint16_t vendor; + uint16_t family; + uint16_t model; + uint16_t feature; /* bit index */ + const void *driver_data; +}; + struct cpuinfo_x86 { __u8 x86; /* CPU family */ __u8 x86_vendor; /* CPU vendor */ @@ -204,6 +212,8 @@ extern u32 cpuid_ext_features; /* Maximum width of physical addresses supported by the hardware */ extern unsigned int paddr_bits; +extern const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id table[]); + extern void identify_cpu(struct cpuinfo_x86 *); extern void setup_clear_cpu_cap(unsigned int); extern void print_cpu_info(unsigned int cpu); -- 1.9.1 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |