Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/arm/sunxi Draft opencrypto support for Allwinner Cr...



details:   https://anonhg.NetBSD.org/src/rev/0aec2813db69
branches:  trunk
changeset: 972918:0aec2813db69
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Sat Jun 13 18:58:26 2020 +0000

description:
Draft opencrypto support for Allwinner Crypto Engine.

XXX Can't handle nonzero crd_skip yet.

diffstat:

 sys/arch/arm/sunxi/sun8i_crypto.c |  976 ++++++++++++++++++++++++++++++++++++-
 1 files changed, 930 insertions(+), 46 deletions(-)

diffs (truncated from 1298 to 300 lines):

diff -r eaeba3fd3536 -r 0aec2813db69 sys/arch/arm/sunxi/sun8i_crypto.c
--- a/sys/arch/arm/sunxi/sun8i_crypto.c Sat Jun 13 18:57:54 2020 +0000
+++ b/sys/arch/arm/sunxi/sun8i_crypto.c Sat Jun 13 18:58:26 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sun8i_crypto.c,v 1.16 2020/06/13 18:57:54 riastradh Exp $      */
+/*     $NetBSD: sun8i_crypto.c,v 1.17 2020/06/13 18:58:26 riastradh Exp $      */
 
 /*-
  * Copyright (c) 2019 The NetBSD Foundation, Inc.
@@ -43,7 +43,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: sun8i_crypto.c,v 1.16 2020/06/13 18:57:54 riastradh Exp $");
+__KERNEL_RCSID(1, "$NetBSD: sun8i_crypto.c,v 1.17 2020/06/13 18:58:26 riastradh Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -51,16 +51,21 @@
 #include <sys/bus.h>
 #include <sys/callout.h>
 #include <sys/conf.h>
+#include <sys/cprng.h>
 #include <sys/device.h>
 #include <sys/kernel.h>
 #include <sys/kmem.h>
+#include <sys/mbuf.h>
 #include <sys/mutex.h>
 #include <sys/rndsource.h>
+#include <sys/sdt.h>
 #include <sys/sysctl.h>
 #include <sys/workqueue.h>
 
 #include <dev/fdt/fdtvar.h>
 
+#include <opencrypto/cryptodev.h>
+
 #include <arm/sunxi/sun8i_crypto.h>
 
 #define        SUN8I_CRYPTO_TIMEOUT    hz
@@ -110,15 +115,22 @@
                const struct sysctlnode         *cy_root_node;
                const struct sysctlnode         *cy_trng_node;
        }                               sc_sysctl;
+       struct sun8i_crypto_opencrypto {
+               uint32_t                        co_driverid;
+       }                               sc_opencrypto;
 };
 
 struct sun8i_crypto_task {
        struct sun8i_crypto_buf ct_descbuf;
        struct sun8i_crypto_taskdesc *ct_desc;
+       struct sun8i_crypto_buf ct_ivbuf;
+       void                    *ct_iv;
+       struct sun8i_crypto_buf ct_ctrbuf;
+       void                    *ct_ctr;
        bus_dmamap_t            ct_descmap;
        bus_dmamap_t            ct_keymap;
-       bus_dmamap_t            ct_ivmap;
-       bus_dmamap_t            ct_ctrmap;
+       bus_dmamap_t            ct_ivmap;       /* IV input */
+       bus_dmamap_t            ct_ctrmap;      /* updated IV output */
        bus_dmamap_t            ct_srcmap;
        bus_dmamap_t            ct_dstmap;
        uint32_t                ct_nbytes;
@@ -159,8 +171,8 @@
 static int     sun8i_crypto_task_load(struct sun8i_crypto_softc *,
                    struct sun8i_crypto_task *, uint32_t,
                    uint32_t, uint32_t, uint32_t);
-static int     sun8i_crypto_task_scatter(struct sun8i_crypto_adrlen *,
-                   bus_dmamap_t, uint32_t);
+static int     sun8i_crypto_task_scatter(struct sun8i_crypto_task *,
+                   struct sun8i_crypto_adrlen *, bus_dmamap_t, uint32_t);
 
 static int     sun8i_crypto_task_load_trng(struct sun8i_crypto_softc *,
                    struct sun8i_crypto_task *, uint32_t);
