xref: /illumos-gate/usr/src/uts/intel/sys/vmm_data.h (revision 5d9d9091f564c198a760790b0bfa72c44e17912b)
1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 /* This file is dual-licensed; see usr/src/contrib/bhyve/LICENSE */
12 
13 /*
14  * Copyright 2022 Oxide Computer Company
15  */
16 
17 #ifndef _VMM_DATA_H_
18 #define	_VMM_DATA_H_
19 
20 /* VMM Data Classes */
21 #define	VDC_VERSION	1	/* Version information for each data class */
22 
23 /* Classes bearing per-CPU data */
24 #define	VDC_REGISTER	2	/* Registers (GPR, segment, etc) */
25 #define	VDC_MSR		3	/* Model-specific registers */
26 #define	VDC_FPU		4	/* FPU (and associated SIMD) */
27 #define	VDC_LAPIC	5	/* Local APIC */
28 #define	VDC_VMM_ARCH	6	/* Arch-specific VMM state (VMX/SVM) */
29 
30 /* Classes for system-wide devices */
31 #define	VDC_IOAPIC	7	/* bhyve IO-APIC */
32 #define	VDC_ATPIT	8	/* i8254 PIT */
33 #define	VDC_ATPIC	9	/* i8259 PIC */
34 #define	VDC_HPET	10	/* HPET */
35 #define	VDC_PM_TIMER	11	/* ACPI Power Management Timer */
36 #define	VDC_RTC		12	/* IBM PC Real Time Clock */
37 
38 /* Indicates top of VMM Data Class range, updated as classes are added */
39 #define	VDC_MAX		(VDC_RTC + 1)
40 
41 
42 /* VMM Data Identifiers */
43 
44 /*
45  * Generic field encoding for 64-bit (or smaller) data which are identified by a
46  * 32-bit (or smaller) name.
47  *
48  * Used by the following classes/version:
49  * - VDC_REGISTER v1: `vm_reg_name` identifiers
50  * - VDC_MSR v1: MSR identifiers
51  * - VDC_VMM_ARCH v1: Identifiers described below
52  */
53 struct vdi_field_entry_v1 {
54 	uint32_t	vfe_ident;
55 	uint32_t	_pad;
56 	uint64_t	vfe_value;
57 };
58 
59 /* VDC_VERSION */
60 struct vdi_version_entry_v1 {
61 	uint16_t	vve_class;
62 	uint16_t	vve_version;
63 	uint16_t	vve_len_expect;
64 	uint16_t	vve_len_per_item;
65 };
66 
67 /*
68  * VDC_FPU:
69  *
70  * Unimplemented for now.  Use VM_GET_FPU/VM_SET_FPU ioctls.
71  */
72 
73 /* VDC_LAPIC: */
74 
75 struct vdi_lapic_page_v1 {
76 	uint32_t	vlp_id;
77 	uint32_t	vlp_version;
78 	uint32_t	vlp_tpr;
79 	uint32_t	vlp_apr;
80 	uint32_t	vlp_ldr;
81 	uint32_t	vlp_dfr;
82 	uint32_t	vlp_svr;
83 	uint32_t	vlp_isr[8];
84 	uint32_t	vlp_tmr[8];
85 	uint32_t	vlp_irr[8];
86 	uint32_t	vlp_esr;
87 	uint32_t	vlp_lvt_cmci;
88 	uint64_t	vlp_icr;
89 	uint32_t	vlp_lvt_timer;
90 	uint32_t	vlp_lvt_thermal;
91 	uint32_t	vlp_lvt_pcint;
92 	uint32_t	vlp_lvt_lint0;
93 	uint32_t	vlp_lvt_lint1;
94 	uint32_t	vlp_lvt_error;
95 	uint32_t	vlp_icr_timer;
96 	uint32_t	vlp_dcr_timer;
97 };
98 
99 struct vdi_lapic_v1 {
100 	struct vdi_lapic_page_v1 vl_lapic;
101 	uint64_t		vl_msr_apicbase;
102 	int64_t			vl_timer_target;
103 	uint32_t		vl_esr_pending;
104 };
105 
106 /*
107  * VDC_VMM_ARCH:
108  */
109 
110 /*
111  * Version 1 identifiers:
112  */
113 
114 /* Offset of guest TSC from system at time of boot */
115 #define	VAI_TSC_BOOT_OFFSET	1
116 /* Time that guest (nominally) booted, as hrtime */
117 #define	VAI_BOOT_HRTIME		2
118 /* Guest TSC frequency measured by hrtime (not effected by wall clock adj.) */
119 #define	VAI_TSC_FREQ		3
120 
121 
122 /* VDC_IOAPIC: */
123 
124 struct vdi_ioapic_v1 {
125 	uint64_t	vi_pin_reg[32];
126 	uint32_t	vi_pin_level[32];
127 	uint32_t	vi_id;
128 	uint32_t	vi_reg_sel;
129 };
130 
131 /* VDC_ATPIT: */
132 
133 struct vdi_atpit_channel_v1 {
134 	uint16_t	vac_initial;
135 	uint16_t	vac_reg_cr;
136 	uint16_t	vac_reg_ol;
137 	uint8_t		vac_reg_status;
138 	uint8_t		vac_mode;
139 	/*
140 	 * vac_status bits:
141 	 * - 0b00001 status latched
142 	 * - 0b00010 output latched
143 	 * - 0b00100 control register sel
144 	 * - 0b01000 output latch sel
145 	 * - 0b10000 free-running timer
146 	 */
147 	uint8_t		vac_status;
148 
149 	int64_t		vac_time_target;
150 };
151 
152 struct vdi_atpit_v1 {
153 	struct vdi_atpit_channel_v1 va_channel[3];
154 };
155 
156 /* VDC_ATPIC: */
157 
158 struct vdi_atpic_chip_v1 {
159 	uint8_t		vac_icw_state;
160 	/*
161 	 * vac_status bits:
162 	 * - 0b00000001 ready
163 	 * - 0b00000010 auto EOI
164 	 * - 0b00000100 poll
165 	 * - 0b00001000 rotate
166 	 * - 0b00010000 special full nested
167 	 * - 0b00100000 read isr next
168 	 * - 0b01000000 intr raised
169 	 * - 0b10000000 special mask mode
170 	 */
171 	uint8_t		vac_status;
172 	uint8_t		vac_reg_irr;
173 	uint8_t		vac_reg_isr;
174 	uint8_t		vac_reg_imr;
175 	uint8_t		vac_irq_base;
176 	uint8_t		vac_lowprio;
177 	uint8_t		vac_elc;
178 	uint32_t	vac_level[8];
179 };
180 
181 struct vdi_atpic_v1 {
182 	struct vdi_atpic_chip_v1 va_chip[2];
183 };
184 
185 /* VDC_HPET: */
186 
187 struct vdi_hpet_timer_v1 {
188 	uint64_t	vht_config;
189 	uint64_t	vht_msi;
190 	uint32_t	vht_comp_val;
191 	uint32_t	vht_comp_rate;
192 	int64_t		vht_time_target;
193 };
194 
195 struct vdi_hpet_v1 {
196 	uint64_t	vh_config;
197 	uint64_t	vh_isr;
198 	uint32_t	vh_count_base;
199 	int64_t		vh_time_base;
200 
201 	struct vdi_hpet_timer_v1	vh_timers[8];
202 };
203 
204 /* VDC_PM_TIMER: */
205 
206 struct vdi_pm_timer_v1 {
207 	int64_t		vpt_time_base;
208 	/*
209 	 * Since the PM-timer IO port registration can be set by a dedicated
210 	 * ioctl today, it is considered a read-only field in the vmm data
211 	 * interface and its contents will be ignored when writing state data to
212 	 * the timer.
213 	 */
214 	uint16_t	vpt_ioport;
215 };
216 
217 /* VDC_RTC: */
218 
219 struct vdi_rtc_v1 {
220 	uint8_t		vr_content[128];
221 	uint8_t		vr_addr;
222 	int64_t		vr_time_base;
223 	uint64_t	vr_rtc_sec;
224 	uint64_t	vr_rtc_nsec;
225 };
226 
227 #endif /* _VMM_DATA_H_ */
228