1*5103e761SPatrick Mooney /*
2*5103e761SPatrick Mooney  * This file and its contents are supplied under the terms of the
3*5103e761SPatrick Mooney  * Common Development and Distribution License ("CDDL"), version 1.0.
4*5103e761SPatrick Mooney  * You may only use this file in accordance with the terms of version
5*5103e761SPatrick Mooney  * 1.0 of the CDDL.
6*5103e761SPatrick Mooney  *
7*5103e761SPatrick Mooney  * A full copy of the text of the CDDL should have accompanied this
8*5103e761SPatrick Mooney  * source.  A copy of the CDDL is also available via the Internet at
9*5103e761SPatrick Mooney  * http://www.illumos.org/license/CDDL.
10*5103e761SPatrick Mooney  */
11*5103e761SPatrick Mooney 
12*5103e761SPatrick Mooney /*
13*5103e761SPatrick Mooney  * Copyright 2022 Oxide Computer Company
14*5103e761SPatrick Mooney  */
15*5103e761SPatrick Mooney 
16*5103e761SPatrick Mooney #include "payload_common.h"
17*5103e761SPatrick Mooney #include "payload_utils.h"
18*5103e761SPatrick Mooney #include "test_defs.h"
19*5103e761SPatrick Mooney 
20*5103e761SPatrick Mooney 
21*5103e761SPatrick Mooney void
timer0_reset(void)22*5103e761SPatrick Mooney timer0_reset(void)
23*5103e761SPatrick Mooney {
24*5103e761SPatrick Mooney 	/*
25*5103e761SPatrick Mooney 	 * Configure timer 0 for interrupt-on-terminal-count mode, and prepare
26*5103e761SPatrick Mooney 	 * it to be loaded with the high and low bytes.
27*5103e761SPatrick Mooney 	 */
28*5103e761SPatrick Mooney 	outb(IOP_ATPIT_CMD, 0x30);
29*5103e761SPatrick Mooney 
30*5103e761SPatrick Mooney 	/* Load timer with max value (0xffff) */
31*5103e761SPatrick Mooney 	outb(IOP_ATPIT_C0, 0xff);
32*5103e761SPatrick Mooney 	outb(IOP_ATPIT_C0, 0xff);
33*5103e761SPatrick Mooney }
34*5103e761SPatrick Mooney 
35*5103e761SPatrick Mooney uint16_t
timer0_read(void)36*5103e761SPatrick Mooney timer0_read(void)
37*5103e761SPatrick Mooney {
38*5103e761SPatrick Mooney 	uint16_t val;
39*5103e761SPatrick Mooney 
40*5103e761SPatrick Mooney 	/* Latch timer0 */
41*5103e761SPatrick Mooney 	outb(IOP_ATPIT_CMD, 0x00);
42*5103e761SPatrick Mooney 
43*5103e761SPatrick Mooney 	/* Read low and high bytes */
44*5103e761SPatrick Mooney 	val = inb(IOP_ATPIT_C0);
45*5103e761SPatrick Mooney 	val |= (uint16_t)inb(IOP_ATPIT_C0) << 8;
46*5103e761SPatrick Mooney 
47*5103e761SPatrick Mooney 	return (val);
48*5103e761SPatrick Mooney }
49*5103e761SPatrick Mooney 
50*5103e761SPatrick Mooney void
start(void)51*5103e761SPatrick Mooney start(void)
52*5103e761SPatrick Mooney {
53*5103e761SPatrick Mooney 
54*5103e761SPatrick Mooney 	/* loop for as long as the host wants */
55*5103e761SPatrick Mooney 	for (;;) {
56*5103e761SPatrick Mooney 		uint16_t start, end;
57*5103e761SPatrick Mooney 
58*5103e761SPatrick Mooney 		timer0_reset();
59*5103e761SPatrick Mooney 
60*5103e761SPatrick Mooney 		start = timer0_read();
61*5103e761SPatrick Mooney 		outw(IOP_TEST_VALUE, start);
62*5103e761SPatrick Mooney 
63*5103e761SPatrick Mooney 		do {
64*5103e761SPatrick Mooney 			end = timer0_read();
65*5103e761SPatrick Mooney 			/* wait for enough ticks to pass */
66*5103e761SPatrick Mooney 		} while (end > (start - ATPIT_TARGET_TICKS));
67*5103e761SPatrick Mooney 		outw(IOP_TEST_VALUE, end);
68*5103e761SPatrick Mooney 	}
69*5103e761SPatrick Mooney }
70