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