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