• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include "hpm_rng_drv.h"
9 
rng_run_selftest(RNG_Type * ptr)10 hpm_stat_t rng_run_selftest(RNG_Type *ptr)
11 {
12     uint32_t status;
13 
14     ptr->CMD |= RNG_CMD_SLFCHK_MASK;
15     do {
16         status = ptr->STA;
17     } while (!(status & (RNG_STA_FUNCERR_MASK | RNG_STA_SCDN_MASK)));
18 
19     if ((status & (RNG_STA_SCPF_MASK | RNG_STA_FUNCERR_MASK))) {
20         return status;
21     }
22 
23     return status_success;
24 }
25 
rng_feed_rand_to_sdp(RNG_Type * ptr)26 hpm_stat_t rng_feed_rand_to_sdp(RNG_Type *ptr)
27 {
28     uint32_t i = 0;
29     uint32_t status;
30     uint32_t fifo_level;
31     hpm_stat_t stat = status_success;
32 
33     for (i = 0; i < ARRAY_SIZE(ptr->R2SK); i++) {
34         status = ptr->STA;
35         if (status & RNG_STA_FUNCERR_MASK) {
36             stat = status_fail;
37             break;
38         }
39 
40         do {
41             fifo_level = (ptr->STA & RNG_STA_FRNNU_MASK) >> RNG_STA_FRNNU_SHIFT;
42         } while (!fifo_level);
43 
44         __asm volatile ("" : : "r" (ptr->R2SK[i]));
45     }
46     return stat;
47 }
48 
rng_rand(RNG_Type * ptr,void * buf,uint32_t count_in_byte,bool wait)49 static hpm_stat_t rng_rand(RNG_Type *ptr, void *buf, uint32_t count_in_byte, bool wait)
50 {
51     uint32_t i;
52     uint32_t status;
53     volatile uint32_t fifo_level;
54     hpm_stat_t stat = status_success;
55 
56     if (count_in_byte < 4) {
57         return status_invalid_argument;
58     }
59 
60     for (i = 0; i < (count_in_byte / 4); i++) {
61         status = ptr->STA;
62         if (status & RNG_STA_FUNCERR_MASK) {
63             stat = status_fail;
64             break;
65         }
66 
67         do {
68             fifo_level = (ptr->STA & RNG_STA_FRNNU_MASK) >> RNG_STA_FRNNU_SHIFT;
69         } while (!fifo_level && wait);
70 
71         if (fifo_level) {
72             *(uint32_t *)(buf + i * sizeof(uint32_t)) = ptr->FO2B;
73         } else {
74             stat = status_rng_not_available;
75             break;
76         }
77     }
78 
79     return stat;
80 }
81 
rng_rand_wait(RNG_Type * ptr,void * buf,uint32_t count_in_byte)82 hpm_stat_t rng_rand_wait(RNG_Type *ptr, void *buf, uint32_t count_in_byte)
83 {
84     return rng_rand(ptr, buf, count_in_byte, true);
85 }
86 
rng_rand_no_wait(RNG_Type * ptr,void * buf,uint32_t count_in_byte)87 hpm_stat_t rng_rand_no_wait(RNG_Type *ptr, void *buf, uint32_t count_in_byte)
88 {
89     return rng_rand(ptr, buf, count_in_byte, false);
90 }
91 
rng_init(RNG_Type * ptr)92 hpm_stat_t rng_init(RNG_Type *ptr)
93 {
94     hpm_stat_t stat = status_success;
95 
96     /* clear interrupt and error */
97     ptr->CMD |= RNG_CMD_CLRERR_MASK;
98 
99     /* generating seed */
100     ptr->CMD |= RNG_CMD_GENSD_MASK;
101     while (!(ptr->STA & RNG_STA_FSDDN_MASK)) {
102         if (ptr->STA & RNG_STA_FUNCERR_MASK) {
103             stat = status_fail;
104             break;
105         }
106     }
107     if (stat != status_success) {
108         return stat;
109     }
110 
111     /* enable auto seeding */
112     ptr->CTRL |= RNG_CTRL_AUTRSD_MASK;
113 
114     return stat;
115 }
116 
117