# HG changeset patch
# User Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
# Date 1223533434 -32400
# Node ID 55ec2b18fe7f1877cedf5ff367e7c05cdcdebb66
# Parent 7d2d7b1deda42a8542f98697ad8f86195432b04b
IA64: add ia64 cpufreq notify hypercall
This patch adds ia64 notify hypercall to pass cpufreq ACPI information to
hypervisor, and get cpufreq statistic data from hypervisor.
Signed-off-by: Yu Ke <ke.yu@xxxxxxxxx>
Signed-off-by: Liu Jinsong <jinsong.liu@xxxxxxxxx>
---
arch/ia64/kernel/Makefile | 3
arch/ia64/kernel/processor_extcntl_xen.c | 164 +++++++++++++++++++++++++++++++
arch/ia64/xen/xcom_hcall.c | 9 +
arch/ia64/xen/xcom_privcmd.c | 25 ++++
drivers/acpi/Kconfig | 2
include/asm-ia64/hypercall.h | 1
include/asm-ia64/xen/xcom_hcall.h | 2
7 files changed, 205 insertions(+), 1 deletion(-)
diff -r 7d2d7b1deda4 -r 55ec2b18fe7f arch/ia64/kernel/Makefile
--- a/arch/ia64/kernel/Makefile Fri Oct 03 13:08:44 2008 +0900
+++ b/arch/ia64/kernel/Makefile Thu Oct 09 15:23:54 2008 +0900
@@ -16,6 +16,9 @@ obj-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += acp
ifneq ($(CONFIG_ACPI_PROCESSOR),)
obj-y += acpi-processor.o
+ifneq ($(CONFIG_PROCESSOR_EXTERNAL_CONTROL),)
+obj-$(CONFIG_XEN) += processor_extcntl_xen.o
+endif
endif
obj-$(CONFIG_IA64_PALINFO) += palinfo.o
diff -r 7d2d7b1deda4 -r 55ec2b18fe7f arch/ia64/kernel/processor_extcntl_xen.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/arch/ia64/kernel/processor_extcntl_xen.c Thu Oct 09 15:23:54 2008 +0900
@@ -0,0 +1,164 @@
+/*
+ * processor_extcntl_xen.c - interface to notify Xen
+ *
+ * Copyright (C) 2008, Intel corporation
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * 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 <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/acpi.h>
+#include <linux/pm.h>
+#include <linux/cpu.h>
+#include <linux/cpufreq.h>
+#include <acpi/processor.h>
+#include <asm/hypercall.h>
+#include <asm/xen/xencomm.h>
+#include <xen/interface/platform.h>
+
+static int xen_cx_notifier(struct acpi_processor *pr, int action)
+{
+ printk(KERN_WARNING "Cx is not supported yet\n");
+
+ return -EINVAL;
+}
+
+static int xen_px_notifier(struct acpi_processor *pr, int action)
+{
+ int ret = -EINVAL;
+ xen_platform_op_t op = {
+ .cmd = XENPF_set_processor_pminfo,
+ .interface_version = XENPF_INTERFACE_VERSION,
+ .u.set_pminfo.id = pr->acpi_id,
+ .u.set_pminfo.type = XEN_PM_PX,
+ };
+ struct xen_processor_performance *perf;
+ struct xen_processor_px *states = NULL;
+ struct acpi_processor_performance *px;
+ struct acpi_psd_package *pdomain;
+ struct xencomm_handle *states_desc;
+
+ if (!pr || !pr->performance)
+ return -EINVAL;
+
+ perf = &op.u.set_pminfo.perf;
+ px = pr->performance;
+
+ switch(action) {
+ case PROCESSOR_PM_CHANGE:
+ /* ppc dynamic handle */
+ perf->flags = XEN_PX_PPC;
+ perf->platform_limit = pr->performance_platform_limit;
+
+ ret = HYPERVISOR_platform_op(&op);
+ break;
+
+ case PROCESSOR_PM_INIT:
+ /* px normal init */
+ perf->flags = XEN_PX_PPC |
+ XEN_PX_PCT |
+ XEN_PX_PSS |
+ XEN_PX_PSD;
+
+ /* ppc */
+ perf->platform_limit = pr->performance_platform_limit;
+
+ /* pct */
+ xen_convert_pct_reg(&perf->control_register,
+ &px->control_register);
+ xen_convert_pct_reg(&perf->status_register,
+ &px->status_register);
+
+ /* pss */
+ perf->state_count = px->state_count;
+ states = kzalloc(
+ px->state_count * sizeof(xen_processor_px_t),
+ GFP_KERNEL);
+ if (!states){
+ ret = -ENOMEM;
+ break;
+ }
+ xen_convert_pss_states(states, px->states,
+ px->state_count);
+ set_xen_guest_handle(perf->states, states);
+ states_desc = xencomm_map_no_alloc(
+ xen_guest_handle(perf->states),
+
sizeof(*xen_guest_handle(perf->states)));
+ set_xen_guest_handle(perf->states,
+ (xen_processor_px_t*)states_desc);
+
+ /* psd */
+ pdomain = &px->domain_info;
+ xen_convert_psd_pack(&perf->domain_info, pdomain);
+ if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ALL)
+ perf->shared_type = CPUFREQ_SHARED_TYPE_ALL;
+ else if (pdomain->coord_type ==
+ DOMAIN_COORD_TYPE_SW_ANY)
+ perf->shared_type = CPUFREQ_SHARED_TYPE_ANY;
+ else if (pdomain->coord_type ==
+ DOMAIN_COORD_TYPE_HW_ALL)
+ perf->shared_type = CPUFREQ_SHARED_TYPE_HW;
+ else {
+ ret = -ENODEV;
+ kfree(states);
+ break;
+ }
+
+ ret = HYPERVISOR_platform_op(&op);
+ kfree(states);
+ break;
+
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int xen_tx_notifier(struct acpi_processor *pr, int action)
+{
+ return -EINVAL;
+}
+static int xen_hotplug_notifier(struct acpi_processor *pr, int event)
+{
+ return -EINVAL;
+}
+
+static struct processor_extcntl_ops xen_extcntl_ops = {
+ .hotplug = xen_hotplug_notifier,
+};
+
+void arch_acpi_processor_init_extcntl(const struct processor_extcntl_ops **ops)
+{
+ unsigned int pmbits = (xen_start_info->flags & SIF_PM_MASK) >> 8;
+
+ if (!pmbits)
+ return;
+
+ if (pmbits & XEN_PROCESSOR_PM_CX)
+ xen_extcntl_ops.pm_ops[PM_TYPE_IDLE] = xen_cx_notifier;
+ if (pmbits & XEN_PROCESSOR_PM_PX)
+ xen_extcntl_ops.pm_ops[PM_TYPE_PERF] = xen_px_notifier;
+ if (pmbits & XEN_PROCESSOR_PM_TX)
+ xen_extcntl_ops.pm_ops[PM_TYPE_THR] = xen_tx_notifier;
+
+ *ops = &xen_extcntl_ops;
+}
+EXPORT_SYMBOL(arch_acpi_processor_init_extcntl);
diff -r 7d2d7b1deda4 -r 55ec2b18fe7f arch/ia64/xen/xcom_hcall.c
--- a/arch/ia64/xen/xcom_hcall.c Fri Oct 03 13:08:44 2008 +0900
+++ b/arch/ia64/xen/xcom_hcall.c Thu Oct 09 15:23:54 2008 +0900
@@ -285,6 +285,15 @@ xencomm_hypercall_sched_op(int cmd, void
}
EXPORT_SYMBOL_GPL(xencomm_hypercall_sched_op);
+int xencomm_hypercall_platform_op(struct xen_platform_op *arg)
+{
+ return xencomm_arch_hypercall_platform_op(
+ xencomm_map_no_alloc(arg,
+ sizeof(struct xen_platform_op))
+ );
+}
+EXPORT_SYMBOL_GPL(xencomm_hypercall_platform_op);
+
int
xencomm_hypercall_multicall(void *call_list, int nr_calls)
{
diff -r 7d2d7b1deda4 -r 55ec2b18fe7f arch/ia64/xen/xcom_privcmd.c
--- a/arch/ia64/xen/xcom_privcmd.c Fri Oct 03 13:08:44 2008 +0900
+++ b/arch/ia64/xen/xcom_privcmd.c Thu Oct 09 15:23:54 2008 +0900
@@ -193,6 +193,31 @@ xencomm_privcmd_sysctl(privcmd_hypercall
set_xen_guest_handle(kern_op.u.physinfo.cpu_to_node,
(void *)desc);
break;
+
+ case XEN_SYSCTL_get_pmstat:
+ if (kern_op.u.get_pmstat.type == PMSTAT_get_pxstat) {
+ struct pm_px_stat *getpx =
+ &kern_op.u.get_pmstat.u.getpx;
+ desc = xencomm_map(
+ xen_guest_handle(getpx->trans_pt),
+ getpx->total * getpx->total *
+ sizeof(uint64_t));
+ if (xen_guest_handle(getpx->trans_pt) != NULL &&
+ getpx->total > 0 && desc == NULL)
+ return -ENOMEM;
+
+ set_xen_guest_handle(getpx->trans_pt, (void *)desc);
+
+ desc1 = xencomm_map(xen_guest_handle(getpx->pt),
+ getpx->total * sizeof(pm_px_val_t));
+ if (xen_guest_handle(getpx->pt) != NULL &&
+ getpx->total > 0 && desc1 == NULL)
+ return -ENOMEM;
+
+ set_xen_guest_handle(getpx->pt, (void *)desc1);
+ }
+ break;
+
default:
printk("%s: unknown sysctl cmd %d\n", __func__, kern_op.cmd);
return -ENOSYS;
diff -r 7d2d7b1deda4 -r 55ec2b18fe7f drivers/acpi/Kconfig
--- a/drivers/acpi/Kconfig Fri Oct 03 13:08:44 2008 +0900
+++ b/drivers/acpi/Kconfig Thu Oct 09 15:23:54 2008 +0900
@@ -370,7 +370,7 @@ config ACPI_PV_SLEEP
config PROCESSOR_EXTERNAL_CONTROL
bool
- depends on X86 && XEN
+ depends on (X86 || IA64) && XEN
default y
endif # ACPI
diff -r 7d2d7b1deda4 -r 55ec2b18fe7f include/asm-ia64/hypercall.h
--- a/include/asm-ia64/hypercall.h Fri Oct 03 13:08:44 2008 +0900
+++ b/include/asm-ia64/hypercall.h Thu Oct 09 15:23:54 2008 +0900
@@ -444,6 +444,7 @@ xencomm_arch_hypercall_kexec_op(int cmd,
/* Use xencomm to do hypercalls. */
#define HYPERVISOR_sched_op xencomm_hypercall_sched_op
+#define HYPERVISOR_platform_op xencomm_hypercall_platform_op
#define HYPERVISOR_event_channel_op xencomm_hypercall_event_channel_op
#define HYPERVISOR_callback_op xencomm_hypercall_callback_op
#define HYPERVISOR_multicall xencomm_hypercall_multicall
diff -r 7d2d7b1deda4 -r 55ec2b18fe7f include/asm-ia64/xen/xcom_hcall.h
--- a/include/asm-ia64/xen/xcom_hcall.h Fri Oct 03 13:08:44 2008 +0900
+++ b/include/asm-ia64/xen/xcom_hcall.h Thu Oct 09 15:23:54 2008 +0900
@@ -36,6 +36,8 @@ extern int xencomm_hypercall_grant_table
extern int xencomm_hypercall_sched_op(int cmd, void *arg);
+extern int xencomm_hypercall_platform_op(struct xen_platform_op *arg);
+
extern int xencomm_hypercall_multicall(void *call_list, int nr_calls);
extern int xencomm_hypercall_callback_op(int cmd, void *arg);
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|