Deleted Added
full compact
vatpit.c (264179) vatpit.c (264631)
1/*-
2 * Copyright (c) 2014 Tycho Nightingale <tycho.nightingale@pluribusnetworks.com>
3 * Copyright (c) 2011 NetApp, Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 12 unchanged lines hidden (view full) ---

21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2014 Tycho Nightingale <tycho.nightingale@pluribusnetworks.com>
3 * Copyright (c) 2011 NetApp, Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 12 unchanged lines hidden (view full) ---

21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD: head/sys/amd64/vmm/io/vatpit.c 264179 2014-04-05 22:43:23Z imp $");
29__FBSDID("$FreeBSD: head/sys/amd64/vmm/io/vatpit.c 264631 2014-04-18 00:02:06Z tychon $");
30
31#include <sys/param.h>
32#include <sys/types.h>
33#include <sys/queue.h>
34#include <sys/cpuset.h>
35#include <sys/kernel.h>
36#include <sys/lock.h>
37#include <sys/malloc.h>

--- 13 unchanged lines hidden (view full) ---

51#define VATPIT_UNLOCK(vatpit) mtx_unlock_spin(&((vatpit)->mtx))
52#define VATPIT_LOCKED(vatpit) mtx_owned(&((vatpit)->mtx))
53
54#define TIMER_SEL_MASK 0xc0
55#define TIMER_RW_MASK 0x30
56#define TIMER_MODE_MASK 0x0f
57#define TIMER_SEL_READBACK 0xc0
58
30
31#include <sys/param.h>
32#include <sys/types.h>
33#include <sys/queue.h>
34#include <sys/cpuset.h>
35#include <sys/kernel.h>
36#include <sys/lock.h>
37#include <sys/malloc.h>

--- 13 unchanged lines hidden (view full) ---

51#define VATPIT_UNLOCK(vatpit) mtx_unlock_spin(&((vatpit)->mtx))
52#define VATPIT_LOCKED(vatpit) mtx_owned(&((vatpit)->mtx))
53
54#define TIMER_SEL_MASK 0xc0
55#define TIMER_RW_MASK 0x30
56#define TIMER_MODE_MASK 0x0f
57#define TIMER_SEL_READBACK 0xc0
58
59#define TMR2_OUT_STS 0x20
60
59#define PIT_8254_FREQ 1193182
60#define TIMER_DIV(freq, hz) (((freq) + (hz) / 2) / (hz))
61
62struct vatpit_callout_arg {
63 struct vatpit *vatpit;
64 int channel_num;
65};
66

--- 16 unchanged lines hidden (view full) ---

83 struct vm *vm;
84 struct mtx mtx;
85
86 sbintime_t freq_sbt;
87
88 struct channel channel[3];
89};
90
61#define PIT_8254_FREQ 1193182
62#define TIMER_DIV(freq, hz) (((freq) + (hz) / 2) / (hz))
63
64struct vatpit_callout_arg {
65 struct vatpit *vatpit;
66 int channel_num;
67};
68

--- 16 unchanged lines hidden (view full) ---

85 struct vm *vm;
86 struct mtx mtx;
87
88 sbintime_t freq_sbt;
89
90 struct channel channel[3];
91};
92
91#define VATPIT_CTR0(vatpit, fmt) \
92 VM_CTR0((vatpit)->vm, fmt)
93static void pit_timer_start_cntr0(struct vatpit *vatpit);
93
94
94#define VATPIT_CTR1(vatpit, fmt, a1) \
95 VM_CTR1((vatpit)->vm, fmt, a1)
95static int
96vatpit_get_out(struct vatpit *vatpit, int channel)
97{
98 struct channel *c;
99 sbintime_t delta_ticks;
100 int out;
96
101
97#define VATPIT_CTR2(vatpit, fmt, a1, a2) \
98 VM_CTR2((vatpit)->vm, fmt, a1, a2)
102 c = &vatpit->channel[channel];
99
103
100#define VATPIT_CTR3(vatpit, fmt, a1, a2, a3) \
101 VM_CTR3((vatpit)->vm, fmt, a1, a2, a3)
104 switch (c->mode) {
105 case TIMER_INTTC:
106 delta_ticks = (sbinuptime() - c->now_sbt) / vatpit->freq_sbt;
107 out = ((c->initial - delta_ticks) <= 0);
108 break;
109 default:
110 out = 0;
111 break;
112 }
102
113
103#define VATPIT_CTR4(vatpit, fmt, a1, a2, a3, a4) \
104 VM_CTR4((vatpit)->vm, fmt, a1, a2, a3, a4)
114 return (out);
115}
105
116
106static void pit_timer_start_cntr0(struct vatpit *vatpit);
107
108static void
109vatpit_callout_handler(void *a)
110{
111 struct vatpit_callout_arg *arg = a;
112 struct vatpit *vatpit;
113 struct callout *callout;
114 struct channel *c;
115
116 vatpit = arg->vatpit;
117 c = &vatpit->channel[arg->channel_num];
118 callout = &c->callout;
119
117static void
118vatpit_callout_handler(void *a)
119{
120 struct vatpit_callout_arg *arg = a;
121 struct vatpit *vatpit;
122 struct callout *callout;
123 struct channel *c;
124
125 vatpit = arg->vatpit;
126 c = &vatpit->channel[arg->channel_num];
127 callout = &c->callout;
128
120 VATPIT_CTR1(vatpit, "atpit t%d fired", arg->channel_num);
129 VM_CTR1(vatpit->vm, "atpit t%d fired", arg->channel_num);
121
122 VATPIT_LOCK(vatpit);
123
124 if (callout_pending(callout)) /* callout was reset */
125 goto done;
126
127 if (!callout_active(callout)) /* callout was stopped */
128 goto done;

