CHERIoT RTOS
A compartmentalised RTOS for CHERIoT hardware
Loading...
Searching...
No Matches
platform-pinmux.hh
1/**
2 * SPDX-FileCopyrightText: lowRISC contributors
3 * SPDX-License-Identifier: Apache-2.0
4 *
5 * This file is generated by ./util/topgen.py
6 * in https://github.com/lowRISC/sonata-system
7 */
8
9#pragma once
10#include <cheri.hh>
11#include <debug.hh>
12#include <stdint.h>
13#include <utils.hh>
14
15namespace SonataPinmux
16{
17 /// The number of pin sinks (pin outputs)
18 static constexpr size_t NumPinSinks = 85;
19
20 /// The number of block sinks (block inputs)
21 static constexpr size_t NumBlockSinks = 70;
22
23 /// Flag to set when debugging the driver for UART log messages.
24 static constexpr bool DebugDriver = false;
25
26 /// Helper for conditional debug logs and assertions.
27 using Debug = ConditionalDebug<DebugDriver, "Pinmux">;
28
29 /// The disable bit that disables a sink
30 constexpr uint8_t SourceDisabled = 0;
31
32 /// The bit that resets a sink to it's default value
33 constexpr uint8_t SourceDefault = 1;
34
35 /**
36 * Each pin sink is configured by an 8-bit register. This enum maps pin sink
37 * names to the offset of their configuration registers. The offsets are
38 * relative to the first pin sink register.
39 *
40 * Documentation sources:
41 * 1. https://lowrisc.github.io/sonata-system/doc/ip/pinmux/
42 * 2.
43 * https://github.com/lowRISC/sonata-system/blob/v1.0/data/pins_sonata.xdc
44 * 3.
45 * https://github.com/newaetech/sonata-pcb/blob/649b11c2fb758f798966605a07a8b6b68dd434e9/sonata-schematics-r09.pdf
46 */
47 enum class PinSink : uint16_t
48 {
49 // Breaking enum naming convention to match cononical names used in PCB
50 // schematic documentation.
51 // When available, it would be neater to use NOLINTBEGIN and NOLINTEND.
52 ser0_tx = 0x000, // NOLINT(readability-identifier-naming)
53 ser1_tx = 0x001, // NOLINT(readability-identifier-naming)
54 rs232_tx = 0x002, // NOLINT(readability-identifier-naming)
55 rs485_tx = 0x003, // NOLINT(readability-identifier-naming)
56 scl0 = 0x004, // NOLINT(readability-identifier-naming)
57 sda0 = 0x005, // NOLINT(readability-identifier-naming)
58 scl1 = 0x006, // NOLINT(readability-identifier-naming)
59 sda1 = 0x007, // NOLINT(readability-identifier-naming)
60 rph_g0 = 0x008, // NOLINT(readability-identifier-naming)
61 rph_g1 = 0x009, // NOLINT(readability-identifier-naming)
62 rph_g2_sda = 0x00a, // NOLINT(readability-identifier-naming)
63 rph_g3_scl = 0x00b, // NOLINT(readability-identifier-naming)
64 rph_g4 = 0x00c, // NOLINT(readability-identifier-naming)
65 rph_g5 = 0x00d, // NOLINT(readability-identifier-naming)
66 rph_g6 = 0x00e, // NOLINT(readability-identifier-naming)
67 rph_g7 = 0x00f, // NOLINT(readability-identifier-naming)
68 rph_g8 = 0x010, // NOLINT(readability-identifier-naming)
69 rph_g9 = 0x011, // NOLINT(readability-identifier-naming)
70 rph_g10 = 0x012, // NOLINT(readability-identifier-naming)
71 rph_g11 = 0x013, // NOLINT(readability-identifier-naming)
72 rph_g12 = 0x014, // NOLINT(readability-identifier-naming)
73 rph_g13 = 0x015, // NOLINT(readability-identifier-naming)
74 rph_txd0 = 0x016, // NOLINT(readability-identifier-naming)
75 rph_rxd0 = 0x017, // NOLINT(readability-identifier-naming)
76 rph_g16 = 0x018, // NOLINT(readability-identifier-naming)
77 rph_g17 = 0x019, // NOLINT(readability-identifier-naming)
78 rph_g18 = 0x01a, // NOLINT(readability-identifier-naming)
79 rph_g19 = 0x01b, // NOLINT(readability-identifier-naming)
80 rph_g20 = 0x01c, // NOLINT(readability-identifier-naming)
81 rph_g21 = 0x01d, // NOLINT(readability-identifier-naming)
82 rph_g22 = 0x01e, // NOLINT(readability-identifier-naming)
83 rph_g23 = 0x01f, // NOLINT(readability-identifier-naming)
84 rph_g24 = 0x020, // NOLINT(readability-identifier-naming)
85 rph_g25 = 0x021, // NOLINT(readability-identifier-naming)
86 rph_g26 = 0x022, // NOLINT(readability-identifier-naming)
87 rph_g27 = 0x023, // NOLINT(readability-identifier-naming)
88 ah_tmpio0 = 0x024, // NOLINT(readability-identifier-naming)
89 ah_tmpio1 = 0x025, // NOLINT(readability-identifier-naming)
90 ah_tmpio2 = 0x026, // NOLINT(readability-identifier-naming)
91 ah_tmpio3 = 0x027, // NOLINT(readability-identifier-naming)
92 ah_tmpio4 = 0x028, // NOLINT(readability-identifier-naming)
93 ah_tmpio5 = 0x029, // NOLINT(readability-identifier-naming)
94 ah_tmpio6 = 0x02a, // NOLINT(readability-identifier-naming)
95 ah_tmpio7 = 0x02b, // NOLINT(readability-identifier-naming)
96 ah_tmpio8 = 0x02c, // NOLINT(readability-identifier-naming)
97 ah_tmpio9 = 0x02d, // NOLINT(readability-identifier-naming)
98 ah_tmpio10 = 0x02e, // NOLINT(readability-identifier-naming)
99 ah_tmpio11 = 0x02f, // NOLINT(readability-identifier-naming)
100 ah_tmpio12 = 0x030, // NOLINT(readability-identifier-naming)
101 ah_tmpio13 = 0x031, // NOLINT(readability-identifier-naming)
102 mb1 = 0x032, // NOLINT(readability-identifier-naming)
103 mb2 = 0x033, // NOLINT(readability-identifier-naming)
104 mb4 = 0x034, // NOLINT(readability-identifier-naming)
105 mb5 = 0x035, // NOLINT(readability-identifier-naming)
106 mb6 = 0x036, // NOLINT(readability-identifier-naming)
107 mb7 = 0x037, // NOLINT(readability-identifier-naming)
108 mb10 = 0x038, // NOLINT(readability-identifier-naming)
109 pmod0_1 = 0x039, // NOLINT(readability-identifier-naming)
110 pmod0_2 = 0x03a, // NOLINT(readability-identifier-naming)
111 pmod0_3 = 0x03b, // NOLINT(readability-identifier-naming)
112 pmod0_4 = 0x03c, // NOLINT(readability-identifier-naming)
113 pmod0_7 = 0x03d, // NOLINT(readability-identifier-naming)
114 pmod0_8 = 0x03e, // NOLINT(readability-identifier-naming)
115 pmod0_9 = 0x03f, // NOLINT(readability-identifier-naming)
116 pmod0_10 = 0x040, // NOLINT(readability-identifier-naming)
117 pmod1_1 = 0x041, // NOLINT(readability-identifier-naming)
118 pmod1_2 = 0x042, // NOLINT(readability-identifier-naming)
119 pmod1_3 = 0x043, // NOLINT(readability-identifier-naming)
120 pmod1_4 = 0x044, // NOLINT(readability-identifier-naming)
121 pmod1_7 = 0x045, // NOLINT(readability-identifier-naming)
122 pmod1_8 = 0x046, // NOLINT(readability-identifier-naming)
123 pmod1_9 = 0x047, // NOLINT(readability-identifier-naming)
124 pmod1_10 = 0x048, // NOLINT(readability-identifier-naming)
125 pmodc_1 = 0x049, // NOLINT(readability-identifier-naming)
126 pmodc_2 = 0x04a, // NOLINT(readability-identifier-naming)
127 pmodc_3 = 0x04b, // NOLINT(readability-identifier-naming)
128 pmodc_4 = 0x04c, // NOLINT(readability-identifier-naming)
129 pmodc_5 = 0x04d, // NOLINT(readability-identifier-naming)
130 pmodc_6 = 0x04e, // NOLINT(readability-identifier-naming)
131 appspi_d0 = 0x04f, // NOLINT(readability-identifier-naming)
132 appspi_clk = 0x050, // NOLINT(readability-identifier-naming)
133 appspi_cs = 0x051, // NOLINT(readability-identifier-naming)
134 microsd_cmd = 0x052, // NOLINT(readability-identifier-naming)
135 microsd_clk = 0x053, // NOLINT(readability-identifier-naming)
136 microsd_dat3 = 0x054, // NOLINT(readability-identifier-naming)
137 };
138
139 /**
140 * Each block sink is configured by an 8-bit register. This enum maps block
141 * sink names to the offset of their configuration registers. The offsets
142 * are relative to the first block sink register.
143 *
144 * For GPIO block reference:
145 * gpio_0 = Raspberry Pi Header Pins
146 * gpio_1 = Arduino Shield Header Pins
147 * gpio_2 = Pmod0 Pins
148 * gpio_3 = Pmod1 Pins
149 * gpio_4 = PmodC Pins
150 *
151 * Documentation source:
152 * https://lowrisc.github.io/sonata-system/doc/ip/pinmux/
153 */
154 enum class BlockSink : uint16_t
155 {
156 // Breaking enum naming convention to match cononical names used in
157 // documentation.
158 // When available, it would be neater to use NOLINTBEGIN and NOLINTEND.
159 gpio_0_ios_0 = 0x000, // NOLINT(readability-identifier-naming)
160 gpio_0_ios_1 = 0x001, // NOLINT(readability-identifier-naming)
161 gpio_0_ios_2 = 0x002, // NOLINT(readability-identifier-naming)
162 gpio_0_ios_3 = 0x003, // NOLINT(readability-identifier-naming)
163 gpio_0_ios_4 = 0x004, // NOLINT(readability-identifier-naming)
164 gpio_0_ios_5 = 0x005, // NOLINT(readability-identifier-naming)
165 gpio_0_ios_6 = 0x006, // NOLINT(readability-identifier-naming)
166 gpio_0_ios_7 = 0x007, // NOLINT(readability-identifier-naming)
167 gpio_0_ios_8 = 0x008, // NOLINT(readability-identifier-naming)
168 gpio_0_ios_9 = 0x009, // NOLINT(readability-identifier-naming)
169 gpio_0_ios_10 = 0x00a, // NOLINT(readability-identifier-naming)
170 gpio_0_ios_11 = 0x00b, // NOLINT(readability-identifier-naming)
171 gpio_0_ios_12 = 0x00c, // NOLINT(readability-identifier-naming)
172 gpio_0_ios_13 = 0x00d, // NOLINT(readability-identifier-naming)
173 gpio_0_ios_14 = 0x00e, // NOLINT(readability-identifier-naming)
174 gpio_0_ios_15 = 0x00f, // NOLINT(readability-identifier-naming)
175 gpio_0_ios_16 = 0x010, // NOLINT(readability-identifier-naming)
176 gpio_0_ios_17 = 0x011, // NOLINT(readability-identifier-naming)
177 gpio_0_ios_18 = 0x012, // NOLINT(readability-identifier-naming)
178 gpio_0_ios_19 = 0x013, // NOLINT(readability-identifier-naming)
179 gpio_0_ios_20 = 0x014, // NOLINT(readability-identifier-naming)
180 gpio_0_ios_21 = 0x015, // NOLINT(readability-identifier-naming)
181 gpio_0_ios_22 = 0x016, // NOLINT(readability-identifier-naming)
182 gpio_0_ios_23 = 0x017, // NOLINT(readability-identifier-naming)
183 gpio_0_ios_24 = 0x018, // NOLINT(readability-identifier-naming)
184 gpio_0_ios_25 = 0x019, // NOLINT(readability-identifier-naming)
185 gpio_0_ios_26 = 0x01a, // NOLINT(readability-identifier-naming)
186 gpio_0_ios_27 = 0x01b, // NOLINT(readability-identifier-naming)
187 gpio_1_ios_0 = 0x01c, // NOLINT(readability-identifier-naming)
188 gpio_1_ios_1 = 0x01d, // NOLINT(readability-identifier-naming)
189 gpio_1_ios_2 = 0x01e, // NOLINT(readability-identifier-naming)
190 gpio_1_ios_3 = 0x01f, // NOLINT(readability-identifier-naming)
191 gpio_1_ios_4 = 0x020, // NOLINT(readability-identifier-naming)
192 gpio_1_ios_5 = 0x021, // NOLINT(readability-identifier-naming)
193 gpio_1_ios_6 = 0x022, // NOLINT(readability-identifier-naming)
194 gpio_1_ios_7 = 0x023, // NOLINT(readability-identifier-naming)
195 gpio_1_ios_8 = 0x024, // NOLINT(readability-identifier-naming)
196 gpio_1_ios_9 = 0x025, // NOLINT(readability-identifier-naming)
197 gpio_1_ios_10 = 0x026, // NOLINT(readability-identifier-naming)
198 gpio_1_ios_11 = 0x027, // NOLINT(readability-identifier-naming)
199 gpio_1_ios_12 = 0x028, // NOLINT(readability-identifier-naming)
200 gpio_1_ios_13 = 0x029, // NOLINT(readability-identifier-naming)
201 gpio_2_ios_0 = 0x02a, // NOLINT(readability-identifier-naming)
202 gpio_2_ios_1 = 0x02b, // NOLINT(readability-identifier-naming)
203 gpio_2_ios_2 = 0x02c, // NOLINT(readability-identifier-naming)
204 gpio_2_ios_3 = 0x02d, // NOLINT(readability-identifier-naming)
205 gpio_2_ios_4 = 0x02e, // NOLINT(readability-identifier-naming)
206 gpio_2_ios_5 = 0x02f, // NOLINT(readability-identifier-naming)
207 gpio_2_ios_6 = 0x030, // NOLINT(readability-identifier-naming)
208 gpio_2_ios_7 = 0x031, // NOLINT(readability-identifier-naming)
209 gpio_3_ios_0 = 0x032, // NOLINT(readability-identifier-naming)
210 gpio_3_ios_1 = 0x033, // NOLINT(readability-identifier-naming)
211 gpio_3_ios_2 = 0x034, // NOLINT(readability-identifier-naming)
212 gpio_3_ios_3 = 0x035, // NOLINT(readability-identifier-naming)
213 gpio_3_ios_4 = 0x036, // NOLINT(readability-identifier-naming)
214 gpio_3_ios_5 = 0x037, // NOLINT(readability-identifier-naming)
215 gpio_3_ios_6 = 0x038, // NOLINT(readability-identifier-naming)
216 gpio_3_ios_7 = 0x039, // NOLINT(readability-identifier-naming)
217 gpio_4_ios_0 = 0x03a, // NOLINT(readability-identifier-naming)
218 gpio_4_ios_1 = 0x03b, // NOLINT(readability-identifier-naming)
219 gpio_4_ios_2 = 0x03c, // NOLINT(readability-identifier-naming)
220 gpio_4_ios_3 = 0x03d, // NOLINT(readability-identifier-naming)
221 gpio_4_ios_4 = 0x03e, // NOLINT(readability-identifier-naming)
222 gpio_4_ios_5 = 0x03f, // NOLINT(readability-identifier-naming)
223 uart_0_rx = 0x040, // NOLINT(readability-identifier-naming)
224 uart_1_rx = 0x041, // NOLINT(readability-identifier-naming)
225 uart_2_rx = 0x042, // NOLINT(readability-identifier-naming)
226 spi_0_cipo = 0x043, // NOLINT(readability-identifier-naming)
227 spi_1_cipo = 0x044, // NOLINT(readability-identifier-naming)
228 spi_2_cipo = 0x045, // NOLINT(readability-identifier-naming)
229 };
230
231 /**
232 * Returns the number of sources available for a pin sink (output pin).
233 *
234 * @param pin_sink The pin sink to query.
235 * @returns The number of sources available for the given sink.
236 */
237 static constexpr uint8_t sources_number(PinSink pinSink)
238 {
239 switch (pinSink)
240 {
241 case PinSink::pmod0_2:
242 case PinSink::pmod1_2:
243 return 5;
244 case PinSink::rph_g18:
245 case PinSink::rph_g20:
246 case PinSink::rph_g21:
247 case PinSink::ah_tmpio10:
248 case PinSink::ah_tmpio11:
249 case PinSink::pmod0_4:
250 case PinSink::pmod1_4:
251 return 4;
252 case PinSink::ser1_tx:
253 case PinSink::rph_g0:
254 case PinSink::rph_g1:
255 case PinSink::rph_g2_sda:
256 case PinSink::rph_g3_scl:
257 case PinSink::rph_g7:
258 case PinSink::rph_g8:
259 case PinSink::rph_g10:
260 case PinSink::rph_g11:
261 case PinSink::rph_g12:
262 case PinSink::rph_g13:
263 case PinSink::rph_txd0:
264 case PinSink::rph_g16:
265 case PinSink::rph_g17:
266 case PinSink::rph_g19:
267 case PinSink::ah_tmpio1:
268 case PinSink::ah_tmpio3:
269 case PinSink::ah_tmpio5:
270 case PinSink::ah_tmpio6:
271 case PinSink::ah_tmpio9:
272 case PinSink::ah_tmpio13:
273 case PinSink::pmod0_1:
274 case PinSink::pmod0_3:
275 case PinSink::pmod0_8:
276 case PinSink::pmod0_9:
277 case PinSink::pmod0_10:
278 case PinSink::pmod1_1:
279 case PinSink::pmod1_3:
280 case PinSink::pmod1_8:
281 case PinSink::pmod1_9:
282 case PinSink::pmod1_10:
283 return 3;
284 default:
285 return 2;
286 }
287 }
288
289 /**
290 * Returns the number of sources available for a block sink (block input).
291 *
292 * @param block_sink The block sink to query.
293 * @returns The number of sources available for the given sink.
294 */
295 static constexpr uint8_t sources_number(BlockSink blockSink)
296 {
297 switch (blockSink)
298 {
299 case BlockSink::uart_1_rx:
300 return 6;
301 case BlockSink::uart_2_rx:
302 return 5;
303 case BlockSink::spi_1_cipo:
304 case BlockSink::spi_2_cipo:
305 return 4;
306 case BlockSink::spi_0_cipo:
307 return 3;
308 default:
309 return 2;
310 }
311 }
312
313 /**
314 * A handle to a sink configuration register. This can be used to select
315 * the source of the handle's associated sink.
316 */
317 template<typename SinkEnum>
318 struct Sink
319 {
321 const SinkEnum SinkId;
322
323 /**
324 * Select a source to connect to the sink.
325 *
326 * To see the sources available for a given sink see the Sonata system
327 * documentation:
328 * https://lowrisc.github.io/sonata-system/doc/ip/pinmux/
329 *
330 * Note, source 0 disconnects the sink from any source disabling it,
331 * and source 1 is the default source for any given sink.
332 */
333 bool select(uint8_t source)
334 {
335 if (source >= sources_number(SinkId))
336 {
337 Debug::log("{} is outside the range of valid sources, [0-{}), "
338 "of pin {}.",
339 source,
340 sources_number(SinkId),
341 SinkId);
342 return false;
343 }
344 *reg = 1 << source;
345 return true;
346 }
347
348 /// Disconnect the sink from all available sources.
349 void disable()
350 {
351 *reg = 1 << SourceDisabled;
352 }
353
354 /// Reset the sink to it's default source.
356 {
357 *reg = 1 << SourceDefault;
358 }
359 };
360
361 namespace
362 {
363 template<typename SinkEnum>
364 // This is used by `BlockSinks` and `PinSinks`
365 // to return a capability to a single sink's configuration register.
366 inline Sink<SinkEnum> get_sink(volatile uint8_t *baseRegister,
367 const SinkEnum SinkId)
368 {
369 CHERI::Capability reg = {baseRegister +
370 static_cast<ptrdiff_t>(SinkId)};
371 reg.bounds() = sizeof(uint8_t);
372 return Sink<SinkEnum>{reg, SinkId};
373 };
374 } // namespace
375
376 /**
377 * A driver for the Sonata system's pin multiplexed output pins.
378 *
379 * The Sonata system's Pin Multiplexer (pinmux) has two sets of registers:
380 * the pin sink registers and the block sink registers. This structure
381 * provides access to the pin sinks registers. Pin sinks are output onto the
382 * Sonata system's pins, which can be connected to a number of block outputs
383 * (their sources). The sources each sink can connect to are limited. See
384 * the documentation for the possible sources for a given pin:
385 *
386 * https://lowrisc.github.io/sonata-system/doc/ip/pinmux/
387 */
389 {
390 volatile uint8_t registers[NumPinSinks];
391
392 /// Returns a handle to a pin sink (an output pin).
393 Sink<PinSink> get(PinSink sink) volatile
394 {
395 return get_sink<PinSink>(registers, sink);
396 };
397 };
398
399 /**
400 * A driver for the Sonata system's pin multiplexed block inputs.
401 *
402 * The Sonata system's Pin Multiplexer (pinmux) has two sets of registers:
403 * the pin sink registers and the block sink registers. This structure
404 * provides access to the block sinks registers. Block sinks are inputs into
405 * the Sonata system's devices that can be connected to a number of system
406 * input pins (their sources). The sources each sink can connect to are
407 * limited. See the documentation for the possible sources for a given pin:
408 *
409 * https://lowrisc.github.io/sonata-system/doc/ip/pinmux
410 */
412 {
413 volatile uint8_t registers[NumBlockSinks];
414
415 /// Returns a handle to a block sink (a block input).
417 {
418 return get_sink<BlockSink>(registers, sink);
419 };
420 };
421} // namespace SonataPinmux
C++ helpers for operating on capabilities.
Helper class for accessing capability properties on pointers.
Definition cheri.hh:482
BoundsProxy bounds()
Access (read, set) the capability's bounds.
Definition cheri.hh:867
Utility class to delete copy and move contructors.
Definition utils.hh:53
C++ APIs for assertions, invariants, and writing formatted debug messages to a UART.
SPDX-FileCopyrightText: lowRISC contributors SPDX-License-Identifier: Apache-2.0.
static constexpr size_t NumPinSinks
The number of pin sinks (pin outputs).
ConditionalDebug< DebugDriver, "Pinmux"> Debug
Helper for conditional debug logs and assertions.
static constexpr uint8_t sources_number(PinSink pinSink)
Returns the number of sources available for a pin sink (output pin).
constexpr uint8_t SourceDefault
The bit that resets a sink to it's default value.
constexpr uint8_t SourceDisabled
The disable bit that disables a sink.
static constexpr bool DebugDriver
Flag to set when debugging the driver for UART log messages.
PinSink
Each pin sink is configured by an 8-bit register.
static constexpr size_t NumBlockSinks
The number of block sinks (block inputs).
BlockSink
Each block sink is configured by an 8-bit register.
A driver for the Sonata system's pin multiplexed block inputs.
Sink< BlockSink > get(BlockSink sink) volatile
Returns a handle to a block sink (a block input).
A driver for the Sonata system's pin multiplexed output pins.
Sink< PinSink > get(PinSink sink) volatile
Returns a handle to a pin sink (an output pin).
A handle to a sink configuration register.
void disable()
Disconnect the sink from all available sources.
bool select(uint8_t source)
Select a source to connect to the sink.
void default_selection()
Reset the sink to it's default source.
Miscellaneous utility functions and classes.