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 #include <sys/cdefs.h>
28
29 __FBSDID("$FreeBSD$");
30
31 #include <sys/param.h>
32 #include <sys/kernel.h>
33 #include <sys/lock.h>
34 #include <sys/malloc.h>
35 #include <sys/module.h>
36 #include <sys/random.h>
37 #include <sys/sbuf.h>
38 #include <sys/sysctl.h>
39 #include <sys/selinfo.h>
40 #include <sys/systm.h>
41 #include <sys/bus.h>
42 #include <sys/rman.h>
43
44 #include <machine/bus.h>
45 #include <machine/resource.h>
46
47 #include <dev/ofw/openfirm.h>
48 #include <dev/ofw/ofw_bus.h>
49 #include <dev/ofw/ofw_bus_subr.h>
50
51 #include <dev/random/randomdev.h>
52 #include <dev/random/random_harvestq.h>
53
54 static device_attach_t bcm2835_rng_attach;
55 static device_detach_t bcm2835_rng_detach;
56 static device_probe_t bcm2835_rng_probe;
57
58 #define RNG_CTRL 0x00 /* RNG Control Register */
59 #define RNG_COMBLK1_OSC 0x003f0000 /* Combiner Blk 1 Oscillator */
60 #define RNG_COMBLK1_OSC_SHIFT 16
61 #define RNG_COMBLK2_OSC 0x0fc00000 /* Combiner Blk 2 Oscillator */
62 #define RNG_COMBLK2_OSC_SHIFT 22
63 #define RNG_JCLK_BYP_DIV_CNT 0x0000ff00 /* Jitter clk bypass divider
64 count */
65 #define RNG_JCLK_BYP_DIV_CNT_SHIFT 8
66 #define RNG_JCLK_BYP_SRC 0x00000020 /* Jitter clk bypass source */
67 #define RNG_JCLK_BYP_SEL 0x00000010 /* Jitter clk bypass select */
68 #define RNG_RBG2X 0x00000002 /* RBG 2X SPEED */
69 #define RNG_RBGEN_BIT 0x00000001 /* Enable RNG bit */
70
71 #define RNG_STATUS 0x04 /* RNG status register */
72 #define RND_VAL_SHIFT 24 /* Shift for valid words */
73 #define RND_VAL_MASK 0x000000ff /* Number valid words mask */
74 #define RND_VAL_WARM_CNT 0x40000 /* RNG Warm Up count */
75 #define RND_WARM_CNT 0xfffff /* RNG Warm Up Count mask */
76
77 #define RNG_DATA 0x08 /* RNG Data Register */
78 #define RNG_FF_THRES 0x0c
79 #define RNG_FF_THRES_MASK 0x0000001f
80
81 #define RNG_INT_MASK 0x10
82 #define RNG_INT_OFF_BIT 0x00000001
83
84 #define RNG_FF_DEFAULT 0x10 /* FIFO threshold default */
85
86 #define RNG_FIFO_WORDS (RNG_FF_DEFAULT / sizeof(uint32_t))
87
88 #define RNG_NUM_OSCILLATORS 6
89 #define RNG_STALL_COUNT_DEFAULT 10
90
91 #define RNG_CALLOUT_TICKS (hz * 4)
92
93 struct bcm2835_rng_softc {
94 device_t sc_dev;
95 struct resource * sc_mem_res;
96 struct resource * sc_irq_res;
97 void * sc_intr_hdl;
98 uint32_t sc_buf[RNG_FIFO_WORDS];
99 struct callout sc_rngto;
100 int sc_stall_count;
101 int sc_rbg2x;
102 long sc_underrun;
103 };
104
105 static struct ofw_compat_data compat_data[] = {
106 {"broadcom,bcm2835-rng", 1},
107 {"brcm,bcm2835-rng", 1},
108 {NULL, 0}
109 };
110
111 static __inline void
bcm2835_rng_stat_inc_underrun(struct bcm2835_rng_softc * sc)112 bcm2835_rng_stat_inc_underrun(struct bcm2835_rng_softc *sc)
113 {
114
115 atomic_add_long(&sc->sc_underrun, 1);
116 }
117
118 static __inline uint32_t
bcm2835_rng_read4(struct bcm2835_rng_softc * sc,bus_size_t off)119 bcm2835_rng_read4(struct bcm2835_rng_softc *sc, bus_size_t off)
120 {
121
122 return bus_read_4(sc->sc_mem_res, off);
123 }
124
125 static __inline void
bcm2835_rng_read_multi4(struct bcm2835_rng_softc * sc,bus_size_t off,uint32_t * datap,bus_size_t count)126 bcm2835_rng_read_multi4(struct bcm2835_rng_softc *sc, bus_size_t off,
127 uint32_t *datap, bus_size_t count)
128 {
129
130 bus_read_multi_4(sc->sc_mem_res, off, datap, count);
131 }
132
133 static __inline void
bcm2835_rng_write4(struct bcm2835_rng_softc * sc,bus_size_t off,uint32_t val)134 bcm2835_rng_write4(struct bcm2835_rng_softc *sc, bus_size_t off, uint32_t val)
135 {
136
137 bus_write_4(sc->sc_mem_res, off, val);
138 }
139
140 static void
bcm2835_rng_dump_registers(struct bcm2835_rng_softc * sc,struct sbuf * sbp)141 bcm2835_rng_dump_registers(struct bcm2835_rng_softc *sc, struct sbuf *sbp)
142 {
143 uint32_t comblk2_osc, comblk1_osc, jclk_byp_div, val;
144 int i;
145
146 /* Display RNG control register contents */
147 val = bcm2835_rng_read4(sc, RNG_CTRL);
148 sbuf_printf(sbp, "RNG_CTRL (%08x)\n", val);
149
150 comblk2_osc = (val & RNG_COMBLK2_OSC) >> RNG_COMBLK2_OSC_SHIFT;
151 sbuf_printf(sbp, " RNG_COMBLK2_OSC (%02x)\n", comblk2_osc);
152 for (i = 0; i < RNG_NUM_OSCILLATORS; i++)
153 if ((comblk2_osc & (1 << i)) == 0)
154 sbuf_printf(sbp, " Oscillator %d enabled\n", i + 1);
155
156 comblk1_osc = (val & RNG_COMBLK1_OSC) >> RNG_COMBLK1_OSC_SHIFT;
157 sbuf_printf(sbp, " RNG_COMBLK1_OSC (%02x)\n", comblk1_osc);
158 for (i = 0; i < RNG_NUM_OSCILLATORS; i++)
159 if ((comblk1_osc & (1 << i)) == 0)
160 sbuf_printf(sbp, " Oscillator %d enabled\n", i + 1);
161
162 jclk_byp_div = (val & RNG_JCLK_BYP_DIV_CNT) >>
163 RNG_JCLK_BYP_DIV_CNT_SHIFT;
164 sbuf_printf(sbp,
165 " RNG_JCLK_BYP_DIV_CNT (%02x)\n APB clock frequency / %d\n",
166 jclk_byp_div, 2 * (jclk_byp_div + 1));
167
168 sbuf_printf(sbp, " RNG_JCLK_BYP_SRC:\n %s\n",
169 (val & RNG_JCLK_BYP_SRC) ? "Use divided down APB clock" :
170 "Use RNG clock (APB clock)");
171
172 sbuf_printf(sbp, " RNG_JCLK_BYP_SEL:\n %s\n",
173 (val & RNG_JCLK_BYP_SEL) ? "Bypass internal jitter clock" :
174 "Use internal jitter clock");
175
176 if ((val & RNG_RBG2X) != 0)
177 sbuf_cat(sbp, " RNG_RBG2X: RNG 2X SPEED enabled\n");
178
179 if ((val & RNG_RBGEN_BIT) != 0)
180 sbuf_cat(sbp, " RNG_RBGEN_BIT: RBG enabled\n");
181
182 /* Display RNG status register contents */
183 val = bcm2835_rng_read4(sc, RNG_STATUS);
184 sbuf_printf(sbp, "RNG_CTRL (%08x)\n", val);
185 sbuf_printf(sbp, " RND_VAL: %02x\n",
186 (val >> RND_VAL_SHIFT) & RND_VAL_MASK);
187 sbuf_printf(sbp, " RND_WARM_CNT: %05x\n", val & RND_WARM_CNT);
188
189 /* Display FIFO threshold register contents */
190 val = bcm2835_rng_read4(sc, RNG_FF_THRES);
191 sbuf_printf(sbp, "RNG_FF_THRES: %05x\n", val & RNG_FF_THRES_MASK);
192
193 /* Display interrupt mask register contents */
194 val = bcm2835_rng_read4(sc, RNG_INT_MASK);
195 sbuf_printf(sbp, "RNG_INT_MASK: interrupt %s\n",
196 ((val & RNG_INT_OFF_BIT) != 0) ? "disabled" : "enabled");
197 }
198
199 static void
bcm2835_rng_disable_intr(struct bcm2835_rng_softc * sc)200 bcm2835_rng_disable_intr(struct bcm2835_rng_softc *sc)
201 {
202 uint32_t mask;
203
204 /* Set the interrupt off bit in the interrupt mask register */
205 mask = bcm2835_rng_read4(sc, RNG_INT_MASK);
206 mask |= RNG_INT_OFF_BIT;
207 bcm2835_rng_write4(sc, RNG_INT_MASK, mask);
208 }
209
210 static void
bcm2835_rng_start(struct bcm2835_rng_softc * sc)211 bcm2835_rng_start(struct bcm2835_rng_softc *sc)
212 {
213 uint32_t ctrl;
214
215 /* Disable the interrupt */
216 bcm2835_rng_disable_intr(sc);
217
218 /* Set the warmup count */
219 bcm2835_rng_write4(sc, RNG_STATUS, RND_VAL_WARM_CNT);
220
221 /* Enable the RNG */
222 ctrl = bcm2835_rng_read4(sc, RNG_CTRL);
223 ctrl |= RNG_RBGEN_BIT;
224 if (sc->sc_rbg2x)
225 ctrl |= RNG_RBG2X;
226 bcm2835_rng_write4(sc, RNG_CTRL, ctrl);
227 }
228
229 static void
bcm2835_rng_stop(struct bcm2835_rng_softc * sc)230 bcm2835_rng_stop(struct bcm2835_rng_softc *sc)
231 {
232 uint32_t ctrl;
233
234 /* Disable the RNG */
235 ctrl = bcm2835_rng_read4(sc, RNG_CTRL);
236 ctrl &= ~RNG_RBGEN_BIT;
237 bcm2835_rng_write4(sc, RNG_CTRL, ctrl);
238 }
239
240 static void
bcm2835_rng_harvest(void * arg)241 bcm2835_rng_harvest(void *arg)
242 {
243 uint32_t *dest;
244 uint32_t status;
245 u_int cnt, nread, num_avail, num_words;
246 int seen_underrun, num_stalls;
247 struct bcm2835_rng_softc *sc = arg;
248
249 dest = sc->sc_buf;
250 nread = num_words = 0;
251 seen_underrun = num_stalls = 0;
252 for (cnt = sizeof(sc->sc_buf) / sizeof(uint32_t); cnt > 0;
253 cnt -= num_words) {
254 /* Read status register to find out how many words available */
255 status = bcm2835_rng_read4(sc, RNG_STATUS);
256 num_avail = (status >> RND_VAL_SHIFT) & RND_VAL_MASK;
257
258 /* If we have none... */
259 if (num_avail == 0) {
260 bcm2835_rng_stat_inc_underrun(sc);
261 if (++seen_underrun >= sc->sc_stall_count) {
262 if (num_stalls++ > 0) {
263 device_printf(sc->sc_dev,
264 "RNG stalled, disabling device\n");
265 bcm2835_rng_stop(sc);
266 break;
267 } else {
268 device_printf(sc->sc_dev,
269 "Too many underruns, resetting\n");
270 bcm2835_rng_stop(sc);
271 bcm2835_rng_start(sc);
272 seen_underrun = 0;
273 }
274 }
275 /* Try again */
276 continue;
277 }
278
279 CTR2(KTR_DEV, "%s: %d words available in RNG FIFO",
280 device_get_nameunit(sc->sc_dev), num_avail);
281
282 /* Pull MIN(num_avail, cnt) words from the FIFO */
283 num_words = (num_avail > cnt) ? cnt : num_avail;
284 bcm2835_rng_read_multi4(sc, RNG_DATA, dest,
285 num_words);
286 dest += num_words;
287 nread += num_words;
288 }
289
290 cnt = nread * sizeof(uint32_t);
291 if (cnt > 0)
292 random_harvest_queue(sc->sc_buf, cnt, cnt * NBBY / 2,
293 RANDOM_PURE_BROADCOM);
294
295 callout_reset(&sc->sc_rngto, RNG_CALLOUT_TICKS, bcm2835_rng_harvest, sc);
296 }
297
298 static int
sysctl_bcm2835_rng_2xspeed(SYSCTL_HANDLER_ARGS)299 sysctl_bcm2835_rng_2xspeed(SYSCTL_HANDLER_ARGS)
300 {
301 struct bcm2835_rng_softc *sc = arg1;
302 int error, rbg2x;
303
304 rbg2x = sc->sc_rbg2x;
305 error = sysctl_handle_int(oidp, &rbg2x, 0, req);
306 if (error)
307 return (error);
308 if (req->newptr == NULL)
309 return (error);
310 if (rbg2x == sc->sc_rbg2x)
311 return (0);
312
313 /* Reset the RNG */
314 bcm2835_rng_stop(sc);
315 sc->sc_rbg2x = rbg2x;
316 bcm2835_rng_start(sc);
317
318 return (0);
319 }
320
321 #ifdef BCM2835_RNG_DEBUG_REGISTERS
322 static int
sysctl_bcm2835_rng_dump(SYSCTL_HANDLER_ARGS)323 sysctl_bcm2835_rng_dump(SYSCTL_HANDLER_ARGS)
324 {
325 struct sbuf sb;
326 struct bcm2835_rng_softc *sc = arg1;
327 int error;
328
329 error = sysctl_wire_old_buffer(req, 0);
330 if (error != 0)
331 return (error);
332 sbuf_new_for_sysctl(&sb, NULL, 128, req);
333 bcm2835_rng_dump_registers(sc, &sb);
334 error = sbuf_finish(&sb);
335 sbuf_delete(&sb);
336 return (error);
337 }
338 #endif
339
340 static int
bcm2835_rng_probe(device_t dev)341 bcm2835_rng_probe(device_t dev)
342 {
343
344 if (!ofw_bus_status_okay(dev))
345 return (ENXIO);
346
347 if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
348 return (ENXIO);
349
350 device_set_desc(dev, "Broadcom BCM2835 RNG");
351
352 return (BUS_PROBE_DEFAULT);
353 }
354
355 static int
bcm2835_rng_attach(device_t dev)356 bcm2835_rng_attach(device_t dev)
357 {
358 struct bcm2835_rng_softc *sc;
359 struct sysctl_ctx_list *sysctl_ctx;
360 struct sysctl_oid *sysctl_tree;
361 int error, rid;
362
363 error = 0;
364 sc = device_get_softc(dev);
365 sc->sc_dev = dev;
366 sc->sc_stall_count = RNG_STALL_COUNT_DEFAULT;
367
368 /* Initialize callout */
369 callout_init(&sc->sc_rngto, CALLOUT_MPSAFE);
370
371 TUNABLE_INT_FETCH("bcmrng.2xspeed", &sc->sc_rbg2x);
372 TUNABLE_INT_FETCH("bcmrng.stall_count", &sc->sc_stall_count);
373
374 /* Allocate memory resources */
375 rid = 0;
376 sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
377 RF_ACTIVE);
378 if (sc->sc_mem_res == NULL) {
379 bcm2835_rng_detach(dev);
380 return (ENXIO);
381 }
382
383 /* Start the RNG */
384 bcm2835_rng_start(sc);
385
386 /* Dump the registers if booting verbose */
387 if (bootverbose) {
388 struct sbuf sb;
389
390 (void) sbuf_new(&sb, NULL, 256,
391 SBUF_AUTOEXTEND | SBUF_INCLUDENUL);
392 bcm2835_rng_dump_registers(sc, &sb);
393 sbuf_trim(&sb);
394 error = sbuf_finish(&sb);
395 if (error == 0)
396 device_printf(dev, "%s", sbuf_data(&sb));
397 sbuf_delete(&sb);
398 }
399
400 sysctl_ctx = device_get_sysctl_ctx(dev);
401 sysctl_tree = device_get_sysctl_tree(dev);
402 SYSCTL_ADD_LONG(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO,
403 "underrun", CTLFLAG_RD, &sc->sc_underrun,
404 "Number of FIFO underruns");
405 SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO,
406 "2xspeed", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
407 sysctl_bcm2835_rng_2xspeed, "I", "Enable RBG 2X SPEED");
408 SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO,
409 "stall_count", CTLFLAG_RW, &sc->sc_stall_count,
410 RNG_STALL_COUNT_DEFAULT, "Number of underruns to assume RNG stall");
411 #ifdef BCM2835_RNG_DEBUG_REGISTERS
412 SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO,
413 "dumpregs", CTLTYPE_STRING | CTLFLAG_RD, sc, 0,
414 sysctl_bcm2835_rng_dump, "S", "Dump RNG registers");
415 #endif
416
417 /*
418 * Schedule the initial harvesting one second from now, which should give the
419 * hardware RNG plenty of time to generate the first random bytes.
420 */
421 callout_reset(&sc->sc_rngto, hz, bcm2835_rng_harvest, sc);
422
423 return (0);
424 }
425
426 static int
bcm2835_rng_detach(device_t dev)427 bcm2835_rng_detach(device_t dev)
428 {
429 struct bcm2835_rng_softc *sc;
430
431 sc = device_get_softc(dev);
432
433 /* Stop the RNG */
434 bcm2835_rng_stop(sc);
435
436 /* Drain the callout it */
437 callout_drain(&sc->sc_rngto);
438
439 /* Release memory resource */
440 if (sc->sc_mem_res != NULL)
441 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
442
443 return (0);
444 }
445
446 static device_method_t bcm2835_rng_methods[] = {
447 /* Device interface */
448 DEVMETHOD(device_probe, bcm2835_rng_probe),
449 DEVMETHOD(device_attach, bcm2835_rng_attach),
450 DEVMETHOD(device_detach, bcm2835_rng_detach),
451
452 DEVMETHOD_END
453 };
454
455 static driver_t bcm2835_rng_driver = {
456 "bcmrng",
457 bcm2835_rng_methods,
458 sizeof(struct bcm2835_rng_softc)
459 };
460 static devclass_t bcm2835_rng_devclass;
461
462 DRIVER_MODULE(bcm2835_rng, simplebus, bcm2835_rng_driver,
463 bcm2835_rng_devclass, 0, 0);
464 DRIVER_MODULE(bcm2835_rng, ofwbus, bcm2835_rng_driver, bcm2835_rng_devclass, 0,
465 0);
466 MODULE_VERSION(bcm2835_rng, 1);
467 MODULE_DEPEND(bcm2835_rng, randomdev, 1, 1, 1);
468