1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016-2017, 2019 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_rnga.h"
10 
11 #if defined(FSL_FEATURE_SOC_RNG_COUNT) && FSL_FEATURE_SOC_RNG_COUNT
12 
13 /*******************************************************************************
14  * Definitions
15  *******************************************************************************/
16 
17 /* Component ID definition, used by tools. */
18 #ifndef FSL_COMPONENT_ID
19 #define FSL_COMPONENT_ID "platform.drivers.rnga"
20 #endif
21 
22 /*******************************************************************************
23  * RNG_CR - RNGA Control Register
24  ******************************************************************************/
25 /*!
26  * @brief RNG_CR - RNGA Control Register (RW)
27  *
28  * Reset value: 0x00000000U
29  *
30  * Controls the operation of RNGA.
31  */
32 /*!
33  * @name Constants and macros for entire RNG_CR register
34  */
35 /*@{*/
36 #define RNG_CR_REG(base)              ((base)->CR)
37 #define RNG_RD_CR(base)               (RNG_CR_REG(base))
38 #define RNG_WR_CR(base, value)        (RNG_CR_REG(base) = (value))
39 #define RNG_RMW_CR(base, mask, value) (RNG_WR_CR(base, (RNG_RD_CR(base) & ~(mask)) | (value)))
40 /*@}*/
41 
42 /*!
43  * @name Register RNG_CR, field GO[0] (RW)
44  *
45  * Specifies whether random-data generation and loading (into OR[RANDOUT]) is
46  * enabled.This field is sticky. You must reset RNGA to stop RNGA from loading
47  * OR[RANDOUT] with data.
48  *
49  * Values:
50  * - 0b0 - Disabled
51  * - 0b1 - Enabled
52  */
53 /*@{*/
54 /*! @brief Read current value of the RNG_CR_GO field. */
55 #define RNG_RD_CR_GO(base) ((RNG_CR_REG(base) & RNG_CR_GO_MASK) >> RNG_CR_GO_SHIFT)
56 
57 /*! @brief Set the GO field to a new value. */
58 #define RNG_WR_CR_GO(base, value) (RNG_RMW_CR(base, RNG_CR_GO_MASK, RNG_CR_GO(value)))
59 /*@}*/
60 
61 /*!
62  * @name Register RNG_CR, field SLP[4] (RW)
63  *
64  * Specifies whether RNGA is in Sleep or Normal mode. You can also enter Sleep
65  * mode by asserting the DOZE signal.
66  *
67  * Values:
68  * - 0b0 - Normal mode
69  * - 0b1 - Sleep (low-power) mode
70  */
71 /*@{*/
72 /*! @brief Read current value of the RNG_CR_SLP field. */
73 #define RNG_RD_CR_SLP(base) ((RNG_CR_REG(base) & RNG_CR_SLP_MASK) >> RNG_CR_SLP_SHIFT)
74 
75 /*! @brief Set the SLP field to a new value. */
76 #define RNG_WR_CR_SLP(base, value) (RNG_RMW_CR(base, RNG_CR_SLP_MASK, RNG_CR_SLP(value)))
77 /*@}*/
78 
79 /*******************************************************************************
80  * RNG_SR - RNGA Status Register
81  ******************************************************************************/
82 #define RNG_SR_REG(base) ((base)->SR)
83 
84 /*!
85  * @name Register RNG_SR, field OREG_LVL[15:8] (RO)
86  *
87  * Indicates the number of random-data words that are in OR[RANDOUT], which
88  * indicates whether OR[RANDOUT] is valid.If you read OR[RANDOUT] when SR[OREG_LVL]
89  * is not 0, then the contents of a random number contained in OR[RANDOUT] are
90  * returned, and RNGA writes 0 to both OR[RANDOUT] and SR[OREG_LVL].
91  *
92  * Values:
93  * - 0b00000000 - No words (empty)
94  * - 0b00000001 - One word (valid)
95  */
96 /*@{*/
97 /*! @brief Read current value of the RNG_SR_OREG_LVL field. */
98 #define RNG_RD_SR_OREG_LVL(base) ((RNG_SR_REG(base) & RNG_SR_OREG_LVL_MASK) >> RNG_SR_OREG_LVL_SHIFT)
99 /*@}*/
100 
101 /*!
102  * @name Register RNG_SR, field SLP[4] (RO)
103  *
104  * Specifies whether RNGA is in Sleep or Normal mode. You can also enter Sleep
105  * mode by asserting the DOZE signal.
106  *
107  * Values:
108  * - 0b0 - Normal mode
109  * - 0b1 - Sleep (low-power) mode
110  */
111 /*@{*/
112 /*! @brief Read current value of the RNG_SR_SLP field. */
113 #define RNG_RD_SR_SLP(base) ((RNG_SR_REG(base) & RNG_SR_SLP_MASK) >> RNG_SR_SLP_SHIFT)
114 /*@}*/
115 
116 /*******************************************************************************
117  * RNG_OR - RNGA Output Register
118  ******************************************************************************/
119 /*!
120  * @brief RNG_OR - RNGA Output Register (RO)
121  *
122  * Reset value: 0x00000000U
123  *
124  * Stores a random-data word generated by RNGA.
125  */
126 /*!
127  * @name Constants and macros for entire RNG_OR register
128  */
129 /*@{*/
130 #define RNG_OR_REG(base) ((base)->OR)
131 #define RNG_RD_OR(base)  (RNG_OR_REG(base))
132 /*@}*/
133 
134 /*******************************************************************************
135  * RNG_ER - RNGA Entropy Register
136  ******************************************************************************/
137 /*!
138  * @brief RNG_ER - RNGA Entropy Register (WORZ)
139  *
140  * Reset value: 0x00000000U
141  *
142  * Specifies an entropy value that RNGA uses in addition to its ring oscillators
143  * to seed its pseudorandom algorithm. This is a write-only register; reads
144  * return all zeros.
145  */
146 /*!
147  * @name Constants and macros for entire RNG_ER register
148  */
149 /*@{*/
150 #define RNG_ER_REG(base)       ((base)->ER)
151 #define RNG_RD_ER(base)        (RNG_ER_REG(base))
152 #define RNG_WR_ER(base, value) (RNG_ER_REG(base) = (value))
153 /*@}*/
154 
155 /*******************************************************************************
156  * Prototypes
157  *******************************************************************************/
158 
159 static uint32_t rnga_ReadEntropy(RNG_Type *base);
160 
161 /*******************************************************************************
162  * Code
163  ******************************************************************************/
164 
165 /*!
166  * brief Initializes the RNGA.
167  *
168  * This function initializes the RNGA.
169  * When called, the RNGA entropy generation starts immediately.
170  *
171  * param base RNGA base address
172  */
RNGA_Init(RNG_Type * base)173 void RNGA_Init(RNG_Type *base)
174 {
175 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
176     /* Enable the clock gate. */
177     CLOCK_EnableClock(kCLOCK_Rnga0);
178 #endif                                /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
179     CLOCK_DisableClock(kCLOCK_Rnga0); /* To solve the release version on twrkm43z75m */
180 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
181     CLOCK_EnableClock(kCLOCK_Rnga0);
182 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
183 
184     /* Reset the registers for RNGA module to reset state. */
185     RNG_WR_CR(base, 0);
186     /* Enables the RNGA random data generation and loading.*/
187     RNG_WR_CR_GO(base, 1);
188 }
189 
190 /*!
191  * brief Shuts down the RNGA.
192  *
193  * This function shuts down the RNGA.
194  *
195  * param base RNGA base address
196  */
RNGA_Deinit(RNG_Type * base)197 void RNGA_Deinit(RNG_Type *base)
198 {
199 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
200     /* Disable the clock for RNGA module.*/
201     CLOCK_DisableClock(kCLOCK_Rnga0);
202 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
203 }
204 
205 /*!
206  * @brief Get a random data from RNGA.
207  *
208  * @param base RNGA base address
209  */
rnga_ReadEntropy(RNG_Type * base)210 static uint32_t rnga_ReadEntropy(RNG_Type *base)
211 {
212     uint32_t data = 0;
213     if (RNGA_GetMode(base) == kRNGA_ModeNormal) /* Is in normal mode.*/
214     {
215         /* Wait for valid random-data.*/
216         while (RNG_RD_SR_OREG_LVL(base) == 0U)
217         {
218         }
219         data = RNG_RD_OR(base);
220     }
221     /* Get random-data word generated by RNGA.*/
222     return data;
223 }
224 
225 /*!
226  * brief Gets random data.
227  *
228  * This function gets random data from the RNGA.
229  *
230  * param base RNGA base address
231  * param data pointer to user buffer to be filled by random data
232  * param data_size size of data in bytes
233  * return RNGA status
234  */
RNGA_GetRandomData(RNG_Type * base,void * data,size_t data_size)235 status_t RNGA_GetRandomData(RNG_Type *base, void *data, size_t data_size)
236 {
237     status_t result = kStatus_Success;
238     uint32_t random_32;
239     uint8_t *random_p;
240     uint32_t random_size;
241     uint8_t *data_p = (uint8_t *)data;
242     uint32_t i;
243 
244     /* Check input parameters.*/
245     if ((NULL != base) && (NULL != data) && (0U != data_size))
246     {
247         do
248         {
249             /* Read Entropy.*/
250             random_32 = rnga_ReadEntropy(base);
251 
252             random_p = (uint8_t *)&random_32;
253 
254             if (data_size < sizeof(random_32))
255             {
256                 random_size = data_size;
257             }
258             else
259             {
260                 random_size = sizeof(random_32);
261             }
262 
263             for (i = 0; i < random_size; i++)
264             {
265                 *data_p++ = *random_p++;
266             }
267 
268             data_size -= random_size;
269         } while (data_size > 0U);
270     }
271     else
272     {
273         result = kStatus_InvalidArgument;
274     }
275 
276     return result;
277 }
278 
279 /*!
280  * brief Sets the RNGA in normal mode or sleep mode.
281  *
282  * This function sets the RNGA in sleep mode or normal mode.
283  *
284  * param base RNGA base address
285  * param mode normal mode or sleep mode
286  */
RNGA_SetMode(RNG_Type * base,rnga_mode_t mode)287 void RNGA_SetMode(RNG_Type *base, rnga_mode_t mode)
288 {
289     RNG_WR_CR_SLP(base, (uint32_t)mode);
290 }
291 
292 /*!
293  * brief Gets the RNGA working mode.
294  *
295  * This function gets the RNGA working mode.
296  *
297  * param base RNGA base address
298  * return normal mode or sleep mode
299  */
RNGA_GetMode(RNG_Type * base)300 rnga_mode_t RNGA_GetMode(RNG_Type *base)
301 {
302     return (rnga_mode_t)((uint32_t)(RNG_RD_SR_SLP(base)));
303 }
304 
305 /*!
306  * brief Feeds the RNGA module.
307  *
308  * This function inputs an entropy value that the RNGA uses to seed its
309  * pseudo-random algorithm.
310  *
311  * param base RNGA base address
312  * param seed input seed value
313  */
RNGA_Seed(RNG_Type * base,uint32_t seed)314 void RNGA_Seed(RNG_Type *base, uint32_t seed)
315 {
316     /* Write to RNGA Entropy Register.*/
317     RNG_WR_ER(base, seed);
318 }
319 
320 #endif /* FSL_FEATURE_SOC_RNG_COUNT */
321