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: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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$"); 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> 38 #include <sys/mutex.h> 39 #include <sys/systm.h> 40 41 #include <machine/vmm.h> 42 43 #include "vmm_ktr.h" 44 #include "vatpic.h" 45 #include "vioapic.h" 46 #include "vatpit.h" 47 48 static MALLOC_DEFINE(M_VATPIT, "atpit", "bhyve virtual atpit (8254)"); 49 50 #define VATPIT_LOCK(vatpit) mtx_lock_spin(&((vatpit)->mtx)) 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 TIMER_STS_OUT 0x80 60 #define TIMER_STS_NULLCNT 0x40 61 62 #define TIMER_RB_LCTR 0x20 63 #define TIMER_RB_LSTATUS 0x10 64 #define TIMER_RB_CTR_2 0x08 65 #define TIMER_RB_CTR_1 0x04 66 #define TIMER_RB_CTR_0 0x02 67 68 #define TMR2_OUT_STS 0x20 69 70 #define PIT_8254_FREQ 1193182 71 #define TIMER_DIV(freq, hz) (((freq) + (hz) / 2) / (hz)) 72 73 struct vatpit_callout_arg { 74 struct vatpit *vatpit; 75 int channel_num; 76 }; 77 78 79 struct channel { 80 int mode; 81 uint16_t initial; /* initial counter value */ 82 sbintime_t now_sbt; /* uptime when counter was loaded */ 83 uint8_t cr[2]; 84 uint8_t ol[2]; 85 bool slatched; /* status latched */ 86 uint8_t status; 87 int crbyte; 88 int olbyte; 89 int frbyte; 90 struct callout callout; 91 sbintime_t callout_sbt; /* target time */ 92 struct vatpit_callout_arg callout_arg; 93 }; 94 95 struct vatpit { 96 struct vm *vm; 97 struct mtx mtx; 98 99 sbintime_t freq_sbt; 100 101 struct channel channel[3]; 102 }; 103 104 static void pit_timer_start_cntr0(struct vatpit *vatpit); 105 106 static int 107 vatpit_get_out(struct vatpit *vatpit, int channel) 108 { 109 struct channel *c; 110 sbintime_t delta_ticks; 111 int out; 112 113 c = &vatpit->channel[channel]; 114 115 switch (c->mode) { 116 case TIMER_INTTC: 117 delta_ticks = (sbinuptime() - c->now_sbt) / vatpit->freq_sbt; 118 out = ((c->initial - delta_ticks) <= 0); 119 break; 120 default: 121 out = 0; 122 break; 123 } 124 125 return (out); 126 } 127 128 static void 129 vatpit_callout_handler(void *a) 130 { 131 struct vatpit_callout_arg *arg = a; 132 struct vatpit *vatpit; 133 struct callout *callout; 134 struct channel *c; 135 136 vatpit = arg->vatpit; 137 c = &vatpit->channel[arg->channel_num]; 138 callout = &c->callout; 139 140 VM_CTR1(vatpit->vm, "atpit t%d fired", arg->channel_num); 141 142 VATPIT_LOCK(vatpit); 143 144 if (callout_pending(callout)) /* callout was reset */ 145 goto done; 146 147 if (!callout_active(callout)) /* callout was stopped */ 148 goto done; 149 150 callout_deactivate(callout); 151 152 if (c->mode == TIMER_RATEGEN) { 153 pit_timer_start_cntr0(vatpit); 154 } 155 156 vatpic_pulse_irq(vatpit->vm, 0); 157 vioapic_pulse_irq(vatpit->vm, 2); 158 159 done: 160 VATPIT_UNLOCK(vatpit); 161 return; 162 } 163 164 static void 165 pit_timer_start_cntr0(struct vatpit *vatpit) 166 { 167 struct channel *c; 168 sbintime_t now, delta, precision; 169 170 c = &vatpit->channel[0]; 171 if (c->initial != 0) { 172 delta = c->initial * vatpit->freq_sbt; 173 precision = delta >> tc_precexp; 174 c->callout_sbt = c->callout_sbt + delta; 175 176 /* 177 * Reset 'callout_sbt' if the time that the callout 178 * was supposed to fire is more than 'c->initial' 179 * ticks in the past. 180 */ 181 now = sbinuptime(); 182 if (c->callout_sbt < now) 183 c->callout_sbt = now + delta; 184 185 callout_reset_sbt(&c->callout, c->callout_sbt, 186 precision, vatpit_callout_handler, &c->callout_arg, 187 C_ABSOLUTE); 188 } 189 } 190 191 static uint16_t 192 pit_update_counter(struct vatpit *vatpit, struct channel *c, bool latch) 193 { 194 uint16_t lval; 195 sbintime_t delta_ticks; 196 197 /* cannot latch a new value until the old one has been consumed */ 198 if (latch && c->olbyte != 0) 199 return (0); 200 201 if (c->initial == 0) { 202 /* 203 * This is possibly an o/s bug - reading the value of 204 * the timer without having set up the initial value. 205 * 206 * The original user-space version of this code set 207 * the timer to 100hz in this condition; do the same 208 * here. 209 */ 210 c->initial = TIMER_DIV(PIT_8254_FREQ, 100); 211 c->now_sbt = sbinuptime(); 212 c->status &= ~TIMER_STS_NULLCNT; 213 } 214 215 delta_ticks = (sbinuptime() - c->now_sbt) / vatpit->freq_sbt; 216 217 lval = c->initial - delta_ticks % c->initial; 218 219 if (latch) { 220 c->olbyte = 2; 221 c->ol[1] = lval; /* LSB */ 222 c->ol[0] = lval >> 8; /* MSB */ 223 } 224 225 return (lval); 226 } 227 228 static int 229 pit_readback1(struct vatpit *vatpit, int channel, uint8_t cmd) 230 { 231 struct channel *c; 232 233 c = &vatpit->channel[channel]; 234 235 /* 236 * Latch the count/status of the timer if not already latched. 237 * N.B. that the count/status latch-select bits are active-low. 238 */ 239 if (!(cmd & TIMER_RB_LCTR) && !c->olbyte) { 240 (void) pit_update_counter(vatpit, c, true); 241 } 242 243 if (!(cmd & TIMER_RB_LSTATUS) && !c->slatched) { 244 c->slatched = true; 245 /* 246 * For mode 0, see if the elapsed time is greater 247 * than the initial value - this results in the 248 * output pin being set to 1 in the status byte. 249 */ 250 if (c->mode == TIMER_INTTC && vatpit_get_out(vatpit, channel)) 251 c->status |= TIMER_STS_OUT; 252 else 253 c->status &= ~TIMER_STS_OUT; 254 } 255 256 return (0); 257 } 258 259 static int 260 pit_readback(struct vatpit *vatpit, uint8_t cmd) 261 { 262 int error; 263 264 /* 265 * The readback command can apply to all timers. 266 */ 267 error = 0; 268 if (cmd & TIMER_RB_CTR_0) 269 error = pit_readback1(vatpit, 0, cmd); 270 if (!error && cmd & TIMER_RB_CTR_1) 271 error = pit_readback1(vatpit, 1, cmd); 272 if (!error && cmd & TIMER_RB_CTR_2) 273 error = pit_readback1(vatpit, 2, cmd); 274 275 return (error); 276 } 277 278 279 static int 280 vatpit_update_mode(struct vatpit *vatpit, uint8_t val) 281 { 282 struct channel *c; 283 int sel, rw, mode; 284 285 sel = val & TIMER_SEL_MASK; 286 rw = val & TIMER_RW_MASK; 287 mode = val & TIMER_MODE_MASK; 288 289 if (sel == TIMER_SEL_READBACK) 290 return (pit_readback(vatpit, val)); 291 292 if (rw != TIMER_LATCH && rw != TIMER_16BIT) 293 return (-1); 294 295 if (rw != TIMER_LATCH) { 296 /* 297 * Counter mode is not affected when issuing a 298 * latch command. 299 */ 300 if (mode != TIMER_INTTC && 301 mode != TIMER_RATEGEN && 302 mode != TIMER_SQWAVE && 303 mode != TIMER_SWSTROBE) 304 return (-1); 305 } 306 307 c = &vatpit->channel[sel >> 6]; 308 if (rw == TIMER_LATCH) 309 pit_update_counter(vatpit, c, true); 310 else { 311 c->mode = mode; 312 c->olbyte = 0; /* reset latch after reprogramming */ 313 c->status |= TIMER_STS_NULLCNT; 314 } 315 316 return (0); 317 } 318 319 int 320 vatpit_handler(void *vm, int vcpuid, bool in, int port, int bytes, 321 uint32_t *eax) 322 { 323 struct vatpit *vatpit; 324 struct channel *c; 325 uint8_t val; 326 int error; 327 328 vatpit = vm_atpit(vm); 329 330 if (bytes != 1) 331 return (-1); 332 333 val = *eax; 334 335 if (port == TIMER_MODE) { 336 if (in) { 337 VM_CTR0(vatpit->vm, "vatpit attempt to read mode"); 338 return (-1); 339 } 340 341 VATPIT_LOCK(vatpit); 342 error = vatpit_update_mode(vatpit, val); 343 VATPIT_UNLOCK(vatpit); 344 345 return (error); 346 } 347 348 /* counter ports */ 349 KASSERT(port >= TIMER_CNTR0 && port <= TIMER_CNTR2, 350 ("invalid port 0x%x", port)); 351 c = &vatpit->channel[port - TIMER_CNTR0]; 352 353 VATPIT_LOCK(vatpit); 354 if (in && c->slatched) { 355 /* 356 * Return the status byte if latched 357 */ 358 *eax = c->status; 359 c->slatched = false; 360 c->status = 0; 361 } else if (in) { 362 /* 363 * The spec says that once the output latch is completely 364 * read it should revert to "following" the counter. Use 365 * the free running counter for this case (i.e. Linux 366 * TSC calibration). Assuming the access mode is 16-bit, 367 * toggle the MSB/LSB bit on each read. 368 */ 369 if (c->olbyte == 0) { 370 uint16_t tmp; 371 372 tmp = pit_update_counter(vatpit, c, false); 373 if (c->frbyte) 374 tmp >>= 8; 375 tmp &= 0xff; 376 *eax = tmp; 377 c->frbyte ^= 1; 378 } else 379 *eax = c->ol[--c->olbyte]; 380 } else { 381 c->cr[c->crbyte++] = *eax; 382 if (c->crbyte == 2) { 383 c->status &= ~TIMER_STS_NULLCNT; 384 c->frbyte = 0; 385 c->crbyte = 0; 386 c->initial = c->cr[0] | (uint16_t)c->cr[1] << 8; 387 c->now_sbt = sbinuptime(); 388 /* Start an interval timer for channel 0 */ 389 if (port == TIMER_CNTR0) { 390 c->callout_sbt = c->now_sbt; 391 pit_timer_start_cntr0(vatpit); 392 } 393 if (c->initial == 0) 394 c->initial = 0xffff; 395 } 396 } 397 VATPIT_UNLOCK(vatpit); 398 399 return (0); 400 } 401 402 int 403 vatpit_nmisc_handler(void *vm, int vcpuid, bool in, int port, int bytes, 404 uint32_t *eax) 405 { 406 struct vatpit *vatpit; 407 408 vatpit = vm_atpit(vm); 409 410 if (in) { 411 VATPIT_LOCK(vatpit); 412 if (vatpit_get_out(vatpit, 2)) 413 *eax = TMR2_OUT_STS; 414 else 415 *eax = 0; 416 417 VATPIT_UNLOCK(vatpit); 418 } 419 420 return (0); 421 } 422 423 struct vatpit * 424 vatpit_init(struct vm *vm) 425 { 426 struct vatpit *vatpit; 427 struct bintime bt; 428 struct vatpit_callout_arg *arg; 429 int i; 430 431 vatpit = malloc(sizeof(struct vatpit), M_VATPIT, M_WAITOK | M_ZERO); 432 vatpit->vm = vm; 433 434 mtx_init(&vatpit->mtx, "vatpit lock", NULL, MTX_SPIN); 435 436 FREQ2BT(PIT_8254_FREQ, &bt); 437 vatpit->freq_sbt = bttosbt(bt); 438 439 for (i = 0; i < 3; i++) { 440 callout_init(&vatpit->channel[i].callout, true); 441 arg = &vatpit->channel[i].callout_arg; 442 arg->vatpit = vatpit; 443 arg->channel_num = i; 444 } 445 446 return (vatpit); 447 } 448 449 void 450 vatpit_cleanup(struct vatpit *vatpit) 451 { 452 int i; 453 454 for (i = 0; i < 3; i++) 455 callout_drain(&vatpit->channel[i].callout); 456 457 free(vatpit, M_VATPIT); 458 } 459