/dev/random on PPC40EXr

Tirumala Reddy Marri tmarri at amcc.com
Thu Apr 2 16:59:46 EST 2009


Here I am copy pasting the files and also attaching.
--------------trng4xx.c-------------
/*******************************************************************************

*

* Copyright (c) 2008 Loc Ho <lho at amcc.com>

*

* This program is free software; you can redistribute it and/or modify

* it under the terms of the GNU General Public License as published by

* the Free Software Foundation; either version 2 of the License, or

* (at your option) any later version.

*

* This program is distributed in the hope that it will be useful,

* but WITHOUT ANY WARRANTY; without even the implied warranty of

* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

* GNU General Public License for more details.

*

*

* Detail Description:

* This file defines ioctl structures for the Linux CryptoAPI interface. It

* provides user space applications accesss into the Linux CryptoAPI

* functionalities.

*

* @file trng4xx.c

*

* This file provides access to the AMCC PPC4XX TRNG for Linux.

*

*******************************************************************************

*/

#include <linux/version.h>

#include <linux/module.h>

#include <linux/kernel.h>

#include <linux/platform_device.h>

#include <linux/hw_random.h>

#include <linux/interrupt.h>

#include <asm/of_platform.h>

#include <asm/io.h>

#include "trng4xx.h"

#define TRNG4XX_VER_STR "0.1"

#define PFX KBUILD_MODNAME ": "

struct trng4xx_dev {

struct resource res;

u32 irq;

volatile char __iomem *csr;

struct semaphore access_prot;

u32 datum;

};

struct hal_config {

struct of_device *ofdev;

};

static struct trng4xx_dev trng4xx_dev;

static int trng4xx_irq_handler(int irq, void * id);

static void trng4xx_chk_overflow(void);

int trng4xx_config_set(struct hal_config *cfg)

{

struct device_node *rng_np = cfg->ofdev->node;

int rc = 0;

rc = of_address_to_resource(rng_np, 0, &trng4xx_dev.res);

if (rc)

return -ENODEV;

trng4xx_dev.csr = ioremap(trng4xx_dev.res.start,

trng4xx_dev.res.end - trng4xx_dev.res.start + 1);

if (trng4xx_dev.csr == NULL) {

printk(KERN_ERR PFX "unable to ioremap 0x%02X_%08X size %d\n",

(u32) (trng4xx_dev.res.start >> 32),

(u32) trng4xx_dev.res.start,

(u32) (trng4xx_dev.res.end - trng4xx_dev.res.start + 1));

return -ENOMEM;

}

#if 0

printk("TRNG1 0x%02X_%08X size %d\n",

(u32) (trng4xx_dev.res.start >> 32),

(u32) trng4xx_dev.res.start,

(u32) (trng4xx_dev.res.end - trng4xx_dev.res.start + 1));

#endif

trng4xx_dev.irq = of_irq_to_resource(rng_np, 0, NULL); 

printk ("TRNG IRQ = %d\n",trng4xx_dev.irq); 

if (trng4xx_dev.irq == NO_IRQ) {

/* Un-map CSR */

iounmap(trng4xx_dev.csr);

trng4xx_dev.csr = NULL;

return -EINVAL;

}

return 0;

}

int trng4xx_pka_config_clear(void)

{

iounmap(trng4xx_dev.csr);

return 0;

}

inline int trng4xx_hw_read32(u32 reg_addr, u32 *data_val)

{

*data_val = in_be32((volatile unsigned __iomem *)

(trng4xx_dev.csr + reg_addr));

return 0;

}

inline int trng4xx_hw_write32(u32 reg_addr, u32 data_val)

{

out_be32((volatile unsigned __iomem *) (trng4xx_dev.csr + reg_addr),

data_val);

return 0;

}

int trng4xx_hw_init(void)

{

int rc;

rc = request_irq(trng4xx_dev.irq, trng4xx_irq_handler,

0, "TRNG", NULL);

if (rc != 0) {

printk(KERN_ERR PFX "failed to register interrupt IRQ %d\n",

trng4xx_dev.irq);

return rc;

}

return 0;

}

int trng4xx_hw_deinit(void)

{

free_irq(trng4xx_dev.irq, NULL);

return 0;

}

static int trng4xx_irq_handler(int irq, void * id)

{

/* TRNG Alarm Counter overflow */

trng4xx_chk_overflow();

return 0;

}

/*******************************************************************************

* TRNG Functions

*******************************************************************************

*/

static void trng4xx_chk_overflow(void)

{

/* TRNG Alarm Counter overflow */

int rc;

u32 val;

struct trng4xx_cfg {

u32 ring1_delay_sel : 3;

u32 ring2_delay_sel : 3;

u32 reset_cnt : 6;

} __attribute__((packed));

 

rc = trng4xx_hw_write32(TRNG4XX_ALARMCNT_ADDR, val);

if (rc != 0)

return;

if (val > 128) {

struct trng4xx_cfg *trng4xx_cfg;

/* Alarm count is half, reset it */

rc = trng4xx_hw_read32(TRNG4XX_CFG_ADDR, &val);

if (rc != 0)

return;

trng4xx_cfg = (struct trng4xx_cfg *) &val;

++trng4xx_cfg->ring1_delay_sel;

trng4xx_cfg->ring2_delay_sel = (~trng4xx_cfg->ring1_delay_sel) & 0x07;

rc = trng4xx_hw_write32(TRNG4XX_CFG_ADDR, val);

if (rc != 0)

return;

trng4xx_hw_write32(TRNG4XX_ALARMCNT_ADDR, 0x00000000);

if (rc != 0)

return;

}

}

