From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jaehoon Chung Date: Thu, 06 Mar 2014 14:43:35 +0900 Subject: [U-Boot] [PATCH V2 1/3] cpu: exynos4: ace_sha: add hardware random number generator support. In-Reply-To: <1882e4320da26486d3759d81f1b440a0f89457b8.1394038415.git.p.marczak@samsung.com> References: <1882e4320da26486d3759d81f1b440a0f89457b8.1394038415.git.p.marczak@samsung.com> Message-ID: <53180B07.1030502@samsung.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de On 03/06/2014 01:57 AM, Przemyslaw Marczak wrote: > This patch adds implementation of function hw_rand() based on exynos > security sub system. > > Signed-off-by: Przemyslaw Marczak > cc: Akshay Saraswat > cc: ARUN MANKUZHI > cc: Minkyu Kang > --- > Changes v2: > - none > > arch/arm/include/asm/arch-exynos/cpu.h | 4 ++-- > drivers/crypto/ace_sha.c | 41 ++++++++++++++++++++++++++++++++ > drivers/crypto/ace_sha.h | 8 ++++--- > 3 files changed, 48 insertions(+), 5 deletions(-) > > diff --git a/arch/arm/include/asm/arch-exynos/cpu.h b/arch/arm/include/asm/arch-exynos/cpu.h > index bccce63..a5c280d 100644 > --- a/arch/arm/include/asm/arch-exynos/cpu.h > +++ b/arch/arm/include/asm/arch-exynos/cpu.h > @@ -48,7 +48,7 @@ > #define EXYNOS4_GPIO_PART4_BASE DEVICE_NOT_AVAILABLE > #define EXYNOS4_DP_BASE DEVICE_NOT_AVAILABLE > #define EXYNOS4_SPI_ISP_BASE DEVICE_NOT_AVAILABLE > -#define EXYNOS4_ACE_SFR_BASE DEVICE_NOT_AVAILABLE > +#define EXYNOS4_ACE_SFR_BASE 0x10830000 > #define EXYNOS4_DMC_PHY_BASE DEVICE_NOT_AVAILABLE > #define EXYNOS4_AUDIOSS_BASE DEVICE_NOT_AVAILABLE > #define EXYNOS4_USB_HOST_XHCI_BASE DEVICE_NOT_AVAILABLE > @@ -87,7 +87,7 @@ > #define EXYNOS4X12_I2S_BASE DEVICE_NOT_AVAILABLE > #define EXYNOS4X12_SPI_BASE DEVICE_NOT_AVAILABLE > #define EXYNOS4X12_SPI_ISP_BASE DEVICE_NOT_AVAILABLE > -#define EXYNOS4X12_ACE_SFR_BASE DEVICE_NOT_AVAILABLE > +#define EXYNOS4X12_ACE_SFR_BASE 0x10830000 > #define EXYNOS4X12_DMC_PHY_BASE DEVICE_NOT_AVAILABLE > #define EXYNOS4X12_AUDIOSS_BASE DEVICE_NOT_AVAILABLE > #define EXYNOS4X12_USB_HOST_XHCI_BASE DEVICE_NOT_AVAILABLE > diff --git a/drivers/crypto/ace_sha.c b/drivers/crypto/ace_sha.c > index acbafde..d12a507 100644 > --- a/drivers/crypto/ace_sha.c > +++ b/drivers/crypto/ace_sha.c > @@ -111,3 +111,44 @@ void hw_sha1(const unsigned char *pbuf, unsigned int buf_len, > if (ace_sha_hash_digest(pbuf, buf_len, pout, ACE_SHA_TYPE_SHA1)) > debug("ACE was not setup properly or it is faulty\n"); > } > + > +unsigned int hw_rand(void) > +{ > + struct exynos_ace_sfr *reg = > + (struct exynos_ace_sfr *)samsung_get_base_ace_sfr(); > + int status, i; > + int seed[5]; > + unsigned int ret = 0; > + > + /* Seed data */ > + for (i = 0; i < ACE_HASH_PRNG_REG_NUM; i++) > + writel(seed[i], ®->hash_seed[i]); > + > + status = 0; > + /* Wait for seed setup done */ > + while (!(status & ACE_HASH_SEEDSETTING_MASK)) { > + status = readl(®->hash_status); > + if (status & ACE_HASH_PRNGERROR_MASK) > + return 0; > + } Can it use "do{ }while"? > + > + /* Start PRNG */ > + writel(ACE_HASH_ENGSEL_PRNG | ACE_HASH_STARTBIT_ON, ®->hash_control); > + > + status = 0; > + /* Wait for PRNG done */ > + while (!(status & ACE_HASH_PRNGDONE_MASK)) { > + status = readl(®->hash_status); > + if (status & ACE_HASH_PRNGERROR_MASK) > + return 0; > + } > + > + /* Clear Done IRQ */ > + writel(ACE_HASH_PRNGDONE_MASK, ®->hash_status); > + > + /* Read a PRNG result */ > + for (i = 0; i < ACE_HASH_PRNG_REG_NUM; i++) > + ret += readl(®->hash_prng[i]); > + > + return ret; > +} > diff --git a/drivers/crypto/ace_sha.h b/drivers/crypto/ace_sha.h > index a426d52..f1097f7 100644 > --- a/drivers/crypto/ace_sha.h > +++ b/drivers/crypto/ace_sha.h > @@ -72,9 +72,10 @@ struct exynos_ace_sfr { > unsigned char res12[0x30]; > unsigned int hash_result[8]; > unsigned char res13[0x20]; > - unsigned int hash_seed[8]; > - unsigned int hash_prng[8]; > - unsigned char res14[0x180]; > + unsigned int hash_seed[5]; > + unsigned char res14[12]; > + unsigned int hash_prng[5]; > + unsigned char res15[0x18c]; > > unsigned int pka_sfr[5]; /* base + 0x700 */ > }; > @@ -291,6 +292,7 @@ struct exynos_ace_sfr { > #define ACE_HASH_PRNGERROR_MASK (1 << 7) > #define ACE_HASH_PRNGERROR_OFF (0 << 7) > #define ACE_HASH_PRNGERROR_ON (1 << 7) > +#define ACE_HASH_PRNG_REG_NUM 5 > > #define ACE_SHA_TYPE_SHA1 1 > #define ACE_SHA_TYPE_SHA256 2 >