1/*
2 * Copyright (c) 2015, 2016, Stephen J. Kiernan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27
28#include <sys/param.h>
29#include <sys/kernel.h>
30#include <sys/ktr.h>
31#include <sys/lock.h>
32#include <sys/malloc.h>
33#include <sys/module.h>
34#include <sys/random.h>
35#include <sys/sbuf.h>
36#include <sys/sysctl.h>
37#include <sys/selinfo.h>
38#include <sys/systm.h>
39#include <sys/bus.h>
40#include <sys/rman.h>
41
42#include <machine/bus.h>
43#include <machine/resource.h>
44
45#include <dev/ofw/openfirm.h>
46#include <dev/ofw/ofw_bus.h>
47#include <dev/ofw/ofw_bus_subr.h>
48
49#include <dev/random/randomdev.h>
50#include <dev/random/random_harvestq.h>
51
52static device_attach_t bcm2835_rng_attach;
53static device_detach_t bcm2835_rng_detach;
54static device_probe_t bcm2835_rng_probe;
55
56#define	RNG_CTRL		0x00		/* RNG Control Register */
57#define	RNG_COMBLK1_OSC		0x003f0000	/*  Combiner Blk 1 Oscillator */
58#define	RNG_COMBLK1_OSC_SHIFT	16
59#define	RNG_COMBLK2_OSC		0x0fc00000	/*  Combiner Blk 2 Oscillator */
60#define	RNG_COMBLK2_OSC_SHIFT	22
61#define	RNG_JCLK_BYP_DIV_CNT	0x0000ff00	/*  Jitter clk bypass divider
62						    count */
63#define	RNG_JCLK_BYP_DIV_CNT_SHIFT 8
64#define	RNG_JCLK_BYP_SRC	0x00000020	/*  Jitter clk bypass source */
65#define	RNG_JCLK_BYP_SEL	0x00000010	/*  Jitter clk bypass select */
66#define	RNG_RBG2X		0x00000002	/*  RBG 2X SPEED */
67#define	RNG_RBGEN_BIT		0x00000001	/*  Enable RNG bit */
68
69#define	BCM2835_RNG_STATUS	0x04		/* BCM2835 RNG status register */
70#define	BCM2838_RNG_STATUS	0x18		/* BCM2838 RNG status register */
71
72#define	BCM2838_RNG_COUNT	0x24		/* How many values available */
73#define	BCM2838_COUNT_VAL_MASK	0x000000ff
74
75#define	BCM2835_RND_VAL_SHIFT	24		/*  Shift for valid words */
76#define	BCM2835_RND_VAL_MASK	0x000000ff	/*  Number valid words mask */
77#define	BCM2835_RND_VAL_WARM_CNT	0x40000		/*  RNG Warm Up count */
78#define	BCM2835_RND_WARM_CNT	0xfffff		/*  RNG Warm Up Count mask */
79
80#define	BCM2835_RNG_DATA	0x08		/* RNG Data Register */
81#define	BCM2838_RNG_DATA	0x20
82#define	RNG_FF_THRES		0x0c
83#define	RNG_FF_THRES_MASK	0x0000001f
84
85#define	BCM2835_RNG_INT_MASK		0x10
86#define	BCM2835_RNG_INT_OFF_BIT		0x00000001
87
88#define	RNG_FF_DEFAULT		0x10		/* FIFO threshold default */
89#define	RNG_FIFO_WORDS		(RNG_FF_DEFAULT / sizeof(uint32_t))
90
91#define	RNG_NUM_OSCILLATORS	6
92#define	RNG_STALL_COUNT_DEFAULT	10
93
94#define	RNG_CALLOUT_TICKS	(hz * 4)
95
96struct bcm_rng_conf {
97	bus_size_t		control_reg;
98	bus_size_t		status_reg;
99	bus_size_t		count_reg;
100	bus_size_t		data_reg;
101	bus_size_t		intr_mask_reg;
102	uint32_t		intr_disable_bit;
103	uint32_t		count_value_shift;
104	uint32_t		count_value_mask;
105	uint32_t		warmup_count;
106	bool			allow_2x_mode;
107	bool			can_diagnose;
108	/* XXX diag regs */
109};
110
111static const struct bcm_rng_conf bcm2835_rng_conf = {
112	.control_reg		= RNG_CTRL,
113	.status_reg		= BCM2835_RNG_STATUS,
114	.count_reg		= BCM2835_RNG_STATUS,	/* Same register */
115	.data_reg		= BCM2835_RNG_DATA,
116	.intr_mask_reg		= BCM2835_RNG_INT_MASK,
117	.intr_disable_bit	= BCM2835_RNG_INT_OFF_BIT,
118	.count_value_shift	= BCM2835_RND_VAL_SHIFT,
119	.count_value_mask	= BCM2835_RND_VAL_MASK,
120	.warmup_count		= BCM2835_RND_VAL_WARM_CNT,
121	.allow_2x_mode		= true,
122	.can_diagnose		= true
123};
124
125static const struct bcm_rng_conf bcm2838_rng_conf = {
126	.control_reg		= RNG_CTRL,
127	.status_reg		= BCM2838_RNG_STATUS,
128	.count_reg		= BCM2838_RNG_COUNT,
129	.data_reg		= BCM2838_RNG_DATA,
130	.intr_mask_reg		= 0,
131	.intr_disable_bit	= 0,
132	.count_value_shift	= 0,
133	.count_value_mask	= BCM2838_COUNT_VAL_MASK,
134	.warmup_count		= 0,
135	.allow_2x_mode		= false,
136	.can_diagnose		= false
137};
138
139struct bcm2835_rng_softc {
140	device_t		sc_dev;
141	struct resource *	sc_mem_res;
142	struct resource *	sc_irq_res;
143	void *			sc_intr_hdl;
144	struct bcm_rng_conf const*	conf;
145	uint32_t		sc_buf[RNG_FIFO_WORDS];
146	struct callout		sc_rngto;
147	int			sc_stall_count;
148	int			sc_rbg2x;
149	long			sc_underrun;
150};
151
152static struct ofw_compat_data compat_data[] = {
153	{"broadcom,bcm2835-rng",	(uintptr_t)&bcm2835_rng_conf},
154	{"brcm,bcm2835-rng",		(uintptr_t)&bcm2835_rng_conf},
155
156	{"brcm,bcm2711-rng200",		(uintptr_t)&bcm2838_rng_conf},
157	{"brcm,bcm2838-rng",		(uintptr_t)&bcm2838_rng_conf},
158	{"brcm,bcm2838-rng200",		(uintptr_t)&bcm2838_rng_conf},
159	{"brcm,bcm7211-rng",		(uintptr_t)&bcm2838_rng_conf},
160	{"brcm,bcm7278-rng",		(uintptr_t)&bcm2838_rng_conf},
161	{"brcm,iproc-rng200",		(uintptr_t)&bcm2838_rng_conf},
162	{NULL,				0}
163};
164
165static __inline void
166bcm2835_rng_stat_inc_underrun(struct bcm2835_rng_softc *sc)
167{
168
169	atomic_add_long(&sc->sc_underrun, 1);
170}
171
172static __inline uint32_t
173bcm2835_rng_read4(struct bcm2835_rng_softc *sc, bus_size_t off)
174{
175
176	return bus_read_4(sc->sc_mem_res, off);
177}
178
179static __inline void
180bcm2835_rng_read_multi4(struct bcm2835_rng_softc *sc, bus_size_t off,
181    uint32_t *datap, bus_size_t count)
182{
183
184	bus_read_multi_4(sc->sc_mem_res, off, datap, count);
185}
186
187static __inline void
188bcm2835_rng_write4(struct bcm2835_rng_softc *sc, bus_size_t off, uint32_t val)
189{
190
191	bus_write_4(sc->sc_mem_res, off, val);
192}
193
194static void
195bcm2835_rng_dump_registers(struct bcm2835_rng_softc *sc, struct sbuf *sbp)
196{
197	uint32_t comblk2_osc, comblk1_osc, jclk_byp_div, val;
198	int i;
199
200	if (!sc->conf->can_diagnose)
201	    /* Not implemented. */
202	    return;
203
204	/* Display RNG control register contents */
205	val = bcm2835_rng_read4(sc, sc->conf->control_reg);
206	sbuf_printf(sbp, "RNG_CTRL (%08x)\n", val);
207
208	comblk2_osc = (val & RNG_COMBLK2_OSC) >> RNG_COMBLK2_OSC_SHIFT;
209	sbuf_printf(sbp, "  RNG_COMBLK2_OSC (%02x)\n", comblk2_osc);
210	for (i = 0; i < RNG_NUM_OSCILLATORS; i++)
211		if ((comblk2_osc & (1 << i)) == 0)
212			sbuf_printf(sbp, "    Oscillator %d enabled\n", i + 1);
213
214	comblk1_osc = (val & RNG_COMBLK1_OSC) >> RNG_COMBLK1_OSC_SHIFT;
215	sbuf_printf(sbp, "  RNG_COMBLK1_OSC (%02x)\n", comblk1_osc);
216	for (i = 0; i < RNG_NUM_OSCILLATORS; i++)
217		if ((comblk1_osc & (1 << i)) == 0)
218			sbuf_printf(sbp, "    Oscillator %d enabled\n", i + 1);
219
220	jclk_byp_div = (val & RNG_JCLK_BYP_DIV_CNT) >>
221	    RNG_JCLK_BYP_DIV_CNT_SHIFT;
222	sbuf_printf(sbp,
223	    "  RNG_JCLK_BYP_DIV_CNT (%02x)\n    APB clock frequency / %d\n",
224	    jclk_byp_div, 2 * (jclk_byp_div + 1));
225
226	sbuf_printf(sbp, "  RNG_JCLK_BYP_SRC:\n    %s\n",
227	    (val & RNG_JCLK_BYP_SRC) ? "Use divided down APB clock" :
228	    "Use RNG clock (APB clock)");
229
230	sbuf_printf(sbp, "  RNG_JCLK_BYP_SEL:\n    %s\n",
231	    (val & RNG_JCLK_BYP_SEL) ? "Bypass internal jitter clock" :
232	    "Use internal jitter clock");
233
234	if ((val & RNG_RBG2X) != 0)
235		sbuf_cat(sbp, "  RNG_RBG2X: RNG 2X SPEED enabled\n");
236
237	if ((val & RNG_RBGEN_BIT) != 0)
238		sbuf_cat(sbp, "  RNG_RBGEN_BIT: RBG enabled\n");
239
240	/* Display RNG status register contents */
241	val = bcm2835_rng_read4(sc, sc->conf->status_reg);
242	sbuf_printf(sbp, "RNG_CTRL (%08x)\n", val);
243	sbuf_printf(sbp, "  RND_VAL: %02x\n",
244	    (val >> sc->conf->count_value_shift) & sc->conf->count_value_mask);
245	sbuf_printf(sbp, "  RND_WARM_CNT: %05x\n", val & sc->conf->warmup_count);
246
247	/* Display FIFO threshold register contents */
248	val = bcm2835_rng_read4(sc, RNG_FF_THRES);
249	sbuf_printf(sbp, "RNG_FF_THRES: %05x\n", val & RNG_FF_THRES_MASK);
250
251	/* Display interrupt mask register contents */
252	val = bcm2835_rng_read4(sc, sc->conf->intr_mask_reg);
253	sbuf_printf(sbp, "RNG_INT_MASK: interrupt %s\n",
254	     ((val & sc->conf->intr_disable_bit) != 0) ? "disabled" : "enabled");
255}
256
257static void
258bcm2835_rng_disable_intr(struct bcm2835_rng_softc *sc)
259{
260	uint32_t mask;
261
262	/* Set the interrupt off bit in the interrupt mask register */
263	mask = bcm2835_rng_read4(sc, sc->conf->intr_mask_reg);
264	mask |= sc->conf->intr_disable_bit;
265	bcm2835_rng_write4(sc, sc->conf->intr_mask_reg, mask);
266}
267
268static void
269bcm2835_rng_start(struct bcm2835_rng_softc *sc)
270{
271	uint32_t ctrl;
272
273	/* Disable the interrupt */
274	if (sc->conf->intr_mask_reg)
275	    bcm2835_rng_disable_intr(sc);
276
277	/* Set the warmup count */
278	if (sc->conf->warmup_count > 0)
279	    bcm2835_rng_write4(sc, sc->conf->status_reg,
280		    sc->conf->warmup_count);
281
282	/* Enable the RNG */
283	ctrl = bcm2835_rng_read4(sc, sc->conf->control_reg);
284	ctrl |= RNG_RBGEN_BIT;
285	if (sc->sc_rbg2x && sc->conf->allow_2x_mode)
286		ctrl |= RNG_RBG2X;
287	bcm2835_rng_write4(sc, sc->conf->control_reg, ctrl);
288}
289
290static void
291bcm2835_rng_stop(struct bcm2835_rng_softc *sc)
292{
293	uint32_t ctrl;
294
295	/* Disable the RNG */
296	ctrl = bcm2835_rng_read4(sc, sc->conf->control_reg);
297	ctrl &= ~RNG_RBGEN_BIT;
298	bcm2835_rng_write4(sc, sc->conf->control_reg, ctrl);
299}
300
301static void
302bcm2835_rng_enqueue_harvest(struct bcm2835_rng_softc *sc, uint32_t nread)
303{
304	char *sc_buf_chunk;
305	uint32_t chunk_size;
306	uint32_t cnt;
307
308	chunk_size = sizeof(((struct harvest_event *)0)->he_entropy);
309	cnt = nread * sizeof(uint32_t);
310	sc_buf_chunk = (void*)sc->sc_buf;
311
312	while (cnt > 0) {
313		uint32_t size;
314
315		size = MIN(cnt, chunk_size);
316
317		random_harvest_queue(sc_buf_chunk, size, RANDOM_PURE_BROADCOM);
318
319		sc_buf_chunk += size;
320		cnt -= size;
321	}
322}
323
324static void
325bcm2835_rng_harvest(void *arg)
326{
327	uint32_t *dest;
328	uint32_t hwcount;
329	u_int cnt, nread, num_avail, num_words;
330	int seen_underrun, num_stalls;
331	struct bcm2835_rng_softc *sc = arg;
332
333	dest = sc->sc_buf;
334	nread = num_words = 0;
335	seen_underrun = num_stalls = 0;
336
337	for (cnt = sizeof(sc->sc_buf) / sizeof(uint32_t); cnt > 0;
338	    cnt -= num_words) {
339		/* Read count register to find out how many words available */
340		hwcount = bcm2835_rng_read4(sc, sc->conf->count_reg);
341		num_avail = (hwcount >> sc->conf->count_value_shift) &
342		    sc->conf->count_value_mask;
343
344		/* If we have none... */
345		if (num_avail == 0) {
346			bcm2835_rng_stat_inc_underrun(sc);
347			if (++seen_underrun >= sc->sc_stall_count) {
348				if (num_stalls++ > 0) {
349					device_printf(sc->sc_dev,
350					    "RNG stalled, disabling device\n");
351					bcm2835_rng_stop(sc);
352					break;
353				} else {
354					device_printf(sc->sc_dev,
355					    "Too many underruns, resetting\n");
356					bcm2835_rng_stop(sc);
357					bcm2835_rng_start(sc);
358					seen_underrun = 0;
359				}
360			}
361			/* Try again */
362			continue;
363		}
364
365		CTR2(KTR_DEV, "%s: %d words available in RNG FIFO",
366		    device_get_nameunit(sc->sc_dev), num_avail);
367
368		/* Pull MIN(num_avail, cnt) words from the FIFO */
369		num_words = (num_avail > cnt) ? cnt : num_avail;
370		bcm2835_rng_read_multi4(sc, sc->conf->data_reg, dest,
371		    num_words);
372		dest += num_words;
373		nread += num_words;
374	}
375
376	bcm2835_rng_enqueue_harvest(sc, nread);
377
378	callout_reset(&sc->sc_rngto, RNG_CALLOUT_TICKS, bcm2835_rng_harvest, sc);
379}
380
381static int
382sysctl_bcm2835_rng_2xspeed(SYSCTL_HANDLER_ARGS)
383{
384	struct bcm2835_rng_softc *sc = arg1;
385	int error, rbg2x;
386
387	rbg2x = sc->sc_rbg2x;
388	error = sysctl_handle_int(oidp, &rbg2x, 0, req);
389	if (error)
390		return (error);
391	if (req->newptr == NULL)
392		return (error);
393	if (rbg2x == sc->sc_rbg2x)
394		return (0);
395
396	/* Reset the RNG */
397	bcm2835_rng_stop(sc);
398	sc->sc_rbg2x = rbg2x;
399	bcm2835_rng_start(sc);
400
401	return (0);
402}
403
404#ifdef BCM2835_RNG_DEBUG_REGISTERS
405static int
406sysctl_bcm2835_rng_dump(SYSCTL_HANDLER_ARGS)
407{
408	struct sbuf sb;
409	struct bcm2835_rng_softc *sc = arg1;
410	int error;
411
412	error = sysctl_wire_old_buffer(req, 0);
413	if (error != 0)
414		return (error);
415	sbuf_new_for_sysctl(&sb, NULL, 128, req);
416	bcm2835_rng_dump_registers(sc, &sb);
417        error = sbuf_finish(&sb);
418        sbuf_delete(&sb);
419        return (error);
420}
421#endif
422
423static int
424bcm2835_rng_probe(device_t dev)
425{
426
427	if (!ofw_bus_status_okay(dev))
428		return (ENXIO);
429
430	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
431		return (ENXIO);
432
433	device_set_desc(dev, "Broadcom BCM2835/BCM2838 RNG");
434
435	return (BUS_PROBE_DEFAULT);
436}
437
438static int
439bcm2835_rng_attach(device_t dev)
440{
441	struct bcm2835_rng_softc *sc;
442	struct sysctl_ctx_list *sysctl_ctx;
443	struct sysctl_oid *sysctl_tree;
444	int error, rid;
445
446	error = 0;
447	sc = device_get_softc(dev);
448	sc->sc_dev = dev;
449
450	sc->conf = (void const*)ofw_bus_search_compatible(dev, compat_data)->ocd_data;
451	KASSERT(sc->conf != NULL, ("bcm2835_rng_attach: sc->conf == NULL"));
452
453	sc->sc_stall_count = RNG_STALL_COUNT_DEFAULT;
454
455	/* Initialize callout */
456	callout_init(&sc->sc_rngto, CALLOUT_MPSAFE);
457
458	TUNABLE_INT_FETCH("bcmrng.stall_count", &sc->sc_stall_count);
459	if (sc->conf->allow_2x_mode)
460	    TUNABLE_INT_FETCH("bcmrng.2xspeed", &sc->sc_rbg2x);
461
462	/* Allocate memory resources */
463	rid = 0;
464	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
465	    RF_ACTIVE);
466	if (sc->sc_mem_res == NULL) {
467		bcm2835_rng_detach(dev);
468		return (ENXIO);
469	}
470
471	/* Start the RNG */
472	bcm2835_rng_start(sc);
473
474	/* Dump the registers if booting verbose */
475	if (bootverbose) {
476		struct sbuf sb;
477
478		(void) sbuf_new(&sb, NULL, 256,
479		    SBUF_AUTOEXTEND | SBUF_INCLUDENUL);
480		bcm2835_rng_dump_registers(sc, &sb);
481		sbuf_trim(&sb);
482		error = sbuf_finish(&sb);
483		if (error == 0)
484			device_printf(dev, "%s", sbuf_data(&sb));
485		sbuf_delete(&sb);
486	}
487
488	sysctl_ctx = device_get_sysctl_ctx(dev);
489	sysctl_tree = device_get_sysctl_tree(dev);
490	SYSCTL_ADD_LONG(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO,
491	    "underrun", CTLFLAG_RD, &sc->sc_underrun,
492	    "Number of FIFO underruns");
493	if (sc->conf->allow_2x_mode)
494		SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO,
495			"2xspeed", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, sc, 0,
496			sysctl_bcm2835_rng_2xspeed, "I", "Enable RBG 2X SPEED");
497	SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO,
498	    "stall_count", CTLFLAG_RW, &sc->sc_stall_count,
499	    RNG_STALL_COUNT_DEFAULT, "Number of underruns to assume RNG stall");
500#ifdef BCM2835_RNG_DEBUG_REGISTERS
501	SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO,
502	    "dumpregs", CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_NEEDGIANT, sc, 0,
503	    sysctl_bcm2835_rng_dump, "S", "Dump RNG registers");
504#endif
505
506	/*
507	 * Schedule the initial harvesting one second from now, which should give the
508	 * hardware RNG plenty of time to generate the first random bytes.
509	 */
510	callout_reset(&sc->sc_rngto, hz, bcm2835_rng_harvest, sc);
511
512	return (0);
513}
514
515static int
516bcm2835_rng_detach(device_t dev)
517{
518	struct bcm2835_rng_softc *sc;
519
520	sc = device_get_softc(dev);
521
522	/* Stop the RNG */
523	bcm2835_rng_stop(sc);
524
525	/* Drain the callout it */
526	callout_drain(&sc->sc_rngto);
527
528	/* Release memory resource */
529	if (sc->sc_mem_res != NULL)
530		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
531
532	return (0);
533}
534
535static device_method_t bcm2835_rng_methods[] = {
536	/* Device interface */
537	DEVMETHOD(device_probe,		bcm2835_rng_probe),
538	DEVMETHOD(device_attach,	bcm2835_rng_attach),
539	DEVMETHOD(device_detach,	bcm2835_rng_detach),
540
541	DEVMETHOD_END
542};
543
544static driver_t bcm2835_rng_driver = {
545	"bcmrng",
546	bcm2835_rng_methods,
547	sizeof(struct bcm2835_rng_softc)
548};
549
550DRIVER_MODULE(bcm2835_rng, simplebus, bcm2835_rng_driver, 0, 0);
551DRIVER_MODULE(bcm2835_rng, ofwbus, bcm2835_rng_driver, 0, 0);
552MODULE_VERSION(bcm2835_rng, 1);
553MODULE_DEPEND(bcm2835_rng, randomdev, 1, 1, 1);
554