Skip to content

Commit eb05fc9

Browse files
SzpejnaDawidDawidSzpejna
authored and
DawidSzpejna
committed
rngb: add the support for TRNG for imx6ull
The driver starts by creating basic structures for a phonix driver. Then it sets flags for tests of rngb and seeding, sequentially. The last things is waiting for system messaga. JIRA: RTOS-317
1 parent 60ac983 commit eb05fc9

File tree

1 file changed

+260
-0
lines changed

1 file changed

+260
-0
lines changed

rngb/imx6ull-rngb.c

Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
/*
2+
* Phoenix-RTOS
3+
*
4+
* i.MX 6ULL RNGB driver
5+
*
6+
* Copyright 2023 Phoenix Systems
7+
* Author: Dawid Szpejna
8+
*
9+
* This file is part of Phoenix-RTOS.
10+
*
11+
* %LICENSE%
12+
*/
13+
14+
#include <sys/msg.h>
15+
#include <errno.h>
16+
#include <unistd.h>
17+
#include <stdint.h>
18+
#include <posix/utils.h>
19+
#include <sys/platform.h>
20+
#include <stdio.h>
21+
#include <sys/threads.h>
22+
#include <sys/interrupt.h>
23+
#include <sys/mman.h>
24+
#include <sys/debug.h>
25+
26+
27+
#define RNG_VER 0
28+
#define RNG_CMD 1
29+
#define RNG_CR 2
30+
#define RNG_SR 3
31+
#define RNG_ESR 4
32+
#define RNG_OUT 5
33+
34+
35+
#define RNGB_START_ADDRESS 0x02284000
36+
#define RNGB_IRQ (6 + 32)
37+
38+
39+
#define AFTER_TEST 0
40+
#define AFTER_SEEDING 1
41+
#define ERRO_OCCURRED 1
42+
#define MMAP_SIZE 4096
43+
44+
45+
#define FIELD(address, top, length) (((*(address)) << (31 - top)) >> (32 - length))
46+
47+
48+
/* Flags indicates whether tests or seeding is done */
49+
typedef struct {
50+
volatile uint32_t *base;
51+
volatile uint32_t flags;
52+
uint32_t port;
53+
54+
handle_t lock;
55+
handle_t cond;
56+
} rngb_t;
57+
58+
59+
static rngb_t common_rngb;
60+
61+
62+
int rngb_hinterrupt(unsigned int n, void *arg)
63+
{
64+
rngb_t *rngb_arg = (rngb_t *)arg;
65+
rngb_arg->flags += 1u;
66+
67+
return 1;
68+
}
69+
70+
71+
int systeminit(void)
72+
{
73+
const char devpath[] = "random";
74+
int err;
75+
oid_t dev;
76+
77+
/* A default value for flags - nothing is done */
78+
common_rngb.flags = 0;
79+
80+
common_rngb.base = mmap(NULL, MMAP_SIZE, PROT_READ | PROT_WRITE, MAP_DEVICE | MAP_UNCACHED, OID_PHYSMEM, RNGB_START_ADDRESS);
81+
if (common_rngb.base == MAP_FAILED) {
82+
printf("rngb: Could not map addr\n");
83+
return -1;
84+
}
85+
86+
if (portCreate(&common_rngb.port) != EOK) {
87+
printf("rngb: Could not create port\n");
88+
89+
munmap((void *)common_rngb.base, MMAP_SIZE);
90+
return -1;
91+
}
92+
93+
dev.port = common_rngb.port;
94+
dev.id = 0;
95+
96+
err = create_dev(&dev, devpath);
97+
if (err != EOK) {
98+
printf("rngb: Could not create port file %s (err %d)\n", devpath, err);
99+
100+
portDestroy(common_rngb.port);
101+
munmap((void *)common_rngb.base, MMAP_SIZE);
102+
return -1;
103+
}
104+
105+
err = mutexCreate(&common_rngb.lock);
106+
if (err < 0) {
107+
printf("rngb: Could not create mutex for rngb\n");
108+
109+
portDestroy(common_rngb.port);
110+
munmap((void *)common_rngb.base, MMAP_SIZE);
111+
return -1;
112+
}
113+
114+
err = condCreate(&common_rngb.cond);
115+
if (err < 0) {
116+
printf("rngb: Could not create cond for rngb\n");
117+
118+
portDestroy(common_rngb.port);
119+
munmap((void *)common_rngb.base, MMAP_SIZE);
120+
return -1;
121+
}
122+
123+
interrupt(RNGB_IRQ, rngb_hinterrupt, &common_rngb, common_rngb.cond, NULL);
124+
125+
return 0;
126+
}
127+
128+
129+
int hardwareinit(void)
130+
{
131+
int err;
132+
mutexLock(common_rngb.lock);
133+
134+
/* Reset and wait until rngb is sleeping */
135+
*(common_rngb.base + RNG_CMD) = (uint32_t)(0x40);
136+
do {
137+
err = *(common_rngb.base + RNG_SR) & (uint32_t)(0x4);
138+
} while(err == 0);
139+
140+
/* Run self test */
141+
*(common_rngb.base + RNG_CMD) = (uint32_t)(0x1);
142+
/* Waiting until tests are done */
143+
while (common_rngb.flags == AFTER_TEST) {
144+
condWait(common_rngb.cond, common_rngb.lock, 0);
145+
}
146+
147+
err = *(common_rngb.base + RNG_SR) & (1 << 16);
148+
if (err == ERRO_OCCURRED) {
149+
printf("rngb: error after slef tests\n");
150+
151+
portDestroy(common_rngb.port);
152+
munmap((void *)common_rngb.base, MMAP_SIZE);
153+
mutexUnlock(common_rngb.lock);
154+
return -1;
155+
}
156+
157+
/* Clear the interrupt and run seeding */
158+
*(common_rngb.base + RNG_CMD) = (uint32_t)(0x20);
159+
*(common_rngb.base + RNG_CMD) = (uint32_t)(0x2);
160+
/* Waiting until seeding is done */
161+
while (common_rngb.flags == AFTER_SEEDING) {
162+
condWait(common_rngb.cond, common_rngb.lock, 0);
163+
}
164+
165+
err = *(common_rngb.base + RNG_SR) & (1 << 16);
166+
if (err == ERRO_OCCURRED) {
167+
printf("rngb: error after generating seed\n");
168+
169+
portDestroy(common_rngb.port);
170+
munmap((void *)common_rngb.base, MMAP_SIZE);
171+
mutexUnlock(common_rngb.lock);
172+
return -1;
173+
}
174+
175+
/* Enable automatic seeding */
176+
*(common_rngb.base + RNG_CR) = (uint32_t)(0x10);
177+
mutexUnlock(common_rngb.lock);
178+
return 0;
179+
}
180+
181+
182+
int readrandoms(char *buff, size_t size)
183+
{
184+
char val[sizeof(uint32_t)];
185+
unsigned int i;
186+
int err, level;
187+
188+
mutexLock(common_rngb.lock);
189+
for (i = 0; i < size; i++) {
190+
err = *(common_rngb.base + RNG_SR) & (1 << 16);
191+
if (err == ERRO_OCCURRED) {
192+
mutexUnlock(common_rngb.lock);
193+
return -EIO;
194+
}
195+
196+
if (i % sizeof(uint32_t) == 0) {
197+
level = FIELD(common_rngb.base + RNG_SR, 11, 4);
198+
if (level == 0) {
199+
i--;
200+
continue;
201+
}
202+
203+
*((uint32_t *)val) = *(common_rngb.base + RNG_OUT);
204+
}
205+
206+
buff[i] = val[i % sizeof(uint32_t)];
207+
}
208+
209+
mutexUnlock(common_rngb.lock);
210+
return i;
211+
}
212+
213+
214+
void thread(void *arg)
215+
{
216+
msg_t msg;
217+
unsigned long int rid;
218+
219+
while (1) {
220+
if (msgRecv(common_rngb.port, &msg, &rid) < 0) {
221+
continue;
222+
}
223+
224+
msg.o.io.err = -EINVAL;
225+
switch (msg.type) {
226+
case mtClose:
227+
case mtOpen:
228+
msg.o.io.err = msg.i.openclose.oid.id != 0 ? -ENOENT : EOK;
229+
break;
230+
231+
case mtRead:
232+
if (msg.o.data != NULL && msg.i.io.oid.id == 0) {
233+
msg.o.io.err = readrandoms(msg.o.data, msg.o.size);
234+
}
235+
236+
break;
237+
}
238+
239+
msgRespond(common_rngb.port, &msg, rid);
240+
}
241+
}
242+
243+
244+
int main(int argc, char **argv)
245+
{
246+
oid_t root;
247+
248+
/* Wait for the filesystem */
249+
while (lookup("/", NULL, &root) < 0) {
250+
usleep(10000);
251+
}
252+
253+
if (systeminit() || hardwareinit()) {
254+
return -EIO;
255+
}
256+
257+
thread(NULL);
258+
259+
return 0;
260+
}

0 commit comments

Comments
 (0)