@@ -196,19 +208,106 @@
 static void    sun8i_crypto_sysctl_rng_done(struct sun8i_crypto_softc *,
                    struct sun8i_crypto_task *, void *, int);
 
+static void    sun8i_crypto_register(struct sun8i_crypto_softc *);
+static void    sun8i_crypto_register1(struct sun8i_crypto_softc *, uint32_t);
+static int     sun8i_crypto_newsession(void *, uint32_t *,
+                   struct cryptoini *);
+static int     sun8i_crypto_freesession(void *, uint64_t);
+static u_int   sun8i_crypto_ivlen(const struct cryptodesc *);
+static int     sun8i_crypto_process(void *, struct cryptop *, int);
+static void    sun8i_crypto_callback(struct sun8i_crypto_softc *,
+                   struct sun8i_crypto_task *, void *, int);
+
+/*
+ * Probes
+ */
+
+SDT_PROBE_DEFINE2(sdt, sun8i_crypto, register, read,
+    "bus_size_t"/*reg*/,
+    "uint32_t"/*value*/);
+SDT_PROBE_DEFINE2(sdt, sun8i_crypto, register, write,
+    "bus_size_t"/*reg*/,
+    "uint32_t"/*write*/);
+
+SDT_PROBE_DEFINE1(sdt, sun8i_crypto, task, ctor__success,
+    "struct sun8i_crypto_task *"/*task*/);
+SDT_PROBE_DEFINE1(sdt, sun8i_crypto, task, ctor__failure,
+    "int"/*error*/);
+SDT_PROBE_DEFINE1(sdt, sun8i_crypto, task, dtor,
+    "struct sun8i_crypto_task *"/*task*/);
+SDT_PROBE_DEFINE1(sdt, sun8i_crypto, task, get,
+    "struct sun8i_crypto_task *"/*task*/);
+SDT_PROBE_DEFINE1(sdt, sun8i_crypto, task, put,
+    "struct sun8i_crypto_task *"/*task*/);
+
+SDT_PROBE_DEFINE6(sdt, sun8i_crypto, task, load,
+    "struct sun8i_crypto_task *"/*task*/,
+    "uint32_t"/*tdqc*/,
+    "uint32_t"/*tdqs*/,
+    "uint32_t"/*tdqa*/,
+    "struct sun8i_crypto_taskdesc *"/*desc*/,
+    "int"/*error*/);
+SDT_PROBE_DEFINE3(sdt, sun8i_crypto, task, misaligned,
+    "struct sun8i_crypto_task *"/*task*/,
+    "bus_addr_t"/*ds_addr*/,
+    "bus_size_t"/*ds_len*/);
+SDT_PROBE_DEFINE2(sdt, sun8i_crypto, task, done,
+    "struct sun8i_crypto_task *"/*task*/,
+    "int"/*error*/);
+
+SDT_PROBE_DEFINE3(sdt, sun8i_crypto, engine, submit__failure,
+    "struct sun8i_crypto_softc *"/*sc*/,
+    "struct sun8i_crypto_task *"/*task*/,
+    "int"/*error*/);
+SDT_PROBE_DEFINE3(sdt, sun8i_crypto, engine, submit__success,
+    "struct sun8i_crypto_softc *"/*sc*/,
+    "struct sun8i_crypto_task *"/*task*/,
+    "unsigned"/*chan*/);
+SDT_PROBE_DEFINE3(sdt, sun8i_crypto, engine, intr,
+    "struct sun8i_crypto_softc *"/*sc*/,
+    "uint32_t"/*isr*/,
+    "uint32_t"/*esr*/);
+SDT_PROBE_DEFINE3(sdt, sun8i_crypto, engine, done,
+    "struct sun8i_crypto_softc *"/*sc*/,
+    "unsigned"/*chan*/,
+    "int"/*error*/);
+
+SDT_PROBE_DEFINE3(sdt, sun8i_crypto, process, entry,
+    "struct sun8i_crypto_softc *"/*sc*/,
+    "struct cryptop *"/*crp*/,
+    "int"/*hint*/);
+SDT_PROBE_DEFINE3(sdt, sun8i_crypto, process, busy,
+    "struct sun8i_crypto_softc *"/*sc*/,
+    "struct cryptop *"/*crp*/,
+    "int"/*hint*/);
+SDT_PROBE_DEFINE4(sdt, sun8i_crypto, process, queued,
+    "struct sun8i_crypto_softc *"/*sc*/,
+    "struct cryptop *"/*crp*/,
+    "int"/*hint*/,
+    "struct sun8i_crypto_task *"/*task*/);
+SDT_PROBE_DEFINE3(sdt, sun8i_crypto, process, done,
+    "struct sun8i_crypto_softc *"/*sc*/,
+    "struct cryptop *"/*crp*/,
+    "int"/*error*/);
+
 /*
  * Register access
  */
 
 static uint32_t
