ia64/xen-unstable

changeset 17657:66ddfc4d6963

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@intel.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed May 14 13:50:46 2008 +0100 (2008-05-14)
parents b57642bcea30
children 50fb7620d05a
files xen/arch/x86/acpi/Makefile xen/arch/x86/acpi/cpu_idle.c xen/arch/x86/acpi/cpufreq/Makefile xen/arch/x86/acpi/cpufreq/cpufreq.c xen/arch/x86/platform_hypercall.c xen/arch/x86/setup.c xen/arch/x86/x86_64/platform_hypercall.c xen/common/domain.c xen/include/acpi/cpufreq/processor_perf.h xen/include/public/platform.h xen/include/xen/domain.h
line diff
     1.1 --- a/xen/arch/x86/acpi/Makefile	Wed May 14 13:25:19 2008 +0100
     1.2 +++ b/xen/arch/x86/acpi/Makefile	Wed May 14 13:50:46 2008 +0100
     1.3 @@ -1,2 +1,4 @@
     1.4 +subdir-y += cpufreq
     1.5 +
     1.6  obj-y += boot.o
     1.7  obj-y += power.o suspend.o wakeup_prot.o cpu_idle.o
     2.1 --- a/xen/arch/x86/acpi/cpu_idle.c	Wed May 14 13:25:19 2008 +0100
     2.2 +++ b/xen/arch/x86/acpi/cpu_idle.c	Wed May 14 13:50:46 2008 +0100
     2.3 @@ -834,7 +834,7 @@ static int set_cx(struct acpi_processor_
     2.4      return 0;   
     2.5  }
     2.6  
     2.7 -static int get_cpu_id(u8 acpi_id)
     2.8 +int get_cpu_id(u8 acpi_id)
     2.9  {
    2.10      int i;
    2.11      u8 apic_id;
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/xen/arch/x86/acpi/cpufreq/Makefile	Wed May 14 13:50:46 2008 +0100
     3.3 @@ -0,0 +1,1 @@
     3.4 +obj-y += cpufreq.o
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/xen/arch/x86/acpi/cpufreq/cpufreq.c	Wed May 14 13:50:46 2008 +0100
     4.3 @@ -0,0 +1,52 @@
     4.4 +/*
     4.5 + *  cpufreq.c - ACPI Processor P-States Driver ($Revision: 1.4 $)
     4.6 + *
     4.7 + *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
     4.8 + *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
     4.9 + *  Copyright (C) 2002 - 2004 Dominik Brodowski <linux@brodo.de>
    4.10 + *  Copyright (C) 2006        Denis Sadykov <denis.m.sadykov@intel.com>
    4.11 + *
    4.12 + *  Feb 2008 - Liu Jinsong <jinsong.liu@intel.com>
    4.13 + *      porting acpi-cpufreq.c from Linux 2.6.23 to Xen hypervisor
    4.14 + *
    4.15 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    4.16 + *
    4.17 + *  This program is free software; you can redistribute it and/or modify
    4.18 + *  it under the terms of the GNU General Public License as published by
    4.19 + *  the Free Software Foundation; either version 2 of the License, or (at
    4.20 + *  your option) any later version.
    4.21 + *
    4.22 + *  This program is distributed in the hope that it will be useful, but
    4.23 + *  WITHOUT ANY WARRANTY; without even the implied warranty of
    4.24 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    4.25 + *  General Public License for more details.
    4.26 + *
    4.27 + *  You should have received a copy of the GNU General Public License along
    4.28 + *  with this program; if not, write to the Free Software Foundation, Inc.,
    4.29 + *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
    4.30 + *
    4.31 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    4.32 + */
    4.33 +
    4.34 +#include <xen/types.h>
    4.35 +#include <xen/errno.h>
    4.36 +#include <xen/delay.h>
    4.37 +#include <xen/cpumask.h>
    4.38 +#include <xen/timer.h>
    4.39 +#include <xen/xmalloc.h>
    4.40 +#include <asm/bug.h>
    4.41 +#include <asm/msr.h>
    4.42 +#include <asm/io.h>
    4.43 +#include <asm/config.h>
    4.44 +#include <asm/processor.h>
    4.45 +#include <asm/percpu.h>
    4.46 +#include <asm/cpufeature.h>
    4.47 +#include <acpi/acpi.h>
    4.48 +#include <acpi/cpufreq/processor_perf.h>
    4.49 +
    4.50 +struct processor_pminfo processor_pminfo[NR_CPUS];
    4.51 +
    4.52 +int acpi_cpufreq_init(void)
    4.53 +{
    4.54 +    return 0;
    4.55 +}
     5.1 --- a/xen/arch/x86/platform_hypercall.c	Wed May 14 13:25:19 2008 +0100
     5.2 +++ b/xen/arch/x86/platform_hypercall.c	Wed May 14 13:50:46 2008 +0100
     5.3 @@ -21,6 +21,7 @@
     5.4  #include <xen/acpi.h>
     5.5  #include <asm/current.h>
     5.6  #include <public/platform.h>
     5.7 +#include <acpi/cpufreq/processor_perf.h>
     5.8  #include <asm/edd.h>
     5.9  #include <asm/mtrr.h>
    5.10  #include "cpu/mtrr/mtrr.h"
    5.11 @@ -346,9 +347,68 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
    5.12          switch ( op->u.set_pminfo.type )
    5.13          {
    5.14          case XEN_PM_PX:
    5.15 -            ret = -EINVAL;
    5.16 +        {
    5.17 +            static int cpu_count = 0;
    5.18 +            struct xenpf_set_processor_pminfo *xenpmpt = &op->u.set_pminfo;
    5.19 +            struct xen_processor_performance *xenpxpt = &op->u.set_pminfo.perf;
    5.20 +            int cpuid = get_cpu_id(xenpmpt->id);
    5.21 +            struct processor_pminfo *pmpt;
    5.22 +            struct processor_performance *pxpt;
    5.23 +
    5.24 +            if ( cpuid < 0 )
    5.25 +            {
    5.26 +                ret = -EINVAL;
    5.27 +                break;
    5.28 +            }
    5.29 +            pmpt = &processor_pminfo[cpuid];
    5.30 +            pxpt = &processor_pminfo[cpuid].perf;
    5.31 +            pmpt->acpi_id = xenpmpt->id;
    5.32 +            pmpt->id = cpuid;
    5.33 +
    5.34 +            if ( xenpxpt->flags & XEN_PX_PCT )
    5.35 +            {
    5.36 +                memcpy ((void *)&pxpt->control_register,
    5.37 +                    (void *)&xenpxpt->control_register,
    5.38 +                    sizeof(struct xen_pct_register));
    5.39 +                memcpy ((void *)&pxpt->status_register,
    5.40 +                    (void *)&xenpxpt->status_register,
    5.41 +                    sizeof(struct xen_pct_register));
    5.42 +            }
    5.43 +            if ( xenpxpt->flags & XEN_PX_PSS ) 
    5.44 +            {
    5.45 +                if ( !(pxpt->states = xmalloc_array(struct xen_processor_px,
    5.46 +                    xenpxpt->state_count)) )
    5.47 +                {
    5.48 +                    ret = -ENOMEM;
    5.49 +                    break;
    5.50 +                }
    5.51 +                if ( copy_from_compat(pxpt->states, xenpxpt->states, 
    5.52 +                    xenpxpt->state_count) )
    5.53 +                {
    5.54 +                    xfree(pxpt->states);
    5.55 +                    ret = -EFAULT;
    5.56 +                    break;
    5.57 +                }
    5.58 +                pxpt->state_count = xenpxpt->state_count;
    5.59 +            }
    5.60 +            if ( xenpxpt->flags & XEN_PX_PSD )
    5.61 +            {
    5.62 +                pxpt->shared_type = xenpxpt->shared_type;
    5.63 +                memcpy ((void *)&pxpt->domain_info,
    5.64 +                    (void *)&xenpxpt->domain_info,
    5.65 +                    sizeof(struct xen_psd_package));
    5.66 +            }
    5.67 +            if ( xenpxpt->flags & XEN_PX_PPC )
    5.68 +                pxpt->ppc = xenpxpt->ppc;
    5.69 +
    5.70 +            if ( xenpxpt->flags == ( XEN_PX_PCT | XEN_PX_PSS | 
    5.71 +                XEN_PX_PSD | XEN_PX_PPC ) )
    5.72 +                cpu_count++;
    5.73 +            if ( cpu_count == num_online_cpus() )
    5.74 +                ret = acpi_cpufreq_init();
    5.75              break;
    5.76 -            
    5.77 +        }
    5.78 + 
    5.79          case XEN_PM_CX:
    5.80              ret = set_cx_pminfo(op->u.set_pminfo.id, &op->u.set_pminfo.power);
    5.81              break;
     6.1 --- a/xen/arch/x86/setup.c	Wed May 14 13:25:19 2008 +0100
     6.2 +++ b/xen/arch/x86/setup.c	Wed May 14 13:50:46 2008 +0100
     6.3 @@ -95,9 +95,9 @@ extern int skip_ioapic_setup;
     6.4  boolean_param("noapic", skip_ioapic_setup);
     6.5  
     6.6  /* **** Linux config option: propagated to domain0. */
     6.7 -/* xen_processor_pm: xen control cstate. */
     6.8 -static int xen_processor_pm;
     6.9 -boolean_param("xen_processor_pm", xen_processor_pm);
    6.10 +/* xen_cpuidle: xen control cstate. */
    6.11 +static int xen_cpuidle;
    6.12 +boolean_param("cpuidle", xen_cpuidle);
    6.13  
    6.14  int early_boot = 1;
    6.15  
    6.16 @@ -988,6 +988,7 @@ void __init __start_xen(unsigned long mb
    6.17      if ( (cmdline != NULL) || (kextra != NULL) )
    6.18      {
    6.19          static char dom0_cmdline[MAX_GUEST_CMDLINE];
    6.20 +        char xen_pm_param[32];
    6.21  
    6.22          cmdline = cmdline_cook(cmdline);
    6.23          safe_strcpy(dom0_cmdline, cmdline);
    6.24 @@ -1012,8 +1013,14 @@ void __init __start_xen(unsigned long mb
    6.25              safe_strcat(dom0_cmdline, " acpi=");
    6.26              safe_strcat(dom0_cmdline, acpi_param);
    6.27          }
    6.28 -        if ( xen_processor_pm && !strstr(dom0_cmdline, "xen_processor_pmbits=") )
    6.29 -            safe_strcat(dom0_cmdline, " xen_processor_pmbits=1");
    6.30 +        if ( xen_cpuidle )
    6.31 +            xen_processor_pmbits |= XEN_PROCESSOR_PM_CX;
    6.32 +
    6.33 +        snprintf(xen_pm_param, sizeof(xen_pm_param), 
    6.34 +            " xen_processor_pmbits=%d", xen_processor_pmbits);
    6.35 +
    6.36 +        if ( !strstr(dom0_cmdline, "xen_processor_pmbits=") )
    6.37 +            safe_strcat(dom0_cmdline, xen_pm_param);
    6.38  
    6.39          cmdline = dom0_cmdline;
    6.40      }
     7.1 --- a/xen/arch/x86/x86_64/platform_hypercall.c	Wed May 14 13:25:19 2008 +0100
     7.2 +++ b/xen/arch/x86/x86_64/platform_hypercall.c	Wed May 14 13:50:46 2008 +0100
     7.3 @@ -11,6 +11,12 @@ DEFINE_XEN_GUEST_HANDLE(compat_platform_
     7.4  #define xen_platform_op_t   compat_platform_op_t
     7.5  #define do_platform_op(x)   compat_platform_op(_##x)
     7.6  
     7.7 +#define xen_processor_px    compat_processor_px
     7.8 +#define xen_processor_px_t  compat_processor_px_t
     7.9 +#define xen_processor_performance    compat_processor_performance
    7.10 +#define xen_processor_performance_t  compat_processor_performance_t
    7.11 +#define xenpf_set_processor_pminfo   compat_pf_set_processor_pminfo
    7.12 +
    7.13  #define xen_processor_power     compat_processor_power
    7.14  #define xen_processor_power_t   compat_processor_power_t
    7.15  #define set_cx_pminfo           compat_set_cx_pminfo
     8.1 --- a/xen/common/domain.c	Wed May 14 13:25:19 2008 +0100
     8.2 +++ b/xen/common/domain.c	Wed May 14 13:50:46 2008 +0100
     8.3 @@ -30,6 +30,10 @@
     8.4  #include <public/vcpu.h>
     8.5  #include <xsm/xsm.h>
     8.6  
     8.7 +/* Linux config option: propageted to domain0 */
     8.8 +/* xen_processor_pmbits: xen control Cx, Px, ... */
     8.9 +unsigned int xen_processor_pmbits = 0;
    8.10 +
    8.11  /* opt_dom0_vcpus_pin: If true, dom0 VCPUs are pinned. */
    8.12  static unsigned int opt_dom0_vcpus_pin;
    8.13  boolean_param("dom0_vcpus_pin", opt_dom0_vcpus_pin);
    8.14 @@ -39,9 +43,15 @@ static void __init setup_cpufreq_option(
    8.15  {
    8.16      if ( !strcmp(str, "dom0-kernel") )
    8.17      {
    8.18 +        xen_processor_pmbits &= ~XEN_PROCESSOR_PM_PX;
    8.19          cpufreq_controller = FREQCTL_dom0_kernel;
    8.20          opt_dom0_vcpus_pin = 1;
    8.21      }
    8.22 +    else if ( !strcmp(str, "xen") )
    8.23 +    {
    8.24 +        xen_processor_pmbits |= XEN_PROCESSOR_PM_PX;
    8.25 +        cpufreq_controller = FREQCTL_none;
    8.26 +    }
    8.27  }
    8.28  custom_param("cpufreq", setup_cpufreq_option);
    8.29  
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/xen/include/acpi/cpufreq/processor_perf.h	Wed May 14 13:50:46 2008 +0100
     9.3 @@ -0,0 +1,30 @@
     9.4 +#ifndef __XEN_PROCESSOR_PM_H__
     9.5 +#define __XEN_PROCESSOR_PM_H__
     9.6 +
     9.7 +#include <public/platform.h>
     9.8 +
     9.9 +int get_cpu_id(u8);
    9.10 +int acpi_cpufreq_init(void);
    9.11 +
    9.12 +struct processor_performance {
    9.13 +    uint32_t state;
    9.14 +    uint32_t ppc;
    9.15 +    struct xen_pct_register control_register;
    9.16 +    struct xen_pct_register status_register;
    9.17 +    uint32_t state_count;
    9.18 +    struct xen_processor_px *states;
    9.19 +    struct xen_psd_package domain_info;
    9.20 +    cpumask_t shared_cpu_map;
    9.21 +    uint32_t shared_type;
    9.22 +};
    9.23 +
    9.24 +struct processor_pminfo {
    9.25 +    uint32_t acpi_id;
    9.26 +    uint32_t id;
    9.27 +    uint32_t flag;
    9.28 +    struct processor_performance    perf;
    9.29 +};
    9.30 +
    9.31 +extern struct processor_pminfo processor_pminfo[NR_CPUS];
    9.32 +
    9.33 +#endif /* __XEN_PROCESSOR_PM_H__ */
    10.1 --- a/xen/include/public/platform.h	Wed May 14 13:25:19 2008 +0100
    10.2 +++ b/xen/include/public/platform.h	Wed May 14 13:50:46 2008 +0100
    10.3 @@ -211,6 +211,12 @@ DEFINE_XEN_GUEST_HANDLE(xenpf_getidletim
    10.4  #define XEN_PM_PX   1
    10.5  #define XEN_PM_TX   2
    10.6  
    10.7 +/* Px sub info type */
    10.8 +#define XEN_PX_PCT   1
    10.9 +#define XEN_PX_PSS   2
   10.10 +#define XEN_PX_PPC   4
   10.11 +#define XEN_PX_PSD   8
   10.12 +
   10.13  struct xen_power_register {
   10.14      uint32_t     space_id;
   10.15      uint32_t     bit_width;
   10.16 @@ -252,12 +258,55 @@ struct xen_processor_power {
   10.17      XEN_GUEST_HANDLE(xen_processor_cx_t) states; /* supported c states */
   10.18  };
   10.19  
   10.20 +struct xen_pct_register {
   10.21 +    uint8_t  descriptor;
   10.22 +    uint16_t length;
   10.23 +    uint8_t  space_id;
   10.24 +    uint8_t  bit_width;
   10.25 +    uint8_t  bit_offset;
   10.26 +    uint8_t  reserved;
   10.27 +    uint64_t address;
   10.28 +};
   10.29 +
   10.30 +struct xen_processor_px {
   10.31 +    uint64_t core_frequency; /* megahertz */
   10.32 +    uint64_t power;      /* milliWatts */
   10.33 +    uint64_t transition_latency; /* microseconds */
   10.34 +    uint64_t bus_master_latency; /* microseconds */
   10.35 +    uint64_t control;        /* control value */
   10.36 +    uint64_t status;     /* success indicator */
   10.37 +};
   10.38 +typedef struct xen_processor_px xen_processor_px_t;
   10.39 +DEFINE_XEN_GUEST_HANDLE(xen_processor_px_t);
   10.40 +
   10.41 +struct xen_psd_package {
   10.42 +    uint64_t num_entries;
   10.43 +    uint64_t revision;
   10.44 +    uint64_t domain;
   10.45 +    uint64_t coord_type;
   10.46 +    uint64_t num_processors;
   10.47 +};
   10.48 +
   10.49 +struct xen_processor_performance {
   10.50 +    uint32_t flags;     /* flag for Px sub info type */
   10.51 +    uint32_t ppc;       /* Platform limitation on freq usage */
   10.52 +    struct xen_pct_register control_register;
   10.53 +    struct xen_pct_register status_register;
   10.54 +    uint32_t state_count;     /* total available performance states */
   10.55 +    XEN_GUEST_HANDLE(xen_processor_px_t) states;
   10.56 +    struct xen_psd_package domain_info;
   10.57 +    uint32_t shared_type;     /* coordination type of this processor */
   10.58 +};
   10.59 +typedef struct xen_processor_performance xen_processor_performance_t;
   10.60 +DEFINE_XEN_GUEST_HANDLE(xen_processor_performance_t);
   10.61 +
   10.62  struct xenpf_set_processor_pminfo {
   10.63      /* IN variables */
   10.64      uint32_t id;    /* ACPI CPU ID */
   10.65 -    uint32_t type;  /* {XEN_PM_CX, ...} */
   10.66 +    uint32_t type;  /* {XEN_PM_CX, XEN_PM_PX} */
   10.67      union {
   10.68          struct xen_processor_power          power;/* Cx: _CST/_CSD */
   10.69 +        struct xen_processor_performance    perf; /* Px: _PPC/_PCT/_PSS/_PSD */
   10.70      };
   10.71  };
   10.72  typedef struct xenpf_set_processor_pminfo xenpf_set_processor_pminfo_t;
    11.1 --- a/xen/include/xen/domain.h	Wed May 14 13:25:19 2008 +0100
    11.2 +++ b/xen/include/xen/domain.h	Wed May 14 13:50:46 2008 +0100
    11.3 @@ -57,4 +57,6 @@ void arch_dump_domain_info(struct domain
    11.4  
    11.5  int arch_vcpu_reset(struct vcpu *v);
    11.6  
    11.7 +extern unsigned int xen_processor_pmbits;
    11.8 +
    11.9  #endif /* __XEN_DOMAIN_H__ */