Hey tech@ Here's a patch that adds octeon's onboard rng chip as a source of entropy. Currently I fire this off every second, which neither seemed to increase the load on my ERL or produce duplicate outputs.
This patch also maps out the rnm register which controls the status of the rng and entropy. Ok? Index: conf/GENERIC =================================================================== RCS file: /cvs/src/sys/arch/octeon/conf/GENERIC,v retrieving revision 1.10 diff -u -b -w -p -r1.10 GENERIC --- conf/GENERIC 19 Sep 2013 00:15:59 -0000 1.10 +++ conf/GENERIC 22 Oct 2013 02:55:23 -0000 @@ -51,3 +51,6 @@ pciide* at pci? flags 0x0000 # IDE hard drives wd* at pciide? flags 0x0000 + +# RNG +octrng0 at iobus0 Index: conf/files.octeon =================================================================== RCS file: /cvs/src/sys/arch/octeon/conf/files.octeon,v retrieving revision 1.14 diff -u -b -w -p -r1.14 files.octeon --- conf/files.octeon 15 Aug 2013 06:54:35 -0000 1.14 +++ conf/files.octeon 22 Oct 2013 02:55:23 -0000 @@ -90,3 +90,8 @@ file arch/octeon/dev/octeon_pcibus.c p file arch/octeon/dev/octeon_bus_space.c file arch/octeon/octeon/pciide_machdep.c pciide + +# Onboard rng +device octrng +attach octrng at iobus +file arch/octeon/dev/octrng.c octrng Index: dev/cn30xxrnmreg.h =================================================================== RCS file: dev/cn30xxrnmreg.h diff -N dev/cn30xxrnmreg.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ dev/cn30xxrnmreg.h 22 Oct 2013 02:55:23 -0000 @@ -0,0 +1,50 @@ +/* $OpenBSD$ */ +/* + * Copyright (c) 2013 William Orr <w...@worrbase.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _CN30XXPKOREG_H_ +#define _CN30XXPKOREG_H_ + +#define RNM_REG_BASE 0x0001180040000000ULL +#define RNM_REG_SIZE 0xFULL + +#define RNM_REG_CTL 0x0001180040000000ULL +#define RNM_REG_BIST 0x0001180040000008ULL + +#define RNM_CTL_ENT_EN 0x0000000000000001ULL +#define RNM_CTL_RNG_EN 0x0000000000000002ULL +#define RNM_CTL_RNM_RST 0x0000000000000004ULL +#define RNM_CTL_RNG_RST 0x0000000000000008ULL +#define RNM_CTL_ENT_SEL 0x00000000000000F0ULL +#define RNM_CTL_EER_VAL 0x0000000000000100ULL +#define RNM_CTL_EER_LCK 0x0000000000000200ULL +#define RNM_CTL_DIS_MAK 0x0000000000000400ULL + +#define RNM_BIST_MEM 0x0000000000000001ULL +#define RNM_BIST_RRC 0x0000000000000002ULL + +#endif + Index: dev/octeon_iobus.c =================================================================== RCS file: /cvs/src/sys/arch/octeon/dev/octeon_iobus.c,v retrieving revision 1.4 diff -u -b -w -p -r1.4 octeon_iobus.c --- dev/octeon_iobus.c 2 Jun 2013 20:29:36 -0000 1.4 +++ dev/octeon_iobus.c 22 Oct 2013 02:55:23 -0000 @@ -154,12 +154,14 @@ struct machine_bus_dma_tag iobus_bus_dma const struct iobus_unit iobus_units[] = { { OCTEON_CF_BASE, 0 }, /* octcf */ { 0, 0 }, /* pcibus */ - { GMX0_BASE_PORT0, CIU_INT_GMX_DRP0 } /* cn30xxgmx */ + { GMX0_BASE_PORT0, CIU_INT_GMX_DRP0 }, /* cn30xxgmx */ + { OCTEON_RNG_BASE, 0 } /* octrng */ }; struct iobus_attach_args iobus_children[] = { IOBUSDEV("octcf", 0, &iobus_units[0]), IOBUSDEV("pcibus", 0, &iobus_units[1]), - IOBUSDEV("cn30xxgmx", 0, &iobus_units[2]) + IOBUSDEV("cn30xxgmx", 0, &iobus_units[2]), + IOBUSDEV("octrng", 0, &iobus_units[3]) }; #undef IOBUSDEV Index: dev/octrng.c =================================================================== RCS file: dev/octrng.c diff -N dev/octrng.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ dev/octrng.c 22 Oct 2013 02:55:23 -0000 @@ -0,0 +1,122 @@ +/* $OpenBSD$ */ +/* + * Copyright (c) 2013 William Orr. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/param.h> +#include <sys/device.h> +#include <sys/systm.h> +#include <sys/timeout.h> + +#include <machine/bus.h> +#include <machine/octeonreg.h> +#include <machine/octeonvar.h> + +#include <dev/rndvar.h> + +#include <octeon/dev/cn30xxrnmreg.h> +#include <octeon/dev/iobusvar.h> + +#define OCTEON_RNG_SIZE 0x8 +#define OCTEON_RNG_TIMEOUT 0x1 + +int octrngprobe(struct device *, void *, void *); +void octrngattach(struct device *, struct device *, void *); +void octrngdettach(struct device *, int); +void octrngrnd(void *); + +struct octrng_softc { + struct device sc_dev; + struct timeout sc_to; + bus_space_tag_t sc_iot; + bus_space_handle_t sc_ioh; +}; + +struct cfattach octrng_ca = { + sizeof(struct octrng_softc), octrngprobe, octrngattach +}; + +struct cfdriver octrng_cd = { + NULL, "octrng", DV_DULL +}; + +int +octrngprobe(struct device *parent, void *match, void *aux) +{ + struct iobus_attach_args *aa = (struct iobus_attach_args *)aux; + struct cfdata *cf = (struct cfdata *)match; + + if (strcmp(aa->aa_name, cf->cf_driver->cd_name) == 0) + return 1; + + return 0; +} + +void +octrngattach(struct device *parent, struct device *self, void *aux) +{ + struct octrng_softc *sc = (void *)self; + struct iobus_attach_args *aa = (struct iobus_attach_args *)aux; + + sc->sc_iot = aa->aa_bust; + + if (bus_space_map(sc->sc_iot, OCTEON_RNG_BASE, + OCTEON_RNG_SIZE, 0, &sc->sc_ioh)) { + printf(": couldn't map registers\n"); + return; + } + + printf("\n"); + + /* We need to initialize the rng by writing some values + * to rnm csr + */ + uint64_t rnm = octeon_xkphys_read_8(RNM_REG_CTL); + rnm |= RNM_CTL_ENT_EN | RNM_CTL_RNG_EN; + octeon_xkphys_write_8(RNM_REG_CTL, rnm); + + /* Add a 5 second timeout to collect entropy for + * the pool + */ + timeout_set(&sc->sc_to, octrngrnd, sc); + timeout_add(&sc->sc_to, OCTEON_RNG_TIMEOUT); +} + +void +octrngrnd(void *v) +{ + struct octrng_softc *sc = v; + uint64_t r; + + r = bus_space_read_8(sc->sc_iot, sc->sc_ioh, 0); + +#ifdef DEBUG + printf("octrng: %lx\n", r); +#endif + + add_true_randomness(r); + add_true_randomness(r >> 32); + + timeout_add(&sc->sc_to, OCTEON_RNG_TIMEOUT); +} +