vatpit.c (264631) | vatpit.c (264648) |
---|---|
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 264631 2014-04-18 00:02:06Z tychon $"); | 29__FBSDID("$FreeBSD: head/sys/amd64/vmm/io/vatpit.c 264648 2014-04-18 15:22:56Z 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> --- 210 unchanged lines hidden (view full) --- 248 c->mode = mode; 249 c->olbyte = 0; /* reset latch after reprogramming */ 250 } 251 252 return (0); 253} 254 255int | 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> --- 210 unchanged lines hidden (view full) --- 248 c->mode = mode; 249 c->olbyte = 0; /* reset latch after reprogramming */ 250 } 251 252 return (0); 253} 254 255int |
256vatpit_handler(void *vm, int vcpuid, struct vm_exit *vmexit) | 256vatpit_handler(void *vm, int vcpuid, bool in, int port, int bytes, 257 uint32_t *eax) |
257{ 258 struct vatpit *vatpit; 259 struct channel *c; | 258{ 259 struct vatpit *vatpit; 260 struct channel *c; |
260 int port; | |
261 uint8_t val; 262 int error; 263 264 vatpit = vm_atpit(vm); 265 | 261 uint8_t val; 262 int error; 263 264 vatpit = vm_atpit(vm); 265 |
266 if (vmexit->u.inout.bytes != 1) | 266 if (bytes != 1) |
267 return (-1); 268 | 267 return (-1); 268 |
269 val = vmexit->u.inout.eax; 270 port = vmexit->u.inout.port; | 269 val = *eax; |
271 272 if (port == TIMER_MODE) { | 270 271 if (port == TIMER_MODE) { |
273 if (vmexit->u.inout.in) { | 272 if (in) { |
274 VM_CTR0(vatpit->vm, "vatpit attempt to read mode"); 275 return (-1); 276 } 277 278 VATPIT_LOCK(vatpit); 279 error = vatpit_update_mode(vatpit, val); 280 VATPIT_UNLOCK(vatpit); 281 282 return (error); 283 } 284 285 /* counter ports */ | 273 VM_CTR0(vatpit->vm, "vatpit attempt to read mode"); 274 return (-1); 275 } 276 277 VATPIT_LOCK(vatpit); 278 error = vatpit_update_mode(vatpit, val); 279 VATPIT_UNLOCK(vatpit); 280 281 return (error); 282 } 283 284 /* counter ports */ |
286 KASSERT(port >= TIMER_CNTR0 && vmexit->u.inout.port <= TIMER_CNTR2, | 285 KASSERT(port >= TIMER_CNTR0 && port <= TIMER_CNTR2, |
287 ("invalid port 0x%x", port)); 288 c = &vatpit->channel[port - TIMER_CNTR0]; 289 290 VATPIT_LOCK(vatpit); | 286 ("invalid port 0x%x", port)); 287 c = &vatpit->channel[port - TIMER_CNTR0]; 288 289 VATPIT_LOCK(vatpit); |
291 if (vmexit->u.inout.in) { | 290 if (in) { |
292 /* 293 * The spec says that once the output latch is completely 294 * read it should revert to "following" the counter. Use 295 * the free running counter for this case (i.e. Linux 296 * TSC calibration). Assuming the access mode is 16-bit, 297 * toggle the MSB/LSB bit on each read. 298 */ 299 if (c->olbyte == 0) { 300 uint16_t tmp; 301 302 tmp = pit_update_counter(vatpit, c, false); 303 if (c->frbyte) 304 tmp >>= 8; 305 tmp &= 0xff; | 291 /* 292 * The spec says that once the output latch is completely 293 * read it should revert to "following" the counter. Use 294 * the free running counter for this case (i.e. Linux 295 * TSC calibration). Assuming the access mode is 16-bit, 296 * toggle the MSB/LSB bit on each read. 297 */ 298 if (c->olbyte == 0) { 299 uint16_t tmp; 300 301 tmp = pit_update_counter(vatpit, c, false); 302 if (c->frbyte) 303 tmp >>= 8; 304 tmp &= 0xff; |
306 vmexit->u.inout.eax = tmp; | 305 *eax = tmp; |
307 c->frbyte ^= 1; 308 } else | 306 c->frbyte ^= 1; 307 } else |
309 vmexit->u.inout.eax = c->ol[--c->olbyte]; | 308 *eax = c->ol[--c->olbyte]; |
310 } else { | 309 } else { |
311 c->cr[c->crbyte++] = vmexit->u.inout.eax; | 310 c->cr[c->crbyte++] = *eax; |
312 if (c->crbyte == 2) { 313 c->frbyte = 0; 314 c->crbyte = 0; 315 c->initial = c->cr[0] | (uint16_t)c->cr[1] << 8; 316 c->now_sbt = sbinuptime(); 317 /* Start an interval timer for channel 0 */ 318 if (port == TIMER_CNTR0) { 319 c->callout_sbt = c->now_sbt; --- 4 unchanged lines hidden (view full) --- 324 } 325 } 326 VATPIT_UNLOCK(vatpit); 327 328 return (0); 329} 330 331int | 311 if (c->crbyte == 2) { 312 c->frbyte = 0; 313 c->crbyte = 0; 314 c->initial = c->cr[0] | (uint16_t)c->cr[1] << 8; 315 c->now_sbt = sbinuptime(); 316 /* Start an interval timer for channel 0 */ 317 if (port == TIMER_CNTR0) { 318 c->callout_sbt = c->now_sbt; --- 4 unchanged lines hidden (view full) --- 323 } 324 } 325 VATPIT_UNLOCK(vatpit); 326 327 return (0); 328} 329 330int |
332vatpit_nmisc_handler(void *vm, int vcpuid, struct vm_exit *vmexit) | 331vatpit_nmisc_handler(void *vm, int vcpuid, bool in, int port, int bytes, 332 uint32_t *eax) |
333{ 334 struct vatpit *vatpit; 335 336 vatpit = vm_atpit(vm); 337 | 333{ 334 struct vatpit *vatpit; 335 336 vatpit = vm_atpit(vm); 337 |
338 if (vmexit->u.inout.in) { | 338 if (in) { |
339 VATPIT_LOCK(vatpit); 340 if (vatpit_get_out(vatpit, 2)) | 339 VATPIT_LOCK(vatpit); 340 if (vatpit_get_out(vatpit, 2)) |
341 vmexit->u.inout.eax = TMR2_OUT_STS; | 341 *eax = TMR2_OUT_STS; |
342 else | 342 else |
343 vmexit->u.inout.eax = 0; | 343 *eax = 0; |
344 345 VATPIT_UNLOCK(vatpit); 346 } 347 348 return (0); 349} 350 351struct vatpit * --- 35 unchanged lines hidden --- | 344 345 VATPIT_UNLOCK(vatpit); 346 } 347 348 return (0); 349} 350 351struct vatpit * --- 35 unchanged lines hidden --- |