Lines Matching +full:channel +full:- +full:0
1 /*-
52 #define VATPIT_LOCK(vatpit) mtx_lock_spin(&((vatpit)->mtx))
53 #define VATPIT_UNLOCK(vatpit) mtx_unlock_spin(&((vatpit)->mtx))
54 #define VATPIT_LOCKED(vatpit) mtx_owned(&((vatpit)->mtx))
56 #define TIMER_SEL_MASK 0xc0
57 #define TIMER_RW_MASK 0x30
58 #define TIMER_MODE_MASK 0x0f
59 #define TIMER_SEL_READBACK 0xc0
61 #define TIMER_STS_OUT 0x80
62 #define TIMER_STS_NULLCNT 0x40
64 #define TIMER_RB_LCTR 0x20
65 #define TIMER_RB_LSTATUS 0x10
66 #define TIMER_RB_CTR_2 0x08
67 #define TIMER_RB_CTR_1 0x04
68 #define TIMER_RB_CTR_0 0x02
70 #define TMR2_OUT_STS 0x20
80 struct channel { struct
102 struct channel channel[3]; argument
108 vatpit_delta_ticks(struct vatpit *vatpit, struct channel *c) in vatpit_delta_ticks()
114 bintime_sub(&delta, &c->now_bt); in vatpit_delta_ticks()
117 result += delta.frac / vatpit->freq_bt.frac; in vatpit_delta_ticks()
123 vatpit_get_out(struct vatpit *vatpit, int channel) in vatpit_get_out() argument
125 struct channel *c; in vatpit_get_out()
129 c = &vatpit->channel[channel]; in vatpit_get_out()
131 switch (c->mode) { in vatpit_get_out()
134 out = (delta_ticks >= c->initial); in vatpit_get_out()
137 out = 0; in vatpit_get_out()
150 struct channel *c; in vatpit_callout_handler()
152 vatpit = arg->vatpit; in vatpit_callout_handler()
153 c = &vatpit->channel[arg->channel_num]; in vatpit_callout_handler()
154 callout = &c->callout; in vatpit_callout_handler()
156 VM_CTR1(vatpit->vm, "atpit t%d fired", arg->channel_num); in vatpit_callout_handler()
168 if (c->mode == TIMER_RATEGEN) { in vatpit_callout_handler()
172 vatpic_pulse_irq(vatpit->vm, 0); in vatpit_callout_handler()
173 vioapic_pulse_irq(vatpit->vm, 2); in vatpit_callout_handler()
183 struct channel *c; in pit_timer_start_cntr0()
187 c = &vatpit->channel[0]; in pit_timer_start_cntr0()
188 if (c->initial != 0) { in pit_timer_start_cntr0()
189 delta.sec = 0; in pit_timer_start_cntr0()
190 delta.frac = vatpit->freq_bt.frac * c->initial; in pit_timer_start_cntr0()
191 bintime_add(&c->callout_bt, &delta); in pit_timer_start_cntr0()
196 * was supposed to fire is more than 'c->initial' in pit_timer_start_cntr0()
200 if (bintime_cmp(&c->callout_bt, &now, <)) { in pit_timer_start_cntr0()
201 c->callout_bt = now; in pit_timer_start_cntr0()
202 bintime_add(&c->callout_bt, &delta); in pit_timer_start_cntr0()
205 callout_reset_sbt(&c->callout, bttosbt(c->callout_bt), in pit_timer_start_cntr0()
206 precision, vatpit_callout_handler, &c->callout_arg, in pit_timer_start_cntr0()
212 pit_update_counter(struct vatpit *vatpit, struct channel *c, bool latch) in pit_update_counter()
218 if (latch && c->olbyte != 0) in pit_update_counter()
219 return (0); in pit_update_counter()
221 if (c->initial == 0) { in pit_update_counter()
223 * This is possibly an o/s bug - reading the value of in pit_update_counter()
226 * The original user-space version of this code set in pit_update_counter()
230 c->initial = TIMER_DIV(PIT_8254_FREQ, 100); in pit_update_counter()
231 binuptime(&c->now_bt); in pit_update_counter()
232 c->status &= ~TIMER_STS_NULLCNT; in pit_update_counter()
236 lval = c->initial - delta_ticks % c->initial; in pit_update_counter()
239 c->olbyte = 2; in pit_update_counter()
240 c->ol[1] = lval; /* LSB */ in pit_update_counter()
241 c->ol[0] = lval >> 8; /* MSB */ in pit_update_counter()
248 pit_readback1(struct vatpit *vatpit, int channel, uint8_t cmd) in pit_readback1() argument
250 struct channel *c; in pit_readback1()
252 c = &vatpit->channel[channel]; in pit_readback1()
256 * N.B. that the count/status latch-select bits are active-low. in pit_readback1()
258 if (!(cmd & TIMER_RB_LCTR) && !c->olbyte) { in pit_readback1()
262 if (!(cmd & TIMER_RB_LSTATUS) && !c->slatched) { in pit_readback1()
263 c->slatched = true; in pit_readback1()
265 * For mode 0, see if the elapsed time is greater in pit_readback1()
266 * than the initial value - this results in the in pit_readback1()
269 if (c->mode == TIMER_INTTC && vatpit_get_out(vatpit, channel)) in pit_readback1()
270 c->status |= TIMER_STS_OUT; in pit_readback1()
272 c->status &= ~TIMER_STS_OUT; in pit_readback1()
275 return (0); in pit_readback1()
286 error = 0; in pit_readback()
288 error = pit_readback1(vatpit, 0, cmd); in pit_readback()
300 struct channel *c; in vatpit_update_mode()
311 return (-1); in vatpit_update_mode()
322 return (-1); in vatpit_update_mode()
325 c = &vatpit->channel[sel >> 6]; in vatpit_update_mode()
329 c->mode = mode; in vatpit_update_mode()
330 c->olbyte = 0; /* reset latch after reprogramming */ in vatpit_update_mode()
331 c->status |= TIMER_STS_NULLCNT; in vatpit_update_mode()
334 return (0); in vatpit_update_mode()
341 struct channel *c; in vatpit_handler()
348 return (-1); in vatpit_handler()
354 VM_CTR0(vatpit->vm, "vatpit attempt to read mode"); in vatpit_handler()
355 return (-1); in vatpit_handler()
367 ("invalid port 0x%x", port)); in vatpit_handler()
368 c = &vatpit->channel[port - TIMER_CNTR0]; in vatpit_handler()
371 if (in && c->slatched) { in vatpit_handler()
375 *eax = c->status; in vatpit_handler()
376 c->slatched = false; in vatpit_handler()
377 c->status = 0; in vatpit_handler()
383 * TSC calibration). Assuming the access mode is 16-bit, in vatpit_handler()
386 if (c->olbyte == 0) { in vatpit_handler()
390 if (c->frbyte) in vatpit_handler()
392 tmp &= 0xff; in vatpit_handler()
394 c->frbyte ^= 1; in vatpit_handler()
396 *eax = c->ol[--c->olbyte]; in vatpit_handler()
398 c->cr[c->crbyte++] = *eax; in vatpit_handler()
399 if (c->crbyte == 2) { in vatpit_handler()
400 c->status &= ~TIMER_STS_NULLCNT; in vatpit_handler()
401 c->frbyte = 0; in vatpit_handler()
402 c->crbyte = 0; in vatpit_handler()
403 c->initial = c->cr[0] | (uint16_t)c->cr[1] << 8; in vatpit_handler()
404 binuptime(&c->now_bt); in vatpit_handler()
405 /* Start an interval timer for channel 0 */ in vatpit_handler()
407 c->callout_bt = c->now_bt; in vatpit_handler()
410 if (c->initial == 0) in vatpit_handler()
411 c->initial = 0xffff; in vatpit_handler()
416 return (0); in vatpit_handler()
432 *eax = 0; in vatpit_nmisc_handler()
437 return (0); in vatpit_nmisc_handler()
448 vatpit->vm = vm; in vatpit_init()
450 mtx_init(&vatpit->mtx, "vatpit lock", NULL, MTX_SPIN); in vatpit_init()
452 FREQ2BT(PIT_8254_FREQ, &vatpit->freq_bt); in vatpit_init()
454 for (i = 0; i < 3; i++) { in vatpit_init()
455 callout_init(&vatpit->channel[i].callout, 1); in vatpit_init()
456 arg = &vatpit->channel[i].callout_arg; in vatpit_init()
457 arg->vatpit = vatpit; in vatpit_init()
458 arg->channel_num = i; in vatpit_init()
469 for (i = 0; i < 3; i++) in vatpit_cleanup()
470 callout_drain(&vatpit->channel[i].callout); in vatpit_cleanup()
472 mtx_destroy(&vatpit->mtx); in vatpit_cleanup()
482 struct channel *channel; in vatpit_snapshot() local
484 SNAPSHOT_VAR_OR_LEAVE(vatpit->freq_bt.sec, meta, ret, done); in vatpit_snapshot()
485 SNAPSHOT_VAR_OR_LEAVE(vatpit->freq_bt.frac, meta, ret, done); in vatpit_snapshot()
490 for (i = 0; i < nitems(vatpit->channel); i++) { in vatpit_snapshot()
491 channel = &vatpit->channel[i]; in vatpit_snapshot()
493 SNAPSHOT_VAR_OR_LEAVE(channel->mode, meta, ret, done); in vatpit_snapshot()
494 SNAPSHOT_VAR_OR_LEAVE(channel->initial, meta, ret, done); in vatpit_snapshot()
495 SNAPSHOT_VAR_OR_LEAVE(channel->now_bt.sec, meta, ret, done); in vatpit_snapshot()
496 SNAPSHOT_VAR_OR_LEAVE(channel->now_bt.frac, meta, ret, done); in vatpit_snapshot()
497 SNAPSHOT_BUF_OR_LEAVE(channel->cr, sizeof(channel->cr), in vatpit_snapshot()
499 SNAPSHOT_BUF_OR_LEAVE(channel->ol, sizeof(channel->ol), in vatpit_snapshot()
501 SNAPSHOT_VAR_OR_LEAVE(channel->slatched, meta, ret, done); in vatpit_snapshot()
502 SNAPSHOT_VAR_OR_LEAVE(channel->status, meta, ret, done); in vatpit_snapshot()
503 SNAPSHOT_VAR_OR_LEAVE(channel->crbyte, meta, ret, done); in vatpit_snapshot()
504 SNAPSHOT_VAR_OR_LEAVE(channel->frbyte, meta, ret, done); in vatpit_snapshot()
505 SNAPSHOT_VAR_OR_LEAVE(channel->callout_bt.sec, meta, ret, done); in vatpit_snapshot()
506 SNAPSHOT_VAR_OR_LEAVE(channel->callout_bt.frac, meta, ret, in vatpit_snapshot()