int trng4xx_random(u32 *rand_val)

{

u32 val = 0;

int rc;

#define MAX_TRY 3

u16 try_cnt = 0;

down(&trng4xx_dev.access_prot);

do {

rc = trng4xx_hw_read32(TRNG4XX_STATUS_ADDR, &val);

if (rc != 0)

goto err;

} while((val & TRNG4XX_STATUS_BUSY) && ++try_cnt <= MAX_TRY);

if (val & TRNG4XX_STATUS_BUSY) {

rc = -EINPROGRESS;

goto err;

}

rc = trng4xx_hw_read32(TRNG4XX_OUTPUT_ADDR, rand_val);

 

err:

//printk("status busy\n");

up(&trng4xx_dev.access_prot);

return rc;

}

EXPORT_SYMBOL_GPL(trng4xx_random);

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)

static int trng4xx_data_present(struct hwrng *rng)

#else

static int trng4xx_data_present(struct hwrng *rng, int wait)

#endif

{

struct trng4xx_dev *dev = (struct trng4xx_dev *) rng->priv;

int i;

u32 val;

printk("inside %s:\n", __FUNCTION__);

down(&trng4xx_dev.access_prot);

/* We should not take more than 200??? us */

for (i = 0; i < 20; i++) {

trng4xx_hw_read32(TRNG4XX_STATUS_ADDR, &val);

if (!(val & TRNG4XX_STATUS_BUSY)) {

trng4xx_hw_read32(TRNG4XX_OUTPUT_ADDR, &dev->datum);

break;

}

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)

break;

#else

if (!wait)

break;

udelay(10);

#endif

}

up(&trng4xx_dev.access_prot);

return (val & TRNG4XX_STATUS_BUSY) ? 0 : 1;

}

static int trng4xx_data_read(struct hwrng *rng, u32 *data)

{

struct trng4xx_dev *dev = (struct trng4xx_dev *) rng->priv;

*data = dev->datum;

printk("data read = %u\n", *data); 

return 0;

}

static int trng4xx_init(struct hwrng *rng)

{

return trng4xx_hw_init();

}

static void trng4xx_cleanup(struct hwrng *rng)

{

trng4xx_hw_deinit();

}

static struct hwrng trng4xx_func = {

.name = "ppc4xx-trng",

.init = trng4xx_init,

.cleanup = trng4xx_cleanup,

.data_present = trng4xx_data_present,

.data_read = trng4xx_data_read,

.priv = (unsigned long) &trng4xx_dev,

};

/*******************************************************************************

*

* Setup Driver with platform registration

*

*******************************************************************************

*/

static int __devinit trng4xx_probe(struct of_device *ofdev,

const struct of_device_id *match)

{

struct hal_config hw_cfg;

int rc;

u32 value, value2;

u32 ctrl_val, control_value;

hw_cfg.ofdev = ofdev;

rc = trng4xx_config_set(&hw_cfg);

if (rc != 0)

return rc;

#if 1

printk( "AMCC 4xx TRNG v%s @0x%02X_%08X size %d IRQ %d\n",

TRNG4XX_VER_STR,

(u32) (trng4xx_dev.res.start >> 32),

(u32) trng4xx_dev.res.start,

(u32) (trng4xx_dev.res.end - trng4xx_dev.res.start + 1),

trng4xx_dev.irq);

#endif

init_MUTEX(&trng4xx_dev.access_prot);

rc = hwrng_register(&trng4xx_func);

if (rc) {

printk(KERN_ERR PFX

"AMCC 4xx TRNG registering failed error %d\n", rc);

goto err;

}

trng4xx_hw_read32(TRNG4XX_CNTL_ADDR, &ctrl_val);

//printk ("cntl value = 0x%x\n", ctrl_val);

value = ctrl_val | TRNG4XX_CNTL_TST_ALARM;

//printk ("value to write = 0x%x\n", value);

/*rc = trng4xx_hw_write32(TRNG4XX_CNTL_ADDR, value);

if (rc != 0)

printk ("ERROR: writing\n");

 

trng4xx_hw_read32(TRNG4XX_CNTL_ADDR, &control_value);

printk ("control value = 0x%x\n", control_value);*/

/*value = 0;

printk ("checking random value register\n");

rc = trng4xx_random (&value);

printk ("checking random value register\n");

rc = trng4xx_random (&value2);*/

return rc;

err:

trng4xx_pka_config_clear();

return rc;

}

static int __devexit trng4xx_remove(struct of_device *dev)

{

hwrng_unregister(&trng4xx_func);

trng4xx_pka_config_clear();

return 0;

}

