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