debuggers.hg

view xen/include/asm-x86/hvm/vpt.h @ 17986:f2148e532c81

x86 hvm: Fix RTC handling.
1. Clean up initialisation/destruction.
2. Better handle per-domain time-offset changes.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Jul 02 17:25:05 2008 +0100 (2008-07-02)
parents 6c4cab061af4
children 978ffdd19c0f
line source
1 /*
2 * vpt.h: Virtual Platform Timer definitions
3 *
4 * Copyright (c) 2004, Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
17 * Place - Suite 330, Boston, MA 02111-1307 USA.
18 */
20 #ifndef __ASM_X86_HVM_VPT_H__
21 #define __ASM_X86_HVM_VPT_H__
23 #include <xen/config.h>
24 #include <xen/init.h>
25 #include <xen/lib.h>
26 #include <xen/time.h>
27 #include <xen/errno.h>
28 #include <xen/time.h>
29 #include <xen/timer.h>
30 #include <xen/list.h>
31 #include <asm/hvm/vpic.h>
32 #include <asm/hvm/irq.h>
33 #include <public/hvm/save.h>
35 struct HPETState;
36 struct HPET_timer_fn_info {
37 struct HPETState *hs;
38 unsigned int tn;
39 };
41 struct hpet_registers {
42 /* Memory-mapped, software visible registers */
43 uint64_t capability; /* capabilities */
44 uint64_t config; /* configuration */
45 uint64_t isr; /* interrupt status reg */
46 uint64_t mc64; /* main counter */
47 struct { /* timers */
48 uint64_t config; /* configuration/cap */
49 uint64_t cmp; /* comparator */
50 uint64_t fsb; /* FSB route, not supported now */
51 } timers[HPET_TIMER_NUM];
53 /* Hidden register state */
54 uint64_t period[HPET_TIMER_NUM]; /* Last value written to comparator */
55 };
57 typedef struct HPETState {
58 struct hpet_registers hpet;
59 struct vcpu *vcpu;
60 uint64_t stime_freq;
61 uint64_t hpet_to_ns_scale; /* hpet ticks to ns (multiplied by 2^10) */
62 uint64_t hpet_to_ns_limit; /* max hpet ticks convertable to ns */
63 uint64_t mc_offset;
64 struct timer timers[HPET_TIMER_NUM];
65 struct HPET_timer_fn_info timer_fn_info[HPET_TIMER_NUM];
66 spinlock_t lock;
67 } HPETState;
70 /*
71 * Abstract layer of periodic time, one short time.
72 */
73 typedef void time_cb(struct vcpu *v, void *opaque);
75 struct periodic_time {
76 struct list_head list;
77 bool_t on_list;
78 bool_t one_shot;
79 bool_t do_not_freeze;
80 bool_t irq_issued;
81 bool_t warned_timeout_too_short;
82 #define PTSRC_isa 1 /* ISA time source */
83 #define PTSRC_lapic 2 /* LAPIC time source */
84 u8 source; /* PTSRC_ */
85 u8 irq;
86 struct vcpu *vcpu; /* vcpu timer interrupt delivers to */
87 u32 pending_intr_nr; /* pending timer interrupts */
88 u64 period; /* frequency in ns */
89 u64 period_cycles; /* frequency in cpu cycles */
90 s_time_t scheduled; /* scheduled timer interrupt */
91 u64 last_plt_gtime; /* platform time when last IRQ is injected */
92 struct timer timer; /* ac_timer */
93 time_cb *cb;
94 void *priv; /* point back to platform time source */
95 };
98 #define PIT_FREQ 1193181
99 #define PIT_BASE 0x40
101 typedef struct PITState {
102 /* Hardware state */
103 struct hvm_hw_pit hw;
104 /* Last time the counters read zero, for calcuating counter reads */
105 int64_t count_load_time[3];
106 /* Channel 0 IRQ handling. */
107 struct periodic_time pt0;
108 spinlock_t lock;
109 } PITState;
111 typedef struct RTCState {
112 /* Hardware state */
113 struct hvm_hw_rtc hw;
114 /* RTC's idea of the current time */
115 struct tm current_tm;
116 /* second update */
117 int64_t next_second_time;
118 struct timer second_timer;
119 struct timer second_timer2;
120 struct periodic_time pt;
121 spinlock_t lock;
122 } RTCState;
124 #define FREQUENCE_PMTIMER 3579545 /* Timer should run at 3.579545 MHz */
125 typedef struct PMTState {
126 struct hvm_hw_pmtimer pm; /* 32bit timer value */
127 struct vcpu *vcpu; /* Keeps sync with this vcpu's guest-time */
128 uint64_t last_gtime; /* Last (guest) time we updated the timer */
129 uint64_t scale; /* Multiplier to get from tsc to timer ticks */
130 struct timer timer; /* To make sure we send SCIs */
131 spinlock_t lock;
132 } PMTState;
134 struct pl_time { /* platform time */
135 struct PITState vpit;
136 struct RTCState vrtc;
137 struct HPETState vhpet;
138 struct PMTState vpmt;
139 /* guest_time = Xen sys time + stime_offset */
140 int64_t stime_offset;
141 /* Ensures monotonicity in appropriate timer modes. */
142 uint64_t last_guest_time;
143 spinlock_t pl_time_lock;
144 };
146 #define ticks_per_sec(v) (v->domain->arch.hvm_domain.tsc_frequency)
148 void pt_save_timer(struct vcpu *v);
149 void pt_restore_timer(struct vcpu *v);
150 void pt_update_irq(struct vcpu *v);
151 void pt_intr_post(struct vcpu *v, struct hvm_intack intack);
152 void pt_reset(struct vcpu *v);
153 void pt_migrate(struct vcpu *v);
155 /* Is given periodic timer active? */
156 #define pt_active(pt) ((pt)->on_list)
158 /*
159 * Create/destroy a periodic (or one-shot!) timer.
160 * The given periodic timer structure must be initialised with zero bytes,
161 * except for the 'source' field which must be initialised with the
162 * correct PTSRC_ value. The initialised timer structure can then be passed
163 * to {create,destroy}_periodic_time() and number of times and in any order.
164 * Note that, for a given periodic timer, invocations of these functions MUST
165 * be serialised.
166 */
167 void create_periodic_time(
168 struct vcpu *v, struct periodic_time *pt, uint64_t period,
169 uint8_t irq, char one_shot, time_cb *cb, void *data);
170 void destroy_periodic_time(struct periodic_time *pt);
172 int pv_pit_handler(int port, int data, int write);
173 void pit_reset(struct domain *d);
175 void pit_init(struct vcpu *v, unsigned long cpu_khz);
176 void pit_stop_channel0_irq(PITState * pit);
177 void pit_deinit(struct domain *d);
178 void rtc_init(struct domain *d);
179 void rtc_migrate_timers(struct vcpu *v);
180 void rtc_deinit(struct domain *d);
181 void rtc_reset(struct domain *d);
182 void rtc_update_clock(struct domain *d);
184 void pmtimer_init(struct vcpu *v);
185 void pmtimer_deinit(struct domain *d);
186 void pmtimer_reset(struct domain *d);
188 void hpet_migrate_timers(struct vcpu *v);
189 void hpet_init(struct vcpu *v);
190 void hpet_deinit(struct domain *d);
191 void hpet_reset(struct domain *d);
193 #endif /* __ASM_X86_HVM_VPT_H__ */