Module Name:    src
Committed By:   jmcneill
Date:           Sat Aug  7 21:21:49 UTC 2021

Modified Files:
        src/sys/arch/arm/arm: smccc.c smccc.h

Log Message:
arm: SMCCC: Add return values to smccc_call


To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/arm/smccc.c \
    src/sys/arch/arm/arm/smccc.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/arm/smccc.c
diff -u src/sys/arch/arm/arm/smccc.c:1.1 src/sys/arch/arm/arm/smccc.c:1.2
--- src/sys/arch/arm/arm/smccc.c:1.1	Fri Aug  6 19:38:53 2021
+++ src/sys/arch/arm/arm/smccc.c	Sat Aug  7 21:21:49 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: smccc.c,v 1.1 2021/08/06 19:38:53 jmcneill Exp $ */
+/* $NetBSD: smccc.c,v 1.2 2021/08/07 21:21:49 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2021 Jared McNeill <jmcne...@invisible.ca>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: smccc.c,v 1.1 2021/08/06 19:38:53 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: smccc.c,v 1.2 2021/08/07 21:21:49 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -42,7 +42,10 @@ __KERNEL_RCSID(0, "$NetBSD: smccc.c,v 1.
 #define	SMCCC_VERSION		0x80000000
 
 /* True if SMCCC is detected. */
-static bool	smccc_present;
+static bool			smccc_present;
+
+/* SMCCC conduit (SMC or HVC) */
+static enum psci_conduit	smccc_conduit = PSCI_CONDUIT_NONE;
 
 /*
  * smccc_probe --
@@ -58,6 +61,13 @@ smccc_probe(void)
 		}
 
 		smccc_present = psci_features(SMCCC_VERSION) == PSCI_SUCCESS;
+		if (smccc_present) {
+			smccc_conduit = psci_conduit();
+
+			aprint_debug("SMCCC: Version %#x (%s)\n",
+			    smccc_version(),
+			    smccc_conduit == PSCI_CONDUIT_SMC ? "SMC" : "HVC");
+		}
 	}
 	return smccc_present;
 }
@@ -70,7 +80,8 @@ smccc_probe(void)
 int
 smccc_version(void)
 {
-	return smccc_call(SMCCC_VERSION, 0, 0, 0);
+	return smccc_call(SMCCC_VERSION, 0, 0, 0, 0,
+			  NULL, NULL, NULL, NULL);
 }
 
 /*
@@ -79,11 +90,54 @@ smccc_version(void)
  *	Generic call interface for SMC/HVC calls.
  */
 int
-smccc_call(register_t fid, register_t arg1, register_t arg2, register_t arg3)
+smccc_call(uint32_t fid,
+    register_t arg1, register_t arg2, register_t arg3, register_t arg4,
+    register_t *res0, register_t *res1, register_t *res2, register_t *res3)
 {
+	register_t args[5] = { fid, arg1, arg2, arg3, arg4 };
+
+	register register_t r0 asm ("r0");
+	register register_t r1 asm ("r1");
+	register register_t r2 asm ("r2");
+	register register_t r3 asm ("r3");
+	register register_t r4 asm ("r4");
+
 	if (!smccc_present) {
 		return SMCCC_NOT_SUPPORTED;
 	}
 
-	return psci_call(fid, arg1, arg2, arg3);
+	KASSERT(smccc_conduit != PSCI_CONDUIT_NONE);
+
+	r0 = args[0];
+	r1 = args[1];
+	r2 = args[2];
+	r3 = args[3];
+	r4 = args[4];
+
+	if (smccc_conduit == PSCI_CONDUIT_SMC) {
+		asm volatile ("smc #0" :
+			      "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3) :
+			      "r" (r0), "r" (r1), "r" (r2), "r" (r3), "r" (r4) :
+			      "memory");
+	} else {
+		asm volatile ("hvc #0" :
+			      "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3) :
+			      "r" (r0), "r" (r1), "r" (r2), "r" (r3), "r" (r4) :
+			      "memory");
+	}
+	
+	if (res0) {
+		*res0 = r0;
+	}
+	if (res1) {
+		*res1 = r1;
+	}
+	if (res2) {
+		*res2 = r2;
+	}
+	if (res3) {
+		*res3 = r3;
+	}
+
+	return r0;
 }
Index: src/sys/arch/arm/arm/smccc.h
diff -u src/sys/arch/arm/arm/smccc.h:1.1 src/sys/arch/arm/arm/smccc.h:1.2
--- src/sys/arch/arm/arm/smccc.h:1.1	Fri Aug  6 19:38:53 2021
+++ src/sys/arch/arm/arm/smccc.h	Sat Aug  7 21:21:49 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: smccc.h,v 1.1 2021/08/06 19:38:53 jmcneill Exp $ */
+/* $NetBSD: smccc.h,v 1.2 2021/08/07 21:21:49 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2021 Jared McNeill <jmcne...@invisible.ca>
@@ -50,6 +50,7 @@ int	smccc_version(void);
 /*
  * Call an SMC/HVC service.
  */
-int	smccc_call(register_t, register_t, register_t, register_t);
+int	smccc_call(uint32_t, register_t, register_t, register_t, register_t,
+		   register_t *, register_t *, register_t *, register_t *);
 
 #endif /* _ARM_SMCCC_H */

Reply via email to