1use thiserror::Error;
18
19#[derive(Error, Debug, PartialEq, Eq, Clone, Hash)]
20pub enum CfgError {
21 #[error("failed to parse Consortium manifest: {0}")]
22 Manifest(String),
23
24 #[error(transparent)]
27 Data(#[from] consortium_data::DataError),
28
29 #[error("failed to parse device-tree source '{file}': {detail}")]
32 DtsParse {
33 file: String,
35 detail: String,
37 },
38
39 #[error(
40 "doorbell '{name}' is not available on chip '{chip}'. Available doorbells: {available}. \
41 Refer to the TRM ({trm}). \
42 Sorry — customized hardware doorbells are not supported yet."
43 )]
44 UnknownDoorbell {
45 name: String,
46 chip: String,
47 trm: String,
49 available: String,
51 },
52
53 #[error("peripheral '{0}' is owned by '{1}', which is not a core on chip '{2}'")]
54 OwnerNotVisible(String, String, String),
55
56 #[error(
57 "peripheral '{name}' is not accessible from core '{core}' on chip '{chip}'. \
58 Only peripherals present in that core's peripheral map may be assigned to it"
59 )]
60 PeripheralNotOnCore {
61 name: String,
62 core: String,
63 chip: String,
64 },
65
66 #[error(
67 "peripheral '{peripheral}' pin '{signal}': no pad on chip '{chip}' carries \
68 {function}. Pin keys are the signal names from the datasheet's alternate-function \
69 table (e.g. `tx`, `sda`, `mosi`)"
70 )]
71 PinSignalUnknown {
72 peripheral: String,
73 signal: String,
74 function: String,
75 chip: String,
76 },
77
78 #[error(
79 "peripheral '{peripheral}' pin '{signal}' = \"{pad}\": that pad cannot carry \
80 {function}. Pads that can: {allowed}"
81 )]
82 PinCannotCarry {
83 peripheral: String,
84 signal: String,
85 pad: String,
86 function: String,
87 allowed: String,
88 },
89
90 #[error(
91 "peripheral '{peripheral}' pin '{signal}' = \"{pad}\": pad is not bonded out in \
92 chip '{chip}''s {package} package"
93 )]
94 PinNotInPackage {
95 peripheral: String,
96 signal: String,
97 pad: String,
98 package: String,
99 chip: String,
100 },
101
102 #[error("pad \"{pad}\" is assigned twice: to {first} and to {second}")]
103 PinConflict {
104 pad: String,
105 first: String,
106 second: String,
107 },
108
109 #[error("IPC channel endpoint '{0}' names core '{1}', which is not visible on chip '{2}'")]
110 IpcEndpointNotVisible(String, String, String),
111
112 #[error(
113 "doorbell '{doorbell}' does not configure party '{party}' on chip '{chip}'. \
114 Configured parties: {available}. Check the doorbell party table in the TRM ({trm}) p. {page}"
115 )]
116 DoorbellPartyUnavailable {
117 doorbell: String,
118 party: String,
119 chip: String,
120 available: String,
121 trm: String,
122 page: u32,
123 },
124
125 #[error(
126 "doorbell '{doorbell}' channel {channel} is unavailable on chip '{chip}'. \
127 Valid channels are 0..{channels}. Check the channel table in the TRM ({trm}) p. {page}"
128 )]
129 DoorbellChannelUnavailable {
130 doorbell: String,
131 channel: u32,
132 channels: u32,
133 chip: String,
134 trm: String,
135 page: u32,
136 },
137
138 #[error(
139 "doorbell '{doorbell}' channel {channel} is assigned more than once: \
140 '{first_party}' and '{second_party}' both use it"
141 )]
142 DoorbellChannelDuplicate {
143 doorbell: String,
144 channel: u32,
145 first_party: String,
146 second_party: String,
147 },
148
149 #[error(
150 "[dbg.ap] is not allowed: the application processor is always the debug host, \
151 not a logger. Declare a coprocessor logger such as [dbg.cm33] instead"
152 )]
153 DbgHostNotLoggable,
154
155 #[error("[dbg.{core}] names core '{core}', which is not a coprocessor on chip '{chip}'")]
156 DbgCoreNotVisible { core: String, chip: String },
157
158 #[error("no memory region set")]
159 MemoryRegionNotSet,
160
161 #[error("UIO device '{device}' exposes {found} mappings, but Linux UIO supports at most {max}")]
162 UioMmapLimit {
163 device: String,
164 found: usize,
165 max: usize,
166 },
167
168 #[error(
169 "[memory.{region}] lies in chip '{chip}' memory region '{window}', which core '{core}' cannot access \
170 (accessible to: {visible}); move it to a region every core using it can reach"
171 )]
172 RegionNotVisible {
173 region: String,
174 window: String,
175 core: String,
176 visible: String,
177 chip: String,
178 },
179
180 #[error(
181 "[memory.{region}] spans {base:#x}..{end:#x}, which is not contained in any memory region of chip '{chip}'. \
182 Check the SRAM memory map in the TRM ({trm}) p. {pages}"
183 )]
184 RegionOutOfBounds {
185 region: String,
186 base: u32,
187 end: u32,
188 chip: String,
189 trm: String,
191 pages: String,
193 },
194
195 #[error(
196 "[memory.{a}] ({a_base:#x}..{a_end:#x}) overlaps [memory.{b}] ({b_base:#x}..{b_end:#x})"
197 )]
198 RegionOverlap {
199 a: String,
200 a_base: u32,
201 a_end: u32,
202 b: String,
203 b_base: u32,
204 b_end: u32,
205 },
206
207 #[error("[memory.{region}] has zero length")]
208 RegionEmpty { region: String },
209
210 #[error(
211 "[memory.{region}] ({base:#x}, len {length:#x}) is not a valid MPU region: {requirement}. \
212 ARMv7-M/ARMv8-M MPU regions must have a power-of-two size of at least 32 bytes, with the \
213 base aligned to the size"
214 )]
215 RegionNotMpuAligned {
216 region: String,
217 base: u32,
218 length: u32,
219 requirement: &'static str,
221 },
222
223 #[error(
224 "[memory.{region}] ({base:#x}, len {length:#x}) is not cache-line aligned: {requirement}. \
225 Cached shared-memory regions must start and end on 64-byte boundaries"
226 )]
227 RegionNotCacheAligned {
228 region: String,
229 base: u32,
230 length: u32,
231 requirement: &'static str,
233 },
234
235 #[error(
236 "ipc channel '{channel}' enables controller-side caching on '{core}', but only Cortex-M7 \
237 cores in the supported chip set have an L1 data cache"
238 )]
239 IpcCacheUnsupported { channel: String, core: String },
240
241 #[error(
242 "ipc channel '{channel}' shared-memory region is {length:#x} bytes, but MTU {mtu} requires \
243 at least {required:#x} bytes for the aligned descriptor and bidirectional slot pair"
244 )]
245 IpcRegionTooSmall {
246 channel: String,
247 length: u32,
248 mtu: u32,
249 required: usize,
250 },
251
252 #[error(
253 "ipc channel '{channel}' sets config.ack, so party '{party}' must declare an ack_chan: acknowledgement needs a doorbell line of its own, because every line carries exactly one waiter"
254 )]
255 IpcAckChannelMissing { channel: String, party: String },
256
257 #[error(
258 "ipc channel '{channel}' party '{party}' declares an ack_chan, but the channel does not set config.ack"
259 )]
260 IpcAckChannelUnexpected { channel: String, party: String },
261}