Skip to main content

device_driver_generation/mir/
mod.rs

1//! The MIR takes its data from HIR and makes sure all required data is there
2//! and all optional data is filled in with defaults.
3
4use std::{fmt::Display, ops::Range};
5
6use convert_case::Boundary;
7
8pub mod lir_transform;
9pub mod passes;
10
11#[derive(Debug, Clone, PartialEq, Eq, Default)]
12pub struct Device {
13    pub name: Option<String>,
14    pub global_config: GlobalConfig,
15    pub objects: Vec<Object>,
16}
17
18#[derive(Debug, Clone, PartialEq, Eq)]
19pub struct GlobalConfig {
20    pub default_register_access: Access,
21    pub default_field_access: Access,
22    pub default_buffer_access: Access,
23    pub default_byte_order: Option<ByteOrder>,
24    pub default_bit_order: BitOrder,
25    pub register_address_type: Option<Integer>,
26    pub command_address_type: Option<Integer>,
27    pub buffer_address_type: Option<Integer>,
28    pub name_word_boundaries: Vec<Boundary>,
29    pub defmt_feature: Option<String>,
30}
31
32impl Default for GlobalConfig {
33    fn default() -> Self {
34        Self {
35            default_register_access: Default::default(),
36            default_field_access: Default::default(),
37            default_buffer_access: Default::default(),
38            default_byte_order: Default::default(),
39            default_bit_order: Default::default(),
40            register_address_type: Default::default(),
41            command_address_type: Default::default(),
42            buffer_address_type: Default::default(),
43            name_word_boundaries: convert_case::Boundary::defaults(),
44            defmt_feature: Default::default(),
45        }
46    }
47}
48
49#[derive(Debug, Clone, Copy, PartialEq, Eq)]
50pub enum Integer {
51    U8,
52    U16,
53    U32,
54    I8,
55    I16,
56    I32,
57    I64,
58}
59
60impl Integer {
61    pub fn min_value(&self) -> i64 {
62        match self {
63            Integer::U8 => u8::MIN as i64,
64            Integer::U16 => u16::MIN as i64,
65            Integer::U32 => u32::MIN as i64,
66            Integer::I8 => i8::MIN as i64,
67            Integer::I16 => i16::MIN as i64,
68            Integer::I32 => i32::MIN as i64,
69            Integer::I64 => i64::MIN,
70        }
71    }
72
73    pub fn max_value(&self) -> i64 {
74        match self {
75            Integer::U8 => u8::MAX as i64,
76            Integer::U16 => u16::MAX as i64,
77            Integer::U32 => u32::MAX as i64,
78            Integer::I8 => i8::MAX as i64,
79            Integer::I16 => i16::MAX as i64,
80            Integer::I32 => i32::MAX as i64,
81            Integer::I64 => i64::MAX,
82        }
83    }
84}
85
86impl Display for Integer {
87    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
88        match self {
89            Integer::U8 => write!(f, "u8"),
90            Integer::U16 => write!(f, "u16"),
91            Integer::U32 => write!(f, "u32"),
92            Integer::I8 => write!(f, "i8"),
93            Integer::I16 => write!(f, "i16"),
94            Integer::I32 => write!(f, "i32"),
95            Integer::I64 => write!(f, "i64"),
96        }
97    }
98}
99
100#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
101pub enum Access {
102    #[default]
103    RW,
104    RO,
105    WO,
106}
107
108impl Access {
109    pub fn is_readable(&self) -> bool {
110        match self {
111            Access::RW => true,
112            Access::RO => true,
113            Access::WO => false,
114        }
115    }
116}
117
118impl Display for Access {
119    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
120        write!(f, "{self:?}")
121    }
122}
123
124#[derive(Debug, Clone, Copy, PartialEq, Eq)]
125pub enum ByteOrder {
126    LE,
127    BE,
128}
129
130impl Display for ByteOrder {
131    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
132        write!(f, "{self:?}")
133    }
134}
135
136#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
137pub enum BitOrder {
138    #[default]
139    LSB0,
140    MSB0,
141}
142
143impl Display for BitOrder {
144    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
145        write!(f, "{self:?}")
146    }
147}
148
149#[derive(Debug, Clone, PartialEq, Eq)]
150pub enum Object {
151    Block(Block),
152    Register(Register),
153    Command(Command),
154    Buffer(Buffer),
155    Ref(RefObject),
156}
157
158impl Object {
159    pub(self) fn get_block_object_list_mut(&mut self) -> Option<&mut Vec<Self>> {
160        match self {
161            Object::Block(b) => Some(&mut b.objects),
162            _ => None,
163        }
164    }
165
166    pub(self) fn get_block_object_list(&self) -> Option<&[Self]> {
167        match self {
168            Object::Block(b) => Some(&b.objects),
169            _ => None,
170        }
171    }
172
173    /// Get a mutable reference to the name of the specific object
174    pub(self) fn name_mut(&mut self) -> &mut String {
175        match self {
176            Object::Block(val) => &mut val.name,
177            Object::Register(val) => &mut val.name,
178            Object::Command(val) => &mut val.name,
179            Object::Buffer(val) => &mut val.name,
180            Object::Ref(val) => &mut val.name,
181        }
182    }
183
184    /// Get a reference to the name of the specific object
185    pub(self) fn name(&self) -> &str {
186        match self {
187            Object::Block(val) => &val.name,
188            Object::Register(val) => &val.name,
189            Object::Command(val) => &val.name,
190            Object::Buffer(val) => &val.name,
191            Object::Ref(val) => &val.name,
192        }
193    }
194
195    /// Get a reference to the cfg of the specific object
196    pub(self) fn cfg_attr_mut(&mut self) -> &mut Cfg {
197        match self {
198            Object::Block(val) => &mut val.cfg_attr,
199            Object::Register(val) => &mut val.cfg_attr,
200            Object::Command(val) => &mut val.cfg_attr,
201            Object::Buffer(val) => &mut val.cfg_attr,
202            Object::Ref(val) => &mut val.cfg_attr,
203        }
204    }
205
206    /// Get an iterator over all the field sets in the object
207    pub(self) fn field_sets_mut(&mut self) -> impl Iterator<Item = &mut [Field]> {
208        match self {
209            Object::Register(val) => vec![val.fields.as_mut_slice()].into_iter(),
210            Object::Command(val) => {
211                vec![val.in_fields.as_mut_slice(), val.out_fields.as_mut_slice()].into_iter()
212            }
213            Object::Block(_) | Object::Buffer(_) | Object::Ref(_) => Vec::new().into_iter(),
214        }
215    }
216
217    /// Get an iterator over all the field sets in the object
218    pub(self) fn field_sets(&self) -> impl Iterator<Item = &[Field]> {
219        match self {
220            Object::Register(val) => vec![val.fields.as_slice()].into_iter(),
221            Object::Command(val) => {
222                vec![val.in_fields.as_slice(), val.out_fields.as_slice()].into_iter()
223            }
224            Object::Block(_) | Object::Buffer(_) | Object::Ref(_) => Vec::new().into_iter(),
225        }
226    }
227
228    pub fn as_block_mut(&mut self) -> Option<&mut Block> {
229        if let Self::Block(v) = self {
230            Some(v)
231        } else {
232            None
233        }
234    }
235
236    pub fn as_register_mut(&mut self) -> Option<&mut Register> {
237        if let Self::Register(v) = self {
238            Some(v)
239        } else {
240            None
241        }
242    }
243
244    pub fn as_register(&self) -> Option<&Register> {
245        if let Self::Register(v) = self {
246            Some(v)
247        } else {
248            None
249        }
250    }
251
252    pub fn as_command_mut(&mut self) -> Option<&mut Command> {
253        if let Self::Command(v) = self {
254            Some(v)
255        } else {
256            None
257        }
258    }
259
260    /// Return the address if it is specified.
261    /// It's only not specified in ref objects where the user hasn't overridden the address
262    fn address(&self) -> Option<i64> {
263        match self {
264            Object::Block(block) => Some(block.address_offset),
265            Object::Register(register) => Some(register.address),
266            Object::Command(command) => Some(command.address),
267            Object::Buffer(buffer) => Some(buffer.address),
268            Object::Ref(ref_object) => match &ref_object.object_override {
269                ObjectOverride::Block(block_override) => block_override.address_offset,
270                ObjectOverride::Register(register_override) => register_override.address,
271                ObjectOverride::Command(command_override) => command_override.address,
272            },
273        }
274    }
275
276    /// Return the repeat value if it exists
277    fn repeat(&self) -> Option<Repeat> {
278        match self {
279            Object::Block(block) => block.repeat,
280            Object::Register(register) => register.repeat,
281            Object::Command(command) => command.repeat,
282            Object::Buffer(_) => None,
283            Object::Ref(ref_object) => match &ref_object.object_override {
284                ObjectOverride::Block(block_override) => block_override.repeat,
285                ObjectOverride::Register(register_override) => register_override.repeat,
286                ObjectOverride::Command(command_override) => command_override.repeat,
287            },
288        }
289    }
290
291    pub fn as_ref_object_mut(&mut self) -> Option<&mut RefObject> {
292        if let Self::Ref(v) = self {
293            Some(v)
294        } else {
295            None
296        }
297    }
298}
299
300#[derive(Debug, Clone, PartialEq, Eq, Default)]
301pub struct Block {
302    pub cfg_attr: Cfg,
303    pub description: String,
304    pub name: String,
305    pub address_offset: i64,
306    pub repeat: Option<Repeat>,
307    pub objects: Vec<Object>,
308}
309
310#[derive(Debug, Copy, Clone, PartialEq, Eq)]
311pub struct Repeat {
312    pub count: u64,
313    pub stride: i64,
314}
315
316#[derive(Debug, Clone, PartialEq, Eq, Default)]
317pub struct Register {
318    pub cfg_attr: Cfg,
319    pub description: String,
320    pub name: String,
321    pub access: Access,
322    pub byte_order: Option<ByteOrder>,
323    pub bit_order: BitOrder,
324    pub allow_bit_overlap: bool,
325    pub allow_address_overlap: bool,
326    pub address: i64,
327    pub size_bits: u32,
328    pub reset_value: Option<ResetValue>,
329    pub repeat: Option<Repeat>,
330    pub fields: Vec<Field>,
331}
332
333#[derive(Debug, Clone, PartialEq, Eq, Default)]
334pub struct Field {
335    pub cfg_attr: Cfg,
336    pub description: String,
337    pub name: String,
338    pub access: Access,
339    pub base_type: BaseType,
340    pub field_conversion: Option<FieldConversion>,
341    pub field_address: Range<u32>,
342}
343
344#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
345pub enum BaseType {
346    Unspecified,
347    Bool,
348    #[default]
349    Uint,
350    Int,
351    FixedSize(Integer),
352}
353
354#[derive(Debug, Clone, PartialEq, Eq)]
355pub enum FieldConversion {
356    Direct { type_name: String, use_try: bool },
357    Enum { enum_value: Enum, use_try: bool },
358}
359
360impl FieldConversion {
361    pub const fn use_try(&self) -> bool {
362        match self {
363            FieldConversion::Direct { use_try, .. } => *use_try,
364            FieldConversion::Enum { use_try, .. } => *use_try,
365        }
366    }
367
368    pub fn type_name(&self) -> &str {
369        match self {
370            FieldConversion::Direct { type_name, .. } => type_name,
371            FieldConversion::Enum { enum_value, .. } => &enum_value.name,
372        }
373    }
374}
375
376#[derive(Debug, Clone, PartialEq, Eq, Default)]
377pub struct Enum {
378    pub cfg_attr: Cfg,
379    pub description: String,
380    pub name: String,
381    pub variants: Vec<EnumVariant>,
382    generation_style: Option<EnumGenerationStyle>,
383}
384
385impl Enum {
386    pub fn new(description: String, name: String, variants: Vec<EnumVariant>) -> Self {
387        Self {
388            cfg_attr: Cfg::default(),
389            description,
390            name,
391            variants,
392            generation_style: None,
393        }
394    }
395
396    #[cfg(test)]
397    pub fn new_with_style(
398        description: String,
399        name: String,
400        variants: Vec<EnumVariant>,
401        generation_style: EnumGenerationStyle,
402    ) -> Self {
403        Self {
404            cfg_attr: Cfg::default(),
405            description,
406            name,
407            variants,
408            generation_style: Some(generation_style),
409        }
410    }
411}
412
413#[derive(Debug, Clone, PartialEq, Eq)]
414pub enum EnumGenerationStyle {
415    Fallible,
416    Infallible { bit_size: u32 },
417}
418
419impl EnumGenerationStyle {
420    /// Returns `true` if the enum generation style is [`Fallible`].
421    ///
422    /// [`Fallible`]: EnumGenerationStyle::Fallible
423    #[must_use]
424    pub fn is_fallible(&self) -> bool {
425        matches!(self, Self::Fallible)
426    }
427}
428
429#[derive(Debug, Clone, PartialEq, Eq, Default)]
430pub struct EnumVariant {
431    pub cfg_attr: Cfg,
432    pub description: String,
433    pub name: String,
434    pub value: EnumValue,
435}
436
437#[derive(Debug, Clone, PartialEq, Eq, Default)]
438pub enum EnumValue {
439    #[default]
440    Unspecified,
441    Specified(i128),
442    Default,
443    CatchAll,
444}
445
446impl EnumValue {
447    /// Returns `true` if the enum value is [`Default`].
448    ///
449    /// [`Default`]: EnumValue::Default
450    #[must_use]
451    pub fn is_default(&self) -> bool {
452        matches!(self, Self::Default)
453    }
454
455    /// Returns `true` if the enum value is [`CatchAll`].
456    ///
457    /// [`CatchAll`]: EnumValue::CatchAll
458    #[must_use]
459    pub fn is_catch_all(&self) -> bool {
460        matches!(self, Self::CatchAll)
461    }
462}
463
464#[derive(Debug, Clone, PartialEq, Eq, Default)]
465pub struct Command {
466    pub cfg_attr: Cfg,
467    pub description: String,
468    pub name: String,
469    pub address: i64,
470    pub byte_order: Option<ByteOrder>,
471    pub bit_order: BitOrder,
472    pub allow_bit_overlap: bool,
473    pub allow_address_overlap: bool,
474    pub size_bits_in: u32,
475    pub size_bits_out: u32,
476    pub repeat: Option<Repeat>,
477    pub in_fields: Vec<Field>,
478    pub out_fields: Vec<Field>,
479}
480
481#[derive(Debug, Clone, PartialEq, Eq, Default)]
482pub struct Buffer {
483    pub cfg_attr: Cfg,
484    pub description: String,
485    pub name: String,
486    pub access: Access,
487    pub address: i64,
488}
489
490#[derive(Debug, Clone, PartialEq, Eq, Default)]
491pub struct RefObject {
492    pub cfg_attr: Cfg,
493    pub description: String,
494    pub name: String,
495    pub object_override: ObjectOverride,
496}
497
498#[derive(Debug, Clone, PartialEq, Eq)]
499pub enum ObjectOverride {
500    Block(BlockOverride),
501    Register(RegisterOverride),
502    Command(CommandOverride),
503}
504
505impl Default for ObjectOverride {
506    fn default() -> Self {
507        Self::Register(Default::default())
508    }
509}
510
511impl ObjectOverride {
512    fn name(&self) -> &str {
513        match self {
514            ObjectOverride::Block(v) => &v.name,
515            ObjectOverride::Register(v) => &v.name,
516            ObjectOverride::Command(v) => &v.name,
517        }
518    }
519
520    fn name_mut(&mut self) -> &mut String {
521        match self {
522            ObjectOverride::Block(v) => &mut v.name,
523            ObjectOverride::Register(v) => &mut v.name,
524            ObjectOverride::Command(v) => &mut v.name,
525        }
526    }
527
528    pub fn as_register(&self) -> Option<&RegisterOverride> {
529        if let Self::Register(v) = self {
530            Some(v)
531        } else {
532            None
533        }
534    }
535
536    pub fn as_register_mut(&mut self) -> Option<&mut RegisterOverride> {
537        if let Self::Register(v) = self {
538            Some(v)
539        } else {
540            None
541        }
542    }
543}
544
545#[derive(Debug, Clone, PartialEq, Eq, Default)]
546pub struct BlockOverride {
547    pub name: String,
548    pub address_offset: Option<i64>,
549    pub repeat: Option<Repeat>,
550}
551
552#[derive(Debug, Clone, PartialEq, Eq, Default)]
553pub struct RegisterOverride {
554    pub name: String,
555    pub access: Option<Access>,
556    pub address: Option<i64>,
557    pub allow_address_overlap: bool,
558    pub reset_value: Option<ResetValue>,
559    pub repeat: Option<Repeat>,
560}
561
562#[derive(Debug, Clone, PartialEq, Eq, Default)]
563pub struct CommandOverride {
564    pub name: String,
565    pub address: Option<i64>,
566    pub allow_address_overlap: bool,
567    pub repeat: Option<Repeat>,
568}
569
570#[derive(Debug, Clone, PartialEq, Eq)]
571pub enum ResetValue {
572    Integer(u128),
573    Array(Vec<u8>),
574}
575
576impl ResetValue {
577    pub fn as_array(&self) -> Option<&Vec<u8>> {
578        if let Self::Array(v) = self {
579            Some(v)
580        } else {
581            None
582        }
583    }
584}
585
586#[derive(Debug, Clone, Eq, PartialEq, Default, Hash)]
587pub struct Cfg {
588    value: Option<String>,
589}
590
591impl Cfg {
592    pub fn new(value: Option<&str>) -> Self {
593        Self {
594            value: value.map(|v| v.into()),
595        }
596    }
597
598    #[must_use]
599    pub fn combine(&self, other: &Self) -> Self {
600        match (&self.value, &other.value) {
601            (None, None) => Self { value: None },
602            (None, Some(val)) => Self {
603                value: Some(val.clone()),
604            },
605            (Some(val), None) => Self {
606                value: Some(val.clone()),
607            },
608            (Some(val1), Some(val2)) if val1 == val2 => Self {
609                value: Some(val1.clone()),
610            },
611            (Some(val1), Some(val2)) => Self {
612                value: Some(format!("all({val1}, {val2})")),
613            },
614        }
615    }
616
617    pub fn inner(&self) -> Option<&str> {
618        self.value.as_deref()
619    }
620}
621
622impl Display for Cfg {
623    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
624        if let Some(value) = self.inner() {
625            write!(f, "#[cfg({value})]")?
626        }
627
628        Ok(())
629    }
630}
631
632#[derive(Debug, Clone, Eq, PartialEq, Hash)]
633pub struct UniqueId {
634    object_name: String,
635    object_cfg: Cfg,
636}
637
638impl Display for UniqueId {
639    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
640        match self.object_cfg.inner() {
641            Some(cfg) => write!(f, "{}(cfg=`{}`)", self.object_name, cfg),
642            None => write!(f, "{}", self.object_name),
643        }
644    }
645}
646
647pub trait Unique {
648    fn id(&self) -> UniqueId;
649}
650
651macro_rules! impl_unique {
652    ($t:ty) => {
653        impl Unique for $t {
654            fn id(&self) -> UniqueId {
655                UniqueId {
656                    object_name: self.name.clone(),
657                    object_cfg: self.cfg_attr.clone(),
658                }
659            }
660        }
661    };
662}
663
664impl_unique!(Register);
665impl_unique!(Command);
666impl_unique!(Buffer);
667impl_unique!(RefObject);
668impl_unique!(Block);
669impl_unique!(Enum);
670impl_unique!(EnumVariant);
671
672impl Unique for Object {
673    fn id(&self) -> UniqueId {
674        match self {
675            Object::Block(val) => val.id(),
676            Object::Register(val) => val.id(),
677            Object::Command(val) => val.id(),
678            Object::Buffer(val) => val.id(),
679            Object::Ref(val) => val.id(),
680        }
681    }
682}