static struct of_device_id trng4xx_match[] = {

{ .compatible = "ppc4xx-trng", },

{ .compatible = "amcc,ppc4xx-trng", },

{ },

};

static struct of_platform_driver trng4xx_driver = {

.name = "ppc4xx-trng",

.match_table = trng4xx_match,

.probe = trng4xx_probe,

.remove = trng4xx_remove,

};

static int __init mod_init(void)

{

printk("entered mod_init\n"); 

return of_register_platform_driver(&trng4xx_driver);

}

static void __exit mod_exit(void)

{

of_unregister_platform_driver(&trng4xx_driver);

}

module_init(mod_init);

module_exit(mod_exit);

MODULE_DESCRIPTION("AMCC 4xx True Random Number Generator");

MODULE_LICENSE("GPL");

 
------------trng4xx.h ------------------- 
 
/*******************************************************************************

*

* Copyright (c) 2008 Loc Ho <lho at amcc.com>

*

* This program is free software; you can redistribute it and/or modify

* it under the terms of the GNU General Public License as published by

* the Free Software Foundation; either version 2 of the License, or

* (at your option) any later version.

*

* This program is distributed in the hope that it will be useful,

* but WITHOUT ANY WARRANTY; without even the implied warranty of

* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

* GNU General Public License for more details.

*

*

* Detail Description:

* This file defines ioctl structures for the Linux CryptoAPI interface. It

* provides user space applications accesss into the Linux CryptoAPI

* functionalities.

*

* @file trng4xx.h

*

* This file provides access to the AMCC SoC TRNG.

*

*******************************************************************************

*/

#ifndef __TRNG4XX_H__

#define __TRNG4XX_H__

/*******************************************************************************

* TRNG Register and bit Definitions

*******************************************************************************

*/

/* Register TRNG4XX_STATUS bit definition */

#define TRNG4XX_STATUS_BUSY 0x00000001

/* Register TRNG4XX_CNTL bit definition */

#define TRNG4XX_CNTL_TST_RING_OUT 0x00000001

#define TRNG4XX_CNTL_TST_MODE 0x00000002

#define TRNG4XX_CNTL_TST_RUN 0x00000004

#define TRNG4XX_CNTL_TST_EN1 0x00000008

#define TRNG4XX_CNTL_TST_EN2 0x00000010

#define TRNG4XX_CNTL_DISABLE_ALARM 0x00000020

#define TRNG4XX_CNTL_CLOCK_ON 0x00000040

#define TRNG4XX_CNTL_SHORT_CYCLE 0x00000080

#define TRNG4XX_CNTL_TST_ALARM 0x00000100

#define TRNG4XX_CNTL_TST_LFSR 0x00000200

#define TRNG4XX_CNTL_RESET_LFSR 0x00000400

#define TRNG4XX_CNTL_BYPASS_TRNG 0x00000800

#define TRNG4XX_CNTL_POST_PROC_EN 0x00001000

/* Register TRNG4XX_CFG bit definition */

#define TRNG4XX_CFG_RING1_DELAY_SEL_SHIFT 0

#define TRNG4XX_CFG_RING1_DELAY_SEL_MASK (7)

#define TRNG4XX_CFG_RING2_DELAY_SEL_SHIFT 3

#define TRNG4XX_CFG_RING2_DELAY_SEL_MASK (7 << TRNG4XX_CFG_RING2_DELAY_SEL_SHIFT)

#define TRNG4XX_CFG_RESET_CNT_SHIFT 6

#define TRNG4XX_CFG_RESET_CNT_SHIFT_MASK (0x3F << TRNG4XX_CFG_RING2_DELAY_SEL_SHIFT)

/* TRNG Register definition */

#define TRNG4XX_OUTPUT_ADDR 0x0000

#define TRNG4XX_STATUS_ADDR 0x0004

#define TRNG4XX_CNTL_ADDR 0x0008

#define TRNG4XX_CFG_ADDR 0x000C

#define TRNG4XX_ALARMCNT_ADDR 0x0010

#define TRNG4XX_AREG_ADDR 0x0014

#define TRNG4XX_BREG_ADDR 0x0018

#define TRNG4XX_XREG_0_ADDR 0x001C

#define TRNG4XX_XREG_1_ADDR 0x0020

#define TRNG4XX_XREG_2_ADDR 0x0024

#define TRNG4XX_LFSR1_L_ADDR 0x0028

#define TRNG4XX_LFSR1_H_ADDR 0x002C

#define TRNG4XX_LFSR2_L_ADDR 0x0030

#define TRNG4XX_LFSR2_H_ADDR 0x0034

#define TRNG4XX_KEY0_L_ADDR 0x0038

#define TRNG4XX_KEY0_H_ADDR 0x003C

#define TRNG4XX_KEY1_L_ADDR 0x0040

#define TRNG4XX_KEY1_H_ADDR 0x0044

#define TRNG4XX_IV_L_ADDR 0x0048

#define TRNG4XX_IV_H_ADDR 0x004C

struct hal_config;

