ia64/xen-unstable

changeset 11969:7957dffb855f

[HVM] Move ACPI timer to HV, which is the last platform timer in Qemu.

We found Vista polls ACPI timer very frequently (about 15 times
averagely) when handling timer (RTC @ 64HZ) interrupt routine. Though
the exact reason is known, it should be related to system time
adjustment. When it's in Qemu, the overhead is big. After moving,
Vista's idle overhead decreases dramatically from ~10% to 0.9%.=20

Another benefit is that Vista can only pass Performance rating with
this patch. The root cause is that ACPI timer in Qemu isn't
synchronous with other platform timer in HV, which results in Vista
complains "can't measure TSC frequency".

This patch changes vpit.h to vpt.h, for it not only has pit structure
in it, but other platform timer's structure. Another change is moving
ACPI timer and related address from acpi.h to ioreq.h, which can be shared
by HV and ACPI firmware.

Signed-off-by: Xiaowei Yang <xiaowei.yang@intel.com>
author kfraser@localhost.localdomain
date Wed Oct 25 11:50:54 2006 +0100 (2006-10-25)
parents ffbd9e4668a6
children a1f987e9640f
files tools/firmware/acpi/acpi_fadt.h xen/arch/x86/hvm/Makefile xen/arch/x86/hvm/hvm.c xen/arch/x86/hvm/i8254.c xen/arch/x86/hvm/io.c xen/arch/x86/hvm/pmtimer.c xen/arch/x86/hvm/rtc.c xen/arch/x86/hvm/svm/svm.c xen/arch/x86/hvm/vmx/vmx.c xen/include/asm-x86/hvm/domain.h xen/include/asm-x86/hvm/vpit.h xen/include/asm-x86/hvm/vpt.h xen/include/public/hvm/ioreq.h
line diff
     1.1 --- a/tools/firmware/acpi/acpi_fadt.h	Wed Oct 25 10:59:00 2006 +0100
     1.2 +++ b/tools/firmware/acpi/acpi_fadt.h	Wed Oct 25 11:50:54 2006 +0100
     1.3 @@ -18,6 +18,8 @@
     1.4  #ifndef _FADT_H_
     1.5  #define _FADT_H_
     1.6  
     1.7 +#include <xen/hvm/ioreq.h>
     1.8 +
     1.9  //
    1.10  // FADT Definitions, see ACPI 2.0 specification for details.
    1.11  //
    1.12 @@ -51,7 +53,9 @@
    1.13  //
    1.14  // Fixed Feature Flags
    1.15  // 
    1.16 -#define ACPI_FIXED_FEATURE_FLAGS (ACPI_PROC_C1|ACPI_SLP_BUTTON|ACPI_WBINVD|ACPI_PWR_BUTTON|ACPI_FIX_RTC)
    1.17 +#define ACPI_FIXED_FEATURE_FLAGS (ACPI_PROC_C1 | ACPI_SLP_BUTTON | \
    1.18 +                                  ACPI_WBINVD | ACPI_PWR_BUTTON | \
    1.19 +                                  ACPI_FIX_RTC | ACPI_TMR_VAL_EXT)
    1.20  
    1.21  //
    1.22  // PM1A Event Register Block Generic Address Information
    1.23 @@ -59,7 +63,6 @@
    1.24  #define ACPI_PM1A_EVT_BLK_ADDRESS_SPACE_ID  ACPI_SYSTEM_IO
    1.25  #define ACPI_PM1A_EVT_BLK_BIT_WIDTH         0x20
    1.26  #define ACPI_PM1A_EVT_BLK_BIT_OFFSET        0x00
    1.27 -#define ACPI_PM1A_EVT_BLK_ADDRESS           0x000000000000c010
    1.28  
    1.29  //
    1.30  // PM1B Event Register Block Generic Address Information
    1.31 @@ -75,7 +78,6 @@
    1.32  #define ACPI_PM1A_CNT_BLK_ADDRESS_SPACE_ID  ACPI_SYSTEM_IO
    1.33  #define ACPI_PM1A_CNT_BLK_BIT_WIDTH         0x10
    1.34  #define ACPI_PM1A_CNT_BLK_BIT_OFFSET        0x00
    1.35 -#define ACPI_PM1A_CNT_BLK_ADDRESS           (ACPI_PM1A_EVT_BLK_ADDRESS + 0x04)
    1.36  
    1.37  //
    1.38  // PM1B Control Register Block Generic Address Information
    1.39 @@ -100,7 +102,6 @@
    1.40  #define ACPI_PM_TMR_BLK_ADDRESS_SPACE_ID    ACPI_SYSTEM_IO
    1.41  #define ACPI_PM_TMR_BLK_BIT_WIDTH           0x20
    1.42  #define ACPI_PM_TMR_BLK_BIT_OFFSET          0x00
    1.43 -#define ACPI_PM_TMR_BLK_ADDRESS             (ACPI_PM1A_EVT_BLK_ADDRESS + 0x08)
    1.44  
    1.45  //
    1.46  // General Purpose Event 0 Register Block Generic Address
     2.1 --- a/xen/arch/x86/hvm/Makefile	Wed Oct 25 10:59:00 2006 +0100
     2.2 +++ b/xen/arch/x86/hvm/Makefile	Wed Oct 25 11:50:54 2006 +0100
     2.3 @@ -5,6 +5,7 @@ obj-y += hvm.o
     2.4  obj-y += i8254.o
     2.5  obj-y += i8259.o
     2.6  obj-y += rtc.o
     2.7 +obj-y += pmtimer.o
     2.8  obj-y += instrlen.o
     2.9  obj-y += intercept.o
    2.10  obj-y += io.o
     3.1 --- a/xen/arch/x86/hvm/hvm.c	Wed Oct 25 10:59:00 2006 +0100
     3.2 +++ b/xen/arch/x86/hvm/hvm.c	Wed Oct 25 11:50:54 2006 +0100
     3.3 @@ -43,7 +43,7 @@
     3.4  #include <asm/mc146818rtc.h>
     3.5  #include <asm/spinlock.h>
     3.6  #include <asm/hvm/hvm.h>
     3.7 -#include <asm/hvm/vpit.h>
     3.8 +#include <asm/hvm/vpt.h>
     3.9  #include <asm/hvm/support.h>
    3.10  #include <public/sched.h>
    3.11  #include <public/hvm/ioreq.h>
    3.12 @@ -285,6 +285,7 @@ void hvm_setup_platform(struct domain* d
    3.13                 pt_timer_fn, v, v->processor);
    3.14      pit_init(v, cpu_khz);
    3.15      rtc_init(v, RTC_PORT(0), RTC_IRQ);
    3.16 +    pmtimer_init(v, ACPI_PM_TMR_BLK_ADDRESS); 
    3.17  }
    3.18  
    3.19  void pic_irq_request(void *data, int level)
     4.1 --- a/xen/arch/x86/hvm/i8254.c	Wed Oct 25 10:59:00 2006 +0100
     4.2 +++ b/xen/arch/x86/hvm/i8254.c	Wed Oct 25 11:50:54 2006 +0100
     4.3 @@ -38,7 +38,7 @@
     4.4  #include <asm/hvm/hvm.h>
     4.5  #include <asm/hvm/io.h>
     4.6  #include <asm/hvm/support.h>
     4.7 -#include <asm/hvm/vpit.h>
     4.8 +#include <asm/hvm/vpt.h>
     4.9  #include <asm/current.h>
    4.10  
    4.11  /* Enable DEBUG_PIT may cause guest calibration inaccuracy */
     5.1 --- a/xen/arch/x86/hvm/io.c	Wed Oct 25 10:59:00 2006 +0100
     5.2 +++ b/xen/arch/x86/hvm/io.c	Wed Oct 25 11:50:54 2006 +0100
     5.3 @@ -35,7 +35,7 @@
     5.4  #include <asm/shadow.h>
     5.5  #include <asm/hvm/hvm.h>
     5.6  #include <asm/hvm/support.h>
     5.7 -#include <asm/hvm/vpit.h>
     5.8 +#include <asm/hvm/vpt.h>
     5.9  #include <asm/hvm/vpic.h>
    5.10  #include <asm/hvm/vlapic.h>
    5.11  
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/xen/arch/x86/hvm/pmtimer.c	Wed Oct 25 11:50:54 2006 +0100
     6.3 @@ -0,0 +1,63 @@
     6.4 +#include <asm/hvm/vpt.h>
     6.5 +#include <asm/hvm/io.h>
     6.6 +#include <asm/hvm/support.h>
     6.7 +
     6.8 +#define TMR_STS (1 << 0)
     6.9 +static void pmt_update_status(void *opaque)
    6.10 +{
    6.11 +   PMTState *s = opaque;
    6.12 +   s->pm1_status |= TMR_STS;
    6.13 +
    6.14 +   /* TODO: When TMR_EN == 1, generate a SCI event */
    6.15 +
    6.16 +   set_timer(&s->timer, NOW() + (1000000000ULL << 31) / FREQUENCE_PMTIMER);
    6.17 +}
    6.18 +
    6.19 +static int handle_pmt_io(ioreq_t *p)
    6.20 +{
    6.21 +    struct vcpu *v = current;
    6.22 +    PMTState *s = &v->domain->arch.hvm_domain.pl_time.vpmt;
    6.23 +    uint64_t curr_gtime;
    6.24 +
    6.25 +    if (p->size != 4 ||
    6.26 +        p->pdata_valid ||
    6.27 +        p->type != IOREQ_TYPE_PIO){
    6.28 +        printk("HVM_PMT: wrong PM timer IO\n");
    6.29 +        return 1;
    6.30 +    }
    6.31 +    
    6.32 +    if (p->dir == 0) { /* write */
    6.33 +        /* PM_TMR_BLK is read-only */
    6.34 +        return 1;
    6.35 +    } else if (p->dir == 1) { /* read */
    6.36 +        curr_gtime = hvm_get_guest_time(s->vcpu);
    6.37 +        s->pm1_timer += ((curr_gtime - s->last_gtime) * s->scale) >> 32;
    6.38 +        p->u.data = s->pm1_timer;
    6.39 +        s->last_gtime = curr_gtime;
    6.40 +        return 1;
    6.41 +    }
    6.42 +    return 0;
    6.43 +}
    6.44 +
    6.45 +void pmtimer_init(struct vcpu *v, int base)
    6.46 +{
    6.47 +    PMTState *s = &v->domain->arch.hvm_domain.pl_time.vpmt;
    6.48 +
    6.49 +    s->pm1_timer = 0;
    6.50 +    s->pm1_status = 0;
    6.51 +    s->scale = ((uint64_t)FREQUENCE_PMTIMER << 32) / ticks_per_sec(v);
    6.52 +    s->vcpu = v;
    6.53 +
    6.54 +    init_timer(&s->timer, pmt_update_status, s, v->processor);
    6.55 +    /* ACPI supports a 32-bit power management timer */
    6.56 +    set_timer(&s->timer, NOW() + (1000000000ULL << 31) / FREQUENCE_PMTIMER);
    6.57 +    
    6.58 +    register_portio_handler(base, 4, handle_pmt_io);
    6.59 +}
    6.60 +
    6.61 +void pmtimer_deinit(struct domain *d)
    6.62 +{
    6.63 +    PMTState *s = &d->arch.hvm_domain.pl_time.vpmt;
    6.64 +
    6.65 +    kill_timer(&s->timer);
    6.66 +}
     7.1 --- a/xen/arch/x86/hvm/rtc.c	Wed Oct 25 10:59:00 2006 +0100
     7.2 +++ b/xen/arch/x86/hvm/rtc.c	Wed Oct 25 11:50:54 2006 +0100
     7.3 @@ -23,7 +23,7 @@
     7.4   */
     7.5  
     7.6  #include <asm/mc146818rtc.h>
     7.7 -#include <asm/hvm/vpit.h>
     7.8 +#include <asm/hvm/vpt.h>
     7.9  #include <asm/hvm/io.h>
    7.10  #include <asm/hvm/support.h>
    7.11  #include <asm/current.h>
     8.1 --- a/xen/arch/x86/hvm/svm/svm.c	Wed Oct 25 10:59:00 2006 +0100
     8.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Wed Oct 25 11:50:54 2006 +0100
     8.3 @@ -922,6 +922,7 @@ static void svm_relinquish_guest_resourc
     8.4  
     8.5      kill_timer(&d->arch.hvm_domain.pl_time.periodic_tm.timer);
     8.6      rtc_deinit(d);
     8.7 +    pmtimer_deinit(d);
     8.8  
     8.9      if ( d->arch.hvm_domain.shared_page_va )
    8.10          unmap_domain_page_global(
    8.11 @@ -937,6 +938,7 @@ static void svm_migrate_timers(struct vc
    8.12      struct periodic_time *pt = 
    8.13          &(v->domain->arch.hvm_domain.pl_time.periodic_tm);
    8.14      struct RTCState *vrtc = &v->domain->arch.hvm_domain.pl_time.vrtc;
    8.15 +    struct PMTState *vpmt = &v->domain->arch.hvm_domain.pl_time.vpmt;
    8.16  
    8.17      if ( pt->enabled )
    8.18      {
    8.19 @@ -947,6 +949,7 @@ static void svm_migrate_timers(struct vc
    8.20          migrate_timer(&VLAPIC(v)->vlapic_timer, v->processor);
    8.21      migrate_timer(&vrtc->second_timer, v->processor);
    8.22      migrate_timer(&vrtc->second_timer2, v->processor);
    8.23 +    migrate_timer(&vpmt->timer, v->processor);
    8.24  }
    8.25  
    8.26  
     9.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Wed Oct 25 10:59:00 2006 +0100
     9.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Wed Oct 25 11:50:54 2006 +0100
     9.3 @@ -147,6 +147,7 @@ static void vmx_relinquish_guest_resourc
     9.4  
     9.5      kill_timer(&d->arch.hvm_domain.pl_time.periodic_tm.timer);
     9.6      rtc_deinit(d);
     9.7 +    pmtimer_deinit(d);
     9.8  
     9.9      if ( d->arch.hvm_domain.shared_page_va )
    9.10          unmap_domain_page_global(
    9.11 @@ -489,6 +490,7 @@ void vmx_migrate_timers(struct vcpu *v)
    9.12  {
    9.13      struct periodic_time *pt = &(v->domain->arch.hvm_domain.pl_time.periodic_tm);
    9.14      struct RTCState *vrtc = &v->domain->arch.hvm_domain.pl_time.vrtc;
    9.15 +    struct PMTState *vpmt = &v->domain->arch.hvm_domain.pl_time.vpmt;
    9.16  
    9.17      if ( pt->enabled )
    9.18      {
    9.19 @@ -499,6 +501,7 @@ void vmx_migrate_timers(struct vcpu *v)
    9.20          migrate_timer(&VLAPIC(v)->vlapic_timer, v->processor);
    9.21      migrate_timer(&vrtc->second_timer, v->processor);
    9.22      migrate_timer(&vrtc->second_timer2, v->processor);
    9.23 +    migrate_timer(&vpmt->timer, v->processor);
    9.24  }
    9.25  
    9.26  static void vmx_store_cpu_guest_regs(
    10.1 --- a/xen/include/asm-x86/hvm/domain.h	Wed Oct 25 10:59:00 2006 +0100
    10.2 +++ b/xen/include/asm-x86/hvm/domain.h	Wed Oct 25 11:50:54 2006 +0100
    10.3 @@ -23,7 +23,7 @@
    10.4  #define __ASM_X86_HVM_DOMAIN_H__
    10.5  
    10.6  #include <asm/hvm/vpic.h>
    10.7 -#include <asm/hvm/vpit.h>
    10.8 +#include <asm/hvm/vpt.h>
    10.9  #include <asm/hvm/vlapic.h>
   10.10  #include <asm/hvm/vioapic.h>
   10.11  #include <public/hvm/params.h>
    11.1 --- a/xen/include/asm-x86/hvm/vpit.h	Wed Oct 25 10:59:00 2006 +0100
    11.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.3 @@ -1,139 +0,0 @@
    11.4 -/*
    11.5 - * vpit.h: Virtual PIT definitions
    11.6 - *
    11.7 - * Copyright (c) 2004, Intel Corporation.
    11.8 - *
    11.9 - * This program is free software; you can redistribute it and/or modify it
   11.10 - * under the terms and conditions of the GNU General Public License,
   11.11 - * version 2, as published by the Free Software Foundation.
   11.12 - *
   11.13 - * This program is distributed in the hope it will be useful, but WITHOUT
   11.14 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   11.15 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   11.16 - * more details.
   11.17 - *
   11.18 - * You should have received a copy of the GNU General Public License along with
   11.19 - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
   11.20 - * Place - Suite 330, Boston, MA 02111-1307 USA.
   11.21 - */
   11.22 -
   11.23 -#ifndef __ASM_X86_HVM_VPIT_H__
   11.24 -#define __ASM_X86_HVM_VPIT_H__
   11.25 -
   11.26 -#include <xen/config.h>
   11.27 -#include <xen/init.h>
   11.28 -#include <xen/lib.h>
   11.29 -#include <xen/time.h>
   11.30 -#include <xen/errno.h>
   11.31 -#include <xen/time.h>
   11.32 -#include <xen/timer.h>
   11.33 -#include <asm/hvm/vpic.h>
   11.34 -
   11.35 -#define PIT_FREQ 1193181
   11.36 -#define PIT_BASE 0x40
   11.37 -
   11.38 -typedef struct PITChannelState {
   11.39 -    int count; /* can be 65536 */
   11.40 -    u16 latched_count;
   11.41 -    u8 count_latched;
   11.42 -    u8 status_latched;
   11.43 -    u8 status;
   11.44 -    u8 read_state;
   11.45 -    u8 write_state;
   11.46 -    u8 write_latch;
   11.47 -    u8 rw_mode;
   11.48 -    u8 mode;
   11.49 -    u8 bcd; /* not supported */
   11.50 -    u8 gate; /* timer start */
   11.51 -    s64 count_load_time;
   11.52 -    /* irq handling */
   11.53 -    struct vcpu      *vcpu;
   11.54 -    struct periodic_time *pt;
   11.55 -} PITChannelState;
   11.56 -
   11.57 -typedef struct PITState {
   11.58 -    PITChannelState channels[3];
   11.59 -    int speaker_data_on;
   11.60 -    int dummy_refresh_clock;
   11.61 -} PITState;
   11.62 -
   11.63 -#define RTC_SIZE 14
   11.64 -typedef struct RTCState {
   11.65 -    uint8_t cmos_data[RTC_SIZE];  /* Only handle time/interrupt part in HV */
   11.66 -    uint8_t cmos_index;
   11.67 -    struct tm current_tm;
   11.68 -    int irq;
   11.69 -    /* second update */
   11.70 -    int64_t next_second_time;
   11.71 -    struct timer second_timer;
   11.72 -    struct timer second_timer2;
   11.73 -    struct vcpu      *vcpu;
   11.74 -    struct periodic_time *pt;
   11.75 -} RTCState;
   11.76 -   
   11.77 -/*
   11.78 - * Abstract layer of periodic time, one short time.
   11.79 - */
   11.80 -typedef void time_cb(struct vcpu *v, void *opaque);
   11.81 -
   11.82 -struct periodic_time {
   11.83 -    char enabled;               /* enabled */
   11.84 -    char one_shot;              /* one shot time */
   11.85 -    char irq;
   11.86 -    char first_injected;        /* flag to prevent shadow window */
   11.87 -    u32 pending_intr_nr;        /* the couner for pending timer interrupts */
   11.88 -    u32 period;                 /* frequency in ns */
   11.89 -    u64 period_cycles;          /* frequency in cpu cycles */
   11.90 -    s_time_t scheduled;         /* scheduled timer interrupt */
   11.91 -    u64 last_plt_gtime;         /* platform time when last IRQ is injected */
   11.92 -    struct timer timer;         /* ac_timer */
   11.93 -    time_cb *cb;
   11.94 -    void *priv;                 /* ponit back to platform time source */
   11.95 -};
   11.96 -
   11.97 -struct pl_time {    /* platform time */
   11.98 -    struct periodic_time periodic_tm;
   11.99 -    struct PITState      vpit;
  11.100 -    struct RTCState      vrtc;
  11.101 -    /* TODO: ACPI time */
  11.102 -};
  11.103 -
  11.104 -static __inline__ s_time_t get_scheduled(
  11.105 -    struct vcpu *v, int irq,
  11.106 -    struct periodic_time *pt)
  11.107 -{
  11.108 -    if ( is_irq_enabled(v, irq) ) {
  11.109 -        return pt->scheduled;
  11.110 -    }
  11.111 -    else
  11.112 -        return -1;
  11.113 -}
  11.114 -
  11.115 -extern u64 hvm_get_guest_time(struct vcpu *v);
  11.116 -/*
  11.117 - * get processor time.
  11.118 - * unit: TSC
  11.119 - */
  11.120 -static __inline__ int64_t hvm_get_clock(struct vcpu *v)
  11.121 -{
  11.122 -    uint64_t  gtsc;
  11.123 -
  11.124 -    gtsc = hvm_get_guest_time(v);
  11.125 -    return gtsc;
  11.126 -}
  11.127 -
  11.128 -#define ticks_per_sec(v)      (v->domain->arch.hvm_domain.tsc_frequency)
  11.129 -
  11.130 -/* to hook the ioreq packet to get the PIT initialization info */
  11.131 -extern void hvm_hooks_assist(struct vcpu *v);
  11.132 -extern void pickup_deactive_ticks(struct periodic_time *vpit);
  11.133 -extern struct periodic_time *create_periodic_time(u32 period, char irq, char one_shot, time_cb *cb, void *data);
  11.134 -extern void destroy_periodic_time(struct periodic_time *pt);
  11.135 -void pit_init(struct vcpu *v, unsigned long cpu_khz);
  11.136 -void rtc_init(struct vcpu *v, int base, int irq);
  11.137 -void rtc_deinit(struct domain *d);
  11.138 -int is_rtc_periodic_irq(void *opaque);
  11.139 -void pt_timer_fn(void *data);
  11.140 -void pit_time_fired(struct vcpu *v, void *priv);
  11.141 -
  11.142 -#endif /* __ASM_X86_HVM_VPIT_H__ */
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/xen/include/asm-x86/hvm/vpt.h	Wed Oct 25 11:50:54 2006 +0100
    12.3 @@ -0,0 +1,151 @@
    12.4 +/*
    12.5 + * vpt.h: Virtual Platform Timer definitions
    12.6 + *
    12.7 + * Copyright (c) 2004, Intel Corporation.
    12.8 + *
    12.9 + * This program is free software; you can redistribute it and/or modify it
   12.10 + * under the terms and conditions of the GNU General Public License,
   12.11 + * version 2, as published by the Free Software Foundation.
   12.12 + *
   12.13 + * This program is distributed in the hope it will be useful, but WITHOUT
   12.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   12.15 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   12.16 + * more details.
   12.17 + *
   12.18 + * You should have received a copy of the GNU General Public License along with
   12.19 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
   12.20 + * Place - Suite 330, Boston, MA 02111-1307 USA.
   12.21 + */
   12.22 +
   12.23 +#ifndef __ASM_X86_HVM_VPT_H__
   12.24 +#define __ASM_X86_HVM_VPT_H__
   12.25 +
   12.26 +#include <xen/config.h>
   12.27 +#include <xen/init.h>
   12.28 +#include <xen/lib.h>
   12.29 +#include <xen/time.h>
   12.30 +#include <xen/errno.h>
   12.31 +#include <xen/time.h>
   12.32 +#include <xen/timer.h>
   12.33 +#include <asm/hvm/vpic.h>
   12.34 +
   12.35 +#define PIT_FREQ 1193181
   12.36 +#define PIT_BASE 0x40
   12.37 +
   12.38 +typedef struct PITChannelState {
   12.39 +    int count; /* can be 65536 */
   12.40 +    u16 latched_count;
   12.41 +    u8 count_latched;
   12.42 +    u8 status_latched;
   12.43 +    u8 status;
   12.44 +    u8 read_state;
   12.45 +    u8 write_state;
   12.46 +    u8 write_latch;
   12.47 +    u8 rw_mode;
   12.48 +    u8 mode;
   12.49 +    u8 bcd; /* not supported */
   12.50 +    u8 gate; /* timer start */
   12.51 +    s64 count_load_time;
   12.52 +    /* irq handling */
   12.53 +    struct vcpu      *vcpu;
   12.54 +    struct periodic_time *pt;
   12.55 +} PITChannelState;
   12.56 +
   12.57 +typedef struct PITState {
   12.58 +    PITChannelState channels[3];
   12.59 +    int speaker_data_on;
   12.60 +    int dummy_refresh_clock;
   12.61 +} PITState;
   12.62 +
   12.63 +#define RTC_SIZE 14
   12.64 +typedef struct RTCState {
   12.65 +    uint8_t cmos_data[RTC_SIZE];  /* Only handle time/interrupt part in HV */
   12.66 +    uint8_t cmos_index;
   12.67 +    struct tm current_tm;
   12.68 +    int irq;
   12.69 +    /* second update */
   12.70 +    int64_t next_second_time;
   12.71 +    struct timer second_timer;
   12.72 +    struct timer second_timer2;
   12.73 +    struct vcpu      *vcpu;
   12.74 +    struct periodic_time *pt;
   12.75 +} RTCState;
   12.76 +
   12.77 +#define FREQUENCE_PMTIMER  3579545
   12.78 +typedef struct PMTState {
   12.79 +    uint32_t pm1_timer;
   12.80 +    uint32_t pm1_status;
   12.81 +    uint64_t last_gtime;
   12.82 +    struct timer timer;
   12.83 +    uint64_t scale;
   12.84 +    struct vcpu *vcpu;
   12.85 +} PMTState;
   12.86 +
   12.87 +/*
   12.88 + * Abstract layer of periodic time, one short time.
   12.89 + */
   12.90 +typedef void time_cb(struct vcpu *v, void *opaque);
   12.91 +
   12.92 +struct periodic_time {
   12.93 +    char enabled;               /* enabled */
   12.94 +    char one_shot;              /* one shot time */
   12.95 +    char irq;
   12.96 +    char first_injected;        /* flag to prevent shadow window */
   12.97 +    u32 pending_intr_nr;        /* the couner for pending timer interrupts */
   12.98 +    u32 period;                 /* frequency in ns */
   12.99 +    u64 period_cycles;          /* frequency in cpu cycles */
  12.100 +    s_time_t scheduled;         /* scheduled timer interrupt */
  12.101 +    u64 last_plt_gtime;         /* platform time when last IRQ is injected */
  12.102 +    struct timer timer;         /* ac_timer */
  12.103 +    time_cb *cb;
  12.104 +    void *priv;                 /* ponit back to platform time source */
  12.105 +};
  12.106 +
  12.107 +struct pl_time {    /* platform time */
  12.108 +    struct periodic_time periodic_tm;
  12.109 +    struct PITState      vpit;
  12.110 +    struct RTCState      vrtc;
  12.111 +    struct PMTState      vpmt;
  12.112 +};
  12.113 +
  12.114 +static __inline__ s_time_t get_scheduled(
  12.115 +    struct vcpu *v, int irq,
  12.116 +    struct periodic_time *pt)
  12.117 +{
  12.118 +    if ( is_irq_enabled(v, irq) ) {
  12.119 +        return pt->scheduled;
  12.120 +    }
  12.121 +    else
  12.122 +        return -1;
  12.123 +}
  12.124 +
  12.125 +extern u64 hvm_get_guest_time(struct vcpu *v);
  12.126 +/*
  12.127 + * get processor time.
  12.128 + * unit: TSC
  12.129 + */
  12.130 +static __inline__ int64_t hvm_get_clock(struct vcpu *v)
  12.131 +{
  12.132 +    uint64_t  gtsc;
  12.133 +
  12.134 +    gtsc = hvm_get_guest_time(v);
  12.135 +    return gtsc;
  12.136 +}
  12.137 +
  12.138 +#define ticks_per_sec(v)      (v->domain->arch.hvm_domain.tsc_frequency)
  12.139 +
  12.140 +/* to hook the ioreq packet to get the PIT initialization info */
  12.141 +extern void hvm_hooks_assist(struct vcpu *v);
  12.142 +extern void pickup_deactive_ticks(struct periodic_time *vpit);
  12.143 +extern struct periodic_time *create_periodic_time(u32 period, char irq, char one_shot, time_cb *cb, void *data);
  12.144 +extern void destroy_periodic_time(struct periodic_time *pt);
  12.145 +void pit_init(struct vcpu *v, unsigned long cpu_khz);
  12.146 +void rtc_init(struct vcpu *v, int base, int irq);
  12.147 +void rtc_deinit(struct domain *d);
  12.148 +void pmtimer_init(struct vcpu *v, int base);
  12.149 +void pmtimer_deinit(struct domain *d);
  12.150 +int is_rtc_periodic_irq(void *opaque);
  12.151 +void pt_timer_fn(void *data);
  12.152 +void pit_time_fired(struct vcpu *v, void *priv);
  12.153 +
  12.154 +#endif /* __ASM_X86_HVM_VPT_H__ */
    13.1 --- a/xen/include/public/hvm/ioreq.h	Wed Oct 25 10:59:00 2006 +0100
    13.2 +++ b/xen/include/public/hvm/ioreq.h	Wed Oct 25 11:50:54 2006 +0100
    13.3 @@ -86,6 +86,10 @@ struct buffered_iopage {
    13.4  };            /* sizeof this structure must be in one page */
    13.5  typedef struct buffered_iopage buffered_iopage_t;
    13.6  
    13.7 +#define ACPI_PM1A_EVT_BLK_ADDRESS           0x000000000000c010
    13.8 +#define ACPI_PM1A_CNT_BLK_ADDRESS           (ACPI_PM1A_EVT_BLK_ADDRESS + 0x04)
    13.9 +#define ACPI_PM_TMR_BLK_ADDRESS             (ACPI_PM1A_EVT_BLK_ADDRESS + 0x08)
   13.10 +
   13.11  #endif /* _IOREQ_H_ */
   13.12  
   13.13  /*