16cf00ef8SSouradeep Chakrabarti /*- SPDX-License-Identifier: BSD-2-Clause-FreeBSD 26cf00ef8SSouradeep Chakrabarti * Copyright (c) 2009-2012,2016-2017, 2022 Microsoft Corp. 36cf00ef8SSouradeep Chakrabarti * Copyright (c) 2012 NetApp Inc. 46cf00ef8SSouradeep Chakrabarti * Copyright (c) 2012 Citrix Inc. 56cf00ef8SSouradeep Chakrabarti * All rights reserved. 66cf00ef8SSouradeep Chakrabarti * 76cf00ef8SSouradeep Chakrabarti * Redistribution and use in source and binary forms, with or without 86cf00ef8SSouradeep Chakrabarti * modification, are permitted provided that the following conditions 96cf00ef8SSouradeep Chakrabarti * are met: 106cf00ef8SSouradeep Chakrabarti * 1. Redistributions of source code must retain the above copyright 116cf00ef8SSouradeep Chakrabarti * notice unmodified, this list of conditions, and the following 126cf00ef8SSouradeep Chakrabarti * disclaimer. 136cf00ef8SSouradeep Chakrabarti * 2. Redistributions in binary form must reproduce the above copyright 146cf00ef8SSouradeep Chakrabarti * notice, this list of conditions and the following disclaimer in the 156cf00ef8SSouradeep Chakrabarti * documentation and/or other materials provided with the distribution. 166cf00ef8SSouradeep Chakrabarti * 176cf00ef8SSouradeep Chakrabarti * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 186cf00ef8SSouradeep Chakrabarti * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 196cf00ef8SSouradeep Chakrabarti * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 206cf00ef8SSouradeep Chakrabarti * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 216cf00ef8SSouradeep Chakrabarti * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 226cf00ef8SSouradeep Chakrabarti * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236cf00ef8SSouradeep Chakrabarti * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246cf00ef8SSouradeep Chakrabarti * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256cf00ef8SSouradeep Chakrabarti * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 266cf00ef8SSouradeep Chakrabarti * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276cf00ef8SSouradeep Chakrabarti */ 286cf00ef8SSouradeep Chakrabarti 296cf00ef8SSouradeep Chakrabarti /** 306cf00ef8SSouradeep Chakrabarti * Implements low-level interactions with Hyper-V/Azure 316cf00ef8SSouradeep Chakrabarti */ 326cf00ef8SSouradeep Chakrabarti 336cf00ef8SSouradeep Chakrabarti #include <sys/cdefs.h> 346cf00ef8SSouradeep Chakrabarti __FBSDID("$FreeBSD$"); 356cf00ef8SSouradeep Chakrabarti 366cf00ef8SSouradeep Chakrabarti #include <sys/param.h> 376cf00ef8SSouradeep Chakrabarti #include <sys/systm.h> 386cf00ef8SSouradeep Chakrabarti #include <sys/kernel.h> 396cf00ef8SSouradeep Chakrabarti #include <sys/malloc.h> 406cf00ef8SSouradeep Chakrabarti #include <sys/timetc.h> 416cf00ef8SSouradeep Chakrabarti 426cf00ef8SSouradeep Chakrabarti #include <vm/vm.h> 436cf00ef8SSouradeep Chakrabarti #include <vm/pmap.h> 446cf00ef8SSouradeep Chakrabarti #include <vm/vm_extern.h> 456cf00ef8SSouradeep Chakrabarti #include <vm/vm_kern.h> 466cf00ef8SSouradeep Chakrabarti 476cf00ef8SSouradeep Chakrabarti #include <dev/hyperv/include/hyperv.h> 486cf00ef8SSouradeep Chakrabarti #include <dev/hyperv/include/hyperv_busdma.h> 496cf00ef8SSouradeep Chakrabarti #include <dev/hyperv/vmbus/aarch64/hyperv_machdep.h> 506cf00ef8SSouradeep Chakrabarti #include <dev/hyperv/vmbus/aarch64/hyperv_reg.h> 516cf00ef8SSouradeep Chakrabarti #include <dev/hyperv/vmbus/hyperv_var.h> 52d16d0b6bSSouradeep Chakrabarti #include <dev/hyperv/vmbus/hyperv_common_reg.h> 53*65474983SSouradeep Chakrabarti #include <contrib/dev/acpica/include/acpi.h> 546cf00ef8SSouradeep Chakrabarti 556cf00ef8SSouradeep Chakrabarti void hyperv_init_tc(void); 566cf00ef8SSouradeep Chakrabarti int hypercall_page_setup(vm_paddr_t); 576cf00ef8SSouradeep Chakrabarti void hypercall_disable(void); 586cf00ef8SSouradeep Chakrabarti bool hyperv_identify_features(void); 596cf00ef8SSouradeep Chakrabarti 60*65474983SSouradeep Chakrabarti static bool is_hyperv(void); 61*65474983SSouradeep Chakrabarti 626cf00ef8SSouradeep Chakrabarti u_int hyperv_ver_major; 636cf00ef8SSouradeep Chakrabarti u_int hyperv_features; 646cf00ef8SSouradeep Chakrabarti u_int hyperv_recommends; 656cf00ef8SSouradeep Chakrabarti 666cf00ef8SSouradeep Chakrabarti hyperv_tc64_t hyperv_tc64; 676cf00ef8SSouradeep Chakrabarti 686cf00ef8SSouradeep Chakrabarti void 696cf00ef8SSouradeep Chakrabarti hyperv_init_tc(void) 706cf00ef8SSouradeep Chakrabarti { 716cf00ef8SSouradeep Chakrabarti hyperv_tc64 = NULL; 726cf00ef8SSouradeep Chakrabarti } 736cf00ef8SSouradeep Chakrabarti 746cf00ef8SSouradeep Chakrabarti int 756cf00ef8SSouradeep Chakrabarti hypercall_page_setup(vm_paddr_t hc) 766cf00ef8SSouradeep Chakrabarti { 776cf00ef8SSouradeep Chakrabarti return (0); 786cf00ef8SSouradeep Chakrabarti } 796cf00ef8SSouradeep Chakrabarti 806cf00ef8SSouradeep Chakrabarti void 816cf00ef8SSouradeep Chakrabarti hypercall_disable(void) 826cf00ef8SSouradeep Chakrabarti { 836cf00ef8SSouradeep Chakrabarti return; 846cf00ef8SSouradeep Chakrabarti } 856cf00ef8SSouradeep Chakrabarti 86*65474983SSouradeep Chakrabarti /* 87*65474983SSouradeep Chakrabarti * This function verifies if the platform is Hyper-V or not. 88*65474983SSouradeep Chakrabarti * To do that we are using ACPI FADT and for that, acpi 89*65474983SSouradeep Chakrabarti * fadt is mapped first. 90*65474983SSouradeep Chakrabarti */ 91*65474983SSouradeep Chakrabarti static bool 92*65474983SSouradeep Chakrabarti is_hyperv(void) 93*65474983SSouradeep Chakrabarti { 94*65474983SSouradeep Chakrabarti ACPI_TABLE_FADT *fadt; 95*65474983SSouradeep Chakrabarti vm_paddr_t physaddr; 96*65474983SSouradeep Chakrabarti uint64_t hypervid; 97*65474983SSouradeep Chakrabarti bool ret; 98*65474983SSouradeep Chakrabarti 99*65474983SSouradeep Chakrabarti physaddr = acpi_find_table(ACPI_SIG_FADT); 100*65474983SSouradeep Chakrabarti if (physaddr == 0) 101*65474983SSouradeep Chakrabarti return (false); 102*65474983SSouradeep Chakrabarti 103*65474983SSouradeep Chakrabarti fadt = acpi_map_table(physaddr, ACPI_SIG_FADT); 104*65474983SSouradeep Chakrabarti if (fadt == NULL) { 105*65474983SSouradeep Chakrabarti printf("hyperv: Unable to map the FADT\n"); 106*65474983SSouradeep Chakrabarti return (false); 107*65474983SSouradeep Chakrabarti } 108*65474983SSouradeep Chakrabarti 109*65474983SSouradeep Chakrabarti hypervid = fadt->HypervisorId; 110*65474983SSouradeep Chakrabarti acpi_unmap_table(fadt); 111*65474983SSouradeep Chakrabarti ret = strncmp((char *)&hypervid, "MsHyperV", 8) == 0 ? true : false; 112*65474983SSouradeep Chakrabarti return (ret); 113*65474983SSouradeep Chakrabarti } 114*65474983SSouradeep Chakrabarti 1156cf00ef8SSouradeep Chakrabarti bool 1166cf00ef8SSouradeep Chakrabarti hyperv_identify_features(void) 1176cf00ef8SSouradeep Chakrabarti { 1186cf00ef8SSouradeep Chakrabarti struct hv_get_vp_registers_output result; 1196cf00ef8SSouradeep Chakrabarti 120*65474983SSouradeep Chakrabarti if (resource_disabled("acpi", 0)) 121*65474983SSouradeep Chakrabarti return (false); 122*65474983SSouradeep Chakrabarti if (!is_hyperv()) 123*65474983SSouradeep Chakrabarti return (false); 124*65474983SSouradeep Chakrabarti 125*65474983SSouradeep Chakrabarti vm_guest = VM_GUEST_HV; 126*65474983SSouradeep Chakrabarti /* use MSRs to get the hyperv specific 127*65474983SSouradeep Chakrabarti * attributes. 128*65474983SSouradeep Chakrabarti */ 1296cf00ef8SSouradeep Chakrabarti hv_get_vpreg_128(CPUID_LEAF_HV_FEATURES, &result); 1306cf00ef8SSouradeep Chakrabarti hyperv_features = result.as32.a; 1316cf00ef8SSouradeep Chakrabarti hv_get_vpreg_128(CPUID_LEAF_HV_IDENTITY, &result); 1326cf00ef8SSouradeep Chakrabarti hyperv_ver_major = result.as32.b >> 16; 1336cf00ef8SSouradeep Chakrabarti hv_get_vpreg_128(CPUID_LEAF_HV_RECOMMENDS, &result); 1346cf00ef8SSouradeep Chakrabarti hyperv_recommends = result.as32.a; 1356cf00ef8SSouradeep Chakrabarti return (true); 1366cf00ef8SSouradeep Chakrabarti } 137