[IA64] implement ia64 cpufreq notify hypercall
authorIsaku Yamahata <yamahata@valinux.co.jp>
Fri, 10 Oct 2008 02:17:24 +0000 (11:17 +0900)
committerIsaku Yamahata <yamahata@valinux.co.jp>
Fri, 10 Oct 2008 02:17:24 +0000 (11:17 +0900)
This patch implement the ia64 cpufreq hypercall to get dom0 cpufreq ACPI info.

Signed-off-by: Yu Ke <ke.yu@intel.com>
Signed-off-by: Liu Jinsong <jinsong.liu@intel.com>
xen/arch/ia64/linux-xen/acpi.c
xen/arch/ia64/linux-xen/entry.S
xen/arch/ia64/xen/Makefile
xen/arch/ia64/xen/cpufreq/cpufreq.c
xen/arch/ia64/xen/domain.c
xen/arch/ia64/xen/platform_hypercall.c [new file with mode: 0644]

index 5abc74c568dc61e25a4d5a6da0f3f681fb79b92b..c686ffa88a5c6772bb684741c172e0a4a23d8c87 100644 (file)
@@ -219,6 +219,32 @@ acpi_parse_lapic_addr_ovr(struct acpi_subtable_header * header,
        return 0;
 }
 
+#ifdef XEN
+
+#define MAX_LOCAL_SAPIC 255
+static u16 ia64_acpiid_to_sapicid[ MAX_LOCAL_SAPIC ] =
+               {[0 ... MAX_LOCAL_SAPIC - 1] = 0xffff };
+
+/* acpi id to cpu id */
+int get_cpu_id(u8 acpi_id)
+{
+       int i;
+       u16 apic_id;
+
+       apic_id = ia64_acpiid_to_sapicid[acpi_id];
+       if ( apic_id == 0xffff )
+               return -EINVAL;
+
+       for ( i = 0; i < NR_CPUS; i++ )
+       {
+               if ( apic_id == ia64_cpu_to_sapicid[i] )
+                       return i;
+       }
+
+       return -1;
+}
+#endif
+
 static int __init
 acpi_parse_lsapic(struct acpi_subtable_header * header, const unsigned long end)
 {
@@ -232,6 +258,10 @@ acpi_parse_lsapic(struct acpi_subtable_header * header, const unsigned long end)
 #ifdef CONFIG_SMP
                smp_boot_data.cpu_phys_id[available_cpus] =
                    (lsapic->id << 8) | lsapic->eid;
+#endif
+#ifdef XEN
+        ia64_acpiid_to_sapicid[lsapic->processor_id] =
+            (lsapic->id << 8) | lsapic->eid;
 #endif
                ++available_cpus;
        }
index ec4b96883ecb4dc93c23aa0d76797bb5b6b0f2f2..6519c64894251f9a90b34d83ac9326e8dddecb2f 100644 (file)
@@ -1524,7 +1524,7 @@ ia64_hypercall_table:
        data8 do_ni_hypercall           /* do_set_callbacks */
        data8 do_ni_hypercall           /* do_fpu_taskswitch *//*  5 */
        data8 do_sched_op_compat
-       data8 do_ni_hypercall
+       data8 do_platform_op
        data8 do_ni_hypercall           /* do_set_debugreg */
        data8 do_ni_hypercall           /* do_get_debugreg */
        data8 do_ni_hypercall           /* do_update_descriptor * 10 */
index da8343a12267eb5fe587532f353713a521a9eb00..a914b9f66aa8077944801551e870800fae3aff46 100644 (file)
@@ -15,6 +15,7 @@ obj-y += dom_fw_sn2.o
 obj-y += fw_emul.o
 obj-y += hpsimserial.o
 obj-y += hypercall.o
+obj-y += platform_hypercall.o
 obj-y += hyperprivop.o
 obj-y += idle0_task.o
 obj-y += irq.o
