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 2023 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 /* 115 * VM-wide: 116 */ 117 118 /* Offset of guest TSC from system at time of boot */ 119 #define VAI_TSC_BOOT_OFFSET 1 120 /* Time that guest (nominally) booted, as hrtime */ 121 #define VAI_BOOT_HRTIME 2 122 /* Guest TSC frequency measured by hrtime (not effected by wall clock adj.) */ 123 #define VAI_TSC_FREQ 3 124 /* Is the VM currently in the "paused" state? (0 or 1) */ 125 #define VAI_VM_IS_PAUSED 4 126 127 /* 128 * per-vCPU: 129 * 130 * Note: While these are currently defined with values disjoint from those in 131 * the VM-wide category, it is not required that they be. The VM-wide and 132 * per-vCPU identifiers are distinguished by vm_data_xfer`vdx_vcpuid. 133 */ 134 135 /* NMI pending injection for vCPU (0 or 1) */ 136 #define VAI_PEND_NMI 10 137 /* extint pending injection for vCPU (0 or 1) */ 138 #define VAI_PEND_EXTINT 11 139 /* HW exception pending injection for vCPU */ 140 #define VAI_PEND_EXCP 12 141 /* exception/interrupt pending injection for vCPU */ 142 #define VAI_PEND_INTINFO 13 143 144 145 /* VDC_IOAPIC: */ 146 147 struct vdi_ioapic_v1 { 148 uint64_t vi_pin_reg[32]; 149 uint32_t vi_pin_level[32]; 150 uint32_t vi_id; 151 uint32_t vi_reg_sel; 152 }; 153 154 /* VDC_ATPIT: */ 155 156 struct vdi_atpit_channel_v1 { 157 uint16_t vac_initial; 158 uint16_t vac_reg_cr; 159 uint16_t vac_reg_ol; 160 uint8_t vac_reg_status; 161 uint8_t vac_mode; 162 /* 163 * vac_status bits: 164 * - 0b00001 status latched 165 * - 0b00010 output latched 166 * - 0b00100 control register sel 167 * - 0b01000 output latch sel 168 * - 0b10000 free-running timer 169 */ 170 uint8_t vac_status; 171 172 int64_t vac_time_target; 173 }; 174 175 struct vdi_atpit_v1 { 176 struct vdi_atpit_channel_v1 va_channel[3]; 177 }; 178 179 /* VDC_ATPIC: */ 180 181 struct vdi_atpic_chip_v1 { 182 uint8_t vac_icw_state; 183 /* 184 * vac_status bits: 185 * - 0b00000001 ready 186 * - 0b00000010 auto EOI 187 * - 0b00000100 poll 188 * - 0b00001000 rotate 189 * - 0b00010000 special full nested 190 * - 0b00100000 read isr next 191 * - 0b01000000 intr raised 192 * - 0b10000000 special mask mode 193 */ 194 uint8_t vac_status; 195 uint8_t vac_reg_irr; 196 uint8_t vac_reg_isr; 197 uint8_t vac_reg_imr; 198 uint8_t vac_irq_base; 199 uint8_t vac_lowprio; 200 uint8_t vac_elc; 201 uint32_t vac_level[8]; 202 }; 203 204 struct vdi_atpic_v1 { 205 struct vdi_atpic_chip_v1 va_chip[2]; 206 }; 207 208 /* VDC_HPET: */ 209 210 struct vdi_hpet_timer_v1 { 211 uint64_t vht_config; 212 uint64_t vht_msi; 213 uint32_t vht_comp_val; 214 uint32_t vht_comp_rate; 215 int64_t vht_time_target; 216 }; 217 218 struct vdi_hpet_v1 { 219 uint64_t vh_config; 220 uint64_t vh_isr; 221 uint32_t vh_count_base; 222 int64_t vh_time_base; 223 224 struct vdi_hpet_timer_v1 vh_timers[8]; 225 }; 226 227 /* VDC_PM_TIMER: */ 228 229 struct vdi_pm_timer_v1 { 230 int64_t vpt_time_base; 231 /* 232 * Since the PM-timer IO port registration can be set by a dedicated 233 * ioctl today, it is considered a read-only field in the vmm data 234 * interface and its contents will be ignored when writing state data to 235 * the timer. 236 */ 237 uint16_t vpt_ioport; 238 }; 239 240 /* VDC_RTC: */ 241 242 struct vdi_rtc_v1 { 243 uint8_t vr_content[128]; 244 uint8_t vr_addr; 245 int64_t vr_time_base; 246 uint64_t vr_rtc_sec; 247 uint64_t vr_rtc_nsec; 248 }; 249 250 #endif /* _VMM_DATA_H_ */ 251