/**

* @brief This function MUSTs be called to initialize the HW

* access function.

* @param amcc_hal_cfg HW access configuration. If NULL,

* default will be used.

* @return PPRO_RC_OK or PPRO_RC_FATAL

* @note To load all access functions from HAL with default initial

* map address, pass a NULL as its parameter.

* @n To load all access functions from HAL with default runtime

* map address, initialize an amcc_hal_config_t struct

* with valid HAL signature and set

* amcc_hal_config->flags |= PPRO_HAL_FLAG_LOADINIT;

*

*******************************************************************************

*/

int trng4xx_config_set(struct hal_config *cfg);

/**

* @brief This function MUSTs be called to de-initialize the HW

* access function.

* @return PPRO_RC_OK or PPRO_RC_FATAL

*

*******************************************************************************

*/

int trng4xx_config_clear(void);

/**

* @brief This functions reads from the TRNG registers.

* @param reg_addr Device register offset

* @param data_val An DWORD pointer to store the returned value

* @return PPRO_RC_OK or PPRO_RC_FATAL

*

*******************************************************************************

*/

inline int trng4xx_hw_read32(u32 reg_addr, u32 *data_val);

/**

* @brief This functions writes to the TRNG registers.

* @param reg_addr Device register offset

* @param data_val An DWORD value to write

* @return PPRO_RC_OK or PPRO_RC_FATAL

*

*******************************************************************************

*/

inline int trng4xx_hw_write32(u32 reg_addr, u32 data_val);

/**

* @brief This functions initializes the TRNG for operation.

* @return PPRO_RC_OK or PPRO_RC_FATAL

*

*******************************************************************************

*/

int trng4xx_hw_init(void);

/**

* @brief This functions de-initializes the TRNG.

* @return PPRO_RC_OK or PPRO_RC_FATAL

*

*******************************************************************************

*/

int trng4xx_hw_deinit(void);

/**

* @brief This functions retrieves an true random number.

* @param rand_val A pointer to a DWORD to store the value

* @return PPRO_RC_OK if successfull. PPRO_RC_EINPROGRESS if failed. This

* should not happen as this means the hardware still busy.

*

*******************************************************************************

*/

int trng4xx_random(u32 *rand_val);

#endif

 

------------------------- DTS file ---------------

/*

* Device Tree Source for AMCC Canyonlands (460EX)

*

* Copyright 2008 DENX Software Engineering, Stefan Roese <sr at denx.de>

*

* This file is licensed under the terms of the GNU General Public

* License version 2. This program is licensed "as is" without

* any warranty of any kind, whether express or implied.

*/

