1 /*- 2 * Copyright (c) 2018 Joyent, Inc. 3 * Copyright (c) 2014 Tycho Nightingale <tycho.nightingale@pluribusnetworks.com> 4 * Copyright (c) 2011 NetApp, Inc. 5 * All rights reserved. 6 * Copyright (c) 2018 Joyent, Inc. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 /* 30 * This file and its contents are supplied under the terms of the 31 * Common Development and Distribution License ("CDDL"), version 1.0. 32 * You may only use this file in accordance with the terms of version 33 * 1.0 of the CDDL. 34 * 35 * A full copy of the text of the CDDL should have accompanied this 36 * source. A copy of the CDDL is also available via the Internet at 37 * http://www.illumos.org/license/CDDL. 38 * 39 * Copyright 2022 Oxide Computer Company 40 */ 41 42 #include <sys/cdefs.h> 43 44 #include <sys/param.h> 45 #include <sys/types.h> 46 #include <sys/queue.h> 47 #include <sys/kernel.h> 48 #include <sys/kmem.h> 49 #include <sys/mutex.h> 50 #include <sys/systm.h> 51 52 #include <machine/vmm.h> 53 54 #include "vatpic.h" 55 #include "vioapic.h" 56 #include "vatpit.h" 57 58 #define VATPIT_LOCK(vatpit) mutex_enter(&((vatpit)->lock)) 59 #define VATPIT_UNLOCK(vatpit) mutex_exit(&((vatpit)->lock)) 60 #define VATPIT_LOCKED(vatpit) MUTEX_HELD(&((vatpit)->lock)) 61 62 #define TIMER_SEL_MASK 0xc0 63 #define TIMER_RW_MASK 0x30 64 #define TIMER_MODE_MASK 0x0f 65 #define TIMER_SEL_READBACK 0xc0 66 67 #define TIMER_STS_OUT 0x80 68 #define TIMER_STS_NULLCNT 0x40 69 70 #define VALID_STATUS_BITS (TIMER_STS_OUT | TIMER_STS_NULLCNT) 71 72 #define TIMER_RB_LCTR 0x20 73 #define TIMER_RB_LSTATUS 0x10 74 #define TIMER_RB_CTR_2 0x08 75 #define TIMER_RB_CTR_1 0x04 76 #define TIMER_RB_CTR_0 0x02 77 78 #define TMR2_OUT_STS 0x20 79 80 #define PIT_8254_FREQ 1193182 81 #define TIMER_DIV(freq, hz) (((freq) + (hz) / 2) / (hz)) 82 83 struct vatpit_callout_arg { 84 struct vatpit *vatpit; 85 int channel_num; 86 }; 87 88 struct channel { 89 uint8_t mode; 90 uint16_t initial; /* initial counter value */ 91 92 uint8_t reg_cr[2]; 93 uint8_t reg_ol[2]; 94 uint8_t reg_status; 95 96 bool slatched; /* status latched */ 97 bool olatched; /* output latched */ 98 bool cr_sel; /* read MSB from control register */ 99 bool ol_sel; /* read MSB from output latch */ 100 bool fr_sel; /* read MSB from free-running timer */ 101 102 hrtime_t time_loaded; /* time when counter was loaded */ 103 hrtime_t time_target; /* target time */ 104 uint64_t total_target; 105 106 struct callout callout; 107 struct vatpit_callout_arg callout_arg; 108 }; 109 110 struct vatpit { 111 struct vm *vm; 112 kmutex_t lock; 113 114 struct channel channel[3]; 115 }; 116 117 static void pit_timer_start_cntr0(struct vatpit *vatpit); 118 119 static uint64_t 120 vatpit_delta_ticks(struct vatpit *vatpit, struct channel *c) 121 { 122 const hrtime_t delta = gethrtime() - c->time_loaded; 123 124 return (hrt_freq_count(delta, PIT_8254_FREQ)); 125 } 126 127 static int 128 vatpit_get_out(struct vatpit *vatpit, int channel) 129 { 130 struct channel *c; 131 uint64_t delta_ticks; 132 int out; 133 134 c = &vatpit->channel[channel]; 135 136 switch (c->mode) { 137 case TIMER_INTTC: 138 delta_ticks = vatpit_delta_ticks(vatpit, c); 139 out = (delta_ticks >= c->initial); 140 break; 141 default: 142 out = 0; 143 break; 144 } 145 146 return (out); 147 } 148 149 static void 150 vatpit_callout_handler(void *a) 151 { 152 struct vatpit_callout_arg *arg = a; 153 struct vatpit *vatpit; 154 struct callout *callout; 155 struct channel *c; 156 157 vatpit = arg->vatpit; 158 c = &vatpit->channel[arg->channel_num]; 159 callout = &c->callout; 160 161 VATPIT_LOCK(vatpit); 162 163 if (callout_pending(callout)) /* callout was reset */ 164 goto done; 165 166 if (!callout_active(callout)) /* callout was stopped */ 167 goto done; 168 169 callout_deactivate(callout); 170 171 if (c->mode == TIMER_RATEGEN || c->mode == TIMER_SQWAVE) { 172 pit_timer_start_cntr0(vatpit); 173 } else { 174 /* 175 * For non-periodic timers, clear the time target to distinguish 176 * between a fired timer (thus a zero value) and a pending one 177 * awaiting VM resumption (holding a non-zero value). 178 */ 179 c->time_target = 0; 180 } 181 182 (void) vatpic_pulse_irq(vatpit->vm, 0); 183 (void) vioapic_pulse_irq(vatpit->vm, 2); 184 185 done: 186 VATPIT_UNLOCK(vatpit); 187 } 188 189 static void 190 vatpit_callout_reset(struct vatpit *vatpit) 191 { 192 struct channel *c = &vatpit->channel[0]; 193 194 ASSERT(VATPIT_LOCKED(vatpit)); 195 callout_reset_hrtime(&c->callout, c->time_target, 196 vatpit_callout_handler, &c->callout_arg, C_ABSOLUTE); 197 } 198 199 static void 200 pit_timer_start_cntr0(struct vatpit *vatpit) 201 { 202 struct channel *c = &vatpit->channel[0]; 203 204 if (c->initial == 0) { 205 return; 206 } 207 208 c->total_target += c->initial; 209 c->time_target = c->time_loaded + 210 hrt_freq_interval(PIT_8254_FREQ, c->total_target); 211 212 /* 213 * If we are more than 'c->initial' ticks behind, reset the timer base 214 * to fire at the next 'c->initial' interval boundary. 215 */ 216 hrtime_t now = gethrtime(); 217 if (c->time_target < now) { 218 const uint64_t ticks_behind = 219 hrt_freq_count(now - c->time_target, PIT_8254_FREQ); 220 221 c->total_target += roundup(ticks_behind, c->initial); 222 c->time_target = c->time_loaded + 223 hrt_freq_interval(PIT_8254_FREQ, c->total_target); 224 } 225 226 vatpit_callout_reset(vatpit); 227 } 228 229 static uint16_t 230 pit_update_counter(struct vatpit *vatpit, struct channel *c, bool latch) 231 { 232 uint16_t lval; 233 uint64_t delta_ticks; 234 235 /* cannot latch a new value until the old one has been consumed */ 236 if (latch && c->olatched) 237 return (0); 238 239 if (c->initial == 0) { 240 /* 241 * This is possibly an OS bug - reading the value of the timer 242 * without having set up the initial value. 243 * 244 * The original user-space version of this code set the timer to 245 * 100hz in this condition; do the same here. 246 */ 247 c->initial = TIMER_DIV(PIT_8254_FREQ, 100); 248 c->time_loaded = gethrtime(); 249 c->reg_status &= ~TIMER_STS_NULLCNT; 250 } 251 252 delta_ticks = vatpit_delta_ticks(vatpit, c); 253 lval = c->initial - delta_ticks % c->initial; 254 255 if (latch) { 256 c->olatched = true; 257 c->ol_sel = true; 258 c->reg_ol[1] = lval; /* LSB */ 259 c->reg_ol[0] = lval >> 8; /* MSB */ 260 } 261 262 return (lval); 263 } 264 265 static int 266 pit_readback1(struct vatpit *vatpit, int channel, uint8_t cmd) 267 { 268 struct channel *c; 269 270 c = &vatpit->channel[channel]; 271 272 /* 273 * Latch the count/status of the timer if not already latched. 274 * N.B. that the count/status latch-select bits are active-low. 275 */ 276 if ((cmd & TIMER_RB_LCTR) == 0 && !c->olatched) { 277 (void) pit_update_counter(vatpit, c, true); 278 } 279 280 if ((cmd & TIMER_RB_LSTATUS) == 0 && !c->slatched) { 281 c->slatched = true; 282 /* 283 * For mode 0, see if the elapsed time is greater 284 * than the initial value - this results in the 285 * output pin being set to 1 in the status byte. 286 */ 287 if (c->mode == TIMER_INTTC && vatpit_get_out(vatpit, channel)) 288 c->reg_status |= TIMER_STS_OUT; 289 else 290 c->reg_status &= ~TIMER_STS_OUT; 291 } 292 293 return (0); 294 } 295 296 static int 297 pit_readback(struct vatpit *vatpit, uint8_t cmd) 298 { 299 int error; 300 301 /* 302 * The readback command can apply to all timers. 303 */ 304 error = 0; 305 if (cmd & TIMER_RB_CTR_0) 306 error = pit_readback1(vatpit, 0, cmd); 307 if (!error && cmd & TIMER_RB_CTR_1) 308 error = pit_readback1(vatpit, 1, cmd); 309 if (!error && cmd & TIMER_RB_CTR_2) 310 error = pit_readback1(vatpit, 2, cmd); 311 312 return (error); 313 } 314 315 static int 316 vatpit_update_mode(struct vatpit *vatpit, uint8_t val) 317 { 318 struct channel *c; 319 int sel, rw; 320 uint8_t mode; 321 322 sel = val & TIMER_SEL_MASK; 323 rw = val & TIMER_RW_MASK; 324 mode = val & TIMER_MODE_MASK; 325 326 /* Clear don't-care bit (M2) when M1 is set */ 327 if ((mode & TIMER_RATEGEN) != 0) { 328 mode &= ~TIMER_SWSTROBE; 329 } 330 331 if (sel == TIMER_SEL_READBACK) 332 return (pit_readback(vatpit, val)); 333 334 if (rw != TIMER_LATCH && rw != TIMER_16BIT) 335 return (-1); 336 337 if (rw != TIMER_LATCH) { 338 /* 339 * Counter mode is not affected when issuing a 340 * latch command. 341 */ 342 if (mode != TIMER_INTTC && 343 mode != TIMER_RATEGEN && 344 mode != TIMER_SQWAVE && 345 mode != TIMER_SWSTROBE) 346 return (-1); 347 } 348 349 c = &vatpit->channel[sel >> 6]; 350 if (rw == TIMER_LATCH) { 351 (void) pit_update_counter(vatpit, c, true); 352 } else { 353 c->mode = mode; 354 c->olatched = false; /* reset latch after reprogramming */ 355 c->reg_status |= TIMER_STS_NULLCNT; 356 } 357 358 return (0); 359 } 360 361 int 362 vatpit_handler(void *arg, bool in, uint16_t port, uint8_t bytes, uint32_t *eax) 363 { 364 struct vatpit *vatpit = arg; 365 struct channel *c; 366 uint8_t val; 367 int error; 368 369 if (bytes != 1) 370 return (-1); 371 372 val = *eax; 373 374 if (port == TIMER_MODE) { 375 if (in) { 376 /* Mode is write-only */ 377 return (-1); 378 } 379 380 VATPIT_LOCK(vatpit); 381 error = vatpit_update_mode(vatpit, val); 382 VATPIT_UNLOCK(vatpit); 383 384 return (error); 385 } 386 387 /* counter ports */ 388 KASSERT(port >= TIMER_CNTR0 && port <= TIMER_CNTR2, 389 ("invalid port 0x%x", port)); 390 c = &vatpit->channel[port - TIMER_CNTR0]; 391 392 VATPIT_LOCK(vatpit); 393 if (in && c->slatched) { 394 /* Return the status byte if latched */ 395 *eax = c->reg_status; 396 c->slatched = false; 397 c->reg_status = 0; 398 } else if (in) { 399 /* 400 * The spec says that once the output latch is completely 401 * read it should revert to "following" the counter. Use 402 * the free running counter for this case (i.e. Linux 403 * TSC calibration). Assuming the access mode is 16-bit, 404 * toggle the MSB/LSB bit on each read. 405 */ 406 if (!c->olatched) { 407 uint16_t tmp; 408 409 tmp = pit_update_counter(vatpit, c, false); 410 if (c->fr_sel) { 411 tmp >>= 8; 412 } 413 tmp &= 0xff; 414 *eax = tmp; 415 c->fr_sel = !c->fr_sel; 416 } else { 417 if (c->ol_sel) { 418 *eax = c->reg_ol[1]; 419 c->ol_sel = false; 420 } else { 421 *eax = c->reg_ol[0]; 422 c->olatched = false; 423 } 424 } 425 } else { 426 if (!c->cr_sel) { 427 c->reg_cr[0] = *eax; 428 c->cr_sel = true; 429 } else { 430 c->reg_cr[1] = *eax; 431 c->cr_sel = false; 432 433 c->reg_status &= ~TIMER_STS_NULLCNT; 434 c->fr_sel = false; 435 c->initial = c->reg_cr[0] | (uint16_t)c->reg_cr[1] << 8; 436 c->time_loaded = gethrtime(); 437 /* Start an interval timer for channel 0 */ 438 if (port == TIMER_CNTR0) { 439 c->time_target = c->time_loaded; 440 c->total_target = 0; 441 pit_timer_start_cntr0(vatpit); 442 } 443 if (c->initial == 0) 444 c->initial = 0xffff; 445 } 446 } 447 VATPIT_UNLOCK(vatpit); 448 449 return (0); 450 } 451 452 int 453 vatpit_nmisc_handler(void *arg, bool in, uint16_t port, uint8_t bytes, 454 uint32_t *eax) 455 { 456 struct vatpit *vatpit = arg; 457 458 if (in) { 459 VATPIT_LOCK(vatpit); 460 if (vatpit_get_out(vatpit, 2)) 461 *eax = TMR2_OUT_STS; 462 else 463 *eax = 0; 464 465 VATPIT_UNLOCK(vatpit); 466 } 467 468 return (0); 469 } 470 471 struct vatpit * 472 vatpit_init(struct vm *vm) 473 { 474 struct vatpit *vatpit; 475 struct vatpit_callout_arg *arg; 476 int i; 477 478 vatpit = kmem_zalloc(sizeof (struct vatpit), KM_SLEEP); 479 vatpit->vm = vm; 480 481 mutex_init(&vatpit->lock, NULL, MUTEX_ADAPTIVE, NULL); 482 483 for (i = 0; i < 3; i++) { 484 callout_init(&vatpit->channel[i].callout, 1); 485 arg = &vatpit->channel[i].callout_arg; 486 arg->vatpit = vatpit; 487 arg->channel_num = i; 488 } 489 490 return (vatpit); 491 } 492 493 void 494 vatpit_cleanup(struct vatpit *vatpit) 495 { 496 int i; 497 498 for (i = 0; i < 3; i++) 499 callout_drain(&vatpit->channel[i].callout); 500 501 mutex_destroy(&vatpit->lock); 502 kmem_free(vatpit, sizeof (*vatpit)); 503 } 504 505 void 506 vatpit_localize_resources(struct vatpit *vatpit) 507 { 508 for (uint_t i = 0; i < 3; i++) { 509 /* Only localize channels which might be running */ 510 if (vatpit->channel[i].mode != 0) { 511 vmm_glue_callout_localize(&vatpit->channel[i].callout); 512 } 513 } 514 } 515 516 void 517 vatpit_pause(struct vatpit *vatpit) 518 { 519 struct channel *c = &vatpit->channel[0]; 520 521 VATPIT_LOCK(vatpit); 522 callout_stop(&c->callout); 523 VATPIT_UNLOCK(vatpit); 524 } 525 526 void 527 vatpit_resume(struct vatpit *vatpit) 528 { 529 struct channel *c = &vatpit->channel[0]; 530 531 VATPIT_LOCK(vatpit); 532 ASSERT(!callout_active(&c->callout)); 533 if (c->time_target != 0) { 534 vatpit_callout_reset(vatpit); 535 } 536 VATPIT_UNLOCK(vatpit); 537 } 538 539 static int 540 vatpit_data_read(void *datap, const vmm_data_req_t *req) 541 { 542 VERIFY3U(req->vdr_class, ==, VDC_ATPIT); 543 VERIFY3U(req->vdr_version, ==, 1); 544 VERIFY3U(req->vdr_len, >=, sizeof (struct vdi_atpit_v1)); 545 546 struct vatpit *vatpit = datap; 547 struct vdi_atpit_v1 *out = req->vdr_data; 548 549 VATPIT_LOCK(vatpit); 550 for (uint_t i = 0; i < 3; i++) { 551 const struct channel *src = &vatpit->channel[i]; 552 struct vdi_atpit_channel_v1 *chan = &out->va_channel[i]; 553 554 chan->vac_initial = src->initial; 555 chan->vac_reg_cr = 556 (src->reg_cr[0] | (uint16_t)src->reg_cr[1] << 8); 557 chan->vac_reg_ol = 558 (src->reg_ol[0] | (uint16_t)src->reg_ol[1] << 8); 559 chan->vac_reg_status = src->reg_status; 560 chan->vac_mode = src->mode; 561 chan->vac_status = 562 (src->slatched ? (1 << 0) : 0) | 563 (src->olatched ? (1 << 1) : 0) | 564 (src->cr_sel ? (1 << 2) : 0) | 565 (src->ol_sel ? (1 << 3) : 0) | 566 (src->fr_sel ? (1 << 4) : 0); 567 /* Only channel 0 has the timer configured */ 568 if (i == 0 && src->time_target != 0) { 569 chan->vac_time_target = 570 vm_normalize_hrtime(vatpit->vm, src->time_target); 571 } else { 572 chan->vac_time_target = 0; 573 } 574 } 575 VATPIT_UNLOCK(vatpit); 576 577 return (0); 578 } 579 580 static bool 581 vatpit_data_validate(const struct vdi_atpit_v1 *src) 582 { 583 for (uint_t i = 0; i < 3; i++) { 584 const struct vdi_atpit_channel_v1 *chan = &src->va_channel[i]; 585 586 if ((chan->vac_status & ~VALID_STATUS_BITS) != 0) { 587 return (false); 588 } 589 } 590 return (true); 591 } 592 593 static int 594 vatpit_data_write(void *datap, const vmm_data_req_t *req) 595 { 596 VERIFY3U(req->vdr_class, ==, VDC_ATPIT); 597 VERIFY3U(req->vdr_version, ==, 1); 598 VERIFY3U(req->vdr_len, >=, sizeof (struct vdi_atpit_v1)); 599 600 struct vatpit *vatpit = datap; 601 const struct vdi_atpit_v1 *src = req->vdr_data; 602 if (!vatpit_data_validate(src)) { 603 return (EINVAL); 604 } 605 606 VATPIT_LOCK(vatpit); 607 for (uint_t i = 0; i < 3; i++) { 608 const struct vdi_atpit_channel_v1 *chan = &src->va_channel[i]; 609 struct channel *out = &vatpit->channel[i]; 610 611 out->initial = chan->vac_initial; 612 out->reg_cr[0] = chan->vac_reg_cr; 613 out->reg_cr[1] = chan->vac_reg_cr >> 8; 614 out->reg_ol[0] = chan->vac_reg_ol; 615 out->reg_ol[1] = chan->vac_reg_ol >> 8; 616 out->reg_status = chan->vac_reg_status; 617 out->mode = chan->vac_mode; 618 out->slatched = (chan->vac_status & (1 << 0)) != 0; 619 out->olatched = (chan->vac_status & (1 << 1)) != 0; 620 out->cr_sel = (chan->vac_status & (1 << 2)) != 0; 621 out->ol_sel = (chan->vac_status & (1 << 3)) != 0; 622 out->fr_sel = (chan->vac_status & (1 << 4)) != 0; 623 624 /* Only channel 0 has the timer configured */ 625 if (i != 0) { 626 continue; 627 } 628 629 struct callout *callout = &out->callout; 630 if (callout_active(callout)) { 631 callout_deactivate(callout); 632 } 633 634 if (chan->vac_time_target == 0) { 635 out->time_loaded = 0; 636 out->time_target = 0; 637 continue; 638 } 639 640 /* back-calculate time_loaded for the appropriate interval */ 641 const uint64_t time_target = 642 vm_denormalize_hrtime(vatpit->vm, chan->vac_time_target); 643 out->total_target = out->initial; 644 out->time_target = time_target; 645 out->time_loaded = time_target - 646 hrt_freq_interval(PIT_8254_FREQ, out->initial); 647 648 if (!vm_is_paused(vatpit->vm)) { 649 vatpit_callout_reset(vatpit); 650 } 651 } 652 VATPIT_UNLOCK(vatpit); 653 654 return (0); 655 } 656 657 static const vmm_data_version_entry_t atpit_v1 = { 658 .vdve_class = VDC_ATPIT, 659 .vdve_version = 1, 660 .vdve_len_expect = sizeof (struct vdi_atpit_v1), 661 .vdve_readf = vatpit_data_read, 662 .vdve_writef = vatpit_data_write, 663 }; 664 VMM_DATA_VERSION(atpit_v1); 665