Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F147387590
D7876.1783170451.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
13 KB
Referenced Files
None
Subscribers
None
D7876.1783170451.diff
View Options
Index: sys/arm/allwinner/a10_crypto.h
===================================================================
--- sys/arm/allwinner/a10_crypto.h
+++ sys/arm/allwinner/a10_crypto.h
@@ -0,0 +1,135 @@
+/*-
+ * Copyright (c) 2016 Ganbold Tsagaankhuu <ganbold@freebsd.org>
+ * All rights reserved.
+ *
+ * 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 AUTHOR 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 AUTHOR 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.
+ */
+
+#ifndef A10_CRYPTO_H_
+#define A10_CRYPTO_H_
+
+#define A10_SS_CTL 0x00
+#define A10_SS_KEY0 0x04
+#define A10_SS_KEY1 0x08
+#define A10_SS_KEY2 0x0C
+#define A10_SS_KEY3 0x10
+#define A10_SS_KEY4 0x14
+#define A10_SS_KEY5 0x18
+#define A10_SS_KEY6 0x1C
+#define A10_SS_KEY7 0x20
+
+#define A10_SS_IV0 0x24
+#define A10_SS_IV1 0x28
+#define A10_SS_IV2 0x2C
+#define A10_SS_IV3 0x30
+
+#define A10_SS_FCSR 0x44
+
+#define A10_SS_MD0 0x4C
+#define A10_SS_MD1 0x50
+#define A10_SS_MD2 0x54
+#define A10_SS_MD3 0x58
+#define A10_SS_MD4 0x5C
+
+#define A10_SS_RXFIFO 0x200
+#define A10_SS_TXFIFO 0x204
+
+/* A10_SS_CTL values */
+
+/* PRNG generator mode - bit 15 */
+#define A10_SS_PRNG_ONESHOT (0 << 15)
+#define A10_SS_PRNG_CONTINUE (1 << 15)
+
+/* IV mode for hash */
+#define A10_SS_IV_ARBITRARY (1 << 14)
+
+/* SS operation mode - bits 12-13 */
+#define A10_SS_ECB (0 << 12)
+#define A10_SS_CBC (1 << 12)
+#define A10_SS_CTS (3 << 12)
+
+/* Counter width for CNT mode - bits 10-11 */
+#define A10_SS_CNT_16BITS (0 << 10)
+#define A10_SS_CNT_32BITS (1 << 10)
+#define A10_SS_CNT_64BITS (2 << 10)
+
+/* Key size for AES - bits 8-9 */
+#define A10_SS_AES_128BITS (0 << 8)
+#define A10_SS_AES_192BITS (1 << 8)
+#define A10_SS_AES_256BITS (2 << 8)
+
+/* Operation direction - bit 7 */
+#define A10_SS_ENCRYPTION (0 << 7)
+#define A10_SS_DECRYPTION (1 << 7)
+
+/* SS Method - bits 4-6 */
+#define A10_SS_OP_AES (0 << 4)
+#define A10_SS_OP_DES (1 << 4)
+#define A10_SS_OP_3DES (2 << 4)
+#define A10_SS_OP_SHA1 (3 << 4)
+#define A10_SS_OP_MD5 (4 << 4)
+#define A10_SS_OP_PRNG (5 << 4)
+
+/* Data end bit - bit 2 */
+#define A10_SS_DATA_END (1 << 2)
+
+/* PRNG start bit - bit 1 */
+#define A10_SS_PRNG_START (1 << 1)
+
+/* SS Enable bit - bit 0 */
+#define A10_SS_DISABLED (0 << 0)
+#define A10_SS_ENABLED (1 << 0)
+
+/* A10_SS_FCSR configuration values */
+/* RX FIFO status - bit 30 */
+#define A10_SS_RXFIFO_FREE (1 << 30)
+
+/* RX FIFO empty spaces - bits 24-29 */
+#define A10_SS_RXFIFO_SPACES(val) (((val) >> 24) & 0x3f)
+
+/* TX FIFO status - bit 22 */
+#define A10_SS_TXFIFO_AVAILABLE (1 << 22)
+
+/* TX FIFO available spaces - bits 16-21 */
+#define A10_SS_TXFIFO_SPACES(val) (((val) >> 16) & 0x3f)
+
+#define A10_SS_RX_MAX 32
+#define A10_SS_RX_DEFAULT A10_SS_RX_MAX
+#define A10_SS_TX_MAX 33
+
+#define A10_SS_RXFIFO_EMP_INT_PENDING (1 << 10)
+#define A10_SS_TXFIFO_AVA_INT_PENDING (1 << 8)
+#define A10_SS_RXFIFO_EMP_INT_ENABLE (1 << 2)
+#define A10_SS_TXFIFO_AVA_INT_ENABLE (1 << 0)
+
+#define A10_SS_SEED_LEN_BITS 192
+#define A10_SS_SEED_LEN (A10_SS_SEED_LEN_BITS / 8)
+
+#define A10_SS_DATA_LEN_BITS 160
+#define A10_SS_DATA_LEN (A10_SS_DATA_LEN_BITS / 8)
+
+#define A10_SS_FIFO_WORDS (A10_SS_SEED_LEN / sizeof(uint32_t))
+
+#define DIE_ID_START_BIT 16
+#define DIE_ID_MASK 0x07
+
+#endif
Index: sys/arm/allwinner/a10_crypto.c
===================================================================
--- sys/arm/allwinner/a10_crypto.c
+++ sys/arm/allwinner/a10_crypto.c
@@ -0,0 +1,268 @@
+/*-
+ * Copyright (c) 2016 Ganbold Tsagaankhuu <ganbold@freebsd.org>
+ * All rights reserved.
+ *
+ * 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 AUTHOR 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 AUTHOR 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.
+ */
+
+/*
+ * Allwinner A10/A20 Security System/Crypto accelerator
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/endian.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/sysctl.h>
+#include <machine/bus.h>
+#include <sys/random.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/extres/clk/clk.h>
+#include <dev/extres/hwreset/hwreset.h>
+
+#include <arm/allwinner/a10_crypto.h>
+
+static struct ofw_compat_data compat_data[] = {
+ { "allwinner,sun4i-a10-crypto", 1 },
+ { NULL, 0 }
+};
+
+struct a10_crypto_softc {
+ device_t dev;
+ struct resource *res;
+ struct callout co;
+ int ticks;
+ uint32_t sc_seed[A10_SS_FIFO_WORDS];
+ uint32_t sc_buf[A10_SS_FIFO_WORDS];
+};
+
+static struct resource_spec a10_crypto_spec[] = {
+ { SYS_RES_MEMORY, 0, RF_ACTIVE },
+ { -1, 0 }
+};
+
+#define RD4(sc, reg) bus_read_4((sc)->res, (reg))
+#define WR4(sc, reg, val) bus_write_4((sc)->res, (reg), (val))
+
+static void
+a10_rng_start(struct a10_crypto_softc *sc)
+{
+ uint32_t prng_mode;
+ int i;
+
+ prng_mode = A10_SS_OP_PRNG | A10_SS_PRNG_CONTINUE | A10_SS_ENABLED;
+
+ /* Write PRNG mode */
+ WR4(sc, A10_SS_CTL, prng_mode);
+
+ /* Write the seed */
+ for (i = 0; i < A10_SS_FIFO_WORDS; i++)
+ WR4(sc, A10_SS_KEY0 + i * 4, sc->sc_seed[i]);
+
+ /* Start PRNG */
+ WR4(sc, A10_SS_CTL, prng_mode | A10_SS_PRNG_START);
+}
+
+static void
+a10_rng_stop(struct a10_crypto_softc *sc)
+{
+ uint32_t ctrl;
+
+ /* Disable PRNG */
+ ctrl = RD4(sc, A10_SS_CTL);
+ ctrl &= ~A10_SS_PRNG_START;
+ WR4(sc, A10_SS_CTL, ctrl);
+
+ /* Disable and flush FIFO */
+ WR4(sc, A10_SS_CTL, A10_SS_DISABLED);
+}
+
+static void
+a10_rng_harvest(void *arg)
+{
+ struct a10_crypto_softc *sc = arg;
+ uint32_t val;
+ int i;
+
+ /* Start PRNG */
+ a10_rng_start(sc);
+
+ /* Read random data */
+ bus_read_multi_4(sc->res, A10_SS_TXFIFO, sc->sc_buf,
+ A10_SS_DATA_LEN / sizeof(uint32_t));
+
+ /* Update the seed */
+ for (i = 0; i < A10_SS_FIFO_WORDS; i++) {
+ val = RD4(sc, A10_SS_KEY0 + i * 4);
+ sc->sc_seed[i] = val;
+ }
+
+ /* Disable and flush FIFO */
+ WR4(sc, A10_SS_CTL, A10_SS_DISABLED);
+
+ random_harvest_queue(sc->sc_buf, sizeof(sc->sc_buf),
+ sizeof(sc->sc_buf) * NBBY / 2, RANDOM_PURE_ALLWINNER);
+
+ callout_reset(&sc->co, sc->ticks, a10_rng_harvest, sc);
+}
+
+static int
+a10_crypto_probe(device_t dev)
+{
+
+ if (!ofw_bus_status_okay(dev))
+ return (ENXIO);
+
+ if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
+ return (ENXIO);
+
+ device_set_desc(dev, "A10/A20 Security System/Crypto accelerator");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+a10_crypto_attach(device_t dev)
+{
+ struct a10_crypto_softc *sc;
+ hwreset_t rst_ahb;
+ clk_t clk_ss, clk_gate;
+ int err, i;
+ uint32_t val = 0;
+
+ sc = device_get_softc(dev);
+ clk_ss = clk_gate = NULL;
+ rst_ahb = NULL;
+
+ if (bus_alloc_resources(dev, a10_crypto_spec, &sc->res) != 0) {
+ device_printf(dev, "cannot allocate resources for device\n");
+ return (ENXIO);
+ }
+
+ /* De-assert reset */
+ if (hwreset_get_by_ofw_name(dev, 0, "ahb", &rst_ahb) == 0) {
+ err = hwreset_deassert(rst_ahb);
+ if (err != 0) {
+ device_printf(dev, "cannot de-assert reset\n");
+ goto error;
+ }
+ }
+
+ /* Get clocks and enable them */
+ err = clk_get_by_ofw_name(dev, 0, "ahb", &clk_gate);
+ if (err != 0) {
+ device_printf(dev, "Cannot get gate clock\n");
+ goto error;
+ }
+ err = clk_get_by_ofw_name(dev, 0, "mod", &clk_ss);
+ if (err != 0) {
+ device_printf(dev, "Cannot get SS clock\n");
+ goto error;
+ }
+ err = clk_enable(clk_gate);
+ if (err != 0) {
+ device_printf(dev, "Cannot enable clk gate\n");
+ goto error;
+ }
+ err = clk_enable(clk_ss);
+ if (err != 0) {
+ device_printf(dev, "Cannot enable SS clock\n");
+ goto error;
+ }
+
+ /*
+ * "Die Bonding ID"
+ */
+ WR4(sc, A10_SS_CTL, A10_SS_ENABLED);
+ val = RD4(sc, A10_SS_CTL);
+ val >>= DIE_ID_START_BIT;
+ val &= DIE_ID_MASK;
+ device_printf(dev, "Die ID %d\n", val);
+ WR4(sc, A10_SS_CTL, 0);
+
+ /* Install a periodic collector for the RNG */
+ if (hz > 100)
+ sc->ticks = hz / 100;
+ else
+ sc->ticks = 1;
+
+ /* Generate the seed fist */
+ for (i = 0; i < A10_SS_FIFO_WORDS; i++)
+ sc->sc_seed[i] = arc4random();
+
+ callout_init(&sc->co, 1);
+ callout_reset(&sc->co, sc->ticks, a10_rng_harvest, sc);
+
+ return (0);
+
+error:
+ if (clk_gate != NULL)
+ clk_release(clk_gate);
+ if (clk_ss != NULL)
+ clk_release(clk_ss);
+ if (rst_ahb != NULL)
+ hwreset_release(rst_ahb);
+ bus_release_resources(dev, a10_crypto_spec, &sc->res);
+ return (ENXIO);
+}
+
+static int
+a10_crypto_detach(device_t dev)
+{
+ struct a10_crypto_softc *sc = device_get_softc(dev);
+
+ a10_rng_stop(sc);
+ callout_drain(&sc->co);
+
+ bus_release_resources(dev, a10_crypto_spec, &sc->res);
+
+ return (0);
+}
+
+static device_method_t a10_crypto_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, a10_crypto_probe),
+ DEVMETHOD(device_attach, a10_crypto_attach),
+ DEVMETHOD(device_detach, a10_crypto_detach),
+
+ DEVMETHOD_END
+};
+
+static driver_t a10_crypto_driver = {
+ "a10_crypto",
+ a10_crypto_methods,
+ sizeof(struct a10_crypto_softc),
+};
+
+static devclass_t a10_crypto_devclass;
+
+DRIVER_MODULE(a10_crypto, simplebus, a10_crypto_driver, a10_crypto_devclass, 0, 0);
+MODULE_VERSION(a10_crypto, 1);
+MODULE_DEPEND(a10_crypto, crypto, 1, 1, 1);
+MODULE_DEPEND(a10_crypto, randomdev, 1, 1, 1);
Index: sys/arm/allwinner/files.allwinner
===================================================================
--- sys/arm/allwinner/files.allwinner
+++ sys/arm/allwinner/files.allwinner
@@ -29,6 +29,7 @@
arm/allwinner/aw_sid.c standard
arm/allwinner/aw_thermal.c standard
dev/iicbus/sy8106a.c optional sy8106a
+arm/allwinner/a10_crypto.c optional a10_crypto random
#arm/allwinner/console.c standard
arm/allwinner/a10_fb.c optional vt
Index: sys/arm/conf/ALLWINNER
===================================================================
--- sys/arm/conf/ALLWINNER
+++ sys/arm/conf/ALLWINNER
@@ -86,6 +86,10 @@
device axp81x # AXP813/818 Power Management Unit
device sy8106a # SY8106A Buck Regulator
+device a10_crypto
+device crypto
+device cryptodev
+
# GPIO
device gpio
device gpioled
Index: sys/arm/conf/ALLWINNER_UP
===================================================================
--- sys/arm/conf/ALLWINNER_UP
+++ sys/arm/conf/ALLWINNER_UP
@@ -70,6 +70,10 @@
device pcf8563 # RTC
+device a10_crypto
+device crypto
+device cryptodev
+
# GPIO
device gpio
device gpioled
Index: sys/dev/random/random_harvestq.c
===================================================================
--- sys/dev/random/random_harvestq.c
+++ sys/dev/random/random_harvestq.c
@@ -280,6 +280,7 @@
"PURE_RDRAND",
"PURE_NEHEMIAH",
"PURE_RNDTEST",
+ "PURE_ALLWINNER",
/* "ENTROPYSOURCE" */
};
Index: sys/sys/random.h
===================================================================
--- sys/sys/random.h
+++ sys/sys/random.h
@@ -90,6 +90,7 @@
RANDOM_PURE_NEHEMIAH,
RANDOM_PURE_RNDTEST,
RANDOM_PURE_VIRTIO,
+ RANDOM_PURE_ALLWINNER,
RANDOM_PURE_BROADCOM,
ENTROPYSOURCE
};
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Jul 4, 1:07 PM (1 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29012396
Default Alt Text
D7876.1783170451.diff (13 KB)
Attached To
Mode
D7876: Add Security System/Crypto (PRNG) driver for Allwinner A10/A20 SoC
Attached
Detach File
Event Timeline
Log In to Comment