/ {

#address-cells = <2>;

#size-cells = <1>;

model = "amcc,canyonlands";

compatible = "amcc,canyonlands";

dcr-parent = <&/cpus/cpu at 0>;

aliases {

ethernet0 = &EMAC0;

ethernet1 = &EMAC1;

serial0 = &UART0;

serial1 = &UART1;

};

cpus {

#address-cells = <1>;

#size-cells = <0>;

cpu at 0 {

device_type = "cpu";

model = "PowerPC,460EX";

reg = <0>;

clock-frequency = <0>; /* Filled in by U-Boot */

timebase-frequency = <0>; /* Filled in by U-Boot */

i-cache-line-size = <20>;

d-cache-line-size = <20>;

i-cache-size = <8000>;

d-cache-size = <8000>;

dcr-controller;

dcr-access-method = "native";

};

};

memory {

device_type = "memory";

reg = <0 0 0>; /* Filled in by U-Boot */

};

UIC0: interrupt-controller0 {

compatible = "ibm,uic-460ex","ibm,uic";

interrupt-controller;

cell-index = <0>;

dcr-reg = <0c0 009>;

#address-cells = <0>;

#size-cells = <0>;

#interrupt-cells = <2>;

};

UIC1: interrupt-controller1 {

compatible = "ibm,uic-460ex","ibm,uic";

interrupt-controller;

cell-index = <1>;

dcr-reg = <0d0 009>;

#address-cells = <0>;

#size-cells = <0>;

#interrupt-cells = <2>;

interrupts = <1e 4 1f 4>; /* cascade */

interrupt-parent = <&UIC0>;

};

UIC2: interrupt-controller2 {

compatible = "ibm,uic-460ex","ibm,uic";

interrupt-controller;

cell-index = <2>;

dcr-reg = <0e0 009>;

#address-cells = <0>;

#size-cells = <0>;

#interrupt-cells = <2>;

interrupts = <a 4 b 4>; /* cascade */

interrupt-parent = <&UIC0>;

};

UIC3: interrupt-controller3 {

compatible = "ibm,uic-460ex","ibm,uic";

interrupt-controller;

cell-index = <3>;

dcr-reg = <0f0 009>;

#address-cells = <0>;

#size-cells = <0>;

#interrupt-cells = <2>;

interrupts = <10 4 11 4>; /* cascade */

interrupt-parent = <&UIC0>;

};

SDR0: sdr {

compatible = "ibm,sdr-460ex";

dcr-reg = <00e 002>;

};

CPR0: cpr {

compatible = "ibm,cpr-460ex";

dcr-reg = <00c 002>;

};

L2C0: l2c {

compatible = "ibm,l2-cache-460ex", "ibm,l2-cache";

dcr-reg = <20 8 /* Internal SRAM DCR's */

30 8>; /* L2 cache DCR's */

cache-line-size = <20>; /* 32 bytes */

cache-size = <40000>; /* L2, 256K */

interrupt-parent = <&UIC2>;

interrupts = <17 1>;

};

plb {

compatible = "ibm,plb-460ex", "ibm,plb4";

#address-cells = <2>;

#size-cells = <1>;

ranges;

clock-frequency = <0>; /* Filled in by U-Boot */

SDRAM0: sdram {

compatible = "ibm,sdram-460ex", "ibm,sdram-405gp";

dcr-reg = <010 2>;

};

MAL0: mcmal {

compatible = "ibm,mcmal-460ex", "ibm,mcmal2";

dcr-reg = <180 62>;

num-tx-chans = <2>;

num-rx-chans = <10>;

#address-cells = <0>;

#size-cells = <0>;

interrupt-parent = <&UIC2>;

interrupts = < /*TXEOB*/ 6 4

/*RXEOB*/ 7 4

/*SERR*/ 3 4

/*TXDE*/ 4 4

/*RXDE*/ 5 4>;

};

USB0: ehci at bffd0400 {

compatible = "ibm,usb-ehci-460ex", "usb-ehci";

interrupt-parent = <&UIC2>;

interrupts = <1d 4>;

reg = <4 bffd0400 90 4 bffd0490 70>;

};

USB1: usb at bffd0000 {

compatible = "ohci-le";

reg = <4 bffd0000 60>;

interrupt-parent = <&UIC2>;

interrupts = <1e 4>;

};

USBOTG0: usbotg at bff80000 {

compatible = "amcc,usb-otg-460ex";

reg = <4 bff80000 10000>;

interrupt-parent = <&USBOTG0>;

interrupts = <0 1 2>;

#interrupt-cells = <1>;

#address-cells = <0>;

#size-cells = <0>;

interrupt-map = </* USB-OTG */ 0 &UIC2 1c 4

/* HIGH-POWER */ 1 &UIC1 1a 8

/* DMA */ 2 &UIC0 c 4>;

interrupt-map-mask = <ffffffff>;

};

CRYPTO: crypto at 180000 {

compatible = "amcc,ppc460ex-crypto", "amcc,ppc4xx-crypto";

reg = <4 00180000 84000>;

interrupt-parent = <&UIC0>;

interrupts = <1d 4>;

};

TRNG: trng at 110000 {

device_type = "trng";

compatible = "ppc4xx-trng", "amcc, ppc4xx-trng";

reg = <4 00110000 100>;

interrupt-parent = <&UIC1>;

interrupts = <3 2>;

};

PKA: pka at 114000 {

device_type = "pka";

compatible = "ppc4xx-pka", "amcc, ppc4xx-pka";

reg = <4 00114000 4000>;

interrupt-parent = <&UIC0>;

interrupts = <14 2>;

};

POB0: opb {

compatible = "ibm,opb-460ex", "ibm,opb";

#address-cells = <1>;

#size-cells = <1>;

ranges = <b0000000 4 b0000000 50000000>;

clock-frequency = <0>; /* Filled in by U-Boot */

EBC0: ebc {

compatible = "ibm,ebc-460ex", "ibm,ebc";

dcr-reg = <012 2>;

#address-cells = <2>;

#size-cells = <1>;

clock-frequency = <0>; /* Filled in by U-Boot */

/* ranges property is supplied by U-Boot */

interrupts = <6 4>;

interrupt-parent = <&UIC1>;

nor_flash at 0,0 {

compatible = "amd,s29gl512n", "cfi-flash";

bank-width = <2>;

reg = <0 000000 4000000>;

#address-cells = <1>;

#size-cells = <1>;

partition at 0 {

label = "kernel";

reg = <0 1e0000>;

};

partition at 1e0000 {

label = "dtb";

reg = <1e0000 20000>;

};

partition at 200000 {

label = "ramdisk";

reg = <200000 1400000>;

};

partition at 1600000 {

label = "jffs2";

reg = <1600000 400000>;

};

partition at 1a00000 {

label = "user";

reg = <1a00000 2560000>;

};

partition at 3f60000 {

label = "env";

reg = <3f60000 40000>;

};

partition at 3fa0000 {

label = "u-boot";

reg = <3fa0000 60000>;

};

};

};

UART0: serial at ef600300 {

device_type = "serial";

compatible = "ns16550";

reg = <ef600300 8>;

virtual-reg = <ef600300>;

clock-frequency = <0>; /* Filled in by U-Boot */

current-speed = <0>; /* Filled in by U-Boot */

interrupt-parent = <&UIC1>;

interrupts = <1 4>;

};

UART1: serial at ef600400 {

device_type = "serial";

compatible = "ns16550";

reg = <ef600400 8>;

virtual-reg = <ef600400>;

clock-frequency = <0>; /* Filled in by U-Boot */

current-speed = <0>; /* Filled in by U-Boot */

interrupt-parent = <&UIC0>;

interrupts = <1 4>;

};

UART2: serial at ef600500 {

device_type = "serial";

compatible = "ns16550";

reg = <ef600500 8>;

virtual-reg = <ef600500>;

clock-frequency = <0>; /* Filled in by U-Boot */

current-speed = <0>; /* Filled in by U-Boot */

interrupt-parent = <&UIC1>;

interrupts = <1d 4>;

};

UART3: serial at ef600600 {

device_type = "serial";

compatible = "ns16550";

reg = <ef600600 8>;

virtual-reg = <ef600600>;

clock-frequency = <0>; /* Filled in by U-Boot */

current-speed = <0>; /* Filled in by U-Boot */

interrupt-parent = <&UIC1>;

interrupts = <1e 4>;

};

 

IIC0: i2c at ef600700 {

compatible = "ibm,iic-460ex", "ibm,iic";

reg = <ef600700 14>;

interrupt-parent = <&UIC0>;

interrupts = <2 4>;

#address-cells = <1>;

#size-cells = <0>;

rtc at 68 {

compatible = "stm,m41t80";

reg = <68>;

};

};

 

 

IIC1: i2c at ef600800 {

compatible = "ibm,iic-460ex", "ibm,iic";

reg = <ef600800 14>;

interrupt-parent = <&UIC0>;

interrupts = <3 4>;

};

ZMII0: emac-zmii at ef600d00 {

compatible = "ibm,zmii-460ex", "ibm,zmii";

reg = <ef600d00 c>;

};

RGMII0: emac-rgmii at ef601500 {

compatible = "ibm,rgmii-460ex", "ibm,rgmii";

reg = <ef601500 8>;

has-mdio;

};

TAH0: emac-tah at ef601350 {

compatible = "ibm,tah-460ex", "ibm,tah";

reg = <ef601350 30>;

};

TAH1: emac-tah at ef601450 {

compatible = "ibm,tah-460ex", "ibm,tah";

reg = <ef601450 30>;

};

EMAC0: ethernet at ef600e00 {

device_type = "network";

compatible = "ibm,emac-460ex", "ibm,emac4";

interrupt-parent = <&EMAC0>;

interrupts = <0 1>;

#interrupt-cells = <1>;

#address-cells = <0>;

#size-cells = <0>;

interrupt-map = </*Status*/ 0 &UIC2 10 4

/*Wake*/ 1 &UIC2 14 4>;

reg = <ef600e00 70>;

local-mac-address = [000000000000]; /* Filled in by U-Boot */

mal-device = <&MAL0>;

mal-tx-channel = <0>;

mal-rx-channel = <0>;

cell-index = <0>;

max-frame-size = <2328>;

rx-fifo-size = <1000>;

tx-fifo-size = <800>;

phy-mode = "rgmii";

phy-map = <00000000>;

rgmii-device = <&RGMII0>;

rgmii-channel = <0>;

tah-device = <&TAH0>;

tah-channel = <0>;

has-inverted-stacr-oc;

has-new-stacr-staopc;

};

EMAC1: ethernet at ef600f00 {

device_type = "network";

compatible = "ibm,emac-460ex", "ibm,emac4";

interrupt-parent = <&EMAC1>;

interrupts = <0 1>;

#interrupt-cells = <1>;

#address-cells = <0>;

#size-cells = <0>;

interrupt-map = </*Status*/ 0 &UIC2 11 4

/*Wake*/ 1 &UIC2 15 4>;

reg = <ef600f00 70>;

local-mac-address = [000000000000]; /* Filled in by U-Boot */

mal-device = <&MAL0>;

mal-tx-channel = <1>;

mal-rx-channel = <8>;

cell-index = <1>;

max-frame-size = <2328>;

rx-fifo-size = <1000>;

tx-fifo-size = <800>;

phy-mode = "rgmii";

phy-map = <00000000>;

rgmii-device = <&RGMII0>;

rgmii-channel = <1>;

tah-device = <&TAH1>;

tah-channel = <1>;

has-inverted-stacr-oc;

has-new-stacr-staopc;

mdio-device = <&EMAC0>;

};

};

PCIX0: pci at c0ec00000 {

device_type = "pci";

#interrupt-cells = <1>;

#size-cells = <2>;

#address-cells = <3>;

compatible = "ibm,plb-pcix-460ex", "ibm,plb-pcix";

primary;

large-inbound-windows;

enable-msi-hole;

reg = <c 0ec00000 8 /* Config space access */

0 0 0 /* no IACK cycles */

c 0ed00000 4 /* Special cycles */

c 0ec80000 100 /* Internal registers */

c 0ec80100 fc>; /* Internal messaging registers */

/* Outbound ranges, one memory and one IO,

* later cannot be changed

*/

ranges = <02000000 0 80000000 0000000d 80000000 0 80000000

01000000 0 00000000 0000000c 08000000 0 00010000>;

/* Inbound 2GB range starting at 0 */

dma-ranges = <42000000 0 0 0 0 0 80000000>;

/* This drives busses 0 to 0x3f */

bus-range = <0 3f>;

/* All PCI interrupts are routed to ext IRQ 2 -> UIC1-0 */

interrupt-map-mask = <0000 0 0 0>;

interrupt-map = < 0000 0 0 0 &UIC1 0 8 >;

};

PCIE0: pciex at d00000000 {

device_type = "pci";

#interrupt-cells = <1>;

#size-cells = <2>;

#address-cells = <3>;

compatible = "ibm,plb-pciex-460ex", "ibm,plb-pciex";

primary;

port = <0>; /* port number */

reg = <d 00000000 20000000 /* Config space access */

c 08010000 00001000>; /* Registers */

dcr-reg = <100 020>;

sdr-base = <300>;

/* Outbound ranges, one memory and one IO,

* later cannot be changed

*/

ranges = <02000000 0 80000000 0000000e 00000000 0 80000000

01000000 0 00000000 0000000f 80000000 0 00010000>;

/* Inbound 2GB range starting at 0 */

dma-ranges = <42000000 0 0 0 0 0 80000000>;

/* This drives busses 40 to 0x7f */

bus-range = <40 7f>;

/* Legacy interrupts (note the weird polarity, the bridge seems

* to invert PCIe legacy interrupts).

* We are de-swizzling here because the numbers are actually for

* port of the root complex virtual P2P bridge. But I want

* to avoid putting a node for it in the tree, so the numbers

* below are basically de-swizzled numbers.

* The real slot is on idsel 0, so the swizzling is 1:1

*/

interrupt-map-mask = <0000 0 0 7>;

interrupt-map = <

0000 0 0 1 &UIC3 c 4 /* swizzled int A */

0000 0 0 2 &UIC3 d 4 /* swizzled int B */

0000 0 0 3 &UIC3 e 4 /* swizzled int C */

0000 0 0 4 &UIC3 f 4 /* swizzled int D */>;

};

PCIE1: pciex at d20000000 {

device_type = "pci";

#interrupt-cells = <1>;

#size-cells = <2>;

#address-cells = <3>;

compatible = "ibm,plb-pciex-460ex", "ibm,plb-pciex";

primary;

port = <1>; /* port number */

reg = <d 20000000 20000000 /* Config space access */

c 08011000 00001000>; /* Registers */

dcr-reg = <120 020>;

sdr-base = <340>;

/* Outbound ranges, one memory and one IO,

* later cannot be changed

*/

ranges = <02000000 0 80000000 0000000e 80000000 0 80000000

01000000 0 00000000 0000000f 80010000 0 00010000>;

/* Inbound 2GB range starting at 0 */

dma-ranges = <42000000 0 0 0 0 0 80000000>;

/* This drives busses 80 to 0xbf */

bus-range = <80 bf>;

/* Legacy interrupts (note the weird polarity, the bridge seems

* to invert PCIe legacy interrupts).

* We are de-swizzling here because the numbers are actually for

* port of the root complex virtual P2P bridge. But I want

* to avoid putting a node for it in the tree, so the numbers

* below are basically de-swizzled numbers.

* The real slot is on idsel 0, so the swizzling is 1:1

*/

interrupt-map-mask = <0000 0 0 7>;

interrupt-map = <

0000 0 0 1 &UIC3 10 4 /* swizzled int A */

0000 0 0 2 &UIC3 11 4 /* swizzled int B */

0000 0 0 3 &UIC3 12 4 /* swizzled int C */

0000 0 0 4 &UIC3 13 4 /* swizzled int D */>;

};

};

};

 
-------------------- Kconfig ----------
#

