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