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 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 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 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 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 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 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 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 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 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 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 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 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 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 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