Source-Changes-HG archive

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

[src-draft/trunk]: src/sys/arch/arm/sunxi WIP: Snapshot of opencrypto support...



details:   https://anonhg.NetBSD.org/src-all/rev/53e5160f7e9d
branches:  trunk
changeset: 934079:53e5160f7e9d
user:      Taylor R Campbell <riastradh%NetBSD.org@localhost>
date:      Fri Jun 05 16:59:07 2020 +0000

description:
WIP: Snapshot of opencrypto support for Allwinner Crypto Engine.

XXX Missing:

- Dealing with IV before/after.
- Dealing with crd_skip and crd_inject.
- Figuring out AES-CTR size.

diffstat:

 sys/arch/arm/sunxi/sun8i_crypto.c |  840 ++++++++++++++++++++++++++++++++++++-
 1 files changed, 814 insertions(+), 26 deletions(-)

diffs (truncated from 1093 to 300 lines):

diff -r af34286b65e3 -r 53e5160f7e9d sys/arch/arm/sunxi/sun8i_crypto.c
--- a/sys/arch/arm/sunxi/sun8i_crypto.c Thu Jun 04 03:40:44 2020 +0000
+++ b/sys/arch/arm/sunxi/sun8i_crypto.c Fri Jun 05 16:59:07 2020 +0000
@@ -54,13 +54,17 @@
 #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,6 +114,9 @@
                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 {
@@ -159,8 +166,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 +203,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 +353,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 +428,9 @@
 
        /* Perform self-tests.  */
        config_interrupts(self, sun8i_crypto_selftest);
+
+       /* Register opencrypto handlers.  */
+       sun8i_crypto_register(sc);
 }
 
 static int
@@ -381,6 +485,7 @@
                goto fail7;
 
        /* Success!  */
+       SDT_PROBE1(sdt, sun8i_crypto, task, ctor__success,  task);
        return 0;
 
 fail8: __unused
@@ -392,7 +497,8 @@
 fail3: bus_dmamap_unload(sc->sc_dmat, task->ct_descmap);
 fail2: bus_dmamap_destroy(sc->sc_dmat, task->ct_descmap);
 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 +507,8 @@
        struct sun8i_crypto_softc *sc = cookie;
        struct sun8i_crypto_task *task = vtask;
 
+       SDT_PROBE1(sdt, sun8i_crypto, task, dtor,  task);
+
        /* XXX Zero the bounce buffers if there are any.  */
 
        bus_dmamap_destroy(sc->sc_dmat, task->ct_dstmap);
@@ -433,12 +541,14 @@
        /* Allocate a task, or fail if we can't.  */
        task = pool_cache_get(sc->sc_taskpool, pflags);
        if (task == NULL)
-               return NULL;
+               goto out;
 
        /* Set up flags and the callback.  */
        task->ct_flags = 0;
        task->ct_callback = callback;
        task->ct_cookie = cookie;
+
+out:   SDT_PROBE1(sdt, sun8i_crypto, task, get,  task);
        return task;
 }
 
@@ -467,6 +577,8 @@
     struct sun8i_crypto_task *task)
 {
 
+       SDT_PROBE1(sdt, sun8i_crypto, task, put,  task);
+
        task->ct_cookie = task->ct_callback;
        task->ct_callback = &sun8i_crypto_task_invalid;
        pool_cache_put(sc->sc_taskpool, task);
@@ -480,7 +592,6 @@
  *     sun8i_crypto_chan_done.  May fail if input is inadequately
  *     aligned.
  *
- *     XXX Teach this to fail gracefully if any alignment is wrong.
  *     XXX Teach this to support task chains.
  */
 static int
@@ -496,6 +607,9 @@
 
        memset(desc, 0, sizeof(*desc));
 
+       /* Always enable interrupt for the task.  */
+       tdqc |= SUN8I_CRYPTO_TDQC_INTR_EN;
+
        desc->td_tdqc = htole32(tdqc);
        desc->td_tdqs = htole32(tdqs);
        desc->td_tdqa = htole32(tdqa);
@@ -530,7 +644,7 @@
        if (task->ct_flags & TASK_SRC) {
                bus_dmamap_t srcmap = task->ct_srcmap;
                KASSERT(srcmap->dm_mapsize == task->ct_dstmap->dm_mapsize);
-               error = sun8i_crypto_task_scatter(desc->td_src, srcmap,
+               error = sun8i_crypto_task_scatter(task, desc->td_src, srcmap,
                    nbytes);
                if (error)
                        return error;
@@ -538,36 +652,52 @@
                    BUS_DMASYNC_PREWRITE);
        }
 
-       error = sun8i_crypto_task_scatter(desc->td_dst, task->ct_dstmap,
+       error = sun8i_crypto_task_scatter(task, desc->td_dst, task->ct_dstmap,
            nbytes);
        if (error)
-               return error;
+               goto out;
        bus_dmamap_sync(sc->sc_dmat, task->ct_dstmap, 0, nbytes,
            BUS_DMASYNC_PREREAD);
 
        task->ct_nbytes = nbytes;
 
        /* Success!  */
-       return 0;
+       error = 0;
+
+out:   SDT_PROBE6(sdt, sun8i_crypto, task, load,
+           task, tdqc, tdqs, tdqa, desc, error);
+       return error;
 }
 
 /*
- * sun8i_crypto_task_scatter(adrlen, map, nbytes)
+ * sun8i_crypto_task_scatter(task, adrlen, map, nbytes)
  *
  *     Set up a task's scatter/gather vector -- src or dst -- with the
  *     given DMA map for a transfer of nbytes.  May fail if input is
  *     inadequately aligned.
  */
 static int
-sun8i_crypto_task_scatter(struct sun8i_crypto_adrlen *adrlen, bus_dmamap_t map,
+sun8i_crypto_task_scatter(struct sun8i_crypto_task *task,
+    struct sun8i_crypto_adrlen *adrlen, bus_dmamap_t map,
     uint32_t nbytes __diagused)
 {
        uint32_t total __diagused = 0;
        unsigned i;
 
+       /*
+        * Verify that the alignment is correct and initialize the
+        * scatter/gather vector.
+        */



Home | Main Index | Thread Index | Old Index