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