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