--- 11 unchanged lines hidden (view full) ---

140 VATPIT_UNLOCK(vatpit);
141 return;
142}
143
144static void
145pit_timer_start_cntr0(struct vatpit *vatpit)
146{
147 struct channel *c;
130
131 VATPIT_LOCK(vatpit);
132
133 if (callout_pending(callout)) /* callout was reset */
134 goto done;
135
136 if (!callout_active(callout)) /* callout was stopped */
137 goto done;

--- 11 unchanged lines hidden (view full) ---

149 VATPIT_UNLOCK(vatpit);
150 return;
151}
152
153static void
154pit_timer_start_cntr0(struct vatpit *vatpit)
155{
156 struct channel *c;
148 sbintime_t delta, precision;
157 sbintime_t now, delta, precision;
149
150 c = &vatpit->channel[0];
151 if (c->initial != 0) {
152 delta = c->initial * vatpit->freq_sbt;
153 precision = delta >> tc_precexp;
154 c->callout_sbt = c->callout_sbt + delta;
155
158
159 c = &vatpit->channel[0];
160 if (c->initial != 0) {
161 delta = c->initial * vatpit->freq_sbt;
162 precision = delta >> tc_precexp;
163 c->callout_sbt = c->callout_sbt + delta;
164
165 /*
166 * Reset 'callout_sbt' if the time that the callout
167 * was supposed to fire is more than 'c->initial'
168 * ticks in the past.
169 */
170 now = sbinuptime();
171 if (c->callout_sbt < now)
172 c->callout_sbt = now + delta;
173
156 callout_reset_sbt(&c->callout, c->callout_sbt,
157 precision, vatpit_callout_handler, &c->callout_arg,
158 C_ABSOLUTE);
159 }
160}
161
162static uint16_t
163pit_update_counter(struct vatpit *vatpit, struct channel *c, bool latch)

--- 83 unchanged lines hidden (view full) ---

247
248 if (vmexit->u.inout.bytes != 1)
249 return (-1);
250
251 val = vmexit->u.inout.eax;
252 port = vmexit->u.inout.port;
253
254 if (port == TIMER_MODE) {
174 callout_reset_sbt(&c->callout, c->callout_sbt,
175 precision, vatpit_callout_handler, &c->callout_arg,
176 C_ABSOLUTE);
177 }
178}
179
180static uint16_t
181pit_update_counter(struct vatpit *vatpit, struct channel *c, bool latch)

--- 83 unchanged lines hidden (view full) ---

265
266 if (vmexit->u.inout.bytes != 1)
267 return (-1);
268
269 val = vmexit->u.inout.eax;
270 port = vmexit->u.inout.port;
271
272 if (port == TIMER_MODE) {
255 if (vmexit->u.inout.in != 0) {
256 VATPIT_CTR0(vatpit, "vatpit attempt to read mode");
273 if (vmexit->u.inout.in) {
274 VM_CTR0(vatpit->vm, "vatpit attempt to read mode");
257 return (-1);
258 }
259
260 VATPIT_LOCK(vatpit);
261 error = vatpit_update_mode(vatpit, val);
262 VATPIT_UNLOCK(vatpit);
263
264 return (error);

--- 40 unchanged lines hidden (view full) ---

305 c->initial = 0xffff;
306 }
307 }
308 VATPIT_UNLOCK(vatpit);
309
310 return (0);
311}
312
275 return (-1);
276 }
277
278 VATPIT_LOCK(vatpit);
279 error = vatpit_update_mode(vatpit, val);
280 VATPIT_UNLOCK(vatpit);
281
282 return (error);

--- 40 unchanged lines hidden (view full) ---

323 c->initial = 0xffff;
324 }
325 }
326 VATPIT_UNLOCK(vatpit);
327
328 return (0);
329}
330
331int
332vatpit_nmisc_handler(void *vm, int vcpuid, struct vm_exit *vmexit)
333{
334 struct vatpit *vatpit;
335
336 vatpit = vm_atpit(vm);
337
338 if (vmexit->u.inout.in) {
339 VATPIT_LOCK(vatpit);
340 if (vatpit_get_out(vatpit, 2))
341 vmexit->u.inout.eax = TMR2_OUT_STS;
342 else
343 vmexit->u.inout.eax = 0;
344
345 VATPIT_UNLOCK(vatpit);
346 }
347
348 return (0);
349}
350
313struct vatpit *
314vatpit_init(struct vm *vm)
315{
316 struct vatpit *vatpit;
317 struct bintime bt;
318 struct vatpit_callout_arg *arg;
319 int i;
320

--- 28 unchanged lines hidden ---
351struct vatpit *
352vatpit_init(struct vm *vm)
353{
354 struct vatpit *vatpit;
355 struct bintime bt;
356 struct vatpit_callout_arg *arg;
357 int i;
358

--- 28 unchanged lines hidden ---