Source-Changes-HG archive

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

[src-draft/trunk]: src/sys/arch Rockchip crypto engine RNG driver.



details:   https://anonhg.NetBSD.org/src-all/rev/e2c21b2e5ce5
branches:  trunk
changeset: 932825:e2c21b2e5ce5
user:      Taylor R Campbell <riastradh%NetBSD.org@localhost>
date:      Fri May 15 15:55:17 2020 +0000

description:
Rockchip crypto engine RNG driver.

As found on the rk3288 and rk3399.  This driver only supports the
TRNG, not the rest of the crypto engine.

There seem to be two versions of the Rockchip crypto engine, v1 and
v2; this one is for v1.  Can't name a driver `rkcryptov1' so we'll
clumsily call it `rk1crypto' instead to leave room for `rk2crypto'
later on.

diffstat:

 sys/arch/arm/dts/rk3399-pinebook-pro.dts |   13 +
 sys/arch/arm/dts/rk3399-rockpro64.dts    |   12 +
 sys/arch/arm/rockchip/files.rockchip     |    5 +
 sys/arch/arm/rockchip/rk3399_cru.c       |   21 ++
 sys/arch/arm/rockchip/rk_1crypto.c       |  321 +++++++++++++++++++++++++++++++
 sys/arch/arm/rockchip/rk_1crypto.h       |  178 +++++++++++++++++
 sys/arch/evbarm/conf/GENERIC64           |    1 +
 7 files changed, 551 insertions(+), 0 deletions(-)

diffs (truncated from 609 to 300 lines):

diff -r a6b6233cc24e -r e2c21b2e5ce5 sys/arch/arm/dts/rk3399-pinebook-pro.dts
--- a/sys/arch/arm/dts/rk3399-pinebook-pro.dts  Fri May 15 12:34:52 2020 +0000
+++ b/sys/arch/arm/dts/rk3399-pinebook-pro.dts  Fri May 15 15:55:17 2020 +0000
@@ -344,6 +344,19 @@
                compatible = "universal-charger";
                extcon = <&fusb0>;
        };
+
+       // XXX Sync with rk3399-rockpro64.dts.
+       crypto: crypto@ff8b8000 {
+               compatible = "rockchip,rk3288-crypto";
+               reg = <0x0 0xff8b8000 0x0 0x1000>;
+               clocks = <&cru HCLK_M_CRYPTO1>, <&cru HCLK_S_CRYPTO1>,
+                        <&cru SCLK_CRYPTO1>, <&cru ACLK_DMAC1_PERILP>;
+               clock-names = "aclk", "hclk", "sclk", "apb_pclk";
+               assigned-clocks = <&cru SCLK_CRYPTO1>, <&cru HCLK_S_CRYPTO1>;
+               assigned-clock-rates = <150000000>, <100000000>;
+               resets = <&cru SRST_CRYPTO1>;
+               reset-names = "crypto-rst";
+       };
 };
 
 &edp {
diff -r a6b6233cc24e -r e2c21b2e5ce5 sys/arch/arm/dts/rk3399-rockpro64.dts
--- a/sys/arch/arm/dts/rk3399-rockpro64.dts     Fri May 15 12:34:52 2020 +0000
+++ b/sys/arch/arm/dts/rk3399-rockpro64.dts     Fri May 15 15:55:17 2020 +0000
@@ -148,6 +148,18 @@
        };
 #endif
 
+       // XXX Sync with rk3399-rockpro64.dts.
+       crypto: crypto@ff8b8000 {
+               compatible = "rockchip,rk3288-crypto";
+               reg = <0x0 0xff8b8000 0x0 0x1000>;
+               clocks = <&cru HCLK_M_CRYPTO1>, <&cru HCLK_S_CRYPTO1>,
+                        <&cru SCLK_CRYPTO1>, <&cru ACLK_DMAC1_PERILP>;
+               clock-names = "aclk", "hclk", "sclk", "apb_pclk";
+               assigned-clocks = <&cru SCLK_CRYPTO1>, <&cru HCLK_S_CRYPTO1>;
+               assigned-clock-rates = <150000000>, <100000000>;
+               resets = <&cru SRST_CRYPTO1>;
+               reset-names = "crypto-rst";
+       };
 };
 
 &pinctrl {
diff -r a6b6233cc24e -r e2c21b2e5ce5 sys/arch/arm/rockchip/files.rockchip
--- a/sys/arch/arm/rockchip/files.rockchip      Fri May 15 12:34:52 2020 +0000
+++ b/sys/arch/arm/rockchip/files.rockchip      Fri May 15 15:55:17 2020 +0000
@@ -112,6 +112,11 @@
 attach  rki2s at fdt with rk_i2s
 file    arch/arm/rockchip/rk_i2s.c             rk_i2s
 
+# Crypto engine
+device rk1crypto
+attach rk1crypto at fdt with rk_1crypto
+file   arch/arm/rockchip/rk_1crypto.c          rk_1crypto
+
 # SOC parameters
 defflag        opt_soc.h                       SOC_ROCKCHIP
 defflag        opt_soc.h                       SOC_RK3328: SOC_ROCKCHIP
diff -r a6b6233cc24e -r e2c21b2e5ce5 sys/arch/arm/rockchip/rk3399_cru.c
--- a/sys/arch/arm/rockchip/rk3399_cru.c        Fri May 15 12:34:52 2020 +0000
+++ b/sys/arch/arm/rockchip/rk3399_cru.c        Fri May 15 15:55:17 2020 +0000
@@ -847,6 +847,27 @@
                     0),
        RK_MUX(RK3399_SCLK_PCIE_CORE, "clk_pcie_core", mux_pciecore_cru_phy_parents, CLKSEL_CON(18), __BIT(7)),
 
