Skip to content

Commit dcf8a36

Browse files
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 520b994 commit dcf8a36

File tree

3 files changed

+316
-1
lines changed

3 files changed

+316
-1
lines changed

_targets/Makefile.armv7a7-imx6ull

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# Copyright 2019 Phoenix Systems
77
#
88

9-
DEFAULT_COMPONENTS := imx6ull-sdma imx6ull-gpio libimx6ull-ecspi libimx6ull-qspi
9+
DEFAULT_COMPONENTS := imx6ull-sdma imx6ull-gpio imx6ull-rngb libimx6ull-ecspi libimx6ull-qspi
1010
DEFAULT_COMPONENTS += imx6ull-flash
1111
DEFAULT_COMPONENTS += imx6ull-flashnor
1212
DEFAULT_COMPONENTS += libusbclient cdc-demo

random/Makefile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#
2+
# Makefile for Phoenix-RTOS rngb
3+
#
4+
# Copyright 2023 Phoenix Systems
5+
#
6+
7+
NAME := imx6ull-rngb
8+
LOCAL_SRCS := imx6ull-rngb.c
9+
10+
include $(binary.mk)

random/imx6ull-rngb.c

Lines changed: 305 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,305 @@
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 <string.h>
15+
#include <fcntl.h>
16+
#include <errno.h>
17+
#include <stdint.h>
18+
#include <stdio.h>
19+
#include <unistd.h>
20+
#include <posix/utils.h>
21+
#include <sys/debug.h>
22+
#include <sys/platform.h>
23+
#include <sys/interrupt.h>
24+
#include <sys/threads.h>
25+
#include <sys/mman.h>
26+
#include <sys/msg.h>
27+
28+
29+
enum { rng_ver = 0,
30+
rng_cmd,
31+
rng_cr,
32+
rng_sr,
33+
rng_esr,
34+
rng_out };
35+
36+
37+
#define RNGB_START_ADDRESS 0x02284000
38+
#define RNGB_IRQ (6 + 32)
39+
40+
41+
#define SELF_TEST_DONE 1U
42+
#define SEED_DONE 2U
43+
#define ERROR_OCCURRED 4U
44+
#define MMAP_SIZE 4096
45+
46+
47+
/* intr_st indicates status of interrupts */
48+
static struct {
49+
volatile uint32_t *base;
50+
volatile uint32_t intr_st;
51+
uint32_t port;
52+
53+
handle_t lock;
54+
handle_t cond;
55+
} common_rngb;
56+
57+
58+
static int rngb_intr(unsigned int n, void *arg)
59+
{
60+
uint32_t status = *(common_rngb.base + rng_sr);
61+
62+
/* Self tests are done */
63+
if ((status & 0x10) != 0) {
64+
common_rngb.intr_st |= SELF_TEST_DONE;
65+
}
66+
67+
/* Seeding is done*/
68+
if ((status & 0x20) != 0) {
69+
common_rngb.intr_st |= SEED_DONE;
70+
}
71+
72+
/* An error occurred*/
73+
if ((status & (1 << 16)) != 0) {
74+
common_rngb.intr_st |= ERROR_OCCURRED;
75+
}
76+
77+
/* Clear interrupt */
78+
*(common_rngb.base + rng_cmd) = 0x20;
79+
return 1;
80+
}
81+
82+
83+
static void systemCleanup(int level)
84+
{
85+
if (level > 3) {
86+
resourceDestroy(common_rngb.cond);
87+
}
88+
89+
if (level > 2) {
90+
resourceDestroy(common_rngb.lock);
91+
}
92+
93+
if (level > 1) {
94+
portDestroy(common_rngb.port);
95+
}
96+
97+
if (level > 0) {
98+
munmap((void *)common_rngb.base, MMAP_SIZE);
99+
}
100+
}
101+
102+
103+
static int systemInit(void)
104+
{
105+
const char devpath[] = "random";
106+
int err;
107+
oid_t dev;
108+
109+
common_rngb.base = mmap(NULL, MMAP_SIZE, PROT_READ | PROT_WRITE, MAP_DEVICE, OID_PHYSMEM, RNGB_START_ADDRESS);
110+
if (common_rngb.base == MAP_FAILED) {
111+
printf("rngb: could not map addr\n");
112+
return -1;
113+
}
114+
115+
err = portCreate(&common_rngb.port);
116+
if (err != EOK) {
117+
printf("rngb: could not create port\n");
118+
systemCleanup(1);
119+
return -1;
120+
}
121+
122+
dev.port = common_rngb.port;
123+
dev.id = 0;
124+
125+
err = mutexCreate(&common_rngb.lock);
126+
if (err != EOK) {
127+
printf("rngb: could not create mutex for rngb\n");
128+
systemCleanup(2);
129+
return -1;
130+
}
131+
132+
err = condCreate(&common_rngb.cond);
133+
if (err != EOK) {
134+
printf("rngb: could not create cond for rngb\n");
135+
systemCleanup(3);
136+
return -1;
137+
}
138+
139+
err = create_dev(&dev, devpath);
140+
if (err != EOK) {
141+
printf("rngb: could not create port file %s (err %d)\n", devpath, err);
142+
systemCleanup(4);
143+
return -1;
144+
}
145+
146+
return 0;
147+
}
148+
149+
150+
static int hardwareInit(void)
151+
{
152+
int err;
153+
154+
/* Reset and wait until rngb is sleeping */
155+
*(common_rngb.base + rng_cmd) = 0x40;
156+
do {
157+
err = *(common_rngb.base + rng_sr) & 0x4;
158+
} while (err == 0);
159+
160+
interrupt(RNGB_IRQ, rngb_intr, NULL, common_rngb.cond, NULL);
161+
162+
/* Run self test */
163+
*(common_rngb.base + rng_cmd) = 0x1;
164+
mutexLock(common_rngb.lock);
165+
while (common_rngb.intr_st == 0) {
166+
condWait(common_rngb.cond, common_rngb.lock, 3000);
167+
}
168+
mutexUnlock(common_rngb.lock);
169+
170+
if ((common_rngb.intr_st & ERROR_OCCURRED) != 0) {
171+
printf("rngb: self-test failed\n");
172+
173+
systemCleanup(4);
174+
return -1;
175+
}
176+
177+
common_rngb.intr_st = 0;
178+
179+
/* Run seeding */
180+
*(common_rngb.base + rng_cmd) = 0x2;
181+
mutexLock(common_rngb.lock);
182+
while (common_rngb.intr_st == 0) {
183+
condWait(common_rngb.cond, common_rngb.lock, 3000);
184+
}
185+
mutexUnlock(common_rngb.lock);
186+
187+
if ((common_rngb.intr_st & ERROR_OCCURRED) != 0) {
188+
printf("rngb: error after generating seed\n");
189+
190+
systemCleanup(4);
191+
return -1;
192+
}
193+
194+
common_rngb.intr_st = 0;
195+
196+
/* Enable automatic seeding */
197+
*(common_rngb.base + rng_cr) = 0x10;
198+
199+
printf("imx6ull-rngb: initialized\n");
200+
201+
return 0;
202+
}
203+
204+
205+
static int readRandoms(char *buff, size_t size, unsigned mode)
206+
{
207+
union {
208+
uint32_t val32;
209+
char val8[sizeof(uint32_t)];
210+
} reg;
211+
unsigned int i;
212+
int status;
213+
214+
if (size == 0) {
215+
return 0;
216+
}
217+
218+
mutexLock(common_rngb.lock);
219+
i = 0;
220+
while (i < size) {
221+
if ((i % sizeof(uint32_t)) == 0) {
222+
status = *(common_rngb.base + rng_sr);
223+
if (((status >> 16) & 1U) == 1) {
224+
mutexUnlock(common_rngb.lock);
225+
return -EIO;
226+
}
227+
if (((status >> 8) & 0xf) == 0) {
228+
if ((mode & O_NONBLOCK) != 0) {
229+
break;
230+
}
231+
/* wait for new values in FIFO */
232+
continue;
233+
}
234+
reg.val32 = *(common_rngb.base + rng_out);
235+
}
236+
buff[i] = reg.val8[i % sizeof(uint32_t)];
237+
i++;
238+
}
239+
mutexUnlock(common_rngb.lock);
240+
241+
return i == 0 ? -EAGAIN : i;
242+
}
243+
244+
245+
static void handleMsg(void *arg)
246+
{
247+
msg_t msg;
248+
unsigned long int rid;
249+
int err;
250+
251+
while (1) {
252+
err = msgRecv(common_rngb.port, &msg, &rid);
253+
if (err < 0) {
254+
if (err == -EINTR) {
255+
continue;
256+
}
257+
else {
258+
printf("rngb: msgRecv returned error: %s\n", strerror(-err));
259+
break;
260+
}
261+
}
262+
263+
switch (msg.type) {
264+
case mtClose:
265+
case mtOpen:
266+
msg.o.io.err = msg.i.openclose.oid.id != 0 ? -ENOENT : EOK;
267+
break;
268+
269+
case mtRead:
270+
if (msg.o.data != NULL) {
271+
msg.o.io.err = readRandoms(msg.o.data, msg.o.size > 512 ? 512 : msg.o.size, msg.i.io.mode);
272+
}
273+
else {
274+
msg.o.io.err = -EINVAL;
275+
}
276+
break;
277+
278+
default:
279+
msg.o.io.err = -EINVAL;
280+
break;
281+
}
282+
283+
msgRespond(common_rngb.port, &msg, rid);
284+
}
285+
}
286+
287+
288+
int main(int argc, char **argv)
289+
{
290+
oid_t root;
291+
(void)argc;
292+
(void)argv;
293+
294+
while (lookup("/", NULL, &root) < 0) {
295+
usleep(10000);
296+
}
297+
298+
if (systemInit() || hardwareInit()) {
299+
return EIO;
300+
}
301+
302+
handleMsg(NULL);
303+
304+
return 0;
305+
}

0 commit comments

Comments
 (0)