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