mirror of
https://github.com/apache/nuttx.git
synced 2026-08-09 06:25:09 +00:00
arch/mips/jz4780: Add hardware Random Number Generator (RNG) support
Add support for the hardware Random Number Generator (RNG) module found on the Ingenic JZ4780 SoC. Changes include: - Update jz4780 chip.h with power management controllor base address JZPMC_BASE and register offsets for the RNG registers. - A new file jz4780_rng.c to provide character driver interfaces for `/dev/random` and `/dev/urandom` utilizing the hardware RNG block. Signed-off-by: Lwazi Dube <lwazeh@gmail.com>
This commit is contained in:
parent
cda33ae4fc
commit
60abe4744f
4 changed files with 260 additions and 11 deletions
|
|
@ -33,10 +33,10 @@
|
|||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define CKPCR 0xB0003040
|
||||
#define CKPCR 0xb0003040
|
||||
#define CKPCR_CK32CTL_RTCLK (3 << 1)
|
||||
|
||||
#define JZINTC_BASE 0xB0001000
|
||||
#define JZINTC_BASE 0xb0001000
|
||||
|
||||
#define ICMSR0 (JZINTC_BASE + 0x08)
|
||||
#define ICMCR0 (JZINTC_BASE + 0x0C)
|
||||
|
|
@ -45,7 +45,7 @@
|
|||
#define ICMCR1 (JZINTC_BASE + 0x2C)
|
||||
#define ICPR1 (JZINTC_BASE + 0x30)
|
||||
|
||||
#define JZTMR_BASE 0xB0002000
|
||||
#define JZTMR_BASE 0xb0002000
|
||||
|
||||
#define WD_TDR (JZTMR_BASE + 0x00) // u16: Watchdog Timer Data
|
||||
#define WD_TCER (JZTMR_BASE + 0x04) // u8 : Watchdog Counter Enable
|
||||
|
|
@ -87,37 +87,43 @@
|
|||
#define TCSR(n) (JZTMR_BASE + 0x4C + (n)*0x10)
|
||||
#define TDFR(n) (JZTMR_BASE + 0x40 + (n)*0x10)
|
||||
|
||||
#define CLKGR0_REG 0xb0000020
|
||||
#define JZPMC_BASE 0xb0000000
|
||||
|
||||
#define CLKGR0_REG (JZPMC_BASE + 0x20)
|
||||
# define CLKGR0_OTG0 (1 << 2)
|
||||
# define CLKGR0_UHC (1 << 24)
|
||||
# define CLKGR0_LCD (1 << 28)
|
||||
# define CLKGR0_TVE (1 << 27)
|
||||
|
||||
#define OPCR_REG 0xb0000024
|
||||
#define OPCR_REG (JZPMC_BASE + 0x24)
|
||||
# define OPCR_SPENDN1 (1 << 6)
|
||||
|
||||
#define CLKGR1_REG 0xb0000028
|
||||
#define CLKGR1_REG (JZPMC_BASE + 0x28)
|
||||
# define CLKGR1_HDMI (1 << 9)
|
||||
|
||||
#define USBPCR_REG 0xb000003c
|
||||
#define USBPCR_REG (JZPMC_BASE + 0x3c)
|
||||
# define USBPCR_POR (1 << 22)
|
||||
|
||||
#define USBPCR1_REG 0xb0000048
|
||||
#define USBPCR1_REG (JZPMC_BASE + 0x48)
|
||||
# define REFCLK_DIV_MSK 0xfcffffff /* clears bits 25:24 */
|
||||
# define REFCLK_DIV_48MHZ 0x02000000 /* bits 25:24 */
|
||||
# define WORD_IF_16BIT 0x000c0000 /* bits 19:18 */
|
||||
|
||||
#define LP1CDR_REG 0xb0000054
|
||||
#define LP1CDR_REG (JZPMC_BASE + 0x54)
|
||||
# define LPCDR_VAL 0x15
|
||||
# define LPCS_VPLL 0X80000000
|
||||
# define CE_LCD (1 << 28)
|
||||
# define LCD_BUSY (1 << 27)
|
||||
|
||||
#define HDMICDR_REG 0xb000008c
|
||||
#define HDMICDR_REG (JZPMC_BASE + 0x8c)
|
||||
|
||||
#define SRBC_REG 0xb00000c4
|
||||
#define SRBC_REG (JZPMC_BASE + 0xc4)
|
||||
# define SRBC_UHC_SR (1 << 14)
|
||||
|
||||
#define ERNG_REG (JZPMC_BASE + 0xd8)
|
||||
# define ENABLE_RNG (1 << 0)
|
||||
#define RNG_REG (JZPMC_BASE + 0xdc)
|
||||
|
||||
#define TICKS_PER_MS (48000/16)
|
||||
|
||||
#define CHIP_JZ4780 1
|
||||
|
|
|
|||
|
|
@ -7,6 +7,12 @@ if ARCH_CHIP_JZ4780
|
|||
comment "JZ4780 Configuration Options"
|
||||
|
||||
menu "JZ4780 Peripheral Support"
|
||||
|
||||
config JZ4780_RNG
|
||||
bool "Random Number Generator (RNG)"
|
||||
default y
|
||||
select ARCH_HAVE_RNG
|
||||
|
||||
config JZ4780_LCD
|
||||
bool "LCD controller"
|
||||
default n
|
||||
|
|
|
|||
|
|
@ -52,6 +52,10 @@ CHIP_CSRCS = jz4780_lowinit.c jz4780_exception.c jz4780_decodeirq.c
|
|||
CHIP_CSRCS += jz4780_irq.c jz4780_timerisr.c jz4780_gpio.c
|
||||
CHIP_CSRCS += jz4780_cache.c
|
||||
|
||||
ifeq ($(CONFIG_JZ4780_RNG),y)
|
||||
CHIP_CSRCS += jz4780_rng.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_USBHOST),y)
|
||||
CHIP_CSRCS += jz_usbhost.c
|
||||
|
||||
|
|
|
|||
233
arch/mips/src/jz4780/jz4780_rng.c
Normal file
233
arch/mips/src/jz4780/jz4780_rng.c
Normal file
|
|
@ -0,0 +1,233 @@
|
|||
/****************************************************************************
|
||||
* arch/mips/src/jz4780/jz4780_rng.c
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <nuttx/debug.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/mutex.h>
|
||||
#include <nuttx/drivers/drivers.h>
|
||||
|
||||
#include "mips_internal.h"
|
||||
|
||||
#if defined(CONFIG_DEV_RANDOM) || defined(CONFIG_DEV_URANDOM_ARCH)
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define ENTROPY_DELAY 10
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
static int jz_rng_initialize(void);
|
||||
static ssize_t jz_rng_read(struct file *filep, char *buffer, size_t);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct rng_dev_s
|
||||
{
|
||||
mutex_t rd_lock;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static struct rng_dev_s g_rngdev =
|
||||
{
|
||||
.rd_lock = NXMUTEX_INITIALIZER,
|
||||
};
|
||||
|
||||
static const struct file_operations g_rngops =
|
||||
{
|
||||
NULL, /* open */
|
||||
NULL, /* close */
|
||||
jz_rng_read, /* read */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: jz_rng_initialize
|
||||
*
|
||||
* Description:
|
||||
* Enable the random number generator
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success; negated errno on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int jz_rng_initialize(void)
|
||||
{
|
||||
uint32_t retval;
|
||||
struct rng_dev_s *priv = (struct rng_dev_s *)&g_rngdev;
|
||||
|
||||
if (nxmutex_lock(&priv->rd_lock) != OK)
|
||||
{
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* Enable RNG if it is disabled */
|
||||
|
||||
if ((getreg32(ERNG_REG) & ENABLE_RNG) == 0)
|
||||
{
|
||||
putreg32(ENABLE_RNG, ERNG_REG);
|
||||
}
|
||||
|
||||
up_mdelay(1);
|
||||
|
||||
retval = (getreg32(ERNG_REG) & ENABLE_RNG) ? OK : -EIO;
|
||||
|
||||
if (retval != OK)
|
||||
{
|
||||
_err("Failed to initialize RNG\n");
|
||||
}
|
||||
|
||||
nxmutex_unlock(&priv->rd_lock);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: jz_rng_read
|
||||
*
|
||||
* Description:
|
||||
* This is the standard, NuttX character driver read method
|
||||
*
|
||||
* Input Parameters:
|
||||
* filep - The VFS file instance
|
||||
* buffer - Buffer in which to return the random samples
|
||||
* buflen - The length of the buffer
|
||||
*
|
||||
* Returned Value:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static ssize_t jz_rng_read(struct file *filep, char *buffer, size_t buflen)
|
||||
{
|
||||
struct rng_dev_s *priv = (struct rng_dev_s *)&g_rngdev;
|
||||
ssize_t bytes_left = buflen;
|
||||
uint8_t *rd_buf = (uint8_t *)buffer;
|
||||
uint32_t last_word;
|
||||
|
||||
if (nxmutex_lock(&priv->rd_lock) != OK)
|
||||
{
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
last_word = getreg32(RNG_REG);
|
||||
while (bytes_left > 0)
|
||||
{
|
||||
up_mdelay(ENTROPY_DELAY);
|
||||
uint32_t word = getreg32(RNG_REG);
|
||||
if (word == last_word)
|
||||
{
|
||||
/* Try again if the same number is repeated */
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
last_word = word;
|
||||
|
||||
uint32_t count = MIN(sizeof(word), bytes_left);
|
||||
|
||||
memcpy(rd_buf, &word, count);
|
||||
rd_buf += count;
|
||||
bytes_left -= count;
|
||||
}
|
||||
|
||||
nxmutex_unlock(&priv->rd_lock);
|
||||
return buflen;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: devrandom_register
|
||||
*
|
||||
* Description:
|
||||
* Initialize the RNG hardware and register the /dev/random driver.
|
||||
* Must be called BEFORE devurandom_register.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_DEV_RANDOM
|
||||
void devrandom_register(void)
|
||||
{
|
||||
if (jz_rng_initialize() == OK)
|
||||
{
|
||||
register_driver("/dev/random", &g_rngops, 0444, NULL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: devurandom_register
|
||||
*
|
||||
* Description:
|
||||
* Register /dev/urandom
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_DEV_URANDOM_ARCH
|
||||
void devurandom_register(void)
|
||||
{
|
||||
if (jz_rng_initialize() == OK)
|
||||
{
|
||||
register_driver("/dev/urandom", &g_rngops, 0444, NULL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_DEV_RANDOM || CONFIG_DEV_URANDOM_ARCH */
|
||||
Loading…
Add table
Add a link
Reference in a new issue