1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
//! Blocking driver for the hardware random number generator.
//!
//! BCM2835/2836/2837 has a dedicated true-RNG block (a free-running
//! ring-oscillator entropy source feeding a whitener and a small output
//! FIFO), distinct from anything derivable in software from timing
//! jitter. Once enabled it fills a FIFO with 32-bit words at hardware
//! speed; a read pops one word and the block refills it. The upper byte
//! of the status register reports how many words are currently
//! available, so reads poll that rather than an interrupt — this is a
//! blocking, poll-only driver.
//!
//! The peripheral isn't modeled in `bcm2837-lpa`'s SVD at all, so this
//! pokes its known physical addresses directly rather than going
//! through the PAC — the same approach `uart.rs`/`sd.rs` take for the
//! legacy GPIO pull registers that SVD also omits. Register layout and
//! the enable/warmup sequence follow the BCM2835 ARM Peripherals
//! behaviour used by Linux's `bcm2835-rng` driver and the widely
//! mirrored bare-metal Pi references (bztsrc's `raspi3-tutorial`
//! `rand.c`).
/// RNG peripheral base address (peripheral base `0x3F00_0000` + the
/// block's `0x0010_4000` offset). BCM2836 and BCM2837 share this
/// low-peripheral base; the value matches `mmu.rs`'s `PERIPHERAL_BASE`.
const RNG_BASE: usize = 0x3f10_4000;
/// Control register: bit 0 (`EN`) enables the generator.
const RNG_CTRL: *mut u32 = RNG_BASE as *mut u32;
/// Status register. Bits [31:24] hold the count of 32-bit words
/// currently available in the output FIFO; writing it sets the warmup
/// count (see [`RNG_WARMUP_COUNT`]).
const RNG_STATUS: *mut u32 = as *mut u32;
/// Data register: reading pops one 32-bit random word from the FIFO.
const RNG_DATA: *mut u32 = as *mut u32;
/// Interrupt mask register: bit 0 (`INT_OFF`) masks the FIFO interrupt.
const RNG_INT_MASK: *mut u32 = as *mut u32;
/// `RNG_CTRL` enable bit.
const RNG_CTRL_EN: u32 = 0x1;
/// `RNG_INT_MASK` bit that masks the block's interrupt. This driver
/// polls the status register, so the interrupt is masked to keep the
/// block from asserting an unhandled IRQ line.
const RNG_INT_OFF: u32 = 0x1;
/// Number of entropy-source samples the block discards before its
/// output is trusted, written into `RNG_STATUS` at init. Until this
/// many samples have been drawn the FIFO stays empty (status word-count
/// reads zero), so the read path's own wait naturally covers warmup —
/// no separate spin in [`Rng::new`]. `0x40000` is the value the
/// reference drivers use.
const RNG_WARMUP_COUNT: u32 = 0x40000;
/// Blocking driver for the hardware random number generator.