-sun8i_crypto_read(struct sun8i_crypto_softc *sc, bus_addr_t reg)
+sun8i_crypto_read(struct sun8i_crypto_softc *sc, bus_size_t reg)
 {
-       return bus_space_read_4(sc->sc_bst, sc->sc_bsh, reg);
+       uint32_t v = bus_space_read_4(sc->sc_bst, sc->sc_bsh, reg);
+
+       SDT_PROBE2(sdt, sun8i_crypto, register, read,  reg, v);
+       return v;
 }
 
 static void
-sun8i_crypto_write(struct sun8i_crypto_softc *sc, bus_addr_t reg, uint32_t v)
+sun8i_crypto_write(struct sun8i_crypto_softc *sc, bus_size_t reg, uint32_t v)
 {
+
+       SDT_PROBE2(sdt, sun8i_crypto, register, write,  reg, v);
        bus_space_write_4(sc->sc_bst, sc->sc_bsh, reg, v);
 }
 
@@ -259,6 +358,13 @@
                return;
        }
 
+       /*
+        * Prime the pool with enough tasks that each channel can be
+        * busy with a task as we prepare another task for when it's
+        * done.
+        */
+       pool_cache_prime(sc->sc_taskpool, 2*SUN8I_CRYPTO_NCHAN);
+
        /* Get and map device registers.  */
        if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
                aprint_error(": couldn't get registers\n");
@@ -327,6 +433,9 @@
 
        /* Perform self-tests.  */
        config_interrupts(self, sun8i_crypto_selftest);
+
+       /* Register opencrypto handlers.  */
+       sun8i_crypto_register(sc);
 }
 
 static int
@@ -344,55 +453,71 @@
                goto fail0;
        task->ct_desc = task->ct_descbuf.cb_kva;
 
+       /* Create DMA buffers for the IV and CTR.  */
+       error = sun8i_crypto_allocbuf(sc, SUN8I_CRYPTO_MAXIVBYTES,
+           &task->ct_ivbuf, dmaflags);
+       if (error)
+               goto fail1;
+       task->ct_iv = task->ct_ivbuf.cb_kva;
+       error = sun8i_crypto_allocbuf(sc, SUN8I_CRYPTO_MAXCTRBYTES,
+           &task->ct_ctrbuf, dmaflags);
+       if (error)
+               goto fail2;
+       task->ct_ctr = task->ct_ctrbuf.cb_kva;
+
        /* Create a DMA map for the task descriptor and preload it.  */
        error = bus_dmamap_create(sc->sc_dmat, sizeof(*task->ct_desc), 1,
            sizeof(*task->ct_desc), 0, dmaflags, &task->ct_descmap);
        if (error)
-               goto fail1;
+               goto fail3;
        error = bus_dmamap_load(sc->sc_dmat, task->ct_descmap, task->ct_desc,
            sizeof(*task->ct_desc), NULL, BUS_DMA_WAITOK);
        if (error)
