1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
// Copyright (C) 2024 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//! Derive/attribute macros for simics-api
use ;
use ;
use ;
use simics_exception_impl;
use simics_init_impl;
use interface_impl;
use TokenStream;
/// Derive Macro for implementing conversion into an `AttrValue` list, where each struct
/// field's value is an entry in the heterogeneous list.
///
/// # Arguments
///
/// At the field level (i.e. on each field of a struct deriving this attribute), the
/// following attributes are supported:
///
/// * `#[attr_value(skip)]` - Do not include this field in the conversion.
/// * `#[attr_value(fallible)]` - If the field type does not implement `Into<AttrValue>`,
/// use its implementation of `TryInto<AttrValue>` instead. Whether this flag is necessary
/// cannot be automatically determined by this macro, so it must be specified manually.
/// Derive Macro for implementing conversion into an `AttrValue` dictionary, where each
/// struct field's key, value pair is an entry in the dictionary.
///
/// # Arguments
///
/// At the field level (i.e. on each field of a struct deriving this attribute), the
/// following attributes are supported:
///
/// * `#[attr_value(skip)]` - Do not include this field in the conversion.
/// * `#[attr_value(fallible)]` - If the field type does not implement `Into<AttrValue>`,
/// use its implementation of `TryInto<AttrValue>` instead. Whether this flag is necessary
/// cannot be automatically determined by this macro, so it must be specified manually.
/// Derive Macro for implementing conversion from an `AttrValue` list into a struct, where
/// each entry in the list is a struct field's value.
///
/// # Arguments
///
/// At the field level (i.e. on each field of a struct deriving this attribute), the
/// following attributes are supported:
///
/// * `#[attr_value(fallible)]` - If the field type does not implement `From<AttrValue>`,
/// use its implementation of `TryFrom<AttrValue>` instead. Whether this flag is necessary
/// cannot be automatically determined by this macro, so it must be specified manually.
/// Derive Macro for implementing conversion from an `AttrValue` dict into a struct, where
/// each key, value pair in the dict is a struct field's name, value pair.
///
/// # Arguments
///
/// At the field level (i.e. on each field of a struct deriving this attribute), the
/// following attributes are supported:
///
/// * `#[attr_value(fallible)]` - If the field type does not implement `From<AttrValue>`,
/// use its implementation of `TryFrom<AttrValue>` instead. Whether this flag is necessary
/// cannot be automatically determined by this macro, so it must be specified manually.
/// Derive macro for implementing the `Class` trait for the annotated type
/// Attribute macro for declaring a Simics class for a Rust struct type
/// Derive macro for implementing conversion to raw `ConfObject` pointers.
/// This macro implements the `AsConfObject` trait for the annotated type.
/// Derive macro for implementing conversion from raw `ConfObject` pointers.
/// This macro implements the `FromConfObject` trait for the annotated type.
///
/// # Arguments
///
/// At the item level (i.e. on the struct deriving this attribute), the following
/// attributes are supported:
///
/// * `#[conf_object(skip_from)]` - Skip also implementing `From<*_ ConfObject>` which is the
/// default behavior.
/// Marks a function as being a SIMICS API that can throw exceptions in called FFI APIs.
///
/// A SIMICS exception can be generated by most APIs. This macro makes the function
/// private, wraps it, and adds the requisite code to check for and report exceptions.
/// `clear_exception` should *not* be called inside the wrapped function. `last_error`
/// may be called, however, as any exceptions will be cleared after the wrapped function
/// returns.
///
/// # Examples
///
/// Add the `#[simics_exception]` attribute to a function which calls a SIMICS API that can throw
/// exceptions. The function will be wrapped and the requisite code to check for and report
/// exceptions will be added.
///
/// ```rust,ignore
/// #[simics_exception]
/// pub fn write_byte(physical_memory: *mut ConfObject, physical_addr: u64, byte: u8) {
/// unsafe { SIM_write_byte(physical_memory, physical_addr, byte) };
/// }
/// ```
///
/// This expands to:
///
/// ```rust,ignore
/// fn _write_byte(physical_memory: *mut ConfObject, physical_addr: u64, byte: u8) {
/// unsafe { SIM_write_byte(physical_memory, physical_addr, byte) };
/// }
///
/// pub fn write_byte(physical_memory: *mut ConfObject, physical_addr: u64, byte: u8) -> Result<()> {
/// let res = _write_byte(physical_memory, physical_addr, byte);
///
/// match simics::get_pending_exception() {
/// SimException::SimExc_No_Exception => Ok(()),
/// exception => {
/// clear_exception();
/// Err(Error::from(exception))
/// }
/// }
/// }
/// ```
/// Mark a function as being the initializer of a Simics module.
///
/// This function will be called on module load and should be used to initialize the
/// module. This macro will add the requisite
/// code to call the function on module load.
/// Declare a struct implementation as a SIMICS API interface.
///
/// This macro will add the requisite code to implement the interface which allows
/// methods in the impl to be called
/// from Simics scripts in Python or the Simics language.