# Hardware Random Number Generator (RNG) configuration

#

config HW_RANDOM

tristate "Hardware Random Number Generator Core support"

default m

---help---

Hardware Random Number Generator Core infrastructure.

To compile this driver as a module, choose M here: the

module will be called rng-core. This provides a device

that's usually called /dev/hw_random, and which exposes one

of possibly several hardware random number generators.

These hardware random number generators do not feed directly

into the kernel's random number generator. That is usually

handled by the "rngd" daemon. Documentation/hw_random.txt

has more information.

If unsure, say Y.

config HW_RANDOM_INTEL

tristate "Intel HW Random Number Generator support"

depends on HW_RANDOM && (X86 || IA64) && PCI

default HW_RANDOM

---help---

This driver provides kernel-side support for the Random Number

Generator hardware found on Intel i8xx-based motherboards.

To compile this driver as a module, choose M here: the

module will be called intel-rng.

If unsure, say Y.

config HW_RANDOM_AMD

tristate "AMD HW Random Number Generator support"

depends on HW_RANDOM && X86 && PCI

default HW_RANDOM

---help---

This driver provides kernel-side support for the Random Number

Generator hardware found on AMD 76x-based motherboards.

To compile this driver as a module, choose M here: the

module will be called amd-rng.

If unsure, say Y.