-               goto fail2;
+               goto fail4;
 
        /* Create DMA maps for the key, IV, and CTR.  */
        error = bus_dmamap_create(sc->sc_dmat, SUN8I_CRYPTO_MAXKEYBYTES, 1,
            SUN8I_CRYPTO_MAXKEYBYTES, 0, dmaflags, &task->ct_keymap);
        if (error)
-               goto fail3;
+               goto fail5;
        error = bus_dmamap_create(sc->sc_dmat, SUN8I_CRYPTO_MAXIVBYTES, 1,
            SUN8I_CRYPTO_MAXIVBYTES, 0, dmaflags, &task->ct_ivmap);
        if (error)
-               goto fail4;
+               goto fail6;
        error = bus_dmamap_create(sc->sc_dmat, SUN8I_CRYPTO_MAXCTRBYTES, 1,
            SUN8I_CRYPTO_MAXCTRBYTES, 0, dmaflags, &task->ct_ctrmap);
        if (error)
-               goto fail5;
+               goto fail7;
 
        /* Create DMA maps for the src and dst scatter/gather vectors.  */
        error = bus_dmamap_create(sc->sc_dmat, SUN8I_CRYPTO_MAXDMASIZE,
            SUN8I_CRYPTO_MAXSEGS, SUN8I_CRYPTO_MAXDMASEGSIZE, 0, dmaflags,
            &task->ct_srcmap);
        if (error)
-               goto fail6;
+               goto fail8;
        error = bus_dmamap_create(sc->sc_dmat, SUN8I_CRYPTO_MAXDMASIZE,
            SUN8I_CRYPTO_MAXSEGS, SUN8I_CRYPTO_MAXDMASEGSIZE, 0, dmaflags,
            &task->ct_dstmap);
        if (error)
-               goto fail7;
+               goto fail9;
 
        /* Success!  */
+       SDT_PROBE1(sdt, sun8i_crypto, task, ctor__success,  task);
        return 0;
 
-fail8: __unused
+fail10: __unused
        bus_dmamap_destroy(sc->sc_dmat, task->ct_dstmap);
-fail7: bus_dmamap_destroy(sc->sc_dmat, task->ct_srcmap);
-fail6: bus_dmamap_destroy(sc->sc_dmat, task->ct_ctrmap);
-fail5: bus_dmamap_destroy(sc->sc_dmat, task->ct_ivmap);
-fail4: bus_dmamap_destroy(sc->sc_dmat, task->ct_keymap);
-fail3: bus_dmamap_unload(sc->sc_dmat, task->ct_descmap);
-fail2: bus_dmamap_destroy(sc->sc_dmat, task->ct_descmap);
+fail9: bus_dmamap_destroy(sc->sc_dmat, task->ct_srcmap);
+fail8: bus_dmamap_destroy(sc->sc_dmat, task->ct_ctrmap);
+fail7: bus_dmamap_destroy(sc->sc_dmat, task->ct_ivmap);
+fail6: bus_dmamap_destroy(sc->sc_dmat, task->ct_keymap);
+fail5: bus_dmamap_unload(sc->sc_dmat, task->ct_descmap);
+fail4: bus_dmamap_destroy(sc->sc_dmat, task->ct_descmap);
+fail3: sun8i_crypto_freebuf(sc, SUN8I_CRYPTO_MAXIVBYTES, &task->ct_ivbuf);
+fail2: sun8i_crypto_freebuf(sc, SUN8I_CRYPTO_MAXCTRBYTES, &task->ct_ctrbuf);
 fail1: sun8i_crypto_freebuf(sc, sizeof(*task->ct_desc), &task->ct_descbuf);
-fail0: return error;
+fail0: SDT_PROBE1(sdt, sun8i_crypto, task, ctor__failure,  error);
+       return error;
 }
 
 static void
@@ -401,6 +526,8 @@
        struct sun8i_crypto_softc *sc = cookie;
        struct sun8i_crypto_task *task = vtask;



Home | Main Index | Thread Index | Old Index