index aca6eb900f4dfb3f88c386d78b84d972ec3db1c0..b26f8550cf2f0e6ee705e162c7c4ee85799f555d 100644 (file)
@@ -305,20 +305,10 @@ static int __init cpufreq_driver_init(void)
 
        return ret;
 }
-__initcall(cpufreq_driver_init);
-
-int get_cpu_id(u8 acpi_id)
-{
-    return -1;
-}
 
-int xenpf_copy_px_states(struct processor_performance *pxpt,
-                         struct xen_processor_performance *dom0_px_info)
-{
-    return -ENOSYS;
-}
+__initcall(cpufreq_driver_init);
 
 int cpufreq_cpu_init(unsigned int cpuid)
 {
-    return -ENOSYS;
+       return cpufreq_add_cpu(cpuid);
 }
index 23911dd6ce7a8a81cd363dc7b190ccdc1a6df842..ade43c0a4e1fc2d5f762a431fd4c5b5aa4855efb 100644 (file)
@@ -2160,6 +2160,7 @@ int __init construct_dom0(struct domain *d,
        snprintf(si->magic, sizeof(si->magic), "xen-3.0-ia64");
        si->nr_pages     = max_pages;
        si->flags = SIF_INITDOMAIN|SIF_PRIVILEGED;
+       si->flags |= (xen_processor_pmbits << 8) & SIF_PM_MASK;
 
        printk("Dom0: 0x%lx\n", (u64)dom0);
 
diff --git a/xen/arch/ia64/xen/platform_hypercall.c b/xen/arch/ia64/xen/platform_hypercall.c
new file mode 100644 (file)
index 0000000..69c6bd5
--- /dev/null
@@ -0,0 +1,87 @@
+/******************************************************************************
+ * platform_hypercall.c
+ * 
+ * Hardware platform operations. Intended for use by domain-0 kernel.
+ * 
+ * Copyright (c) 2002-2006, K Fraser
+ */
+
+#include <xen/config.h>
+#include <xen/types.h>
+#include <xen/lib.h>
+#include <xen/sched.h>
+#include <xen/guest_access.h>
+#include <xen/acpi.h>
+#include <public/platform.h>
+#include <acpi/cpufreq/processor_perf.h>
+
+DEFINE_SPINLOCK(xenpf_lock);
+
+extern int set_px_pminfo(uint32_t cpu, struct xen_processor_performance *perf);
+extern long set_cx_pminfo(uint32_t cpu, struct xen_processor_power *power);
+
+int xenpf_copy_px_states(struct processor_performance *pxpt,
+        struct xen_processor_performance *dom0_px_info)
+{
+    if (!pxpt || !dom0_px_info)
+        return -EINVAL;
+    return  copy_from_guest(pxpt->states, dom0_px_info->states,
+                    dom0_px_info->state_count);
+}
+
+long do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op)
+{
+    long ret = 0;
+    struct xen_platform_op curop, *op = &curop;
+
+    if ( !IS_PRIV(current->domain) )
+        return -EPERM;
+
+    if ( copy_from_guest(op, u_xenpf_op, 1) )
+        return -EFAULT;
+
+    if ( op->interface_version != XENPF_INTERFACE_VERSION )
+        return -EACCES;
+
+    switch ( op->cmd )
+    {
+    case XENPF_set_processor_pminfo:
+        spin_lock(&xenpf_lock);
+        switch ( op->u.set_pminfo.type )
+        {
+        case XEN_PM_PX:
+            ret = set_px_pminfo(op->u.set_pminfo.id,
+                    &op->u.set_pminfo.perf);
+            break;
+
+        case XEN_PM_CX:
+            /* Place holder for Cx */
+            ret = -ENOSYS;
+            break;
+
+        default:
+            ret = -EINVAL;
+            break;
+        }
+        spin_unlock(&xenpf_lock);
+        break;
+
+    default:
+        printk("Unknown platform hypercall op 0x%x\n", op->cmd);
+        ret = -ENOSYS;
+        break;
+    }
+
+    return ret;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
+