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 --- |