-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathriscv_csr_macros.rs
242 lines (224 loc) · 6.96 KB
/
riscv_csr_macros.rs
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
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
/*
Register access functions for RISC-V system registers.
SPDX-License-Identifier: Unlicense
https://five-embeddev.com/
*/
#![no_std]
#[cfg(target_pointer_width = "32")]
pub type UintXlen = u32;
#[cfg(target_pointer_width = "32")]
pub type UintCsr64 = u32;
#[cfg(target_pointer_width = "64")]
pub type UintXlen = u64;
#[cfg(target_pointer_width = "64")]
pub type UintCsr64 = u64;
pub type UintCsr32 = u32;
#[allow(non_upper_case_globals)]
#[cfg(target_pointer_width = "32")]
const __riscv_xlen : isize = 32;
#[allow(non_upper_case_globals)]
#[cfg(target_pointer_width = "64")]
const __riscv_xlen : isize = 64;
{%- for reg_name,reg_data in data.regs.items() %}
{%- if not reg_data.mmio %}
/*******************************************
* {{reg_name}} - {{reg_data.priv}} - {{reg_data.desc}}
*/
{%- set ctype_reg = reg_data|csr_ctype_rs %}
{%- set ctype_arg = reg_data|arg_ctype %}
/* {{reg_name}}: CSR Whole register access */
{%- if "R" in reg_data.priv %}
/* {{reg_name}}: CSR read.
e.g.
let _v = csr_read_{{reg_name}}!();
*/
#[macro_export]
macro_rules! csr_read_{{reg_name}} {
( ) => (
{
let tmp_value: {{ctype_reg}};
unsafe {
use core::arch::asm;
asm!("csrr {0}, {{reg_name}}" , out(reg) tmp_value);
}
tmp_value
}
);
}
{%- endif %}
{%- if "W" in reg_data.priv %}
/* {{reg_name}}: CSR write
e.g.
csr_write_{{reg_name}}!(0x1234567);
*/
#[macro_export]
macro_rules! csr_write_{{reg_name}} {
( $x:expr ) => (
unsafe {
use core::arch::asm;
asm!("csrw {{reg_name}}, {0}" , in(reg) $x);
}
);
}
/* {{reg_name}}: CSR Read and Write
e.g.
let v_ = csr_read_write_{{reg_name}}!(0x1234567);
*/
#[macro_export]
macro_rules! csr_read_write_{{reg_name}} {
( $x:expr ) => (
{
let tmp_value: {{ctype_reg}};
unsafe {
use core::arch::asm;
asm!("csrrw {0}, {{reg_name}}, {1}" , out(reg) tmp_value, in(reg) $x);
}
tmp_value
}
);
}
{%- endif%}
/* {{reg_name}}: CSR Field Modifications - via register */
{%- if reg_data.fields %}
{%- if "W" in reg_data.priv %}
/* Register CSR bit set instructions.
e.g.
csr_set_bits_{{reg_name}}!(0x0F0F0F);
*/
#[macro_export]
macro_rules! csr_set_bits_{{reg_name}} {
( $mask:expr ) => (
unsafe {
use core::arch::asm;
asm!("csrrs zero, {{reg_name}}, {{'{'}}{{0}}{{'}'}}", in(reg) $mask);
}
);
}
/* Register CSR bit clear instructions
e.g.
csr_clr_bits_{{reg_name}}!(0x0F0F0F)
*/
#[macro_export]
macro_rules! csr_clr_bits_{{reg_name}} {
( $mask:expr ) => (
unsafe {
use core::arch::asm;
asm!("csrrc zero, {{reg_name}}, {{'{'}}{{0}}{{'}'}}", in(reg) $mask);
}
);
}
/* Register CSR read and then bit set instructions
e.g.
let org_value_ = csr_read_set_bits_{{reg_name}}!(0x0F0F0F)
*/
#[macro_export]
macro_rules! csr_read_set_bits_{{reg_name}} {
( $mask:expr ) => (
{
let tmp_value: {{ctype_reg}};
unsafe {
use core::arch::asm;
asm!("csrrs {{'{'}}{{0}}{{'}'}}, {{reg_name}}, {{'{'}}{{1}}{{'}'}}", out(reg) tmp_value, in(reg) $mask);
}
tmp_value
}
);
}
/* Register CSR read and then bit clear instructions
e.g.
let org_value_ = csr_read_clr_bits_{{reg_name}}!(0x0F0F0F)
*/
#[macro_export]
macro_rules! csr_read_clr_bits_{{reg_name}} {
( $mask:expr ) => (
{
let tmp_value: {{ctype_reg}};
unsafe {
use core::arch::asm;
asm!("csrrc {{'{'}}{{0}}{{'}'}}, {{reg_name}}, {{'{'}}{{1}}{{'}'}}", out(reg) tmp_value, in(reg) $mask);
}
tmp_value
}
);
}
/* {{reg_name}}: CSR Field Modifications - via immediate */
/* {{reg_name}}, CSR write value via immediate value (only up to 5 bits).
e.g.
csr_write_imm_{{reg_name}}!(0x1F);
*/
#[macro_export]
macro_rules! csr_write_imm_{{reg_name}} {
( $value:ident ) => (
unsafe {
use core::arch::asm;
asm!(concat!("csrrwi zero, {{reg_name}}, ", stringify!($value)));
}
);
}
/* {{reg_name}}, CSR set bits via immediate value mask (only up to 5 bits).
e.g.
csr_set_bits_imm_{{reg_name}}!(0x1F);
*/
#[macro_export]
macro_rules! csr_set_bits_imm_{{reg_name}} {
{%- if reg_data.fields %}
{%-for field_name,field_data in reg_data.fields.items() %}
{%- if field_data|csr_field_imm_valid %}
{%- set bit_width = field_data|csr_bit_width_rs %}
{%- set bit_offset = field_data|csr_bit_offset_rs %}
( {{reg_name|upper}}_{{field_name|upper}}_BIT_MASK) => { csr_set_bits_imm_{{reg_name}}!({{bit_offset|csr_format_mask_rs(bit_width)}})};
{%- endif %}
{%- endfor %}
{%- endif %}
( $value:literal ) => (
unsafe {
use core::arch::asm;
asm!(concat!("csrrsi zero, {{reg_name}}, ", stringify!($value)));
}
);
}
/* {{reg_name}}, CSR clear bits via immediate value mask (only up to 5 bits).
e.g.
csr_clr_bits_imm_{{reg_name}}!(0x1F);
*/
#[macro_export]
macro_rules! csr_clr_bits_imm_{{reg_name}} {
{%- if reg_data.fields %}
{%-for field_name,field_data in reg_data.fields.items() %}
{%- if field_data|csr_field_imm_valid %}
{%- set bit_width = field_data|csr_bit_width_rs %}
{%- set bit_offset = field_data|csr_bit_offset_rs %}
( {{reg_name|upper}}_{{field_name|upper}}_BIT_MASK) => { csr_clr_bits_imm_{{reg_name}}!({{bit_offset|csr_format_mask_rs(bit_width)}})};
{%- endif %}
{%- endfor %}
{%- endif %}
( $value:ident ) => (
unsafe {
use core::arch::asm;
asm!(concat!("csrrci zero, {{reg_name}}, ", stringify!($value)));
}
);
}
{%- endif %}
{%-endif%}
{%- endif%}
{%- endfor%}
{%- for reg_name,reg_data in data.regs.items() %}
{%- if not reg_data.mmio %}
{%- if reg_data.fields %}
/*******************************************
* {{reg_name}} - {{reg_data.priv}} - {{reg_data.desc}}
*/
{%- set ctype_reg = reg_data|csr_ctype %}
{%- set ctype_arg = reg_data|arg_ctype %}
{%-for field_name,field_data in reg_data.fields.items() %}
{%- set bit_width = field_data|csr_bit_width_rs %}
{%- set bit_offset = field_data|csr_bit_offset_rs %}
pub const {{reg_name|upper}}_{{field_name|upper}}_BIT_OFFSET:isize = {{bit_offset}};
pub const {{reg_name|upper}}_{{field_name|upper}}_BIT_WIDTH:isize = {{bit_width}};
pub const {{reg_name|upper}}_{{field_name|upper}}_BIT_MASK:UintXlen = {{bit_offset|csr_format_mask_rs(bit_width)}};
pub const {{reg_name|upper}}_{{field_name|upper}}_ALL_SET_MASK:UintXlen = {{0|csr_format_mask_rs(bit_width)}};
{%- endfor%}
{%-endif%}
{%-endif%}
{%- endfor%}