From owner-svn-src-head@freebsd.org Tue Jul 19 18:10:02 2016 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 83B00B9D0C6; Tue, 19 Jul 2016 18:10:02 +0000 (UTC) (envelope-from markm@FreeBSD.org) Received: from gromit.grondar.org (grandfather.grondar.org [IPv6:2a01:348:0:15:5d59:5c20:0:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 3931D119F; Tue, 19 Jul 2016 18:10:02 +0000 (UTC) (envelope-from markm@FreeBSD.org) Received: from graveyard.grondar.org ([88.96.155.33] helo=gronkulator.grondar.org) by gromit.grondar.org with esmtpsa (TLSv1:ECDHE-RSA-AES256-SHA:256) (Exim 4.87 (FreeBSD)) (envelope-from ) id 1bPZSv-000Bt2-TX; Tue, 19 Jul 2016 19:09:59 +0100 Subject: Re: svn commit: r303035 - in head/sys: arm/broadcom/bcm2835 boot/fdt/dts/arm sys Mime-Version: 1.0 (Mac OS X Mail 9.3 \(3124\)) Content-Type: multipart/signed; boundary="Apple-Mail=_B71B2847-D9CF-4269-8A6B-B7E495B14AC2"; protocol="application/pgp-signature"; micalg=pgp-sha1 X-Pgp-Agent: GPGMail 2.6.1 From: Mark R V Murray In-Reply-To: <201607191807.u6JI7lAq099753@repo.freebsd.org> Date: Tue, 19 Jul 2016 19:09:51 +0100 Cc: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Message-Id: References: <201607191807.u6JI7lAq099753@repo.freebsd.org> To: Mark Robert Vaughan Murray X-Mailer: Apple Mail (2.3124) X-SA-Score: -1.0 X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 19 Jul 2016 18:10:02 -0000 --Apple-Mail=_B71B2847-D9CF-4269-8A6B-B7E495B14AC2 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii Hi * I'm going to get a bollicking for the formatting in this. Apologies in = advance! M > On 19 Jul 2016, at 19:07, Mark Murray wrote: >=20 > Author: markm > Date: Tue Jul 19 18:07:47 2016 > New Revision: 303035 > URL: https://svnweb.freebsd.org/changeset/base/303035 >=20 > Log: > Random bit generator (RBG) driver for RPi and RPi2. >=20 > Summary: > This driver supports the following methods to trigger gathering = random bits from the hardware: > 1. interrupt when the FIFO is full (default) fed into the harvest = queue > 2. callout (when BCM2835_RNG_USE_CALLOUT is defined) every second if = hz is less than 100, otherwise hz / 100, feeding the random bits into = the harvest queue >=20 > If the kernel is booted with verbose enabled, the contents of the = registers will be dumped after the RBG is started during the attach = routine. >=20 > Author: hackagadget_gmail.com (Stephen J. Kiernan) >=20 > Test Plan: Built RPI2 kernel and booted on board. Tested the = different methods to feed the harvest queue (callout, interrupt) and the = interrupt driven approach seems best. However, keeping the other method = for people to be able to experiment with. >=20 > Reviewed By: adrian, delphij, markm >=20 > Differential Revision: https://reviews.freebsd.org/D6888 >=20 > Added: > head/sys/arm/broadcom/bcm2835/bcm2835_rng.c (contents, props = changed) > Modified: > head/sys/arm/broadcom/bcm2835/files.bcm283x > head/sys/boot/fdt/dts/arm/bcm2835.dtsi > head/sys/boot/fdt/dts/arm/bcm2836.dtsi > head/sys/sys/random.h >=20 > Added: head/sys/arm/broadcom/bcm2835/bcm2835_rng.c > = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D > --- /dev/null 00:00:00 1970 (empty, because file is newly added) > +++ head/sys/arm/broadcom/bcm2835/bcm2835_rng.c Tue Jul 19 = 18:07:47 2016 (r303035) > @@ -0,0 +1,534 @@ > +/* > + * Copyright (c) 2015, 2016, Stephen J. Kiernan > + * 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. > + */ > + > +#include > + > +__FBSDID("$FreeBSD$"); > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > + > +#include > +#include > +#include > + > +#include > +#include > + > +#if !defined(BCM2835_RNG_USE_CALLOUT) > +#define BCM2835_RNG_USE_INTERRUPT > +#endif > + > +static device_attach_t bcm2835_rng_attach; > +static device_detach_t bcm2835_rng_detach; > +static device_probe_t bcm2835_rng_probe; > + > +#define RNG_CTRL 0x00 /* RNG Control = Register */ > +#define RNG_COMBLK1_OSC 0x003f0000 /* Combiner Blk = 1 Oscillator */ > +#define RNG_COMBLK1_OSC_SHIFT 16 > +#define RNG_COMBLK2_OSC 0x0fc00000 /* Combiner Blk = 2 Oscillator */ > +#define RNG_COMBLK2_OSC_SHIFT 22 > +#define RNG_JCLK_BYP_DIV_CNT 0x0000ff00 /* Jitter clk = bypass divider > + count */ > +#define RNG_JCLK_BYP_DIV_CNT_SHIFT 8 > +#define RNG_JCLK_BYP_SRC 0x00000020 /* Jitter clk = bypass source */ > +#define RNG_JCLK_BYP_SEL 0x00000010 /* Jitter clk = bypass select */ > +#define RNG_RBG2X 0x00000002 /* RBG 2X SPEED = */ > +#define RNG_RBGEN_BIT 0x00000001 /* Enable RNG = bit */ > + > +#define RNG_STATUS 0x04 /* RNG status = register */ > +#define RND_VAL_SHIFT 24 /* Shift for = valid words */ > +#define RND_VAL_MASK 0x000000ff /* Number valid = words mask */ > +#define RND_VAL_WARM_CNT 0x40000 /* RNG Warm Up = count */ > +#define RND_WARM_CNT 0xfffff /* RNG Warm Up = Count mask */ > + > +#define RNG_DATA 0x08 /* RNG Data = Register */ > +#define RNG_FF_THRES 0x0c > +#define RNG_FF_THRES_MASK 0x0000001f > + > +#define RNG_INT_MASK 0x10 > +#define RNG_INT_OFF_BIT 0x00000001 > + > +#define RNG_FF_DEFAULT 0x10 /* FIFO = threshold default */ > + > +#define RNG_FIFO_WORDS (RNG_FF_DEFAULT / = sizeof(uint32_t)) > + > +#define RNG_NUM_OSCILLATORS 6 > +#define RNG_STALL_COUNT_DEFAULT 10 > + > +struct bcm2835_rng_softc { > + device_t sc_dev; > + struct resource * sc_mem_res; > + struct resource * sc_irq_res; > + void * sc_intr_hdl; > +#if defined(BCM2835_RNG_USE_CALLOUT) || = defined(BCM2835_RNG_USE_INTERRUPT) > + uint32_t sc_buf[RNG_FIFO_WORDS]; > +#endif > +#if defined(BCM2835_RNG_USE_CALLOUT) > + struct callout sc_rngto; > + int sc_rnghz; > +#endif > + int sc_stall_count; > + int sc_rbg2x; > + long sc_underrun; > +}; > + > +static __inline void > +bcm2835_rng_stat_inc_underrun(struct bcm2835_rng_softc *sc) > +{ > + > + atomic_add_long(&sc->sc_underrun, 1); > +} > + > +static __inline uint32_t > +bcm2835_rng_read4(struct bcm2835_rng_softc *sc, bus_size_t off) > +{ > + > + return bus_read_4(sc->sc_mem_res, off); > +} > + > +static __inline void > +bcm2835_rng_read_multi4(struct bcm2835_rng_softc *sc, bus_size_t off, > + uint32_t *datap, bus_size_t count) > +{ > + > + bus_read_multi_4(sc->sc_mem_res, off, datap, count); > +} > + > +static __inline void > +bcm2835_rng_write4(struct bcm2835_rng_softc *sc, bus_size_t off, = uint32_t val) > +{ > + > + bus_write_4(sc->sc_mem_res, off, val); > +} > + > +static void > +bcm2835_rng_dump_registers(struct bcm2835_rng_softc *sc, struct sbuf = *sbp) > +{ > + uint32_t comblk2_osc, comblk1_osc, jclk_byp_div, val; > + int i; > + > + /* Display RNG control register contents */ > + val =3D bcm2835_rng_read4(sc, RNG_CTRL); > + sbuf_printf(sbp, "RNG_CTRL (%08x)\n", val); > + > + comblk2_osc =3D (val & RNG_COMBLK2_OSC) >> = RNG_COMBLK2_OSC_SHIFT; > + sbuf_printf(sbp, " RNG_COMBLK2_OSC (%02x)\n", comblk2_osc); > + for (i =3D 0; i < RNG_NUM_OSCILLATORS; i++) > + if ((comblk2_osc & (1 << i)) =3D=3D 0) > + sbuf_printf(sbp, " Oscillator %d enabled\n", = i + 1); > + > + comblk1_osc =3D (val & RNG_COMBLK1_OSC) >> = RNG_COMBLK1_OSC_SHIFT; > + sbuf_printf(sbp, " RNG_COMBLK1_OSC (%02x)\n", comblk1_osc); > + for (i =3D 0; i < RNG_NUM_OSCILLATORS; i++) > + if ((comblk1_osc & (1 << i)) =3D=3D 0) > + sbuf_printf(sbp, " Oscillator %d enabled\n", = i + 1); > + > + jclk_byp_div =3D (val & RNG_JCLK_BYP_DIV_CNT) >> > + RNG_JCLK_BYP_DIV_CNT_SHIFT; > + sbuf_printf(sbp, > + " RNG_JCLK_BYP_DIV_CNT (%02x)\n APB clock frequency / = %d\n", > + jclk_byp_div, 2 * (jclk_byp_div + 1)); > + > + sbuf_printf(sbp, " RNG_JCLK_BYP_SRC:\n %s\n", > + (val & RNG_JCLK_BYP_SRC) ? "Use divided down APB clock" : > + "Use RNG clock (APB clock)"); > + > + sbuf_printf(sbp, " RNG_JCLK_BYP_SEL:\n %s\n", > + (val & RNG_JCLK_BYP_SEL) ? "Bypass internal jitter clock" : > + "Use internal jitter clock"); > + > + if ((val & RNG_RBG2X) !=3D 0) > + sbuf_cat(sbp, " RNG_RBG2X: RNG 2X SPEED enabled\n"); > + > + if ((val & RNG_RBGEN_BIT) !=3D 0) > + sbuf_cat(sbp, " RNG_RBGEN_BIT: RBG enabled\n"); > + > + /* Display RNG status register contents */ > + val =3D bcm2835_rng_read4(sc, RNG_STATUS); > + sbuf_printf(sbp, "RNG_CTRL (%08x)\n", val); > + sbuf_printf(sbp, " RND_VAL: %02x\n", > + (val >> RND_VAL_SHIFT) & RND_VAL_MASK); > + sbuf_printf(sbp, " RND_WARM_CNT: %05x\n", val & RND_WARM_CNT); > + > + /* Display FIFO threshold register contents */ > + val =3D bcm2835_rng_read4(sc, RNG_FF_THRES); > + sbuf_printf(sbp, "RNG_FF_THRES: %05x\n", val & = RNG_FF_THRES_MASK); > + > + /* Display interrupt mask register contents */ > + val =3D bcm2835_rng_read4(sc, RNG_INT_MASK); > + sbuf_printf(sbp, "RNG_INT_MASK: interrupt %s\n", > + ((val & RNG_INT_OFF_BIT) !=3D 0) ? "disabled" : "enabled"); > +} > + > +static void > +bcm2835_rng_disable_intr(struct bcm2835_rng_softc *sc) > +{ > + uint32_t mask; > + > + /* Set the interrupt off bit in the interrupt mask register */ > + mask =3D bcm2835_rng_read4(sc, RNG_INT_MASK); > + mask |=3D RNG_INT_OFF_BIT; > + bcm2835_rng_write4(sc, RNG_INT_MASK, mask); > +} > + > +#if defined(BCM2835_RNG_USE_INTERRUPT) > +static void > +bcm2835_rng_enable_intr(struct bcm2835_rng_softc *sc) > +{ > + uint32_t mask; > + > + /* Clear the interrupt off bit in the interrupt mask register */ > + mask =3D bcm2835_rng_read4(sc, RNG_INT_MASK); > + mask &=3D ~RNG_INT_OFF_BIT; > + bcm2835_rng_write4(sc, RNG_INT_MASK, mask); > +} > +#endif > + > +static void > +bcm2835_rng_start(struct bcm2835_rng_softc *sc) > +{ > + uint32_t ctrl; > + > + /* Disable the interrupt */ > + bcm2835_rng_disable_intr(sc); > + > + /* Set the warmup count */ > + bcm2835_rng_write4(sc, RNG_STATUS, RND_VAL_WARM_CNT); > + > + /* Enable the RNG */ > + ctrl =3D bcm2835_rng_read4(sc, RNG_CTRL); > + ctrl |=3D RNG_RBGEN_BIT; > + if (sc->sc_rbg2x) > + ctrl |=3D RNG_RBG2X; > + bcm2835_rng_write4(sc, RNG_CTRL, ctrl); > + > +#if defined(BCM2835_RNG_USE_INTERRUPT) > + /* Enable the interrupt */ > + bcm2835_rng_enable_intr(sc); > +#endif > +} > + > +static void > +bcm2835_rng_stop(struct bcm2835_rng_softc *sc) > +{ > + uint32_t ctrl; > + > + /* Disable the RNG */ > + ctrl =3D bcm2835_rng_read4(sc, RNG_CTRL); > + ctrl &=3D ~RNG_RBGEN_BIT; > + bcm2835_rng_write4(sc, RNG_CTRL, ctrl); > +} > + > +static void > +bcm2835_rng_harvest(struct bcm2835_rng_softc *sc) > +{ > + uint32_t *dest; > + uint32_t status; > + u_int cnt, nread, num_avail, num_words; > + int seen_underrun, num_stalls; > + > + dest =3D sc->sc_buf; > + nread =3D num_words =3D 0; > + seen_underrun =3D num_stalls =3D 0; > + for (cnt =3D sizeof(sc->sc_buf) / sizeof(uint32_t); cnt > 0; > + cnt -=3D num_words) { > + /* Read status register to find out how many words = available */ > + status =3D bcm2835_rng_read4(sc, RNG_STATUS); > + num_avail =3D (status >> RND_VAL_SHIFT) & RND_VAL_MASK; > + > + /* If we have none... */ > + if (num_avail =3D=3D 0) { > + bcm2835_rng_stat_inc_underrun(sc); > + if (++seen_underrun >=3D sc->sc_stall_count) { > + if (num_stalls++ > 0) { > + device_printf(sc->sc_dev, > + "RNG stalled, disabling = device\n"); > + bcm2835_rng_stop(sc); > + break; > + } else { > + device_printf(sc->sc_dev, > + "Too many underruns, = resetting\n"); > + bcm2835_rng_stop(sc); > + bcm2835_rng_start(sc); > + seen_underrun =3D 0; > + } > + } > + /* Try again */ > + continue; > + } > + > + CTR2(KTR_DEV, "%s: %d words available in RNG FIFO", > + device_get_nameunit(sc->sc_dev), num_avail); > + > + /* Pull MIN(num_avail, cnt) words from the FIFO */ > + num_words =3D (num_avail > cnt) ? cnt : num_avail; > + bcm2835_rng_read_multi4(sc, RNG_DATA, dest, > + num_words); > + dest +=3D num_words; > + nread +=3D num_words; > + } > + > + cnt =3D nread * sizeof(uint32_t); > + if (cnt > 0) > + random_harvest_queue(sc->sc_buf, cnt, cnt * NBBY / 2, > + RANDOM_PURE_BROADCOM); > + > +#if defined(BCM2835_RNG_USE_CALLOUT) > + callout_reset(&sc->sc_rngto, sc->sc_rnghz, bcm2835_rng_harvest, = sc); > +#endif > +} > + > +static int > +sysctl_bcm2835_rng_2xspeed(SYSCTL_HANDLER_ARGS) > +{ > + struct bcm2835_rng_softc *sc =3D arg1; > + int error, rbg2x; > + > + rbg2x =3D sc->sc_rbg2x; > + error =3D sysctl_handle_int(oidp, &rbg2x, 0, req); > + if (error) > + return (error); > + if (req->newptr =3D=3D NULL) > + return (error); > + if (rbg2x =3D=3D sc->sc_rbg2x) > + return (0); > + > + /* Reset the RNG */ > + bcm2835_rng_stop(sc); > + sc->sc_rbg2x =3D rbg2x; > + bcm2835_rng_start(sc); > + > + return (0); > +} > + > +#ifdef BCM2835_RNG_DEBUG_REGISTERS > +static int > +sysctl_bcm2835_rng_dump(SYSCTL_HANDLER_ARGS) > +{ > + struct sbuf sb; > + struct bcm2835_rng_softc *sc =3D arg1; > + int error; > + > + error =3D sysctl_wire_old_buffer(req, 0); > + if (error !=3D 0) > + return (error); > + sbuf_new_for_sysctl(&sb, NULL, 128, req); > + bcm2835_rng_dump_registers(sc, &sb); > + error =3D sbuf_finish(&sb); > + sbuf_delete(&sb); > + return (error); > +} > +#endif > + > +static int > +bcm2835_rng_probe(device_t dev) > +{ > + > + if (!ofw_bus_status_okay(dev)) > + return (ENXIO); > + > + if (!ofw_bus_is_compatible(dev, "broadcom,bcm2835-rng")) > + return (ENXIO); > + > + device_set_desc(dev, "Broadcom BCM2835 RNG"); > + > + return (BUS_PROBE_DEFAULT); > +} > + > +static int > +bcm2835_rng_attach(device_t dev) > +{ > + struct bcm2835_rng_softc *sc; > + struct sysctl_ctx_list *sysctl_ctx; > + struct sysctl_oid *sysctl_tree; > + int error, rid; > + > + error =3D 0; > + sc =3D device_get_softc(dev); > + sc->sc_dev =3D dev; > + sc->sc_stall_count =3D RNG_STALL_COUNT_DEFAULT; > +#ifdef BCM2835_RNG_USE_CALLOUT > + /* Initialize callout */ > + callout_init(&sc->sc_rngto, CALLOUT_MPSAFE); > +#endif > + TUNABLE_INT_FETCH("bcmrng.2xspeed", &sc->sc_rbg2x); > + TUNABLE_INT_FETCH("bcmrng.stall_count", &sc->sc_stall_count); > + > + /* Allocate memory resources */ > + rid =3D 0; > + sc->sc_mem_res =3D bus_alloc_resource_any(dev, SYS_RES_MEMORY, = &rid, > + RF_ACTIVE); > + if (sc->sc_mem_res =3D=3D NULL) { > + bcm2835_rng_detach(dev); > + return (ENXIO); > + } > + > +#if defined(BCM2835_RNG_USE_INTERRUPT) > + /* Allocate interrupt resource */ > + rid =3D 0; > + sc->sc_irq_res =3D bus_alloc_resource_any(dev, SYS_RES_IRQ, = &rid, > + RF_SHAREABLE | RF_ACTIVE); > + if (sc->sc_irq_res =3D=3D NULL) { > + bcm2835_rng_detach(dev); > + return (ENXIO); > + } > + > + /* Set up the interrupt handler */ > + error =3D bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | = INTR_MPSAFE, > + NULL, (driver_intr_t *)bcm2835_rng_harvest, sc, = &sc->sc_intr_hdl); > + if (error) { > + device_printf(dev, "Failed to set up IRQ\n"); > + sc->sc_intr_hdl =3D NULL; > + bcm2835_rng_detach(dev); > + return (error); > + } > +#endif > + > + /* Start the RNG */ > + bcm2835_rng_start(sc); > + > + /* Dump the registers if booting verbose */ > + if (bootverbose) { > + struct sbuf sb; > + > + (void) sbuf_new(&sb, NULL, 256, > + SBUF_AUTOEXTEND | SBUF_INCLUDENUL); > + bcm2835_rng_dump_registers(sc, &sb); > + sbuf_trim(&sb); > + error =3D sbuf_finish(&sb); > + if (error =3D=3D 0) > + device_printf(dev, "%s", sbuf_data(&sb)); > + sbuf_delete(&sb); > + } > + > + sysctl_ctx =3D device_get_sysctl_ctx(dev); > + sysctl_tree =3D device_get_sysctl_tree(dev); > + SYSCTL_ADD_LONG(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), = OID_AUTO, > + "underrun", CTLFLAG_RD, &sc->sc_underrun, > + "Number of FIFO underruns"); > + SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), = OID_AUTO, > + "2xspeed", CTLTYPE_INT | CTLFLAG_RW, sc, 0, > + sysctl_bcm2835_rng_2xspeed, "I", "Enable RBG 2X SPEED"); > + SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), = OID_AUTO, > + "stall_count", CTLFLAG_RW, &sc->sc_stall_count, > + RNG_STALL_COUNT_DEFAULT, "Number of underruns to assume RNG = stall"); > +#ifdef BCM2835_RNG_DEBUG_REGISTERS > + SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), = OID_AUTO, > + "dumpregs", CTLTYPE_STRING | CTLFLAG_RD, sc, 0, > + sysctl_bcm2835_rng_dump, "S", "Dump RNG registers"); > +#endif > + > +#if defined(BCM2835_RNG_USE_CALLOUT) > + /* Reset callout */ > + if (hz >=3D 100) > + sc->sc_rnghz =3D hz / 100; > + else > + sc->sc_rnghz =3D 1; > + callout_reset(&sc->sc_rngto, sc->sc_rnghz, bcm2835_rng_harvest, = sc); > +#endif > + > + return (0); > +} > + > +static int > +bcm2835_rng_detach(device_t dev) > +{ > + struct bcm2835_rng_softc *sc; > +#if defined(BCM2835_RNG_USE_INTERRUPT) > + int error; > +#endif > + > + sc =3D device_get_softc(dev); > + > + /* Stop the RNG */ > + bcm2835_rng_stop(sc); > + > + /* Drain the callout it */ > +#if defined(BCM2835_RNG_USE_CALLOUT) > + callout_drain(&sc->sc_rngto); > +#endif > + > +#if defined(BCM2835_RNG_USE_INTERRUPT) > + /* Tear down the interrupt */ > + if (sc->sc_irq_res && sc->sc_intr_hdl) { > + error =3D bus_teardown_intr(dev, sc->sc_irq_res, = sc->sc_intr_hdl); > + if (error !=3D 0) { > + device_printf(dev, "could not tear down IRQ\n"); > + return (error); > + } > + sc->sc_intr_hdl =3D NULL; > + } > + > + /* Release interrupt resource */ > + if (sc->sc_irq_res) { > + bus_release_resource(dev, SYS_RES_IRQ, 0, = sc->sc_irq_res); > + sc->sc_irq_res =3D NULL; > + } > +#endif > + > + /* Release memory resource */ > + if (sc->sc_mem_res !=3D NULL) > + bus_release_resource(dev, SYS_RES_MEMORY, 0, = sc->sc_mem_res); > + > + return (0); > +} > + > +static device_method_t bcm2835_rng_methods[] =3D { > + /* Device interface */ > + DEVMETHOD(device_probe, bcm2835_rng_probe), > + DEVMETHOD(device_attach, bcm2835_rng_attach), > + DEVMETHOD(device_detach, bcm2835_rng_detach), > + > + DEVMETHOD_END > +}; > + > +static driver_t bcm2835_rng_driver =3D { > + "bcmrng", > + bcm2835_rng_methods, > + sizeof(struct bcm2835_rng_softc) > +}; > +static devclass_t bcm2835_rng_devclass; > + > +DRIVER_MODULE(bcm2835_rng, simplebus, bcm2835_rng_driver, > + bcm2835_rng_devclass, 0, 0); > +DRIVER_MODULE(bcm2835_rng, ofwbus, bcm2835_rng_driver, = bcm2835_rng_devclass, 0, > + 0); > +MODULE_VERSION(bcm2835_rng, 1); > +MODULE_DEPEND(bcm2835_rng, randomdev, 1, 1, 1); >=20 > Modified: head/sys/arm/broadcom/bcm2835/files.bcm283x > = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D > --- head/sys/arm/broadcom/bcm2835/files.bcm283x Tue Jul 19 = 18:05:25 2016 (r303034) > +++ head/sys/arm/broadcom/bcm2835/files.bcm283x Tue Jul 19 = 18:07:47 2016 (r303035) > @@ -10,6 +10,7 @@ arm/broadcom/bcm2835/bcm2835_gpio.c opt > arm/broadcom/bcm2835/bcm2835_intr.c standard > arm/broadcom/bcm2835/bcm2835_machdep.c standard > arm/broadcom/bcm2835/bcm2835_mbox.c standard > +arm/broadcom/bcm2835/bcm2835_rng.c optional random > arm/broadcom/bcm2835/bcm2835_sdhci.c optional sdhci > arm/broadcom/bcm2835/bcm2835_spi.c optional bcm2835_spi > arm/broadcom/bcm2835/bcm2835_vcio.c standard >=20 > Modified: head/sys/boot/fdt/dts/arm/bcm2835.dtsi > = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D > --- head/sys/boot/fdt/dts/arm/bcm2835.dtsi Tue Jul 19 18:05:25 2016 = (r303034) > +++ head/sys/boot/fdt/dts/arm/bcm2835.dtsi Tue Jul 19 18:07:47 2016 = (r303035) > @@ -396,6 +396,14 @@ > }; > }; >=20 > + rng { > + compatible =3D "broadcom,bcm2835-rng", > + "broadcom,bcm2708-rng"; > + reg =3D <0x104000 0x20>; > + interrupts =3D <69>; > + interrupt-parent =3D <&intc>; > + }; > + > bsc0 { > #address-cells =3D <1>; > #size-cells =3D <0>; >=20 > Modified: head/sys/boot/fdt/dts/arm/bcm2836.dtsi > = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D > --- head/sys/boot/fdt/dts/arm/bcm2836.dtsi Tue Jul 19 18:05:25 2016 = (r303034) > +++ head/sys/boot/fdt/dts/arm/bcm2836.dtsi Tue Jul 19 18:07:47 2016 = (r303035) > @@ -389,6 +389,14 @@ > }; > }; >=20 > + rng { > + compatible =3D "broadcom,bcm2835-rng", > + "broadcom,bcm2708-rng"; > + reg =3D <0x104000 0x20>; > + interrupts =3D <69>; > + interrupt-parent =3D <&intc>; > + }; > + > bsc0 { > #address-cells =3D <1>; > #size-cells =3D <0>; >=20 > Modified: head/sys/sys/random.h > = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D > --- head/sys/sys/random.h Tue Jul 19 18:05:25 2016 = (r303034) > +++ head/sys/sys/random.h Tue Jul 19 18:07:47 2016 = (r303035) > @@ -90,6 +90,7 @@ enum random_entropy_source { > RANDOM_PURE_NEHEMIAH, > RANDOM_PURE_RNDTEST, > RANDOM_PURE_VIRTIO, > + RANDOM_PURE_BROADCOM, > ENTROPYSOURCE > }; >=20 >=20 -- Mark R V Murray --Apple-Mail=_B71B2847-D9CF-4269-8A6B-B7E495B14AC2 Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=signature.asc Content-Type: application/pgp-signature; name=signature.asc Content-Description: Message signed with OpenPGP using GPGMail -----BEGIN PGP SIGNATURE----- Version: GnuPG/MacGPG2 v2.0.30 Comment: GPGTools - http://gpgtools.org iEYEARECAAYFAleObPUACgkQzQuKNftX15Ow7gCgpqW4NCMmkhQci4TOSrj/mFzK dmIAnjNBi+ycgdd/b8kJNbh3oMnj6NX6 =X9dj -----END PGP SIGNATURE----- --Apple-Mail=_B71B2847-D9CF-4269-8A6B-B7E495B14AC2--