root / hw / i386 / kvm / i8254.c @ 54976b75
History | View | Annotate | Download (9.2 kB)
1 | 5d17c0d2 | Jan Kiszka | /*
|
---|---|---|---|
2 | 5d17c0d2 | Jan Kiszka | * KVM in-kernel PIT (i8254) support
|
3 | 5d17c0d2 | Jan Kiszka | *
|
4 | 5d17c0d2 | Jan Kiszka | * Copyright (c) 2003-2004 Fabrice Bellard
|
5 | 5d17c0d2 | Jan Kiszka | * Copyright (c) 2012 Jan Kiszka, Siemens AG
|
6 | 5d17c0d2 | Jan Kiszka | *
|
7 | 5d17c0d2 | Jan Kiszka | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 | 5d17c0d2 | Jan Kiszka | * of this software and associated documentation files (the "Software"), to deal
|
9 | 5d17c0d2 | Jan Kiszka | * in the Software without restriction, including without limitation the rights
|
10 | 5d17c0d2 | Jan Kiszka | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 | 5d17c0d2 | Jan Kiszka | * copies of the Software, and to permit persons to whom the Software is
|
12 | 5d17c0d2 | Jan Kiszka | * furnished to do so, subject to the following conditions:
|
13 | 5d17c0d2 | Jan Kiszka | *
|
14 | 5d17c0d2 | Jan Kiszka | * The above copyright notice and this permission notice shall be included in
|
15 | 5d17c0d2 | Jan Kiszka | * all copies or substantial portions of the Software.
|
16 | 5d17c0d2 | Jan Kiszka | *
|
17 | 5d17c0d2 | Jan Kiszka | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 | 5d17c0d2 | Jan Kiszka | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 | 5d17c0d2 | Jan Kiszka | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
20 | 5d17c0d2 | Jan Kiszka | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 | 5d17c0d2 | Jan Kiszka | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 | 5d17c0d2 | Jan Kiszka | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 | 5d17c0d2 | Jan Kiszka | * THE SOFTWARE.
|
24 | 5d17c0d2 | Jan Kiszka | */
|
25 | 1de7afc9 | Paolo Bonzini | #include "qemu/timer.h" |
26 | 9c17d615 | Paolo Bonzini | #include "sysemu/sysemu.h" |
27 | 0d09e41a | Paolo Bonzini | #include "hw/timer/i8254.h" |
28 | 0d09e41a | Paolo Bonzini | #include "hw/timer/i8254_internal.h" |
29 | 9c17d615 | Paolo Bonzini | #include "sysemu/kvm.h" |
30 | 5d17c0d2 | Jan Kiszka | |
31 | 5d17c0d2 | Jan Kiszka | #define KVM_PIT_REINJECT_BIT 0 |
32 | 5d17c0d2 | Jan Kiszka | |
33 | 0cdd3d14 | Jan Kiszka | #define CALIBRATION_ROUNDS 3 |
34 | 0cdd3d14 | Jan Kiszka | |
35 | 5d17c0d2 | Jan Kiszka | typedef struct KVMPITState { |
36 | 5d17c0d2 | Jan Kiszka | PITCommonState pit; |
37 | 5d17c0d2 | Jan Kiszka | LostTickPolicy lost_tick_policy; |
38 | 205df4d1 | Jan Kiszka | bool vm_stopped;
|
39 | 205df4d1 | Jan Kiszka | int64_t kernel_clock_offset; |
40 | 5d17c0d2 | Jan Kiszka | } KVMPITState; |
41 | 5d17c0d2 | Jan Kiszka | |
42 | 0cdd3d14 | Jan Kiszka | static int64_t abs64(int64_t v)
|
43 | 5d17c0d2 | Jan Kiszka | { |
44 | 0cdd3d14 | Jan Kiszka | return v < 0 ? -v : v; |
45 | 0cdd3d14 | Jan Kiszka | } |
46 | 0cdd3d14 | Jan Kiszka | |
47 | 205df4d1 | Jan Kiszka | static void kvm_pit_update_clock_offset(KVMPITState *s) |
48 | 0cdd3d14 | Jan Kiszka | { |
49 | 0cdd3d14 | Jan Kiszka | int64_t offset, clock_offset; |
50 | 0cdd3d14 | Jan Kiszka | struct timespec ts;
|
51 | 205df4d1 | Jan Kiszka | int i;
|
52 | 0cdd3d14 | Jan Kiszka | |
53 | 0cdd3d14 | Jan Kiszka | /*
|
54 | 0cdd3d14 | Jan Kiszka | * Measure the delta between CLOCK_MONOTONIC, the base used for
|
55 | 0cdd3d14 | Jan Kiszka | * kvm_pit_channel_state::count_load_time, and vm_clock. Take the
|
56 | 0cdd3d14 | Jan Kiszka | * minimum of several samples to filter out scheduling noise.
|
57 | 0cdd3d14 | Jan Kiszka | */
|
58 | 0cdd3d14 | Jan Kiszka | clock_offset = INT64_MAX; |
59 | 0cdd3d14 | Jan Kiszka | for (i = 0; i < CALIBRATION_ROUNDS; i++) { |
60 | 0cdd3d14 | Jan Kiszka | offset = qemu_get_clock_ns(vm_clock); |
61 | 0cdd3d14 | Jan Kiszka | clock_gettime(CLOCK_MONOTONIC, &ts); |
62 | 0cdd3d14 | Jan Kiszka | offset -= ts.tv_nsec; |
63 | 0cdd3d14 | Jan Kiszka | offset -= (int64_t)ts.tv_sec * 1000000000;
|
64 | 0cdd3d14 | Jan Kiszka | if (abs64(offset) < abs64(clock_offset)) {
|
65 | 0cdd3d14 | Jan Kiszka | clock_offset = offset; |
66 | 0cdd3d14 | Jan Kiszka | } |
67 | 0cdd3d14 | Jan Kiszka | } |
68 | 205df4d1 | Jan Kiszka | s->kernel_clock_offset = clock_offset; |
69 | 205df4d1 | Jan Kiszka | } |
70 | 205df4d1 | Jan Kiszka | |
71 | 205df4d1 | Jan Kiszka | static void kvm_pit_get(PITCommonState *pit) |
72 | 205df4d1 | Jan Kiszka | { |
73 | 205df4d1 | Jan Kiszka | KVMPITState *s = DO_UPCAST(KVMPITState, pit, pit); |
74 | 205df4d1 | Jan Kiszka | struct kvm_pit_state2 kpit;
|
75 | 205df4d1 | Jan Kiszka | struct kvm_pit_channel_state *kchan;
|
76 | 205df4d1 | Jan Kiszka | struct PITChannelState *sc;
|
77 | 205df4d1 | Jan Kiszka | int i, ret;
|
78 | 205df4d1 | Jan Kiszka | |
79 | 205df4d1 | Jan Kiszka | /* No need to re-read the state if VM is stopped. */
|
80 | 205df4d1 | Jan Kiszka | if (s->vm_stopped) {
|
81 | 205df4d1 | Jan Kiszka | return;
|
82 | 205df4d1 | Jan Kiszka | } |
83 | 0cdd3d14 | Jan Kiszka | |
84 | 5d17c0d2 | Jan Kiszka | if (kvm_has_pit_state2()) {
|
85 | 5d17c0d2 | Jan Kiszka | ret = kvm_vm_ioctl(kvm_state, KVM_GET_PIT2, &kpit); |
86 | 5d17c0d2 | Jan Kiszka | if (ret < 0) { |
87 | 5d17c0d2 | Jan Kiszka | fprintf(stderr, "KVM_GET_PIT2 failed: %s\n", strerror(ret));
|
88 | 5d17c0d2 | Jan Kiszka | abort(); |
89 | 5d17c0d2 | Jan Kiszka | } |
90 | 0cdd3d14 | Jan Kiszka | pit->channels[0].irq_disabled = kpit.flags & KVM_PIT_FLAGS_HPET_LEGACY;
|
91 | 5d17c0d2 | Jan Kiszka | } else {
|
92 | 5d17c0d2 | Jan Kiszka | /*
|
93 | 5d17c0d2 | Jan Kiszka | * kvm_pit_state2 is superset of kvm_pit_state struct,
|
94 | 5d17c0d2 | Jan Kiszka | * so we can use it for KVM_GET_PIT as well.
|
95 | 5d17c0d2 | Jan Kiszka | */
|
96 | 5d17c0d2 | Jan Kiszka | ret = kvm_vm_ioctl(kvm_state, KVM_GET_PIT, &kpit); |
97 | 5d17c0d2 | Jan Kiszka | if (ret < 0) { |
98 | 5d17c0d2 | Jan Kiszka | fprintf(stderr, "KVM_GET_PIT failed: %s\n", strerror(ret));
|
99 | 5d17c0d2 | Jan Kiszka | abort(); |
100 | 5d17c0d2 | Jan Kiszka | } |
101 | 5d17c0d2 | Jan Kiszka | } |
102 | 5d17c0d2 | Jan Kiszka | for (i = 0; i < 3; i++) { |
103 | 5d17c0d2 | Jan Kiszka | kchan = &kpit.channels[i]; |
104 | 0cdd3d14 | Jan Kiszka | sc = &pit->channels[i]; |
105 | 5d17c0d2 | Jan Kiszka | sc->count = kchan->count; |
106 | 5d17c0d2 | Jan Kiszka | sc->latched_count = kchan->latched_count; |
107 | 5d17c0d2 | Jan Kiszka | sc->count_latched = kchan->count_latched; |
108 | 5d17c0d2 | Jan Kiszka | sc->status_latched = kchan->status_latched; |
109 | 5d17c0d2 | Jan Kiszka | sc->status = kchan->status; |
110 | 5d17c0d2 | Jan Kiszka | sc->read_state = kchan->read_state; |
111 | 5d17c0d2 | Jan Kiszka | sc->write_state = kchan->write_state; |
112 | 5d17c0d2 | Jan Kiszka | sc->write_latch = kchan->write_latch; |
113 | 5d17c0d2 | Jan Kiszka | sc->rw_mode = kchan->rw_mode; |
114 | 5d17c0d2 | Jan Kiszka | sc->mode = kchan->mode; |
115 | 5d17c0d2 | Jan Kiszka | sc->bcd = kchan->bcd; |
116 | 5d17c0d2 | Jan Kiszka | sc->gate = kchan->gate; |
117 | 205df4d1 | Jan Kiszka | sc->count_load_time = kchan->count_load_time + s->kernel_clock_offset; |
118 | 5d17c0d2 | Jan Kiszka | } |
119 | 5d17c0d2 | Jan Kiszka | |
120 | 0cdd3d14 | Jan Kiszka | sc = &pit->channels[0];
|
121 | 5d17c0d2 | Jan Kiszka | sc->next_transition_time = |
122 | 5d17c0d2 | Jan Kiszka | pit_get_next_transition_time(sc, sc->count_load_time); |
123 | 5d17c0d2 | Jan Kiszka | } |
124 | 5d17c0d2 | Jan Kiszka | |
125 | 050a4606 | Jan Kiszka | static void kvm_pit_put(PITCommonState *pit) |
126 | 5d17c0d2 | Jan Kiszka | { |
127 | 050a4606 | Jan Kiszka | KVMPITState *s = DO_UPCAST(KVMPITState, pit, pit); |
128 | 5d17c0d2 | Jan Kiszka | struct kvm_pit_state2 kpit;
|
129 | 5d17c0d2 | Jan Kiszka | struct kvm_pit_channel_state *kchan;
|
130 | 5d17c0d2 | Jan Kiszka | struct PITChannelState *sc;
|
131 | 5d17c0d2 | Jan Kiszka | int i, ret;
|
132 | 5d17c0d2 | Jan Kiszka | |
133 | 050a4606 | Jan Kiszka | /* The offset keeps changing as long as the VM is stopped. */
|
134 | 050a4606 | Jan Kiszka | if (s->vm_stopped) {
|
135 | 050a4606 | Jan Kiszka | kvm_pit_update_clock_offset(s); |
136 | 050a4606 | Jan Kiszka | } |
137 | 050a4606 | Jan Kiszka | |
138 | 050a4606 | Jan Kiszka | kpit.flags = pit->channels[0].irq_disabled ? KVM_PIT_FLAGS_HPET_LEGACY : 0; |
139 | 5d17c0d2 | Jan Kiszka | for (i = 0; i < 3; i++) { |
140 | 5d17c0d2 | Jan Kiszka | kchan = &kpit.channels[i]; |
141 | 050a4606 | Jan Kiszka | sc = &pit->channels[i]; |
142 | 5d17c0d2 | Jan Kiszka | kchan->count = sc->count; |
143 | 5d17c0d2 | Jan Kiszka | kchan->latched_count = sc->latched_count; |
144 | 5d17c0d2 | Jan Kiszka | kchan->count_latched = sc->count_latched; |
145 | 5d17c0d2 | Jan Kiszka | kchan->status_latched = sc->status_latched; |
146 | 5d17c0d2 | Jan Kiszka | kchan->status = sc->status; |
147 | 5d17c0d2 | Jan Kiszka | kchan->read_state = sc->read_state; |
148 | 5d17c0d2 | Jan Kiszka | kchan->write_state = sc->write_state; |
149 | 5d17c0d2 | Jan Kiszka | kchan->write_latch = sc->write_latch; |
150 | 5d17c0d2 | Jan Kiszka | kchan->rw_mode = sc->rw_mode; |
151 | 5d17c0d2 | Jan Kiszka | kchan->mode = sc->mode; |
152 | 5d17c0d2 | Jan Kiszka | kchan->bcd = sc->bcd; |
153 | 5d17c0d2 | Jan Kiszka | kchan->gate = sc->gate; |
154 | 050a4606 | Jan Kiszka | kchan->count_load_time = sc->count_load_time - s->kernel_clock_offset; |
155 | 5d17c0d2 | Jan Kiszka | } |
156 | 5d17c0d2 | Jan Kiszka | |
157 | 5d17c0d2 | Jan Kiszka | ret = kvm_vm_ioctl(kvm_state, |
158 | 5d17c0d2 | Jan Kiszka | kvm_has_pit_state2() ? KVM_SET_PIT2 : KVM_SET_PIT, |
159 | 5d17c0d2 | Jan Kiszka | &kpit); |
160 | 5d17c0d2 | Jan Kiszka | if (ret < 0) { |
161 | 5d17c0d2 | Jan Kiszka | fprintf(stderr, "%s failed: %s\n",
|
162 | 5d17c0d2 | Jan Kiszka | kvm_has_pit_state2() ? "KVM_SET_PIT2" : "KVM_SET_PIT", |
163 | 5d17c0d2 | Jan Kiszka | strerror(ret)); |
164 | 5d17c0d2 | Jan Kiszka | abort(); |
165 | 5d17c0d2 | Jan Kiszka | } |
166 | 5d17c0d2 | Jan Kiszka | } |
167 | 5d17c0d2 | Jan Kiszka | |
168 | 5d17c0d2 | Jan Kiszka | static void kvm_pit_set_gate(PITCommonState *s, PITChannelState *sc, int val) |
169 | 5d17c0d2 | Jan Kiszka | { |
170 | 5d17c0d2 | Jan Kiszka | kvm_pit_get(s); |
171 | 5d17c0d2 | Jan Kiszka | |
172 | 5d17c0d2 | Jan Kiszka | switch (sc->mode) {
|
173 | 5d17c0d2 | Jan Kiszka | default:
|
174 | 5d17c0d2 | Jan Kiszka | case 0: |
175 | 5d17c0d2 | Jan Kiszka | case 4: |
176 | 5d17c0d2 | Jan Kiszka | /* XXX: just disable/enable counting */
|
177 | 5d17c0d2 | Jan Kiszka | break;
|
178 | 5d17c0d2 | Jan Kiszka | case 1: |
179 | 5d17c0d2 | Jan Kiszka | case 2: |
180 | 5d17c0d2 | Jan Kiszka | case 3: |
181 | 5d17c0d2 | Jan Kiszka | case 5: |
182 | 5d17c0d2 | Jan Kiszka | if (sc->gate < val) {
|
183 | 5d17c0d2 | Jan Kiszka | /* restart counting on rising edge */
|
184 | 5d17c0d2 | Jan Kiszka | sc->count_load_time = qemu_get_clock_ns(vm_clock); |
185 | 5d17c0d2 | Jan Kiszka | } |
186 | 5d17c0d2 | Jan Kiszka | break;
|
187 | 5d17c0d2 | Jan Kiszka | } |
188 | 5d17c0d2 | Jan Kiszka | sc->gate = val; |
189 | 5d17c0d2 | Jan Kiszka | |
190 | 5d17c0d2 | Jan Kiszka | kvm_pit_put(s); |
191 | 5d17c0d2 | Jan Kiszka | } |
192 | 5d17c0d2 | Jan Kiszka | |
193 | 5d17c0d2 | Jan Kiszka | static void kvm_pit_get_channel_info(PITCommonState *s, PITChannelState *sc, |
194 | 5d17c0d2 | Jan Kiszka | PITChannelInfo *info) |
195 | 5d17c0d2 | Jan Kiszka | { |
196 | 5d17c0d2 | Jan Kiszka | kvm_pit_get(s); |
197 | 5d17c0d2 | Jan Kiszka | |
198 | 5d17c0d2 | Jan Kiszka | pit_get_channel_info_common(s, sc, info); |
199 | 5d17c0d2 | Jan Kiszka | } |
200 | 5d17c0d2 | Jan Kiszka | |
201 | 5d17c0d2 | Jan Kiszka | static void kvm_pit_reset(DeviceState *dev) |
202 | 5d17c0d2 | Jan Kiszka | { |
203 | 5d17c0d2 | Jan Kiszka | PITCommonState *s = DO_UPCAST(PITCommonState, dev.qdev, dev); |
204 | 5d17c0d2 | Jan Kiszka | |
205 | 5d17c0d2 | Jan Kiszka | pit_reset_common(s); |
206 | 5d17c0d2 | Jan Kiszka | |
207 | 5d17c0d2 | Jan Kiszka | kvm_pit_put(s); |
208 | 5d17c0d2 | Jan Kiszka | } |
209 | 5d17c0d2 | Jan Kiszka | |
210 | 5d17c0d2 | Jan Kiszka | static void kvm_pit_irq_control(void *opaque, int n, int enable) |
211 | 5d17c0d2 | Jan Kiszka | { |
212 | 5d17c0d2 | Jan Kiszka | PITCommonState *pit = opaque; |
213 | 5d17c0d2 | Jan Kiszka | PITChannelState *s = &pit->channels[0];
|
214 | 5d17c0d2 | Jan Kiszka | |
215 | 5d17c0d2 | Jan Kiszka | kvm_pit_get(pit); |
216 | 5d17c0d2 | Jan Kiszka | |
217 | 5d17c0d2 | Jan Kiszka | s->irq_disabled = !enable; |
218 | 5d17c0d2 | Jan Kiszka | |
219 | 5d17c0d2 | Jan Kiszka | kvm_pit_put(pit); |
220 | 5d17c0d2 | Jan Kiszka | } |
221 | 5d17c0d2 | Jan Kiszka | |
222 | 0cdd3d14 | Jan Kiszka | static void kvm_pit_vm_state_change(void *opaque, int running, |
223 | 0cdd3d14 | Jan Kiszka | RunState state) |
224 | 0cdd3d14 | Jan Kiszka | { |
225 | 0cdd3d14 | Jan Kiszka | KVMPITState *s = opaque; |
226 | 0cdd3d14 | Jan Kiszka | |
227 | 0cdd3d14 | Jan Kiszka | if (running) {
|
228 | 205df4d1 | Jan Kiszka | kvm_pit_update_clock_offset(s); |
229 | 205df4d1 | Jan Kiszka | s->vm_stopped = false;
|
230 | 0cdd3d14 | Jan Kiszka | } else {
|
231 | 205df4d1 | Jan Kiszka | kvm_pit_update_clock_offset(s); |
232 | 0cdd3d14 | Jan Kiszka | kvm_pit_get(&s->pit); |
233 | 205df4d1 | Jan Kiszka | s->vm_stopped = true;
|
234 | 0cdd3d14 | Jan Kiszka | } |
235 | 0cdd3d14 | Jan Kiszka | } |
236 | 0cdd3d14 | Jan Kiszka | |
237 | 5d17c0d2 | Jan Kiszka | static int kvm_pit_initfn(PITCommonState *pit) |
238 | 5d17c0d2 | Jan Kiszka | { |
239 | 5d17c0d2 | Jan Kiszka | KVMPITState *s = DO_UPCAST(KVMPITState, pit, pit); |
240 | 5d17c0d2 | Jan Kiszka | struct kvm_pit_config config = {
|
241 | 5d17c0d2 | Jan Kiszka | .flags = 0,
|
242 | 5d17c0d2 | Jan Kiszka | }; |
243 | 5d17c0d2 | Jan Kiszka | int ret;
|
244 | 5d17c0d2 | Jan Kiszka | |
245 | 5d17c0d2 | Jan Kiszka | if (kvm_check_extension(kvm_state, KVM_CAP_PIT2)) {
|
246 | 5d17c0d2 | Jan Kiszka | ret = kvm_vm_ioctl(kvm_state, KVM_CREATE_PIT2, &config); |
247 | 5d17c0d2 | Jan Kiszka | } else {
|
248 | 5d17c0d2 | Jan Kiszka | ret = kvm_vm_ioctl(kvm_state, KVM_CREATE_PIT); |
249 | 5d17c0d2 | Jan Kiszka | } |
250 | 5d17c0d2 | Jan Kiszka | if (ret < 0) { |
251 | 5d17c0d2 | Jan Kiszka | fprintf(stderr, "Create kernel PIC irqchip failed: %s\n",
|
252 | 5d17c0d2 | Jan Kiszka | strerror(ret)); |
253 | 5d17c0d2 | Jan Kiszka | return ret;
|
254 | 5d17c0d2 | Jan Kiszka | } |
255 | 5d17c0d2 | Jan Kiszka | switch (s->lost_tick_policy) {
|
256 | 5d17c0d2 | Jan Kiszka | case LOST_TICK_DELAY:
|
257 | 5d17c0d2 | Jan Kiszka | break; /* enabled by default */ |
258 | 5d17c0d2 | Jan Kiszka | case LOST_TICK_DISCARD:
|
259 | 5d17c0d2 | Jan Kiszka | if (kvm_check_extension(kvm_state, KVM_CAP_REINJECT_CONTROL)) {
|
260 | 5d17c0d2 | Jan Kiszka | struct kvm_reinject_control control = { .pit_reinject = 0 }; |
261 | 5d17c0d2 | Jan Kiszka | |
262 | 5d17c0d2 | Jan Kiszka | ret = kvm_vm_ioctl(kvm_state, KVM_REINJECT_CONTROL, &control); |
263 | 5d17c0d2 | Jan Kiszka | if (ret < 0) { |
264 | 5d17c0d2 | Jan Kiszka | fprintf(stderr, |
265 | 5d17c0d2 | Jan Kiszka | "Can't disable in-kernel PIT reinjection: %s\n",
|
266 | 5d17c0d2 | Jan Kiszka | strerror(ret)); |
267 | 5d17c0d2 | Jan Kiszka | return ret;
|
268 | 5d17c0d2 | Jan Kiszka | } |
269 | 5d17c0d2 | Jan Kiszka | } |
270 | 5d17c0d2 | Jan Kiszka | break;
|
271 | 5d17c0d2 | Jan Kiszka | default:
|
272 | 5d17c0d2 | Jan Kiszka | return -EINVAL;
|
273 | 5d17c0d2 | Jan Kiszka | } |
274 | 5d17c0d2 | Jan Kiszka | |
275 | 5d17c0d2 | Jan Kiszka | memory_region_init_reservation(&pit->ioports, "kvm-pit", 4); |
276 | 5d17c0d2 | Jan Kiszka | |
277 | 5d17c0d2 | Jan Kiszka | qdev_init_gpio_in(&pit->dev.qdev, kvm_pit_irq_control, 1);
|
278 | 5d17c0d2 | Jan Kiszka | |
279 | 0cdd3d14 | Jan Kiszka | qemu_add_vm_change_state_handler(kvm_pit_vm_state_change, s); |
280 | 0cdd3d14 | Jan Kiszka | |
281 | 5d17c0d2 | Jan Kiszka | return 0; |
282 | 5d17c0d2 | Jan Kiszka | } |
283 | 5d17c0d2 | Jan Kiszka | |
284 | 5d17c0d2 | Jan Kiszka | static Property kvm_pit_properties[] = {
|
285 | 5d17c0d2 | Jan Kiszka | DEFINE_PROP_HEX32("iobase", KVMPITState, pit.iobase, -1), |
286 | 5d17c0d2 | Jan Kiszka | DEFINE_PROP_LOSTTICKPOLICY("lost_tick_policy", KVMPITState,
|
287 | 5d17c0d2 | Jan Kiszka | lost_tick_policy, LOST_TICK_DELAY), |
288 | 5d17c0d2 | Jan Kiszka | DEFINE_PROP_END_OF_LIST(), |
289 | 5d17c0d2 | Jan Kiszka | }; |
290 | 5d17c0d2 | Jan Kiszka | |
291 | 5d17c0d2 | Jan Kiszka | static void kvm_pit_class_init(ObjectClass *klass, void *data) |
292 | 5d17c0d2 | Jan Kiszka | { |
293 | 5d17c0d2 | Jan Kiszka | PITCommonClass *k = PIT_COMMON_CLASS(klass); |
294 | 5d17c0d2 | Jan Kiszka | DeviceClass *dc = DEVICE_CLASS(klass); |
295 | 5d17c0d2 | Jan Kiszka | |
296 | 5d17c0d2 | Jan Kiszka | k->init = kvm_pit_initfn; |
297 | 5d17c0d2 | Jan Kiszka | k->set_channel_gate = kvm_pit_set_gate; |
298 | 5d17c0d2 | Jan Kiszka | k->get_channel_info = kvm_pit_get_channel_info; |
299 | 5d17c0d2 | Jan Kiszka | k->pre_save = kvm_pit_get; |
300 | 5d17c0d2 | Jan Kiszka | k->post_load = kvm_pit_put; |
301 | 5d17c0d2 | Jan Kiszka | dc->reset = kvm_pit_reset; |
302 | 5d17c0d2 | Jan Kiszka | dc->props = kvm_pit_properties; |
303 | 5d17c0d2 | Jan Kiszka | } |
304 | 5d17c0d2 | Jan Kiszka | |
305 | 8c43a6f0 | Andreas Färber | static const TypeInfo kvm_pit_info = { |
306 | 5d17c0d2 | Jan Kiszka | .name = "kvm-pit",
|
307 | 5d17c0d2 | Jan Kiszka | .parent = TYPE_PIT_COMMON, |
308 | 5d17c0d2 | Jan Kiszka | .instance_size = sizeof(KVMPITState),
|
309 | 5d17c0d2 | Jan Kiszka | .class_init = kvm_pit_class_init, |
310 | 5d17c0d2 | Jan Kiszka | }; |
311 | 5d17c0d2 | Jan Kiszka | |
312 | 5d17c0d2 | Jan Kiszka | static void kvm_pit_register(void) |
313 | 5d17c0d2 | Jan Kiszka | { |
314 | 5d17c0d2 | Jan Kiszka | type_register_static(&kvm_pit_info); |
315 | 5d17c0d2 | Jan Kiszka | } |
316 | 5d17c0d2 | Jan Kiszka | |
317 | 5d17c0d2 | Jan Kiszka | type_init(kvm_pit_register) |