xref: /freebsd/sys/dev/hyperv/vmbus/aarch64/hyperv_machdep.c (revision 4d846d260e2b9a3d4d0a701462568268cbfe7a5b)
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