Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/arm/arm arm: SMCCC: Add return values to smccc_call



details:   https://anonhg.NetBSD.org/src/rev/c28538fa5ccc
branches:  trunk
changeset: 1022795:c28538fa5ccc
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Sat Aug 07 21:21:49 2021 +0000

description:
arm: SMCCC: Add return values to smccc_call

diffstat:

 sys/arch/arm/arm/smccc.c |  66 +++++++++++++++++++++++++++++++++++++++++++----
 sys/arch/arm/arm/smccc.h |   5 ++-
 2 files changed, 63 insertions(+), 8 deletions(-)

diffs (129 lines):

diff -r a94461e01542 -r c28538fa5ccc sys/arch/arm/arm/smccc.c
--- a/sys/arch/arm/arm/smccc.c  Sat Aug 07 21:20:14 2021 +0000
+++ b/sys/arch/arm/arm/smccc.c  Sat Aug 07 21:21:49 2021 +0000
@@ -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 <jmcneill%invisible.ca@localhost>
@@ -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 @@
 #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_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 @@
 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 @@
  *     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;
 }
diff -r a94461e01542 -r c28538fa5ccc sys/arch/arm/arm/smccc.h
--- a/sys/arch/arm/arm/smccc.h  Sat Aug 07 21:20:14 2021 +0000
+++ b/sys/arch/arm/arm/smccc.h  Sat Aug 07 21:21:49 2021 +0000
@@ -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 <jmcneill%invisible.ca@localhost>
@@ -50,6 +50,7 @@
 /*
  * 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 */



Home | Main Index | Thread Index | Old Index