+       /* Crypto */
+       RK_COMPOSITE(RK3399_SCLK_CRYPTO0, "clk_crypto0", mux_pll_src_cpll_gpll_ppll_parents,
+                    CLKSEL_CON(24),    /* muxdiv_reg */
+                    __BITS(7,6),       /* mux_mask */
+                    __BITS(4,0),       /* div_mask */
+                    CLKGATE_CON(7),    /* gate_reg */
+                    __BIT(7),          /* gate_mask */
+                    RK_COMPOSITE_ROUND_DOWN /*???*/),
+       RK_COMPOSITE(RK3399_SCLK_CRYPTO1, "clk_crypto1", mux_pll_src_cpll_gpll_ppll_parents,
+                    CLKSEL_CON(26),    /* muxdiv_reg */
+                    __BITS(7,6),       /* mux_mask */
+                    __BITS(4,0),       /* div_mask */
+                    CLKGATE_CON(8),    /* gate_reg */
+                    __BIT(7),          /* gate_mask */
+                    RK_COMPOSITE_ROUND_DOWN /*???*/),
+       RK_GATE(RK3399_HCLK_M_CRYPTO0, "hclk_m_crypto0", "pclk_perilp0", CLKGATE_CON(24), 5),
+       RK_GATE(RK3399_HCLK_S_CRYPTO0, "hclk_s_crypto0", "pclk_perilp0", CLKGATE_CON(24), 6),
+       RK_GATE(RK3399_HCLK_M_CRYPTO1, "hclk_m_crypto1", "pclk_perilp0", CLKGATE_CON(24), 14),
+       RK_GATE(RK3399_HCLK_S_CRYPTO1, "hclk_s_crypto1", "pclk_perilp0", CLKGATE_CON(24), 15),
+       RK_GATE(RK3399_ACLK_DMAC1_PERILP, "aclk_dmac1_perilp", "pclk_perilp", CLKGATE_CON(25), 6),
+
        /* TSADC */
        RK_COMPOSITE(RK3399_SCLK_TSADC, "clk_tsadc", mux_clk_tsadc_parents,
                     CLKSEL_CON(27),    /* muxdiv_reg */
diff -r a6b6233cc24e -r e2c21b2e5ce5 sys/arch/arm/rockchip/rk_1crypto.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/arm/rockchip/rk_1crypto.c        Fri May 15 15:55:17 2020 +0000
@@ -0,0 +1,321 @@
+/*     $NetBSD$        */
+
+/*-
+ * Copyright (c) 2020 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Taylor R. Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * rk_1crypto -- Rockchip crypto v1 driver
+ *
+ * This is just the RNG for now.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(1, "$NetBSD$");
+
+#include <sys/types.h>
+
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/errno.h>
+#include <sys/mutex.h>
+#include <sys/rndsource.h>
+#include <sys/sysctl.h>
+
+#include <dev/fdt/fdtvar.h>
+
+#include <arm/rockchip/rk_1crypto.h>
+
+struct rk_1crypto_softc {
+       device_t                        sc_dev;
+       bus_space_tag_t                 sc_bst;
+       bus_space_handle_t              sc_bsh;
+       kmutex_t                        sc_lock;
+       struct krndsource               sc_rndsource;
+       struct rk_1crypto_sysctl {
+               struct sysctllog                *cy_log;
+               const struct sysctlnode         *cy_root_node;
+       }                               sc_sysctl;
+};
+
+static int rk_1crypto_match(device_t, cfdata_t, void *);
+static void rk_1crypto_attach(device_t, device_t, void *);
+static void rk_1crypto_rndsource_attach(struct rk_1crypto_softc *);
+static void rk_1crypto_rng_get(size_t, void *);
+static void rk_1crypto_sysctl_attach(struct rk_1crypto_softc *);
+static int rk_1crypto_sysctl_rng(SYSCTLFN_ARGS);
+static int rk_1crypto_rng(struct rk_1crypto_softc *,
+    uint32_t[static RK_1CRYPTO_TRNG_NOUT]);
+
+static uint32_t
+RKC_READ(struct rk_1crypto_softc *sc, bus_addr_t reg)
+{
+       return bus_space_read_4(sc->sc_bst, sc->sc_bsh, reg);
+}
+
+static void
+RKC_WRITE(struct rk_1crypto_softc *sc, bus_addr_t reg, uint32_t v)
+{
+       return bus_space_write_4(sc->sc_bst, sc->sc_bsh, reg, v);
+}
+
+static inline void
+RKC_CTRL(struct rk_1crypto_softc *sc, uint16_t m, uint16_t v)
+{
+       uint32_t c = 0;
+
+       c |= __SHIFTIN(m, RK_1CRYPTO_CTRL_MASK);
+       c |= __SHIFTIN(v, m);
+       RKC_WRITE(sc, RK_1CRYPTO_CTRL, c);
+}
+
+CFATTACH_DECL_NEW(rk_1crypto, sizeof(struct rk_1crypto_softc),
+    rk_1crypto_match, rk_1crypto_attach, NULL, NULL);
+
+static const struct of_compat_data compat_data[] = {
+       {"rockchip,rk3288-crypto", 0},
+       {NULL}
+};
+
+static int
+rk_1crypto_match(device_t parent, cfdata_t cf, void *aux)
+{
+       const struct fdt_attach_args *const faa = aux;
+
+       return of_match_compat_data(faa->faa_phandle, compat_data);
+}
+
+static void
+rk_1crypto_attach(device_t parent, device_t self, void *aux)
+{
+       static const char *const clks[] = {"aclk", "hclk", "sclk", "apb_pclk"};
+       struct rk_1crypto_softc *const sc = device_private(self);
+       const struct fdt_attach_args *const faa = aux;
+       bus_addr_t addr;
+       bus_size_t size;
+       const int phandle = faa->faa_phandle;
+       struct fdtbus_reset *rst;
+       unsigned i;
+       uint32_t ctrl;
+
+       fdtbus_clock_assign(phandle);
+
+       sc->sc_dev = self;
+       sc->sc_bst = faa->faa_bst;
+       mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM);
+
+       /* Get and map device registers.  */
+       if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
+               aprint_error(": couldn't get registers\n");
+               return;
+       }
+       if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
+               aprint_error(": couldn't map registers\n");
+               return;
+       }
+
+       /* Enable the clocks.  */
+       for (i = 0; i < __arraycount(clks); i++) {
+               if (fdtbus_clock_enable(phandle, clks[i], true) != 0) {
+                       aprint_error(": couldn't enable %s clock\n", clks[i]);
+                       return;
+               }
+       }
+
+       /* Get a reset handle if we need and try to deassert it.  */
+       if ((rst = fdtbus_reset_get_index(phandle, 0)) != NULL) {
+               if (fdtbus_reset_deassert(rst) != 0) {
+                       aprint_error(": couldn't de-assert reset\n");
+                       return;
+               }
+       }
+
+       aprint_naive("\n");
+       aprint_normal(": Crypto v1\n");
+
+       /*
+        * Enable ring oscillator to start gathering entropy, and set
+        * up the crypto clock to sample it once every 100 cycles.
+        *
+        * The ring oscillator can run even when the clock is gated or
+        * flush is asserted, and the longer we run it, the less it
+        * will be synchronized with the main clock owing to jitter
+        * ideally from unpredictable thermal noise.
+        */
+       ctrl = RK_1CRYPTO_TRNG_CTRL_OSC_ENABLE;
+       ctrl |= __SHIFTIN(100, RK_1CRYPTO_TRNG_CTRL_CYCLES);
+       RKC_WRITE(sc, RK_1CRYPTO_TRNG_CTRL, ctrl);
+
+       rk_1crypto_rndsource_attach(sc);
+       rk_1crypto_sysctl_attach(sc);
+}
+
+static void
+rk_1crypto_rndsource_attach(struct rk_1crypto_softc *sc)
+{
+       device_t self = sc->sc_dev;
+
+       rndsource_setcb(&sc->sc_rndsource, rk_1crypto_rng_get, sc);
+       rnd_attach_source(&sc->sc_rndsource, device_xname(self),
+           RND_TYPE_RNG, RND_FLAG_DEFAULT|RND_FLAG_HASCB);
+}
+
+static void
+rk_1crypto_rng_get(size_t nbytes, void *cookie)
+{
+       struct rk_1crypto_softc *sc = cookie;
+       device_t self = sc->sc_dev;
+       uint32_t buf[RK_1CRYPTO_TRNG_NOUT];
+       uint32_t entropybits = NBBY*sizeof(buf)/2; /* be conservative */
+       unsigned n = RK_1CRYPTO_TRNG_NOUT;
+       int error;
+       size_t nbits = NBBY*nbytes;
+
+       while (nbits) {
+               CTASSERT((RK_1CRYPTO_TRNG_NOUT % 2) == 0);
+
+               error = rk_1crypto_rng(sc, buf);
+               if (error) {
+                       device_printf(self, "timed out\n");
+                       break;



Home | Main Index | Thread Index | Old Index