14d846d26SWarner 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 #include <dev/hyperv/include/hyperv.h>
296cf00ef8SSouradeep Chakrabarti #include <dev/hyperv/include/hyperv_busdma.h>
306cf00ef8SSouradeep Chakrabarti #include <dev/hyperv/vmbus/aarch64/hyperv_machdep.h>
316cf00ef8SSouradeep Chakrabarti #include <dev/hyperv/vmbus/aarch64/hyperv_reg.h>
326cf00ef8SSouradeep Chakrabarti #include <dev/hyperv/vmbus/hyperv_var.h>
33d16d0b6bSSouradeep Chakrabarti #include <dev/hyperv/vmbus/hyperv_common_reg.h>
346cf00ef8SSouradeep Chakrabarti #include <dev/psci/smccc.h>
356cf00ef8SSouradeep Chakrabarti
366cf00ef8SSouradeep Chakrabarti #define HVCALL_SET_VP_REGISTERS 0x0051
376cf00ef8SSouradeep Chakrabarti #define HVCALL_GET_VP_REGISTERS 0x0050
386cf00ef8SSouradeep Chakrabarti #define BIT(A) (1 << (A))
396cf00ef8SSouradeep Chakrabarti #define HV_HYPERCALL_FAST_BIT BIT(16)
406cf00ef8SSouradeep Chakrabarti #define BIT_ULL(a) (1ULL << (a))
416cf00ef8SSouradeep Chakrabarti #define HV_HYPERCALL_REP_COMP_1 BIT_ULL(32)
426cf00ef8SSouradeep Chakrabarti #define HV_PARTITION_ID_SELF ((u64)-1)
436cf00ef8SSouradeep Chakrabarti #define HV_VP_INDEX_SELF ((u32)-2)
446cf00ef8SSouradeep Chakrabarti #define HV_SMCCC_FUNC_NUMBER 1
456cf00ef8SSouradeep Chakrabarti
466cf00ef8SSouradeep Chakrabarti #define HV_FUNC_ID \
476cf00ef8SSouradeep Chakrabarti SMCCC_FUNC_ID(SMCCC_YIELDING_CALL, SMCCC_64BIT_CALL, \
486cf00ef8SSouradeep Chakrabarti SMCCC_VENDOR_HYP_SERVICE_CALLS, HV_SMCCC_FUNC_NUMBER)
496cf00ef8SSouradeep Chakrabarti
506cf00ef8SSouradeep Chakrabarti void
arm_hv_set_vreg(u32 msr,u64 value)516cf00ef8SSouradeep Chakrabarti arm_hv_set_vreg(u32 msr, u64 value)
526cf00ef8SSouradeep Chakrabarti {
53*b9cd72b0SAndrew Turner arm_smccc_invoke_hvc(HV_FUNC_ID,
546cf00ef8SSouradeep Chakrabarti HVCALL_SET_VP_REGISTERS | HV_HYPERCALL_FAST_BIT |
556cf00ef8SSouradeep Chakrabarti HV_HYPERCALL_REP_COMP_1,
56*b9cd72b0SAndrew Turner HV_PARTITION_ID_SELF, HV_VP_INDEX_SELF, msr, 0, value, NULL);
576cf00ef8SSouradeep Chakrabarti }
586cf00ef8SSouradeep Chakrabarti
596cf00ef8SSouradeep Chakrabarti void
hv_get_vpreg_128(u32 msr,struct hv_get_vp_registers_output * result)606cf00ef8SSouradeep Chakrabarti hv_get_vpreg_128(u32 msr, struct hv_get_vp_registers_output *result)
616cf00ef8SSouradeep Chakrabarti {
626cf00ef8SSouradeep Chakrabarti struct arm_smccc_1_2_regs args;
636cf00ef8SSouradeep Chakrabarti struct arm_smccc_1_2_regs res;
646cf00ef8SSouradeep Chakrabarti
656cf00ef8SSouradeep Chakrabarti args.a0 = HV_FUNC_ID;
666cf00ef8SSouradeep Chakrabarti args.a1 = HVCALL_GET_VP_REGISTERS | HV_HYPERCALL_FAST_BIT |
676cf00ef8SSouradeep Chakrabarti HV_HYPERCALL_REP_COMP_1;
686cf00ef8SSouradeep Chakrabarti args.a2 = HV_PARTITION_ID_SELF;
696cf00ef8SSouradeep Chakrabarti args.a3 = HV_VP_INDEX_SELF;
706cf00ef8SSouradeep Chakrabarti args.a4 = msr;
716cf00ef8SSouradeep Chakrabarti
726cf00ef8SSouradeep Chakrabarti /*
736cf00ef8SSouradeep Chakrabarti * Use the SMCCC 1.2 interface because the results are in registers
746cf00ef8SSouradeep Chakrabarti * beyond X0-X3.
756cf00ef8SSouradeep Chakrabarti */
766cf00ef8SSouradeep Chakrabarti arm_smccc_1_2_hvc(&args, &res);
776cf00ef8SSouradeep Chakrabarti
786cf00ef8SSouradeep Chakrabarti result->as64.low = res.a6;
796cf00ef8SSouradeep Chakrabarti result->as64.high = res.a7;
806cf00ef8SSouradeep Chakrabarti }
816cf00ef8SSouradeep Chakrabarti
826cf00ef8SSouradeep Chakrabarti u64
arm_hv_get_vreg(u32 msr)836cf00ef8SSouradeep Chakrabarti arm_hv_get_vreg(u32 msr)
846cf00ef8SSouradeep Chakrabarti {
856cf00ef8SSouradeep Chakrabarti struct hv_get_vp_registers_output output;
866cf00ef8SSouradeep Chakrabarti
876cf00ef8SSouradeep Chakrabarti hv_get_vpreg_128(msr, &output);
886cf00ef8SSouradeep Chakrabarti
896cf00ef8SSouradeep Chakrabarti return (output.as64.low);
906cf00ef8SSouradeep Chakrabarti }
916cf00ef8SSouradeep Chakrabarti
926cf00ef8SSouradeep Chakrabarti uint64_t
hypercall_md(volatile void * hc_addr,uint64_t in_val,uint64_t in_paddr,uint64_t out_paddr)936cf00ef8SSouradeep Chakrabarti hypercall_md(volatile void *hc_addr, uint64_t in_val, uint64_t in_paddr,
946cf00ef8SSouradeep Chakrabarti uint64_t out_paddr)
956cf00ef8SSouradeep Chakrabarti {
966cf00ef8SSouradeep Chakrabarti struct arm_smccc_res res;
976cf00ef8SSouradeep Chakrabarti
98*b9cd72b0SAndrew Turner arm_smccc_invoke_hvc(HV_FUNC_ID, in_val, in_paddr, out_paddr, &res);
996cf00ef8SSouradeep Chakrabarti
1006cf00ef8SSouradeep Chakrabarti return (res.a0);
1016cf00ef8SSouradeep Chakrabarti }
102