Page MenuHomeFreeBSD

D37882.diff
No OneTemporary

D37882.diff

diff --git a/sys/arm64/conf/std.qcom b/sys/arm64/conf/std.qcom
--- a/sys/arm64/conf/std.qcom
+++ b/sys/arm64/conf/std.qcom
@@ -4,6 +4,8 @@
# Qualcomm Snapdragon drivers
device qcom_gcc # Global Clock Controller
+device qcom_rng # Pseudo Random Number Generator
+device qcom_mdio # MDIO support
# Serial (COM) ports
device uart_msm # Qualcomm MSM UART driver
diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64
--- a/sys/conf/files.arm64
+++ b/sys/conf/files.arm64
@@ -618,6 +618,8 @@
# Qualcomm
arm64/qualcomm/qcom_gcc.c optional qcom_gcc fdt
+dev/qcom_rnd/qcom_rnd.c optional qcom_rng fdt
+dev/qcom_mdio/qcom_mdio_ipq4018.c optional qcom_mdio fdt mdio mii
# RockChip Drivers
arm64/rockchip/rk3328_codec.c optional fdt rk3328codec soc_rockchip_rk3328
diff --git a/sys/dev/qcom_mdio/qcom_mdio_ipq4018.c b/sys/dev/qcom_mdio/qcom_mdio_ipq4018.c
--- a/sys/dev/qcom_mdio/qcom_mdio_ipq4018.c
+++ b/sys/dev/qcom_mdio/qcom_mdio_ipq4018.c
@@ -273,6 +273,9 @@
DEVMETHOD(device_attach, qcom_mdio_ipq4018_attach),
DEVMETHOD(device_detach, qcom_mdio_ipq4018_detach),
+ /* Bus interface */
+ DEVMETHOD(bus_add_child, bus_generic_add_child),
+
/* MDIO interface */
DEVMETHOD(mdio_readreg, qcom_mdio_ipq4018_readreg),
DEVMETHOD(mdio_writereg, qcom_mdio_ipq4018_writereg),
diff --git a/sys/dev/qcom_rnd/qcom_rnd.c b/sys/dev/qcom_rnd/qcom_rnd.c
--- a/sys/dev/qcom_rnd/qcom_rnd.c
+++ b/sys/dev/qcom_rnd/qcom_rnd.c
@@ -2,6 +2,7 @@
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2021, Adrian Chadd <adrian@FreeBSD.org>
+ * Copyright (c) 2022, Bjoern A. Zeeb
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -32,15 +33,14 @@
#include <sys/param.h>
#include <sys/kernel.h>
-#include <sys/malloc.h>
#include <sys/module.h>
-#include <sys/sglist.h>
+#include <sys/bus.h>
#include <sys/random.h>
+#include <sys/rman.h>
#include <sys/stdatomic.h>
#include <machine/bus.h>
#include <machine/resource.h>
-#include <sys/bus.h>
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/ofw_bus.h>
@@ -49,64 +49,96 @@
#include <dev/random/randomdev.h>
#include <dev/random/random_harvestq.h>
-#include <dev/qcom_rnd/qcom_rnd_reg.h>
+#include "qcom_rnd_reg.h"
struct qcom_rnd_softc {
- device_t dev;
+ device_t dev;
int reg_rid;
struct resource *reg;
};
-static int qcom_rnd_modevent(module_t, int, void *);
-
-static int qcom_rnd_probe(device_t);
-static int qcom_rnd_attach(device_t);
-static int qcom_rnd_detach(device_t);
-
-static int qcom_rnd_harvest(struct qcom_rnd_softc *, void *, size_t *);
-static unsigned qcom_rnd_read(void *, unsigned);
-
-static struct random_source random_qcom_rnd = {
- .rs_ident = "Qualcomm Entropy Adapter",
- .rs_source = RANDOM_PURE_QUALCOMM,
- .rs_read = qcom_rnd_read,
-};
-
/* Kludge for API limitations of random(4). */
static _Atomic(struct qcom_rnd_softc *) g_qcom_rnd_softc;
static int
-qcom_rnd_modevent(module_t mod, int type, void *unused)
+qcom_rnd_harvest(struct qcom_rnd_softc *sc, void *buf, size_t *sz)
{
- int error;
+ /*
+ * Add data to buf until we either run out of entropy or we
+ * fill the buffer.
+ *
+ * Note - be mindful of the provided buffer size; we're reading
+ * 4 bytes at a time but we only want to supply up to the max
+ * buffer size, so don't write past it!
+ */
+ size_t rz = 0;
+ uint32_t reg;
- switch (type) {
- case MOD_LOAD:
- case MOD_QUIESCE:
- case MOD_UNLOAD:
- case MOD_SHUTDOWN:
- error = 0;
- break;
- default:
- error = EOPNOTSUPP;
- break;
+ while (rz < *sz) {
+ bus_barrier(sc->reg, 0, rman_get_size(sc->reg),
+ BUS_SPACE_BARRIER_READ);
+ reg = bus_read_4(sc->reg, QCOM_RND_PRNG_STATUS);
+ if ((reg & QCOM_RND_PRNG_STATUS_DATA_AVAIL) == 0)
+ break;
+ reg = bus_read_4(sc->reg, QCOM_RND_PRNG_DATA_OUT);
+ memcpy(((char *) buf) + rz, &reg, sizeof(uint32_t));
+ rz += sizeof(uint32_t);
}
- return (error);
+ if (rz == 0)
+ return (EAGAIN);
+ *sz = rz;
+ return (0);
+}
+
+static unsigned
+qcom_rnd_read(void *buf, unsigned usz)
+{
+ struct qcom_rnd_softc *sc;
+ size_t sz;
+ int error;
+
+ sc = g_qcom_rnd_softc;
+ if (sc == NULL)
+ return (0);
+
+ sz = usz;
+ error = qcom_rnd_harvest(sc, buf, &sz);
+ if (error != 0)
+ return (0);
+
+ return (sz);
}
+static struct random_source random_qcom_rnd = {
+ .rs_ident = "Qualcomm Entropy Adapter",
+ .rs_source = RANDOM_PURE_QUALCOMM,
+ .rs_read = qcom_rnd_read,
+};
+
+static const struct ofw_compat_data qcom_prng_compat_data[] = {
+ {"qcom,prng", (uintptr_t)"Qualcomm PRNG"},
+#ifdef __notyet__
+ {"qcom,prng-ee", (uintptr_t)"Qualcomm PRNG-EE"},
+#endif
+ { NULL, 0 }
+};
+
static int
qcom_rnd_probe(device_t dev)
{
- if (! ofw_bus_status_okay(dev)) {
- return (ENXIO);
- }
+ const struct ofw_compat_data *compat;
- if (ofw_bus_is_compatible(dev, "qcom,prng") == 0) {
+ if (!ofw_bus_status_okay(dev))
return (ENXIO);
+
+ compat = ofw_bus_search_compatible(dev, qcom_prng_compat_data);
+ if (compat->ocd_str != NULL) {
+ device_set_desc(dev, (const char *)compat->ocd_data);
+ return (BUS_PROBE_DEFAULT);
}
- return (0);
+ return (ENXIO);
}
static int
@@ -116,54 +148,50 @@
uint32_t reg;
sc = device_get_softc(dev);
-
-
- /* Found a compatible device! */
-
sc->dev = dev;
exp = NULL;
if (!atomic_compare_exchange_strong_explicit(&g_qcom_rnd_softc, &exp,
- sc, memory_order_release, memory_order_acquire)) {
+ sc, memory_order_release, memory_order_acquire))
return (ENXIO);
- }
sc->reg_rid = 0;
- sc->reg = bus_alloc_resource_anywhere(dev, SYS_RES_MEMORY,
- &sc->reg_rid, 0x140, RF_ACTIVE);
+ sc->reg = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->reg_rid,
+ RF_SHAREABLE | RF_ACTIVE);
if (sc->reg == NULL) {
- device_printf(dev, "Couldn't allocate memory resource!\n");
+ device_printf(dev, "Failed to allocate memory resource!\n");
return (ENXIO);
}
- device_set_desc(dev, "Qualcomm PRNG");
-
- /*
- * Check to see whether the PRNG has already been setup or not.
- */
- bus_barrier(sc->reg, 0, 0x120, BUS_SPACE_BARRIER_READ);
+ return (0);
+ /* Check to see whether the PRNG is already setup. */
+ /* XXX this is still racy? */
+ bus_barrier(sc->reg, 0, rman_get_size(sc->reg), BUS_SPACE_BARRIER_READ);
reg = bus_read_4(sc->reg, QCOM_RND_PRNG_CONFIG);
- if (reg & QCOM_RND_PRNG_CONFIG_HW_ENABLE) {
- device_printf(dev, "PRNG HW already enabled\n");
- } else {
- /*
- * Do PRNG setup and then enable it.
- */
+/* XXX-BZ this panics */
+ if ((reg & QCOM_RND_PRNG_CONFIG_HW_ENABLE) == 0) {
+
+ /* Do PRNG setup and then enable it. */
reg = bus_read_4(sc->reg, QCOM_RND_PRNG_LFSR_CFG);
reg &= QCOM_RND_PRNG_LFSR_CFG_MASK;
reg |= QCOM_RND_PRNG_LFSR_CFG_CLOCKS;
bus_write_4(sc->reg, QCOM_RND_PRNG_LFSR_CFG, reg);
- bus_barrier(sc->reg, 0, 0x120, BUS_SPACE_BARRIER_WRITE);
+ bus_barrier(sc->reg, 0, rman_get_size(sc->reg),
+ BUS_SPACE_BARRIER_WRITE);
reg = bus_read_4(sc->reg, QCOM_RND_PRNG_CONFIG);
reg |= QCOM_RND_PRNG_CONFIG_HW_ENABLE;
bus_write_4(sc->reg, QCOM_RND_PRNG_CONFIG, reg);
- bus_barrier(sc->reg, 0, 0x120, BUS_SPACE_BARRIER_WRITE);
+ bus_barrier(sc->reg, 0, rman_get_size(sc->reg),
+ BUS_SPACE_BARRIER_WRITE);
+ } else {
+ device_printf(dev, "PRNG HW already enabled\n");
+ /* XXX we should clear up and error? */
}
random_source_register(&random_qcom_rnd);
- return (0);
+ return (0);
}
static int
@@ -177,62 +205,15 @@
("only one global instance at a time"));
random_source_deregister(&random_qcom_rnd);
- if (sc->reg != NULL) {
- bus_release_resource(sc->dev, SYS_RES_MEMORY, sc->reg_rid, sc->reg);
- }
- atomic_store_explicit(&g_qcom_rnd_softc, NULL, memory_order_release);
- return (0);
-}
-static int
-qcom_rnd_harvest(struct qcom_rnd_softc *sc, void *buf, size_t *sz)
-{
- /*
- * Add data to buf until we either run out of entropy or we
- * fill the buffer.
- *
- * Note - be mindful of the provided buffer size; we're reading
- * 4 bytes at a time but we only want to supply up to the max
- * buffer size, so don't write past it!
- */
- size_t rz = 0;
- uint32_t reg;
+ if (sc->reg != NULL)
+ bus_release_resource(sc->dev, SYS_RES_MEMORY, sc->reg_rid, sc->reg);
- while (rz < *sz) {
- bus_barrier(sc->reg, 0, 0x120, BUS_SPACE_BARRIER_READ);
- reg = bus_read_4(sc->reg, QCOM_RND_PRNG_STATUS);
- if ((reg & QCOM_RND_PRNG_STATUS_DATA_AVAIL) == 0)
- break;
- reg = bus_read_4(sc->reg, QCOM_RND_PRNG_DATA_OUT);
- memcpy(((char *) buf) + rz, &reg, sizeof(uint32_t));
- rz += sizeof(uint32_t);
- }
+ atomic_store_explicit(&g_qcom_rnd_softc, NULL, memory_order_release);
- if (rz == 0)
- return (EAGAIN);
- *sz = rz;
return (0);
}
-static unsigned
-qcom_rnd_read(void *buf, unsigned usz)
-{
- struct qcom_rnd_softc *sc;
- size_t sz;
- int error;
-
- sc = g_qcom_rnd_softc;
- if (sc == NULL)
- return (0);
-
- sz = usz;
- error = qcom_rnd_harvest(sc, buf, &sz);
- if (error != 0)
- return (0);
-
- return (sz);
-}
-
static device_method_t qcom_rnd_methods[] = {
/* Device methods. */
DEVMETHOD(device_probe, qcom_rnd_probe),
@@ -248,9 +229,7 @@
sizeof(struct qcom_rnd_softc)
};
-DRIVER_MODULE(qcom_rnd_random, simplebus, qcom_rnd_driver,
- qcom_rnd_modevent, 0);
-DRIVER_MODULE(qcom_rnd_random, ofwbus, qcom_rnd_driver,
- qcom_rnd_modevent, 0);
+DRIVER_MODULE(qcom_rnd_random, simplebus, qcom_rnd_driver, NULL, NULL);
+DRIVER_MODULE(qcom_rnd_random, ofwbus, qcom_rnd_driver, NULL, NULL);
MODULE_DEPEND(qcom_rnd_random, random_device, 1, 1, 1);
MODULE_VERSION(qcom_rnd_random, 1);

File Metadata

Mime Type
text/plain
Expires
Mon, Apr 13, 11:18 AM (9 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31407798
Default Alt Text
D37882.diff (9 KB)

Event Timeline