arm64: Add support for bcm2838 RNG
The hardware random number generator of the RPi4 differs slightly from the version found on the RPi3. This commit extends the existing bcm2835_rng driver to function on the RPi4. Submitted by: James Mintram <me at jamesrm dot com> Reviewed by: markm, cem, delphij Approved by: csprng(cem, markm) MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D22493
This commit is contained in:
parent
c743a6bd4f
commit
e797dc58bd
@ -69,21 +69,26 @@ static device_probe_t bcm2835_rng_probe;
|
|||||||
#define RNG_RBG2X 0x00000002 /* RBG 2X SPEED */
|
#define RNG_RBG2X 0x00000002 /* RBG 2X SPEED */
|
||||||
#define RNG_RBGEN_BIT 0x00000001 /* Enable RNG bit */
|
#define RNG_RBGEN_BIT 0x00000001 /* Enable RNG bit */
|
||||||
|
|
||||||
#define RNG_STATUS 0x04 /* RNG status register */
|
#define BCM2835_RNG_STATUS 0x04 /* BCM2835 RNG status register */
|
||||||
#define RND_VAL_SHIFT 24 /* Shift for valid words */
|
#define BCM2838_RNG_STATUS 0x18 /* BCM2838 RNG status register */
|
||||||
#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 BCM2838_RNG_COUNT 0x24 /* How many values available */
|
||||||
|
#define BCM2838_COUNT_VAL_MASK 0x000000ff
|
||||||
|
|
||||||
|
#define BCM2835_RND_VAL_SHIFT 24 /* Shift for valid words */
|
||||||
|
#define BCM2835_RND_VAL_MASK 0x000000ff /* Number valid words mask */
|
||||||
|
#define BCM2835_RND_VAL_WARM_CNT 0x40000 /* RNG Warm Up count */
|
||||||
|
#define BCM2835_RND_WARM_CNT 0xfffff /* RNG Warm Up Count mask */
|
||||||
|
|
||||||
|
#define BCM2835_RNG_DATA 0x08 /* RNG Data Register */
|
||||||
|
#define BCM2838_RNG_DATA 0x20
|
||||||
#define RNG_FF_THRES 0x0c
|
#define RNG_FF_THRES 0x0c
|
||||||
#define RNG_FF_THRES_MASK 0x0000001f
|
#define RNG_FF_THRES_MASK 0x0000001f
|
||||||
|
|
||||||
#define RNG_INT_MASK 0x10
|
#define BCM2835_RNG_INT_MASK 0x10
|
||||||
#define RNG_INT_OFF_BIT 0x00000001
|
#define BCM2835_RNG_INT_OFF_BIT 0x00000001
|
||||||
|
|
||||||
#define RNG_FF_DEFAULT 0x10 /* FIFO threshold default */
|
#define RNG_FF_DEFAULT 0x10 /* FIFO threshold default */
|
||||||
|
|
||||||
#define RNG_FIFO_WORDS (RNG_FF_DEFAULT / sizeof(uint32_t))
|
#define RNG_FIFO_WORDS (RNG_FF_DEFAULT / sizeof(uint32_t))
|
||||||
|
|
||||||
#define RNG_NUM_OSCILLATORS 6
|
#define RNG_NUM_OSCILLATORS 6
|
||||||
@ -91,11 +96,55 @@ static device_probe_t bcm2835_rng_probe;
|
|||||||
|
|
||||||
#define RNG_CALLOUT_TICKS (hz * 4)
|
#define RNG_CALLOUT_TICKS (hz * 4)
|
||||||
|
|
||||||
|
struct bcm_rng_conf {
|
||||||
|
bus_size_t control_reg;
|
||||||
|
bus_size_t status_reg;
|
||||||
|
bus_size_t count_reg;
|
||||||
|
bus_size_t data_reg;
|
||||||
|
bus_size_t intr_mask_reg;
|
||||||
|
uint32_t intr_disable_bit;
|
||||||
|
uint32_t count_value_shift;
|
||||||
|
uint32_t count_value_mask;
|
||||||
|
uint32_t warmup_count;
|
||||||
|
bool allow_2x_mode;
|
||||||
|
bool can_diagnose;
|
||||||
|
/* XXX diag regs */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct bcm_rng_conf bcm2835_rng_conf = {
|
||||||
|
.control_reg = RNG_CTRL,
|
||||||
|
.status_reg = BCM2835_RNG_STATUS,
|
||||||
|
.count_reg = BCM2835_RNG_STATUS, /* Same register */
|
||||||
|
.data_reg = BCM2835_RNG_DATA,
|
||||||
|
.intr_mask_reg = BCM2835_RNG_INT_MASK,
|
||||||
|
.intr_disable_bit = BCM2835_RNG_INT_OFF_BIT,
|
||||||
|
.count_value_shift = BCM2835_RND_VAL_SHIFT,
|
||||||
|
.count_value_mask = BCM2835_RND_VAL_MASK,
|
||||||
|
.warmup_count = BCM2835_RND_VAL_WARM_CNT,
|
||||||
|
.allow_2x_mode = true,
|
||||||
|
.can_diagnose = true
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct bcm_rng_conf bcm2838_rng_conf = {
|
||||||
|
.control_reg = RNG_CTRL,
|
||||||
|
.status_reg = BCM2838_RNG_STATUS,
|
||||||
|
.count_reg = BCM2838_RNG_COUNT,
|
||||||
|
.data_reg = BCM2838_RNG_DATA,
|
||||||
|
.intr_mask_reg = 0,
|
||||||
|
.intr_disable_bit = 0,
|
||||||
|
.count_value_shift = 0,
|
||||||
|
.count_value_mask = BCM2838_COUNT_VAL_MASK,
|
||||||
|
.warmup_count = 0,
|
||||||
|
.allow_2x_mode = false,
|
||||||
|
.can_diagnose = false
|
||||||
|
};
|
||||||
|
|
||||||
struct bcm2835_rng_softc {
|
struct bcm2835_rng_softc {
|
||||||
device_t sc_dev;
|
device_t sc_dev;
|
||||||
struct resource * sc_mem_res;
|
struct resource * sc_mem_res;
|
||||||
struct resource * sc_irq_res;
|
struct resource * sc_irq_res;
|
||||||
void * sc_intr_hdl;
|
void * sc_intr_hdl;
|
||||||
|
struct bcm_rng_conf const* conf;
|
||||||
uint32_t sc_buf[RNG_FIFO_WORDS];
|
uint32_t sc_buf[RNG_FIFO_WORDS];
|
||||||
struct callout sc_rngto;
|
struct callout sc_rngto;
|
||||||
int sc_stall_count;
|
int sc_stall_count;
|
||||||
@ -104,8 +153,15 @@ struct bcm2835_rng_softc {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static struct ofw_compat_data compat_data[] = {
|
static struct ofw_compat_data compat_data[] = {
|
||||||
{"broadcom,bcm2835-rng", 1},
|
{"broadcom,bcm2835-rng", (uintptr_t)&bcm2835_rng_conf},
|
||||||
{"brcm,bcm2835-rng", 1},
|
{"brcm,bcm2835-rng", (uintptr_t)&bcm2835_rng_conf},
|
||||||
|
|
||||||
|
{"brcm,bcm2711-rng200", (uintptr_t)&bcm2838_rng_conf},
|
||||||
|
{"brcm,bcm2838-rng", (uintptr_t)&bcm2838_rng_conf},
|
||||||
|
{"brcm,bcm2838-rng200", (uintptr_t)&bcm2838_rng_conf},
|
||||||
|
{"brcm,bcm7211-rng", (uintptr_t)&bcm2838_rng_conf},
|
||||||
|
{"brcm,bcm7278-rng", (uintptr_t)&bcm2838_rng_conf},
|
||||||
|
{"brcm,iproc-rng200", (uintptr_t)&bcm2838_rng_conf},
|
||||||
{NULL, 0}
|
{NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -144,8 +200,12 @@ bcm2835_rng_dump_registers(struct bcm2835_rng_softc *sc, struct sbuf *sbp)
|
|||||||
uint32_t comblk2_osc, comblk1_osc, jclk_byp_div, val;
|
uint32_t comblk2_osc, comblk1_osc, jclk_byp_div, val;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (!sc->conf->can_diagnose)
|
||||||
|
/* Not implemented. */
|
||||||
|
return;
|
||||||
|
|
||||||
/* Display RNG control register contents */
|
/* Display RNG control register contents */
|
||||||
val = bcm2835_rng_read4(sc, RNG_CTRL);
|
val = bcm2835_rng_read4(sc, sc->conf->control_reg);
|
||||||
sbuf_printf(sbp, "RNG_CTRL (%08x)\n", val);
|
sbuf_printf(sbp, "RNG_CTRL (%08x)\n", val);
|
||||||
|
|
||||||
comblk2_osc = (val & RNG_COMBLK2_OSC) >> RNG_COMBLK2_OSC_SHIFT;
|
comblk2_osc = (val & RNG_COMBLK2_OSC) >> RNG_COMBLK2_OSC_SHIFT;
|
||||||
@ -181,20 +241,20 @@ bcm2835_rng_dump_registers(struct bcm2835_rng_softc *sc, struct sbuf *sbp)
|
|||||||
sbuf_cat(sbp, " RNG_RBGEN_BIT: RBG enabled\n");
|
sbuf_cat(sbp, " RNG_RBGEN_BIT: RBG enabled\n");
|
||||||
|
|
||||||
/* Display RNG status register contents */
|
/* Display RNG status register contents */
|
||||||
val = bcm2835_rng_read4(sc, RNG_STATUS);
|
val = bcm2835_rng_read4(sc, sc->conf->status_reg);
|
||||||
sbuf_printf(sbp, "RNG_CTRL (%08x)\n", val);
|
sbuf_printf(sbp, "RNG_CTRL (%08x)\n", val);
|
||||||
sbuf_printf(sbp, " RND_VAL: %02x\n",
|
sbuf_printf(sbp, " RND_VAL: %02x\n",
|
||||||
(val >> RND_VAL_SHIFT) & RND_VAL_MASK);
|
(val >> sc->conf->count_value_shift) & sc->conf->count_value_mask);
|
||||||
sbuf_printf(sbp, " RND_WARM_CNT: %05x\n", val & RND_WARM_CNT);
|
sbuf_printf(sbp, " RND_WARM_CNT: %05x\n", val & sc->conf->warmup_count);
|
||||||
|
|
||||||
/* Display FIFO threshold register contents */
|
/* Display FIFO threshold register contents */
|
||||||
val = bcm2835_rng_read4(sc, RNG_FF_THRES);
|
val = bcm2835_rng_read4(sc, RNG_FF_THRES);
|
||||||
sbuf_printf(sbp, "RNG_FF_THRES: %05x\n", val & RNG_FF_THRES_MASK);
|
sbuf_printf(sbp, "RNG_FF_THRES: %05x\n", val & RNG_FF_THRES_MASK);
|
||||||
|
|
||||||
/* Display interrupt mask register contents */
|
/* Display interrupt mask register contents */
|
||||||
val = bcm2835_rng_read4(sc, RNG_INT_MASK);
|
val = bcm2835_rng_read4(sc, sc->conf->intr_mask_reg);
|
||||||
sbuf_printf(sbp, "RNG_INT_MASK: interrupt %s\n",
|
sbuf_printf(sbp, "RNG_INT_MASK: interrupt %s\n",
|
||||||
((val & RNG_INT_OFF_BIT) != 0) ? "disabled" : "enabled");
|
((val & sc->conf->intr_disable_bit) != 0) ? "disabled" : "enabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -203,9 +263,9 @@ bcm2835_rng_disable_intr(struct bcm2835_rng_softc *sc)
|
|||||||
uint32_t mask;
|
uint32_t mask;
|
||||||
|
|
||||||
/* Set the interrupt off bit in the interrupt mask register */
|
/* Set the interrupt off bit in the interrupt mask register */
|
||||||
mask = bcm2835_rng_read4(sc, RNG_INT_MASK);
|
mask = bcm2835_rng_read4(sc, sc->conf->intr_mask_reg);
|
||||||
mask |= RNG_INT_OFF_BIT;
|
mask |= sc->conf->intr_disable_bit;
|
||||||
bcm2835_rng_write4(sc, RNG_INT_MASK, mask);
|
bcm2835_rng_write4(sc, sc->conf->intr_mask_reg, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -214,17 +274,20 @@ bcm2835_rng_start(struct bcm2835_rng_softc *sc)
|
|||||||
uint32_t ctrl;
|
uint32_t ctrl;
|
||||||
|
|
||||||
/* Disable the interrupt */
|
/* Disable the interrupt */
|
||||||
bcm2835_rng_disable_intr(sc);
|
if (sc->conf->intr_mask_reg)
|
||||||
|
bcm2835_rng_disable_intr(sc);
|
||||||
|
|
||||||
/* Set the warmup count */
|
/* Set the warmup count */
|
||||||
bcm2835_rng_write4(sc, RNG_STATUS, RND_VAL_WARM_CNT);
|
if (sc->conf->warmup_count > 0)
|
||||||
|
bcm2835_rng_write4(sc, sc->conf->status_reg,
|
||||||
|
sc->conf->warmup_count);
|
||||||
|
|
||||||
/* Enable the RNG */
|
/* Enable the RNG */
|
||||||
ctrl = bcm2835_rng_read4(sc, RNG_CTRL);
|
ctrl = bcm2835_rng_read4(sc, sc->conf->control_reg);
|
||||||
ctrl |= RNG_RBGEN_BIT;
|
ctrl |= RNG_RBGEN_BIT;
|
||||||
if (sc->sc_rbg2x)
|
if (sc->sc_rbg2x && sc->conf->allow_2x_mode)
|
||||||
ctrl |= RNG_RBG2X;
|
ctrl |= RNG_RBG2X;
|
||||||
bcm2835_rng_write4(sc, RNG_CTRL, ctrl);
|
bcm2835_rng_write4(sc, sc->conf->control_reg, ctrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -233,16 +296,39 @@ bcm2835_rng_stop(struct bcm2835_rng_softc *sc)
|
|||||||
uint32_t ctrl;
|
uint32_t ctrl;
|
||||||
|
|
||||||
/* Disable the RNG */
|
/* Disable the RNG */
|
||||||
ctrl = bcm2835_rng_read4(sc, RNG_CTRL);
|
ctrl = bcm2835_rng_read4(sc, sc->conf->control_reg);
|
||||||
ctrl &= ~RNG_RBGEN_BIT;
|
ctrl &= ~RNG_RBGEN_BIT;
|
||||||
bcm2835_rng_write4(sc, RNG_CTRL, ctrl);
|
bcm2835_rng_write4(sc, sc->conf->control_reg, ctrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
bcm2835_rng_enqueue_harvest(struct bcm2835_rng_softc *sc, uint32_t nread)
|
||||||
|
{
|
||||||
|
char *sc_buf_chunk;
|
||||||
|
uint32_t chunk_size;
|
||||||
|
uint32_t cnt;
|
||||||
|
|
||||||
|
chunk_size = sizeof(((struct harvest_event *)0)->he_entropy);
|
||||||
|
cnt = nread * sizeof(uint32_t);
|
||||||
|
sc_buf_chunk = (void*)sc->sc_buf;
|
||||||
|
|
||||||
|
while (cnt > 0) {
|
||||||
|
uint32_t size;
|
||||||
|
|
||||||
|
size = MIN(cnt, chunk_size);
|
||||||
|
|
||||||
|
random_harvest_queue(sc_buf_chunk, size, RANDOM_PURE_BROADCOM);
|
||||||
|
|
||||||
|
sc_buf_chunk += size;
|
||||||
|
cnt -= size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
bcm2835_rng_harvest(void *arg)
|
bcm2835_rng_harvest(void *arg)
|
||||||
{
|
{
|
||||||
uint32_t *dest;
|
uint32_t *dest;
|
||||||
uint32_t status;
|
uint32_t hwcount;
|
||||||
u_int cnt, nread, num_avail, num_words;
|
u_int cnt, nread, num_avail, num_words;
|
||||||
int seen_underrun, num_stalls;
|
int seen_underrun, num_stalls;
|
||||||
struct bcm2835_rng_softc *sc = arg;
|
struct bcm2835_rng_softc *sc = arg;
|
||||||
@ -250,11 +336,13 @@ bcm2835_rng_harvest(void *arg)
|
|||||||
dest = sc->sc_buf;
|
dest = sc->sc_buf;
|
||||||
nread = num_words = 0;
|
nread = num_words = 0;
|
||||||
seen_underrun = num_stalls = 0;
|
seen_underrun = num_stalls = 0;
|
||||||
|
|
||||||
for (cnt = sizeof(sc->sc_buf) / sizeof(uint32_t); cnt > 0;
|
for (cnt = sizeof(sc->sc_buf) / sizeof(uint32_t); cnt > 0;
|
||||||
cnt -= num_words) {
|
cnt -= num_words) {
|
||||||
/* Read status register to find out how many words available */
|
/* Read count register to find out how many words available */
|
||||||
status = bcm2835_rng_read4(sc, RNG_STATUS);
|
hwcount = bcm2835_rng_read4(sc, sc->conf->count_reg);
|
||||||
num_avail = (status >> RND_VAL_SHIFT) & RND_VAL_MASK;
|
num_avail = (hwcount >> sc->conf->count_value_shift) &
|
||||||
|
sc->conf->count_value_mask;
|
||||||
|
|
||||||
/* If we have none... */
|
/* If we have none... */
|
||||||
if (num_avail == 0) {
|
if (num_avail == 0) {
|
||||||
@ -282,15 +370,13 @@ bcm2835_rng_harvest(void *arg)
|
|||||||
|
|
||||||
/* Pull MIN(num_avail, cnt) words from the FIFO */
|
/* Pull MIN(num_avail, cnt) words from the FIFO */
|
||||||
num_words = (num_avail > cnt) ? cnt : num_avail;
|
num_words = (num_avail > cnt) ? cnt : num_avail;
|
||||||
bcm2835_rng_read_multi4(sc, RNG_DATA, dest,
|
bcm2835_rng_read_multi4(sc, sc->conf->data_reg, dest,
|
||||||
num_words);
|
num_words);
|
||||||
dest += num_words;
|
dest += num_words;
|
||||||
nread += num_words;
|
nread += num_words;
|
||||||
}
|
}
|
||||||
|
|
||||||
cnt = nread * sizeof(uint32_t);
|
bcm2835_rng_enqueue_harvest(sc, nread);
|
||||||
if (cnt > 0)
|
|
||||||
random_harvest_queue(sc->sc_buf, cnt, RANDOM_PURE_BROADCOM);
|
|
||||||
|
|
||||||
callout_reset(&sc->sc_rngto, RNG_CALLOUT_TICKS, bcm2835_rng_harvest, sc);
|
callout_reset(&sc->sc_rngto, RNG_CALLOUT_TICKS, bcm2835_rng_harvest, sc);
|
||||||
}
|
}
|
||||||
@ -347,7 +433,7 @@ bcm2835_rng_probe(device_t dev)
|
|||||||
if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
|
if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
|
||||||
return (ENXIO);
|
return (ENXIO);
|
||||||
|
|
||||||
device_set_desc(dev, "Broadcom BCM2835 RNG");
|
device_set_desc(dev, "Broadcom BCM2835/BCM2838 RNG");
|
||||||
|
|
||||||
return (BUS_PROBE_DEFAULT);
|
return (BUS_PROBE_DEFAULT);
|
||||||
}
|
}
|
||||||
@ -363,13 +449,18 @@ bcm2835_rng_attach(device_t dev)
|
|||||||
error = 0;
|
error = 0;
|
||||||
sc = device_get_softc(dev);
|
sc = device_get_softc(dev);
|
||||||
sc->sc_dev = dev;
|
sc->sc_dev = dev;
|
||||||
|
|
||||||
|
sc->conf = (void const*)ofw_bus_search_compatible(dev, compat_data)->ocd_data;
|
||||||
|
KASSERT(sc->conf != NULL, ("bcm2835_rng_attach: sc->conf == NULL"));
|
||||||
|
|
||||||
sc->sc_stall_count = RNG_STALL_COUNT_DEFAULT;
|
sc->sc_stall_count = RNG_STALL_COUNT_DEFAULT;
|
||||||
|
|
||||||
/* Initialize callout */
|
/* Initialize callout */
|
||||||
callout_init(&sc->sc_rngto, CALLOUT_MPSAFE);
|
callout_init(&sc->sc_rngto, CALLOUT_MPSAFE);
|
||||||
|
|
||||||
TUNABLE_INT_FETCH("bcmrng.2xspeed", &sc->sc_rbg2x);
|
|
||||||
TUNABLE_INT_FETCH("bcmrng.stall_count", &sc->sc_stall_count);
|
TUNABLE_INT_FETCH("bcmrng.stall_count", &sc->sc_stall_count);
|
||||||
|
if (sc->conf->allow_2x_mode)
|
||||||
|
TUNABLE_INT_FETCH("bcmrng.2xspeed", &sc->sc_rbg2x);
|
||||||
|
|
||||||
/* Allocate memory resources */
|
/* Allocate memory resources */
|
||||||
rid = 0;
|
rid = 0;
|
||||||
@ -402,9 +493,10 @@ bcm2835_rng_attach(device_t dev)
|
|||||||
SYSCTL_ADD_LONG(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO,
|
SYSCTL_ADD_LONG(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO,
|
||||||
"underrun", CTLFLAG_RD, &sc->sc_underrun,
|
"underrun", CTLFLAG_RD, &sc->sc_underrun,
|
||||||
"Number of FIFO underruns");
|
"Number of FIFO underruns");
|
||||||
SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO,
|
if (sc->conf->allow_2x_mode)
|
||||||
"2xspeed", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, sc, 0,
|
SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO,
|
||||||
sysctl_bcm2835_rng_2xspeed, "I", "Enable RBG 2X SPEED");
|
"2xspeed", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, sc, 0,
|
||||||
|
sysctl_bcm2835_rng_2xspeed, "I", "Enable RBG 2X SPEED");
|
||||||
SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO,
|
SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO,
|
||||||
"stall_count", CTLFLAG_RW, &sc->sc_stall_count,
|
"stall_count", CTLFLAG_RW, &sc->sc_stall_count,
|
||||||
RNG_STALL_COUNT_DEFAULT, "Number of underruns to assume RNG stall");
|
RNG_STALL_COUNT_DEFAULT, "Number of underruns to assume RNG stall");
|
||||||
@ -414,7 +506,7 @@ bcm2835_rng_attach(device_t dev)
|
|||||||
sysctl_bcm2835_rng_dump, "S", "Dump RNG registers");
|
sysctl_bcm2835_rng_dump, "S", "Dump RNG registers");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Schedule the initial harvesting one second from now, which should give the
|
* Schedule the initial harvesting one second from now, which should give the
|
||||||
* hardware RNG plenty of time to generate the first random bytes.
|
* hardware RNG plenty of time to generate the first random bytes.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user