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 Draft opencrypto support for Allwin...
details: https://anonhg.NetBSD.org/src-all/rev/aee58f7d9683
branches: trunk
changeset: 934505:aee58f7d9683
user: Taylor R Campbell <riastradh%NetBSD.org@localhost>
date: Fri Jun 05 16:59:07 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 | 972 ++++++++++++++++++++++++++++++++++++-
1 files changed, 928 insertions(+), 44 deletions(-)
diffs (truncated from 1283 to 300 lines):
diff -r 5d5cc150dee4 -r aee58f7d9683 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
@@ -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;
+ 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);
@@ -410,6 +537,8 @@
bus_dmamap_destroy(sc->sc_dmat, task->ct_keymap);
bus_dmamap_unload(sc->sc_dmat, task->ct_descmap);
bus_dmamap_destroy(sc->sc_dmat, task->ct_descmap);
+ sun8i_crypto_freebuf(sc, SUN8I_CRYPTO_MAXIVBYTES, &task->ct_ivbuf);
+ sun8i_crypto_freebuf(sc, SUN8I_CRYPTO_MAXCTRBYTES, &task->ct_ctrbuf);
sun8i_crypto_freebuf(sc, sizeof(*task->ct_desc), &task->ct_descbuf);
}
Home |
Main Index |
Thread Index |
Old Index