[IA64] implement ia64 cpufreq notify hypercall This patch implement the ia64 cpufreq hypercall to get dom0 cpufreq ACPI info. Signed-off-by: Yu Ke Signed-off-by: Liu Jinsong diff -r 9db62718c197 xen/arch/ia64/linux-xen/acpi.c --- a/xen/arch/ia64/linux-xen/acpi.c Thu Oct 02 16:28:57 2008 +0900 +++ b/xen/arch/ia64/linux-xen/acpi.c Thu Oct 02 16:29:23 2008 +0900 @@ -219,6 +219,32 @@ 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 @@ #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; } diff -r 9db62718c197 xen/arch/ia64/linux-xen/entry.S --- a/xen/arch/ia64/linux-xen/entry.S Thu Oct 02 16:28:57 2008 +0900 +++ b/xen/arch/ia64/linux-xen/entry.S Thu Oct 02 16:29:23 2008 +0900 @@ -1524,7 +1524,7 @@ 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 */ diff -r 9db62718c197 xen/arch/ia64/xen/Makefile --- a/xen/arch/ia64/xen/Makefile Thu Oct 02 16:28:57 2008 +0900 +++ b/xen/arch/ia64/xen/Makefile Thu Oct 02 16:29:23 2008 +0900 @@ -15,6 +15,7 @@ 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 diff -r 9db62718c197 xen/arch/ia64/xen/cpufreq/cpufreq.c --- a/xen/arch/ia64/xen/cpufreq/cpufreq.c Thu Oct 02 16:28:57 2008 +0900 +++ b/xen/arch/ia64/xen/cpufreq/cpufreq.c Thu Oct 02 16:29:23 2008 +0900 @@ -305,20 +305,10 @@ 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; -} int cpufreq_cpu_init(unsigned int cpuid) { - return -ENOSYS; + return cpufreq_add_cpu(cpuid); } diff -r 9db62718c197 xen/arch/ia64/xen/domain.c --- a/xen/arch/ia64/xen/domain.c Thu Oct 02 16:28:57 2008 +0900 +++ b/xen/arch/ia64/xen/domain.c Thu Oct 02 16:29:23 2008 +0900 @@ -2160,6 +2160,7 @@ 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 -r 9db62718c197 xen/arch/ia64/xen/platform_hypercall.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/arch/ia64/xen/platform_hypercall.c Thu Oct 02 16:29:23 2008 +0900 @@ -0,0 +1,87 @@ +/****************************************************************************** + * platform_hypercall.c + * + * Hardware platform operations. Intended for use by domain-0 kernel. + * + * Copyright (c) 2002-2006, K Fraser + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +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: + */ +