# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1210769446 -3600
# Node ID 66ddfc4d69631a069d8914bff12bd54fe97a4e9f
# Parent b57642bcea300036e151d4f8776b58eb66acb707
Get ACPI Px from dom0 and choose Px controller
Add platform op hypercall case to get ACPI Px info from dom0.
Chose Px controller from dom0 (cpufreq=dom0-kernel)
or hypervisor (cpufreq=xen).
Signed-off-by: Liu Jinsong <jinsong.liu@xxxxxxxxx>
---
xen/arch/x86/acpi/Makefile | 2
xen/arch/x86/acpi/cpu_idle.c | 2
xen/arch/x86/acpi/cpufreq/Makefile | 1
xen/arch/x86/acpi/cpufreq/cpufreq.c | 52 +++++++++++++++++++++++
xen/arch/x86/platform_hypercall.c | 66 ++++++++++++++++++++++++++++--
xen/arch/x86/setup.c | 17 +++++--
xen/arch/x86/x86_64/platform_hypercall.c | 6 ++
xen/common/domain.c | 10 ++++
xen/include/acpi/cpufreq/processor_perf.h | 30 +++++++++++++
xen/include/public/platform.h | 51 ++++++++++++++++++++++-
xen/include/xen/domain.h | 2
11 files changed, 229 insertions(+), 10 deletions(-)
diff -r b57642bcea30 -r 66ddfc4d6963 xen/arch/x86/acpi/Makefile
--- a/xen/arch/x86/acpi/Makefile Wed May 14 13:25:19 2008 +0100
+++ b/xen/arch/x86/acpi/Makefile Wed May 14 13:50:46 2008 +0100
@@ -1,2 +1,4 @@ obj-y += boot.o
+subdir-y += cpufreq
+
obj-y += boot.o
obj-y += power.o suspend.o wakeup_prot.o cpu_idle.o
diff -r b57642bcea30 -r 66ddfc4d6963 xen/arch/x86/acpi/cpu_idle.c
--- a/xen/arch/x86/acpi/cpu_idle.c Wed May 14 13:25:19 2008 +0100
+++ b/xen/arch/x86/acpi/cpu_idle.c Wed May 14 13:50:46 2008 +0100
@@ -834,7 +834,7 @@ static int set_cx(struct acpi_processor_
return 0;
}
-static int get_cpu_id(u8 acpi_id)
+int get_cpu_id(u8 acpi_id)
{
int i;
u8 apic_id;
diff -r b57642bcea30 -r 66ddfc4d6963 xen/arch/x86/acpi/cpufreq/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/acpi/cpufreq/Makefile Wed May 14 13:50:46 2008 +0100
@@ -0,0 +1,1 @@
+obj-y += cpufreq.o
diff -r b57642bcea30 -r 66ddfc4d6963 xen/arch/x86/acpi/cpufreq/cpufreq.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/acpi/cpufreq/cpufreq.c Wed May 14 13:50:46 2008 +0100
@@ -0,0 +1,52 @@
+/*
+ * cpufreq.c - ACPI Processor P-States Driver ($Revision: 1.4 $)
+ *
+ * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@xxxxxxxxx>
+ * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@xxxxxxxxx>
+ * Copyright (C) 2002 - 2004 Dominik Brodowski <linux@xxxxxxxx>
+ * Copyright (C) 2006 Denis Sadykov <denis.m.sadykov@xxxxxxxxx>
+ *
+ * Feb 2008 - Liu Jinsong <jinsong.liu@xxxxxxxxx>
+ * porting acpi-cpufreq.c from Linux 2.6.23 to Xen hypervisor
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <xen/types.h>
+#include <xen/errno.h>
+#include <xen/delay.h>
+#include <xen/cpumask.h>
+#include <xen/timer.h>
+#include <xen/xmalloc.h>
+#include <asm/bug.h>
+#include <asm/msr.h>
+#include <asm/io.h>
+#include <asm/config.h>
+#include <asm/processor.h>
+#include <asm/percpu.h>
+#include <asm/cpufeature.h>
+#include <acpi/acpi.h>
+#include <acpi/cpufreq/processor_perf.h>
+
+struct processor_pminfo processor_pminfo[NR_CPUS];
+
+int acpi_cpufreq_init(void)
+{
+ return 0;
+}
diff -r b57642bcea30 -r 66ddfc4d6963 xen/arch/x86/platform_hypercall.c
--- a/xen/arch/x86/platform_hypercall.c Wed May 14 13:25:19 2008 +0100
+++ b/xen/arch/x86/platform_hypercall.c Wed May 14 13:50:46 2008 +0100
@@ -21,6 +21,7 @@
#include <xen/acpi.h>
#include <asm/current.h>
#include <public/platform.h>
+#include <acpi/cpufreq/processor_perf.h>
#include <asm/edd.h>
#include <asm/mtrr.h>
#include "cpu/mtrr/mtrr.h"
@@ -346,9 +347,68 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
switch ( op->u.set_pminfo.type )
{
case XEN_PM_PX:
- ret = -EINVAL;
- break;
-
+ {
+ static int cpu_count = 0;
+ struct xenpf_set_processor_pminfo *xenpmpt = &op->u.set_pminfo;
+ struct xen_processor_performance *xenpxpt = &op->u.set_pminfo.perf;
+ int cpuid = get_cpu_id(xenpmpt->id);
+ struct processor_pminfo *pmpt;
+ struct processor_performance *pxpt;
+
+ if ( cpuid < 0 )
+ {
+ ret = -EINVAL;
+ break;
+ }
+ pmpt = &processor_pminfo[cpuid];
+ pxpt = &processor_pminfo[cpuid].perf;
+ pmpt->acpi_id = xenpmpt->id;
+ pmpt->id = cpuid;
+
+ if ( xenpxpt->flags & XEN_PX_PCT )
+ {
+ memcpy ((void *)&pxpt->control_register,
+ (void *)&xenpxpt->control_register,
+ sizeof(struct xen_pct_register));
+ memcpy ((void *)&pxpt->status_register,
+ (void *)&xenpxpt->status_register,
+ sizeof(struct xen_pct_register));
+ }
+ if ( xenpxpt->flags & XEN_PX_PSS )
+ {
+ if ( !(pxpt->states = xmalloc_array(struct xen_processor_px,
+ xenpxpt->state_count)) )
+ {
+ ret = -ENOMEM;
+ break;
+ }
+ if ( copy_from_compat(pxpt->states, xenpxpt->states,
+ xenpxpt->state_count) )
+ {
+ xfree(pxpt->states);
+ ret = -EFAULT;
+ break;
+ }
+ pxpt->state_count = xenpxpt->state_count;
+ }
+ if ( xenpxpt->flags & XEN_PX_PSD )
+ {
+ pxpt->shared_type = xenpxpt->shared_type;
+ memcpy ((void *)&pxpt->domain_info,
+ (void *)&xenpxpt->domain_info,
+ sizeof(struct xen_psd_package));
+ }
+ if ( xenpxpt->flags & XEN_PX_PPC )
+ pxpt->ppc = xenpxpt->ppc;
+
+ if ( xenpxpt->flags == ( XEN_PX_PCT | XEN_PX_PSS |
+ XEN_PX_PSD | XEN_PX_PPC ) )
+ cpu_count++;
+ if ( cpu_count == num_online_cpus() )
+ ret = acpi_cpufreq_init();
+ break;
+ }
+
case XEN_PM_CX:
ret = set_cx_pminfo(op->u.set_pminfo.id, &op->u.set_pminfo.power);
break;
diff -r b57642bcea30 -r 66ddfc4d6963 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c Wed May 14 13:25:19 2008 +0100
+++ b/xen/arch/x86/setup.c Wed May 14 13:50:46 2008 +0100
@@ -95,9 +95,9 @@ boolean_param("noapic", skip_ioapic_setu
boolean_param("noapic", skip_ioapic_setup);
/* **** Linux config option: propagated to domain0. */
-/* xen_processor_pm: xen control cstate. */
-static int xen_processor_pm;
-boolean_param("xen_processor_pm", xen_processor_pm);
+/* xen_cpuidle: xen control cstate. */
+static int xen_cpuidle;
+boolean_param("cpuidle", xen_cpuidle);
int early_boot = 1;
@@ -988,6 +988,7 @@ void __init __start_xen(unsigned long mb
if ( (cmdline != NULL) || (kextra != NULL) )
{
static char dom0_cmdline[MAX_GUEST_CMDLINE];
+ char xen_pm_param[32];
cmdline = cmdline_cook(cmdline);
safe_strcpy(dom0_cmdline, cmdline);
@@ -1012,8 +1013,14 @@ void __init __start_xen(unsigned long mb
safe_strcat(dom0_cmdline, " acpi=");
safe_strcat(dom0_cmdline, acpi_param);
}
- if ( xen_processor_pm && !strstr(dom0_cmdline,
"xen_processor_pmbits=") )
- safe_strcat(dom0_cmdline, " xen_processor_pmbits=1");
+ if ( xen_cpuidle )
+ xen_processor_pmbits |= XEN_PROCESSOR_PM_CX;
+
+ snprintf(xen_pm_param, sizeof(xen_pm_param),
+ " xen_processor_pmbits=%d", xen_processor_pmbits);
+
+ if ( !strstr(dom0_cmdline, "xen_processor_pmbits=") )
+ safe_strcat(dom0_cmdline, xen_pm_param);
cmdline = dom0_cmdline;
}
diff -r b57642bcea30 -r 66ddfc4d6963 xen/arch/x86/x86_64/platform_hypercall.c
--- a/xen/arch/x86/x86_64/platform_hypercall.c Wed May 14 13:25:19 2008 +0100
+++ b/xen/arch/x86/x86_64/platform_hypercall.c Wed May 14 13:50:46 2008 +0100
@@ -10,6 +10,12 @@ DEFINE_XEN_GUEST_HANDLE(compat_platform_
#define xen_platform_op compat_platform_op
#define xen_platform_op_t compat_platform_op_t
#define do_platform_op(x) compat_platform_op(_##x)
+
+#define xen_processor_px compat_processor_px
+#define xen_processor_px_t compat_processor_px_t
+#define xen_processor_performance compat_processor_performance
+#define xen_processor_performance_t compat_processor_performance_t
+#define xenpf_set_processor_pminfo compat_pf_set_processor_pminfo
#define xen_processor_power compat_processor_power
#define xen_processor_power_t compat_processor_power_t
diff -r b57642bcea30 -r 66ddfc4d6963 xen/common/domain.c
--- a/xen/common/domain.c Wed May 14 13:25:19 2008 +0100
+++ b/xen/common/domain.c Wed May 14 13:50:46 2008 +0100
@@ -30,6 +30,10 @@
#include <public/vcpu.h>
#include <xsm/xsm.h>
+/* Linux config option: propageted to domain0 */
+/* xen_processor_pmbits: xen control Cx, Px, ... */
+unsigned int xen_processor_pmbits = 0;
+
/* opt_dom0_vcpus_pin: If true, dom0 VCPUs are pinned. */
static unsigned int opt_dom0_vcpus_pin;
boolean_param("dom0_vcpus_pin", opt_dom0_vcpus_pin);
@@ -39,8 +43,14 @@ static void __init setup_cpufreq_option(
{
if ( !strcmp(str, "dom0-kernel") )
{
+ xen_processor_pmbits &= ~XEN_PROCESSOR_PM_PX;
cpufreq_controller = FREQCTL_dom0_kernel;
opt_dom0_vcpus_pin = 1;
+ }
+ else if ( !strcmp(str, "xen") )
+ {
+ xen_processor_pmbits |= XEN_PROCESSOR_PM_PX;
+ cpufreq_controller = FREQCTL_none;
}
}
custom_param("cpufreq", setup_cpufreq_option);
diff -r b57642bcea30 -r 66ddfc4d6963 xen/include/acpi/cpufreq/processor_perf.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/acpi/cpufreq/processor_perf.h Wed May 14 13:50:46 2008 +0100
@@ -0,0 +1,30 @@
+#ifndef __XEN_PROCESSOR_PM_H__
+#define __XEN_PROCESSOR_PM_H__
+
+#include <public/platform.h>
+
+int get_cpu_id(u8);
+int acpi_cpufreq_init(void);
+
+struct processor_performance {
+ uint32_t state;
+ uint32_t ppc;
+ struct xen_pct_register control_register;
+ struct xen_pct_register status_register;
+ uint32_t state_count;
+ struct xen_processor_px *states;
+ struct xen_psd_package domain_info;
+ cpumask_t shared_cpu_map;
+ uint32_t shared_type;
+};
+
+struct processor_pminfo {
+ uint32_t acpi_id;
+ uint32_t id;
+ uint32_t flag;
+ struct processor_performance perf;
+};
+
+extern struct processor_pminfo processor_pminfo[NR_CPUS];
+
+#endif /* __XEN_PROCESSOR_PM_H__ */
diff -r b57642bcea30 -r 66ddfc4d6963 xen/include/public/platform.h
--- a/xen/include/public/platform.h Wed May 14 13:25:19 2008 +0100
+++ b/xen/include/public/platform.h Wed May 14 13:50:46 2008 +0100
@@ -211,6 +211,12 @@ DEFINE_XEN_GUEST_HANDLE(xenpf_getidletim
#define XEN_PM_PX 1
#define XEN_PM_TX 2
+/* Px sub info type */
+#define XEN_PX_PCT 1
+#define XEN_PX_PSS 2
+#define XEN_PX_PPC 4
+#define XEN_PX_PSD 8
+
struct xen_power_register {
uint32_t space_id;
uint32_t bit_width;
@@ -252,12 +258,55 @@ struct xen_processor_power {
XEN_GUEST_HANDLE(xen_processor_cx_t) states; /* supported c states */
};
+struct xen_pct_register {
+ uint8_t descriptor;
+ uint16_t length;
+ uint8_t space_id;
+ uint8_t bit_width;
+ uint8_t bit_offset;
+ uint8_t reserved;
+ uint64_t address;
+};
+
+struct xen_processor_px {
+ uint64_t core_frequency; /* megahertz */
+ uint64_t power; /* milliWatts */
+ uint64_t transition_latency; /* microseconds */
+ uint64_t bus_master_latency; /* microseconds */
+ uint64_t control; /* control value */
+ uint64_t status; /* success indicator */
+};
+typedef struct xen_processor_px xen_processor_px_t;
+DEFINE_XEN_GUEST_HANDLE(xen_processor_px_t);
+
+struct xen_psd_package {
+ uint64_t num_entries;
+ uint64_t revision;
+ uint64_t domain;
+ uint64_t coord_type;
+ uint64_t num_processors;
+};
+
+struct xen_processor_performance {
+ uint32_t flags; /* flag for Px sub info type */
+ uint32_t ppc; /* Platform limitation on freq usage */
+ struct xen_pct_register control_register;
+ struct xen_pct_register status_register;
+ uint32_t state_count; /* total available performance states */
+ XEN_GUEST_HANDLE(xen_processor_px_t) states;
+ struct xen_psd_package domain_info;
+ uint32_t shared_type; /* coordination type of this processor */
+};
+typedef struct xen_processor_performance xen_processor_performance_t;
+DEFINE_XEN_GUEST_HANDLE(xen_processor_performance_t);
+
struct xenpf_set_processor_pminfo {
/* IN variables */
uint32_t id; /* ACPI CPU ID */
- uint32_t type; /* {XEN_PM_CX, ...} */
+ uint32_t type; /* {XEN_PM_CX, XEN_PM_PX} */
union {
struct xen_processor_power power;/* Cx: _CST/_CSD */
+ struct xen_processor_performance perf; /* Px: _PPC/_PCT/_PSS/_PSD */
};
};
typedef struct xenpf_set_processor_pminfo xenpf_set_processor_pminfo_t;
diff -r b57642bcea30 -r 66ddfc4d6963 xen/include/xen/domain.h
--- a/xen/include/xen/domain.h Wed May 14 13:25:19 2008 +0100
+++ b/xen/include/xen/domain.h Wed May 14 13:50:46 2008 +0100
@@ -57,4 +57,6 @@ void arch_dump_domain_info(struct domain
int arch_vcpu_reset(struct vcpu *v);
+extern unsigned int xen_processor_pmbits;
+
#endif /* __XEN_DOMAIN_H__ */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|