1*4d846d26SWarner Losh /*- SPDX-License-Identifier: BSD-2-Clause 26cf00ef8SSouradeep Chakrabarti * 36cf00ef8SSouradeep Chakrabarti * Copyright (c) 2016-2017,2022 Microsoft Corp. 46cf00ef8SSouradeep Chakrabarti * 56cf00ef8SSouradeep Chakrabarti * Redistribution and use in source and binary forms, with or without 66cf00ef8SSouradeep Chakrabarti * modification, are permitted provided that the following conditions 76cf00ef8SSouradeep Chakrabarti * are met: 86cf00ef8SSouradeep Chakrabarti * 1. Redistributions of source code must retain the above copyright 96cf00ef8SSouradeep Chakrabarti * notice unmodified, this list of conditions, and the following 106cf00ef8SSouradeep Chakrabarti * disclaimer. 116cf00ef8SSouradeep Chakrabarti * 2. Redistributions in binary form must reproduce the above copyright 126cf00ef8SSouradeep Chakrabarti * notice, this list of conditions and the following disclaimer in the 136cf00ef8SSouradeep Chakrabarti * documentation and/or other materials provided with the distribution. 146cf00ef8SSouradeep Chakrabarti * 156cf00ef8SSouradeep Chakrabarti * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 166cf00ef8SSouradeep Chakrabarti * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 176cf00ef8SSouradeep Chakrabarti * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 186cf00ef8SSouradeep Chakrabarti * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 196cf00ef8SSouradeep Chakrabarti * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 206cf00ef8SSouradeep Chakrabarti * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 216cf00ef8SSouradeep Chakrabarti * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 226cf00ef8SSouradeep Chakrabarti * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 236cf00ef8SSouradeep Chakrabarti * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 246cf00ef8SSouradeep Chakrabarti * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 256cf00ef8SSouradeep Chakrabarti */ 266cf00ef8SSouradeep Chakrabarti 276cf00ef8SSouradeep Chakrabarti #include <sys/cdefs.h> 286cf00ef8SSouradeep Chakrabarti __FBSDID("$FreeBSD$"); 296cf00ef8SSouradeep Chakrabarti 306cf00ef8SSouradeep Chakrabarti #include <dev/hyperv/include/hyperv.h> 316cf00ef8SSouradeep Chakrabarti #include <dev/hyperv/include/hyperv_busdma.h> 326cf00ef8SSouradeep Chakrabarti #include <dev/hyperv/vmbus/aarch64/hyperv_machdep.h> 336cf00ef8SSouradeep Chakrabarti #include <dev/hyperv/vmbus/aarch64/hyperv_reg.h> 346cf00ef8SSouradeep Chakrabarti #include <dev/hyperv/vmbus/hyperv_var.h> 35d16d0b6bSSouradeep Chakrabarti #include <dev/hyperv/vmbus/hyperv_common_reg.h> 366cf00ef8SSouradeep Chakrabarti #include <dev/psci/smccc.h> 376cf00ef8SSouradeep Chakrabarti 386cf00ef8SSouradeep Chakrabarti #define HVCALL_SET_VP_REGISTERS 0x0051 396cf00ef8SSouradeep Chakrabarti #define HVCALL_GET_VP_REGISTERS 0x0050 406cf00ef8SSouradeep Chakrabarti #define BIT(A) (1 << (A)) 416cf00ef8SSouradeep Chakrabarti #define HV_HYPERCALL_FAST_BIT BIT(16) 426cf00ef8SSouradeep Chakrabarti #define BIT_ULL(a) (1ULL << (a)) 436cf00ef8SSouradeep Chakrabarti #define HV_HYPERCALL_REP_COMP_1 BIT_ULL(32) 446cf00ef8SSouradeep Chakrabarti #define HV_PARTITION_ID_SELF ((u64)-1) 456cf00ef8SSouradeep Chakrabarti #define HV_VP_INDEX_SELF ((u32)-2) 466cf00ef8SSouradeep Chakrabarti #define HV_SMCCC_FUNC_NUMBER 1 476cf00ef8SSouradeep Chakrabarti 486cf00ef8SSouradeep Chakrabarti #define HV_FUNC_ID \ 496cf00ef8SSouradeep Chakrabarti SMCCC_FUNC_ID(SMCCC_YIELDING_CALL, SMCCC_64BIT_CALL, \ 506cf00ef8SSouradeep Chakrabarti SMCCC_VENDOR_HYP_SERVICE_CALLS, HV_SMCCC_FUNC_NUMBER) 516cf00ef8SSouradeep Chakrabarti 526cf00ef8SSouradeep Chakrabarti void 536cf00ef8SSouradeep Chakrabarti arm_hv_set_vreg(u32 msr, u64 value) 546cf00ef8SSouradeep Chakrabarti { 556cf00ef8SSouradeep Chakrabarti arm_smccc_hvc(HV_FUNC_ID, 566cf00ef8SSouradeep Chakrabarti HVCALL_SET_VP_REGISTERS | HV_HYPERCALL_FAST_BIT | 576cf00ef8SSouradeep Chakrabarti HV_HYPERCALL_REP_COMP_1, 586cf00ef8SSouradeep Chakrabarti HV_PARTITION_ID_SELF, HV_VP_INDEX_SELF, msr, 0, value, 0, NULL); 596cf00ef8SSouradeep Chakrabarti } 606cf00ef8SSouradeep Chakrabarti 616cf00ef8SSouradeep Chakrabarti void 626cf00ef8SSouradeep Chakrabarti hv_get_vpreg_128(u32 msr, struct hv_get_vp_registers_output *result) 636cf00ef8SSouradeep Chakrabarti { 646cf00ef8SSouradeep Chakrabarti struct arm_smccc_1_2_regs args; 656cf00ef8SSouradeep Chakrabarti struct arm_smccc_1_2_regs res; 666cf00ef8SSouradeep Chakrabarti 676cf00ef8SSouradeep Chakrabarti args.a0 = HV_FUNC_ID; 686cf00ef8SSouradeep Chakrabarti args.a1 = HVCALL_GET_VP_REGISTERS | HV_HYPERCALL_FAST_BIT | 696cf00ef8SSouradeep Chakrabarti HV_HYPERCALL_REP_COMP_1; 706cf00ef8SSouradeep Chakrabarti args.a2 = HV_PARTITION_ID_SELF; 716cf00ef8SSouradeep Chakrabarti args.a3 = HV_VP_INDEX_SELF; 726cf00ef8SSouradeep Chakrabarti args.a4 = msr; 736cf00ef8SSouradeep Chakrabarti 746cf00ef8SSouradeep Chakrabarti /* 756cf00ef8SSouradeep Chakrabarti * Use the SMCCC 1.2 interface because the results are in registers 766cf00ef8SSouradeep Chakrabarti * beyond X0-X3. 776cf00ef8SSouradeep Chakrabarti */ 786cf00ef8SSouradeep Chakrabarti arm_smccc_1_2_hvc(&args, &res); 796cf00ef8SSouradeep Chakrabarti 806cf00ef8SSouradeep Chakrabarti result->as64.low = res.a6; 816cf00ef8SSouradeep Chakrabarti result->as64.high = res.a7; 826cf00ef8SSouradeep Chakrabarti } 836cf00ef8SSouradeep Chakrabarti 846cf00ef8SSouradeep Chakrabarti u64 856cf00ef8SSouradeep Chakrabarti arm_hv_get_vreg(u32 msr) 866cf00ef8SSouradeep Chakrabarti { 876cf00ef8SSouradeep Chakrabarti struct hv_get_vp_registers_output output; 886cf00ef8SSouradeep Chakrabarti 896cf00ef8SSouradeep Chakrabarti hv_get_vpreg_128(msr, &output); 906cf00ef8SSouradeep Chakrabarti 916cf00ef8SSouradeep Chakrabarti return (output.as64.low); 926cf00ef8SSouradeep Chakrabarti } 936cf00ef8SSouradeep Chakrabarti 946cf00ef8SSouradeep Chakrabarti uint64_t 956cf00ef8SSouradeep Chakrabarti hypercall_md(volatile void *hc_addr, uint64_t in_val, uint64_t in_paddr, 966cf00ef8SSouradeep Chakrabarti uint64_t out_paddr) 976cf00ef8SSouradeep Chakrabarti { 986cf00ef8SSouradeep Chakrabarti struct arm_smccc_res res; 996cf00ef8SSouradeep Chakrabarti 1006cf00ef8SSouradeep Chakrabarti arm_smccc_hvc(HV_FUNC_ID, in_val, in_paddr, out_paddr, 0, 0, 0, 0, 1016cf00ef8SSouradeep Chakrabarti &res); 1026cf00ef8SSouradeep Chakrabarti 1036cf00ef8SSouradeep Chakrabarti return (res.a0); 1046cf00ef8SSouradeep Chakrabarti } 105