Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F150669426
D48943.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D48943.diff
View Options
diff --git a/sys/dev/clk/starfive/jh7110_clk_stg.c b/sys/dev/clk/starfive/jh7110_clk_stg.c
--- a/sys/dev/clk/starfive/jh7110_clk_stg.c
+++ b/sys/dev/clk/starfive/jh7110_clk_stg.c
@@ -52,6 +52,9 @@
static const char *pcie0_apb_p[] = { "apb_bus" };
static const char *pcie1_apb_p[] = { "apb_bus" };
+static const char *sec_ahb_p[] = { "stg_axiahb" };
+static const char *sec_misc_ahb_p[] = { "stg_axiahb" };
+
static const char *usb0_lpm_p[] = { "osc" };
static const char *usb0_stb_p[] = { "osc" };
static const char *usb0_apb_p[] = { "apb_bus" };
@@ -86,6 +89,9 @@
JH7110_GATE(JH7110_STGCLK_PCIE_SLV_MAIN, "pcie_slv_main",
pcie_slv_main_p),
+ JH7110_GATE(JH7110_STGCLK_SEC_AHB, "sec_ahb", sec_ahb_p),
+ JH7110_GATE(JH7110_STGCLK_SEC_MISC_AHB, "sec_misc_ahb", sec_misc_ahb_p),
+
JH7110_GATEDIV(JH7110_STGCLK_E2_RTC, "e2_rtc", e2_rtc_p, 24),
JH7110_GATE(JH7110_STGCLK_E2_CORE, "e2_core", e2_core_p),
JH7110_GATE(JH7110_STGCLK_E2_DBG, "e2_dbg", e2_dbg_p),
diff --git a/sys/dev/random/random_harvestq.c b/sys/dev/random/random_harvestq.c
--- a/sys/dev/random/random_harvestq.c
+++ b/sys/dev/random/random_harvestq.c
@@ -387,6 +387,7 @@
[RANDOM_PURE_QUALCOMM] = "PURE_QUALCOMM",
[RANDOM_PURE_ARMV8] = "PURE_ARMV8",
[RANDOM_PURE_ARM_TRNG] = "PURE_ARM_TRNG",
+ [RANDOM_PURE_STARFIVE_TRNG] = "PURE_STARFIVE_TRNG",
/* "ENTROPYSOURCE" */
};
diff --git a/sys/riscv/starfive/files.starfive b/sys/riscv/starfive/files.starfive
--- a/sys/riscv/starfive/files.starfive
+++ b/sys/riscv/starfive/files.starfive
@@ -4,5 +4,6 @@
dev/clk/starfive/jh7110_clk_sys.c standard
dev/clk/starfive/jh7110_clk_stg.c standard
dev/mmc/host/dwmmc_starfive.c optional dwmmc_starfive fdt
+riscv/starfive/jh7110_trng.c optional !random_loadable fdt
riscv/starfive/starfive_syscon.c standard
diff --git a/sys/riscv/starfive/jh7110_trng.c b/sys/riscv/starfive/jh7110_trng.c
new file mode 100644
--- /dev/null
+++ b/sys/riscv/starfive/jh7110_trng.c
@@ -0,0 +1,205 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2025 Jari Sihvola <jsihv@gmx.com>
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/random.h>
+#include <sys/rman.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include <dev/clk/clk.h>
+#include <dev/hwreset/hwreset.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+/* Registers */
+#define JH7110_TRNG_CTRL 0x0000
+#define CTRL_GEN_RAND 0x1
+#define CTRL_RESEED 0x2
+#define JH7110_TRNG_STAT 0x0004
+#define STAT_SEEDING_DONE (1 << 9)
+#define JH7110_TRNG_MODE 0x000c
+#define MODE_256BIT (1 << 3)
+#define JH7110_TRNG_ISTAT 0x0014
+#define ISTAT_RAND_DONE (1 << 0)
+#define ISTAT_LFSR_LOCKUP (1 << 4)
+/* There is eight adjacent 32-bit registers for random data */
+#define JH7110_TRNG_DATA 0x0020
+#define DATA_REGS 8
+#define DATA_BYTESIZE (DATA_REGS * sizeof(uint32_t))
+
+struct jh7110_trng_softc {
+ device_t dev;
+ struct resource *mem_res;
+ struct callout trngto;
+ clk_t clk_hclk;
+ clk_t clk_ahb;
+ hwreset_t rst;
+};
+
+static struct ofw_compat_data compat_data[] = {
+ {"starfive,jh7110-trng", 1},
+ {NULL, 0}
+};
+
+#define RD4(sc, reg) bus_read_4((sc)->mem_res, (reg))
+#define WR4(sc, reg, val) bus_write_4((sc)->mem_res, (reg), (val))
+
+static int
+jh7110_trng_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, "StarFive JH7110 TRNG");
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+static void
+jh7110_trng_harvest(void *arg)
+{
+ struct jh7110_trng_softc *sc = arg;
+ uint32_t val, buf[DATA_REGS];
+ int i;
+
+ val = RD4(sc, JH7110_TRNG_STAT);
+ if (val & STAT_SEEDING_DONE) {
+ val = RD4(sc, JH7110_TRNG_ISTAT);
+ if (val & ISTAT_RAND_DONE) {
+ WR4(sc, JH7110_TRNG_ISTAT, ISTAT_RAND_DONE);
+
+ for (i = 0; i != DATA_REGS; i++)
+ buf[i] = RD4(sc, JH7110_TRNG_DATA +
+ i * sizeof(uint32_t));
+
+ random_harvest_queue(buf, DATA_BYTESIZE,
+ RANDOM_PURE_STARFIVE_TRNG);
+ }
+ if (val & ISTAT_LFSR_LOCKUP)
+ WR4(sc, JH7110_TRNG_CTRL, CTRL_RESEED);
+ else
+ WR4(sc, JH7110_TRNG_CTRL, CTRL_GEN_RAND);
+ }
+ callout_reset(&sc->trngto, hz, jh7110_trng_harvest, sc);
+}
+
+static int
+jh7110_trng_detach(device_t dev)
+{
+ struct jh7110_trng_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ callout_drain(&sc->trngto);
+
+ if (sc->mem_res != NULL)
+ bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res);
+
+ if (sc->clk_hclk != NULL)
+ clk_release(sc->clk_hclk);
+ if (sc->clk_ahb != NULL)
+ clk_release(sc->clk_ahb);
+
+ hwreset_release(sc->rst);
+
+ return (0);
+}
+
+static int
+jh7110_trng_attach(device_t dev)
+{
+ struct jh7110_trng_softc *sc;
+ uint32_t val;
+ int rid;
+
+ sc = device_get_softc(dev);
+ sc->dev = dev;
+ sc->clk_hclk = NULL;
+ sc->clk_ahb = NULL;
+
+ /* Initialize callout */
+ callout_init(&sc->trngto, CALLOUT_MPSAFE);
+
+ /* Allocate memory resources */
+ rid = 0;
+ sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+ RF_ACTIVE);
+ if (sc->mem_res == NULL) {
+ jh7110_trng_detach(dev);
+ return (ENXIO);
+ }
+
+ /* Get and enable clocks */
+ if (clk_get_by_ofw_name(dev, 0, "hclk", &sc->clk_hclk) != 0) {
+ device_printf(dev, "could not get hclk clock\n");
+ sc->clk_hclk = NULL;
+ return (ENXIO);
+ }
+ if (clk_get_by_ofw_name(dev, 0, "ahb", &sc->clk_ahb) != 0) {
+ device_printf(dev, "could not get ahb clock\n");
+ sc->clk_ahb = NULL;
+ return (ENXIO);
+ }
+ if (clk_enable(sc->clk_hclk) != 0) {
+ device_printf(dev, "could not enable hclk clock\n");
+ return (ENXIO);
+ }
+ if (clk_enable(sc->clk_ahb) != 0) {
+ device_printf(dev, "could not enable ahb clock\n");
+ return (ENXIO);
+ }
+
+ /* Get and de-assert reset */
+ if (hwreset_get_by_ofw_idx(dev, 0, 0, &sc->rst) != 0) {
+ device_printf(dev, "could not get reset\n");
+ return (ENXIO);
+ }
+ if (hwreset_deassert(sc->rst) != 0) {
+ device_printf(dev, "could not deassert reset\n");
+ return (ENXIO);
+ }
+
+ /* Clear register ISTAT */
+ val = RD4(sc, JH7110_TRNG_ISTAT);
+ WR4(sc, JH7110_TRNG_ISTAT, val);
+
+ /* Set 256 bit mode */
+ WR4(sc, JH7110_TRNG_MODE, MODE_256BIT);
+
+ /* Start harvesting */
+ WR4(sc, JH7110_TRNG_CTRL, CTRL_RESEED);
+ callout_reset(&sc->trngto, hz, jh7110_trng_harvest, sc);
+ jh7110_trng_harvest(sc);
+
+ return (0);
+}
+
+static device_method_t jh7110_trng_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, jh7110_trng_probe),
+ DEVMETHOD(device_attach, jh7110_trng_attach),
+ DEVMETHOD(device_detach, jh7110_trng_detach),
+
+ DEVMETHOD_END
+};
+
+static driver_t jh7110_trng_driver = {
+ "jh7110trng",
+ jh7110_trng_methods,
+ sizeof(struct jh7110_trng_softc)
+};
+
+DRIVER_MODULE(jh7110_trng, simplebus, jh7110_trng_driver, 0, 0);
+MODULE_VERSION(jh7110_trng, 1);
+MODULE_DEPEND(jh7110_trng, randomdev, 1, 1, 1);
diff --git a/sys/sys/random.h b/sys/sys/random.h
--- a/sys/sys/random.h
+++ b/sys/sys/random.h
@@ -104,6 +104,7 @@
RANDOM_PURE_QUALCOMM,
RANDOM_PURE_ARMV8,
RANDOM_PURE_ARM_TRNG,
+ RANDOM_PURE_STARFIVE_TRNG,
ENTROPYSOURCE
};
_Static_assert(ENTROPYSOURCE <= 32,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Apr 4, 5:56 AM (12 m, 30 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30802410
Default Alt Text
D48943.diff (7 KB)
Attached To
Mode
D48943: Add StarFive JH7110 true random number generator driver
Attached
Detach File
Event Timeline
Log In to Comment