/root/src/xen/xen/include/asm/hvm/vpt.h
Line | Count | Source (jump to first uncovered line) |
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, see <http://www.gnu.org/licenses/>. |
17 | | */ |
18 | | |
19 | | #ifndef __ASM_X86_HVM_VPT_H__ |
20 | | #define __ASM_X86_HVM_VPT_H__ |
21 | | |
22 | | #include <xen/init.h> |
23 | | #include <xen/lib.h> |
24 | | #include <xen/time.h> |
25 | | #include <xen/errno.h> |
26 | | #include <xen/time.h> |
27 | | #include <xen/timer.h> |
28 | | #include <xen/list.h> |
29 | | #include <asm/hvm/vpic.h> |
30 | | #include <asm/hvm/irq.h> |
31 | | #include <public/hvm/save.h> |
32 | | |
33 | | /* |
34 | | * Abstract layer of periodic time, one short time. |
35 | | */ |
36 | | typedef void time_cb(struct vcpu *v, void *opaque); |
37 | | |
38 | | struct periodic_time { |
39 | | struct list_head list; |
40 | | bool_t on_list; |
41 | | bool_t one_shot; |
42 | | bool_t do_not_freeze; |
43 | | bool_t irq_issued; |
44 | | bool_t warned_timeout_too_short; |
45 | 0 | #define PTSRC_isa 1 /* ISA time source */ |
46 | 18.4E | #define PTSRC_lapic 2 /* LAPIC time source */ |
47 | | u8 source; /* PTSRC_ */ |
48 | | u8 irq; |
49 | | struct vcpu *vcpu; /* vcpu timer interrupt delivers to */ |
50 | | u32 pending_intr_nr; /* pending timer interrupts */ |
51 | | u64 period; /* frequency in ns */ |
52 | | s_time_t scheduled; /* scheduled timer interrupt */ |
53 | | u64 last_plt_gtime; /* platform time when last IRQ is injected */ |
54 | | struct timer timer; /* ac_timer */ |
55 | | time_cb *cb; |
56 | | void *priv; /* point back to platform time source */ |
57 | | }; |
58 | | |
59 | | |
60 | 0 | #define PIT_FREQ 1193182 |
61 | 0 | #define PIT_BASE 0x40 |
62 | | |
63 | | typedef struct PITState { |
64 | | /* Hardware state */ |
65 | | struct hvm_hw_pit hw; |
66 | | /* Last time the counters read zero, for calcuating counter reads */ |
67 | | int64_t count_load_time[3]; |
68 | | /* Channel 0 IRQ handling. */ |
69 | | struct periodic_time pt0; |
70 | | spinlock_t lock; |
71 | | } PITState; |
72 | | |
73 | | struct hpet_registers { |
74 | | /* Memory-mapped, software visible registers */ |
75 | | uint64_t capability; /* capabilities */ |
76 | | uint64_t config; /* configuration */ |
77 | | uint64_t isr; /* interrupt status reg */ |
78 | | uint64_t mc64; /* main counter */ |
79 | | struct { /* timers */ |
80 | | uint64_t config; /* configuration/cap */ |
81 | | uint64_t cmp; /* comparator */ |
82 | | uint64_t fsb; /* FSB route, not supported now */ |
83 | | } timers[HPET_TIMER_NUM]; |
84 | | |
85 | | /* Hidden register state */ |
86 | | uint64_t period[HPET_TIMER_NUM]; /* Last value written to comparator */ |
87 | | uint64_t comparator64[HPET_TIMER_NUM]; /* 64 bit running comparator */ |
88 | | }; |
89 | | |
90 | | typedef struct HPETState { |
91 | | struct hpet_registers hpet; |
92 | | uint64_t stime_freq; |
93 | | uint64_t hpet_to_ns_scale; /* hpet ticks to ns (multiplied by 2^10) */ |
94 | | uint64_t hpet_to_ns_limit; /* max hpet ticks convertable to ns */ |
95 | | uint64_t mc_offset; |
96 | | struct periodic_time pt[HPET_TIMER_NUM]; |
97 | | rwlock_t lock; |
98 | | } HPETState; |
99 | | |
100 | | typedef struct RTCState { |
101 | | /* Hardware state */ |
102 | | struct hvm_hw_rtc hw; |
103 | | /* RTC's idea of the current time */ |
104 | | struct tm current_tm; |
105 | | /* update-ended timer */ |
106 | | struct timer update_timer; |
107 | | struct timer update_timer2; |
108 | | uint64_t next_update_time; |
109 | | /* alarm timer */ |
110 | | struct timer alarm_timer; |
111 | | /* periodic timer */ |
112 | | struct periodic_time pt; |
113 | | s_time_t start_time; |
114 | | s_time_t check_ticks_since; |
115 | | int period; |
116 | | uint8_t pt_dead_ticks; |
117 | | uint32_t use_timer; |
118 | | spinlock_t lock; |
119 | | } RTCState; |
120 | | |
121 | 0 | #define FREQUENCE_PMTIMER 3579545 /* Timer should run at 3.579545 MHz */ |
122 | | typedef struct PMTState { |
123 | | struct vcpu *vcpu; /* Keeps sync with this vcpu's guest-time */ |
124 | | uint64_t last_gtime; /* Last (guest) time we updated the timer */ |
125 | | uint32_t not_accounted; /* time not accounted at last update */ |
126 | | uint64_t scale; /* Multiplier to get from tsc to timer ticks */ |
127 | | struct timer timer; /* To make sure we send SCIs */ |
128 | | spinlock_t lock; |
129 | | } PMTState; |
130 | | |
131 | | struct pl_time { /* platform time */ |
132 | | struct RTCState vrtc; |
133 | | struct HPETState vhpet; |
134 | | struct PMTState vpmt; |
135 | | /* guest_time = Xen sys time + stime_offset */ |
136 | | int64_t stime_offset; |
137 | | /* Ensures monotonicity in appropriate timer modes. */ |
138 | | uint64_t last_guest_time; |
139 | | spinlock_t pl_time_lock; |
140 | | struct domain *domain; |
141 | | }; |
142 | | |
143 | | void pt_save_timer(struct vcpu *v); |
144 | | void pt_restore_timer(struct vcpu *v); |
145 | | int pt_update_irq(struct vcpu *v); |
146 | | void pt_intr_post(struct vcpu *v, struct hvm_intack intack); |
147 | | void pt_migrate(struct vcpu *v); |
148 | | |
149 | | void pt_adjust_global_vcpu_target(struct vcpu *v); |
150 | | #define pt_global_vcpu_target(d) \ |
151 | 0 | (is_hvm_domain(d) && (d)->arch.hvm_domain.i8259_target ? \ |
152 | 0 | (d)->arch.hvm_domain.i8259_target : \ |
153 | 0 | (d)->vcpu ? (d)->vcpu[0] : NULL) |
154 | | |
155 | | void pt_may_unmask_irq(struct domain *d, struct periodic_time *vlapic_pt); |
156 | | |
157 | | /* Is given periodic timer active? */ |
158 | 0 | #define pt_active(pt) ((pt)->on_list || (pt)->pending_intr_nr) |
159 | | |
160 | | /* |
161 | | * Create/destroy a periodic (or one-shot!) timer. |
162 | | * The given periodic timer structure must be initialised with zero bytes, |
163 | | * except for the 'source' field which must be initialised with the |
164 | | * correct PTSRC_ value. The initialised timer structure can then be passed |
165 | | * to {create,destroy}_periodic_time() any number of times and in any order. |
166 | | * Note that, for a given periodic timer, invocations of these functions MUST |
167 | | * be serialised. |
168 | | */ |
169 | | void create_periodic_time( |
170 | | struct vcpu *v, struct periodic_time *pt, uint64_t delta, |
171 | | uint64_t period, uint8_t irq, time_cb *cb, void *data); |
172 | | void destroy_periodic_time(struct periodic_time *pt); |
173 | | |
174 | | int pv_pit_handler(int port, int data, int write); |
175 | | void pit_reset(struct domain *d); |
176 | | |
177 | | void pit_init(struct domain *d, unsigned long cpu_khz); |
178 | | void pit_stop_channel0_irq(PITState * pit); |
179 | | void pit_deinit(struct domain *d); |
180 | | void rtc_init(struct domain *d); |
181 | | void rtc_migrate_timers(struct vcpu *v); |
182 | | void rtc_deinit(struct domain *d); |
183 | | void rtc_reset(struct domain *d); |
184 | | void rtc_update_clock(struct domain *d); |
185 | | |
186 | | void pmtimer_init(struct vcpu *v); |
187 | | void pmtimer_deinit(struct domain *d); |
188 | | void pmtimer_reset(struct domain *d); |
189 | | int pmtimer_change_ioport(struct domain *d, unsigned int version); |
190 | | |
191 | | void hpet_init(struct domain *d); |
192 | | void hpet_deinit(struct domain *d); |
193 | | void hpet_reset(struct domain *d); |
194 | | |
195 | | #endif /* __ASM_X86_HVM_VPT_H__ */ |