Skip to main content

device_driver_lir/
model.rs

1use device_driver_common::{
2    identifier::{All, Identifier, Operation, Type},
3    span::Spanned,
4    specifiers::{Access, AddressMode, AddressRange, ByteOrder, Integer},
5};
6
7pub struct Driver {
8    pub devices: Vec<Device>,
9    pub field_sets: Vec<FieldSet>,
10    pub enums: Vec<Enum>,
11}
12
13pub struct Device {
14    pub internal_address_type: Integer,
15    pub address_offset: i128,
16    pub blocks: Vec<Block>,
17}
18
19pub struct Block {
20    pub description: String,
21    /// True for the root (top-level) block
22    pub root: bool,
23    pub name: Identifier<Type>,
24    pub register_address_type: Integer,
25    pub command_address_type: Integer,
26    pub buffer_address_type: Integer,
27    pub register_address_mode: Option<AddressMode>,
28    pub methods: Vec<BlockMethod>,
29}
30
31pub struct BlockMethod {
32    pub description: String,
33    pub name: Identifier<Operation>,
34    pub address: i128,
35    pub repeat: Repeat,
36    pub method_type: BlockMethodType,
37}
38
39pub enum Repeat {
40    None,
41    Count {
42        count: u32,
43        stride: i128,
44    },
45    Enum {
46        enum_name: Identifier<Type>,
47        enum_variants: Vec<Identifier<All>>,
48        stride: i128,
49    },
50}
51
52pub enum BlockMethodType {
53    Block {
54        name: Identifier<Type>,
55    },
56    Register {
57        field_set_name: Identifier<Type>,
58        access: Access,
59        reset_value: Option<Spanned<Vec<u8>>>,
60    },
61    Command {
62        field_set_name_in: Option<Identifier<Type>>,
63        field_set_name_out: Option<Identifier<Type>>,
64    },
65    Buffer {
66        access: Access,
67    },
68}
69
70/// A set of fields, like a register or command in/out
71pub struct FieldSet {
72    pub description: String,
73    pub name: Identifier<Type>,
74    pub byte_order: ByteOrder,
75    pub size_bytes: u32,
76    pub fields: Vec<Field>,
77}
78
79pub struct Field {
80    pub description: String,
81    pub name: Identifier<All>,
82    pub address: AddressRange,
83    pub base_type: String,
84    pub conversion_method: FieldConversionMethod,
85    pub access: Access,
86    pub repeat: Repeat,
87}
88
89impl Field {
90    pub fn address_text(&self) -> String {
91        if self.address.len() <= 1 {
92            format!("bit {}", self.address.start)
93        } else {
94            format!("{}:{}", self.address.end, self.address.start)
95        }
96    }
97}
98
99pub enum FieldConversionMethod {
100    None,
101    Into(Identifier<Type>),
102    UnsafeInto(Identifier<Type>),
103    TryInto(Identifier<Type>),
104    Bool,
105}
106
107impl FieldConversionMethod {
108    pub fn conversion_type(&self) -> Option<&Identifier<Type>> {
109        match self {
110            FieldConversionMethod::None => None,
111            FieldConversionMethod::Into(type_path) => Some(type_path),
112            FieldConversionMethod::UnsafeInto(type_path) => Some(type_path),
113            FieldConversionMethod::TryInto(type_path) => Some(type_path),
114            FieldConversionMethod::Bool => None,
115        }
116    }
117}
118
119pub struct Enum {
120    pub description: String,
121    pub name: Identifier<Type>,
122    pub base_type: String,
123    pub variants: Vec<EnumVariant>,
124}
125
126impl Enum {
127    pub fn default_variant(&self) -> Option<&EnumVariant> {
128        self.variants.iter().find(|v| v.default)
129    }
130
131    pub fn catch_all_variant(&self) -> Option<&EnumVariant> {
132        self.variants.iter().find(|v| v.catch_all)
133    }
134}
135
136pub struct EnumVariant {
137    pub description: String,
138    pub name: Identifier<All>,
139    pub discriminant: i128,
140    pub default: bool,
141    pub catch_all: bool,
142}