config HW_RANDOM_GEODE

tristate "AMD Geode HW Random Number Generator support"

depends on HW_RANDOM && X86_32 && PCI

default HW_RANDOM

---help---

This driver provides kernel-side support for the Random Number

Generator hardware found on the AMD Geode LX.

To compile this driver as a module, choose M here: the

module will be called geode-rng.

If unsure, say Y.

config HW_RANDOM_VIA

tristate "VIA HW Random Number Generator support"

depends on HW_RANDOM && X86_32

default HW_RANDOM

---help---

This driver provides kernel-side support for the Random Number

Generator hardware found on VIA based motherboards.

To compile this driver as a module, choose M here: the

module will be called via-rng.

If unsure, say Y.

config HW_RANDOM_IXP4XX

tristate "Intel IXP4xx NPU HW Random Number Generator support"

depends on HW_RANDOM && ARCH_IXP4XX

default HW_RANDOM

---help---

This driver provides kernel-side support for the Random

Number Generator hardware found on the Intel IXP4xx NPU.

To compile this driver as a module, choose M here: the

module will be called ixp4xx-rng.

If unsure, say Y.

config HW_RANDOM_OMAP

tristate "OMAP Random Number Generator support"

depends on HW_RANDOM && (ARCH_OMAP16XX || ARCH_OMAP24XX)

default HW_RANDOM

---help---

This driver provides kernel-side support for the Random Number

Generator hardware found on OMAP16xx and OMAP24xx multimedia

processors.

To compile this driver as a module, choose M here: the

module will be called omap-rng.

If unsure, say Y.

config HW_RANDOM_PASEMI

tristate "PA Semi HW Random Number Generator support"

depends on HW_RANDOM && PPC_PASEMI

default HW_RANDOM

---help---

This driver provides kernel-side support for the Random Number

Generator hardware found on PA Semi PWRficient SoCs.

To compile this driver as a module, choose M here: the

module will be called pasemi-rng.

If unsure, say Y.

config HW_RANDOM_TRNG4xx

tristate "AMCC 4xx TRNG True Random Number Generator support"

depends on HW_RANDOM && PPC

default HW_RANDOM

---help---

This driver provides kernel-side support for the Random Number

Generator hardware found on PA Semi PWRficient SoCs.

To compile this driver as a module, choose M here: the

module will be called pasemi-rng.

If unsure, say Y.

----------------------------------------Makefile --------------------
#

# Makefile for HW Random Number Generator (RNG) device drivers.

#

obj-$(CONFIG_HW_RANDOM) += rng-core.o

rng-core-y := core.o

obj-$(CONFIG_HW_RANDOM_INTEL) += intel-rng.o

obj-$(CONFIG_HW_RANDOM_AMD) += amd-rng.o

obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o

obj-$(CONFIG_HW_RANDOM_VIA) += via-rng.o

obj-$(CONFIG_HW_RANDOM_IXP4XX) += ixp4xx-rng.o

obj-$(CONFIG_HW_RANDOM_OMAP) += omap-rng.o

obj-$(CONFIG_HW_RANDOM_PASEMI) += pasemi-rng.o

obj-$(CONFIG_HW_RANDOM_TRNG4xx) += trng4xx.o


________________________________

From: linuxppc-dev-bounces+tmarri=amcc.com at ozlabs.org on behalf of Tirumala Reddy Marri
Sent: Wed 4/1/2009 10:05 AM
To: Felix Radensky; linuxppc-dev at ozlabs.org
Subject: RE: /dev/random on PPC40EXr



There is PKA/TRNG driver for sure. Let me check if it was accepted in
opensource yet. Otherwise I will forward you the driver which may not be
there in opensource yet.


-----Original Message-----
From: linuxppc-dev-bounces+tmarri=amcc.com at ozlabs.org
[mailto:linuxppc-dev-bounces+tmarri=amcc.com at ozlabs.org] On Behalf Of
Felix Radensky
Sent: Wednesday, April 01, 2009 5:00 AM
To: linuxppc-dev at ozlabs.org
Subject: /dev/random on PPC40EXr


Hi,

On my custom board based on 405EXr /dev/random produces no output
at all, and /dev/urandom is not random enough for our purposes. Saving
entropy pool between reboots doesn't help much.

What can be done to increase the entropy of the system ?
I was thinking of adding IRQF_SAMPLE_RANDOM to network driver,
but since not too many drivers implement it, I don't know whether
it's a good idea or not.

Is there any work in progress to develop hw_random driver for 4xx
TRNG ?

Thanks a lot.

Felix.
--
View this message in context:
http://www.nabble.com/-dev-random-on-PPC40EXr-tp22824979p22824979.html
Sent from the linuxppc-dev mailing list archive at Nabble.com.

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev at ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev
_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev at ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ozlabs.org/pipermail/linuxppc-dev/attachments/20090401/da919353/attachment.htm>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: trng4xx.c
URL: <http://lists.ozlabs.org/pipermail/linuxppc-dev/attachments/20090401/da919353/attachment.txt>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: trng4xx.h
URL: <http://lists.ozlabs.org/pipermail/linuxppc-dev/attachments/20090401/da919353/attachment.asc>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: canyonlands.dts
Type: application/octet-stream
Size: 13219 bytes
Desc: canyonlands.dts
URL: <http://lists.ozlabs.org/pipermail/linuxppc-dev/attachments/20090401/da919353/attachment.obj>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: Kconfig
URL: <http://lists.ozlabs.org/pipermail/linuxppc-dev/attachments/20090401/da919353/attachment-0001.asc>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: Makefile
URL: <http://lists.ozlabs.org/pipermail/linuxppc-dev/attachments/20090401/da919353/attachment-0001.txt>


More information about the Linuxppc-dev mailing list