1
- use crate :: {
2
- svd:: { Peripheral , Riscv } ,
3
- util, Config ,
4
- } ;
1
+ use crate :: { svd:: Peripheral , util, Config } ;
5
2
use anyhow:: Result ;
6
3
use log:: debug;
7
4
use proc_macro2:: TokenStream ;
8
5
use quote:: quote;
9
6
use std:: { collections:: HashMap , fmt:: Write , str:: FromStr } ;
10
7
11
- pub fn is_riscv_peripheral ( p : & Peripheral ) -> bool {
12
- [ "PLIC" , "CLINT" ] . contains ( & p. name . to_uppercase ( ) . as_ref ( ) )
8
+ pub fn is_riscv_peripheral ( p : & Peripheral , c : & Config ) -> bool {
9
+ // TODO cleaner implementation of this
10
+ match & c. riscv_config {
11
+ Some ( c) => {
12
+ c. clint . as_ref ( ) . is_some_and ( |clint| clint. name == p. name )
13
+ || c. plic . as_ref ( ) . is_some_and ( |plic| plic == & p. name )
14
+ }
15
+ _ => false ,
16
+ }
13
17
}
14
18
15
19
/// Whole RISC-V generation
16
20
pub fn render (
17
- r : Option < & Riscv > ,
18
21
peripherals : & [ Peripheral ] ,
19
22
device_x : & mut String ,
20
23
config : & Config ,
21
24
) -> Result < TokenStream > {
22
25
let mut mod_items = TokenStream :: new ( ) ;
23
26
24
- if let Some ( r ) = r {
25
- if !r . core_interrupts . is_empty ( ) {
27
+ if let Some ( c ) = config . riscv_config . as_ref ( ) {
28
+ if let Some ( i ) = c . core_interrupts . as_ref ( ) {
26
29
debug ! ( "Rendering target-specific core interrupts" ) ;
27
30
writeln ! ( device_x, "/* Core interrupt sources and trap handlers */" ) ?;
28
31
let mut interrupts = vec ! [ ] ;
29
- for i in r. core_interrupts . iter ( ) {
30
- let name = TokenStream :: from_str ( & i. name ) . unwrap ( ) ;
31
- let value = TokenStream :: from_str ( & format ! ( "{}" , i. value) ) . unwrap ( ) ;
32
- let description = format ! (
33
- "{} - {}" ,
34
- i. value,
35
- i. description
36
- . as_ref( )
37
- . map( |s| util:: respace( s) )
38
- . as_ref( )
39
- . map( |s| util:: escape_special_chars( s) )
40
- . unwrap_or_else( || i. name. clone( ) )
41
- ) ;
32
+ for interrupt in i. iter ( ) {
33
+ let name = TokenStream :: from_str ( & interrupt. name ) . unwrap ( ) ;
34
+ let value = TokenStream :: from_str ( & format ! ( "{}" , interrupt. value) ) . unwrap ( ) ;
35
+ let description = interrupt. description ( ) ;
42
36
43
37
writeln ! ( device_x, "PROVIDE({name} = DefaultHandler);" ) ?;
44
38
writeln ! (
@@ -64,23 +58,14 @@ pub fn render(
64
58
mod_items. extend ( quote ! { pub use riscv:: interrupt:: Interrupt as CoreInterrupt ; } ) ;
65
59
}
66
60
67
- if !r . exceptions . is_empty ( ) {
61
+ if let Some ( e ) = c . exceptions . as_ref ( ) {
68
62
debug ! ( "Rendering target-specific exceptions" ) ;
69
63
writeln ! ( device_x, "/* Exception sources */" ) ?;
70
64
let mut exceptions = vec ! [ ] ;
71
- for e in r. exceptions . iter ( ) {
72
- let name = TokenStream :: from_str ( & e. name ) . unwrap ( ) ;
73
- let value = TokenStream :: from_str ( & format ! ( "{}" , e. value) ) . unwrap ( ) ;
74
- let description = format ! (
75
- "{} - {}" ,
76
- e. value,
77
- e. description
78
- . as_ref( )
79
- . map( |s| util:: respace( s) )
80
- . as_ref( )
81
- . map( |s| util:: escape_special_chars( s) )
82
- . unwrap_or_else( || e. name. clone( ) )
83
- ) ;
65
+ for exception in e. iter ( ) {
66
+ let name = TokenStream :: from_str ( & exception. name ) . unwrap ( ) ;
67
+ let value = TokenStream :: from_str ( & format ! ( "{}" , exception. value) ) . unwrap ( ) ;
68
+ let description = exception. description ( ) ;
84
69
85
70
writeln ! ( device_x, "PROVIDE({name} = ExceptionHandler);" ) ?;
86
71
@@ -102,21 +87,12 @@ pub fn render(
102
87
mod_items. extend ( quote ! { pub use riscv:: interrupt:: Exception ; } ) ;
103
88
}
104
89
105
- if !r . priorities . is_empty ( ) {
90
+ if let Some ( p ) = c . priorities . as_ref ( ) {
106
91
debug ! ( "Rendering target-specific priority levels" ) ;
107
- let priorities = r. priorities . iter ( ) . map ( |p| {
108
- let name = TokenStream :: from_str ( & p. name ) . unwrap ( ) ;
109
- let value = TokenStream :: from_str ( & format ! ( "{}" , p. value) ) . unwrap ( ) ;
110
- let description = format ! (
111
- "{} - {}" ,
112
- p. value,
113
- p. description
114
- . as_ref( )
115
- . map( |s| util:: respace( s) )
116
- . as_ref( )
117
- . map( |s| util:: escape_special_chars( s) )
118
- . unwrap_or_else( || p. name. clone( ) )
119
- ) ;
92
+ let priorities = p. iter ( ) . map ( |priority| {
93
+ let name = TokenStream :: from_str ( & priority. name ) . unwrap ( ) ;
94
+ let value = TokenStream :: from_str ( & format ! ( "{}" , priority. value) ) . unwrap ( ) ;
95
+ let description = priority. description ( ) ;
120
96
121
97
quote ! {
122
98
#[ doc = #description]
@@ -133,21 +109,12 @@ pub fn render(
133
109
} ) ;
134
110
}
135
111
136
- if !r . harts . is_empty ( ) {
112
+ if let Some ( h ) = c . harts . as_ref ( ) {
137
113
debug ! ( "Rendering target-specific HART IDs" ) ;
138
- let harts = r. harts . iter ( ) . map ( |h| {
139
- let name = TokenStream :: from_str ( & h. name ) . unwrap ( ) ;
140
- let value = TokenStream :: from_str ( & format ! ( "{}" , h. value) ) . unwrap ( ) ;
141
- let description = format ! (
142
- "{} - {}" ,
143
- h. value,
144
- h. description
145
- . as_ref( )
146
- . map( |s| util:: respace( s) )
147
- . as_ref( )
148
- . map( |s| util:: escape_special_chars( s) )
149
- . unwrap_or_else( || h. name. clone( ) )
150
- ) ;
114
+ let harts = h. iter ( ) . map ( |hart| {
115
+ let name = TokenStream :: from_str ( & hart. name ) . unwrap ( ) ;
116
+ let value = TokenStream :: from_str ( & format ! ( "{}" , hart. value) ) . unwrap ( ) ;
117
+ let description = hart. description ( ) ;
151
118
152
119
quote ! {
153
120
#[ doc = #description]
@@ -238,80 +205,72 @@ pub fn render(
238
205
}
239
206
240
207
let mut riscv_peripherals = TokenStream :: new ( ) ;
241
- if config. use_riscv_peripheral {
242
- let harts = match r {
243
- Some ( r) => r
244
- . harts
208
+ if let Some ( c) = & config. riscv_config {
209
+ let harts = match & c. harts {
210
+ Some ( harts) => harts
245
211
. iter ( )
246
- . map ( |h| {
247
- let name = TokenStream :: from_str ( & h. name ) . unwrap ( ) ;
248
- let value = h. value ;
249
- ( name, value)
250
- } )
212
+ . map ( |h| ( TokenStream :: from_str ( & h. name ) . unwrap ( ) , h. value ) )
251
213
. collect :: < Vec < _ > > ( ) ,
252
214
None => vec ! [ ] ,
253
215
} ;
254
- for p in peripherals. iter ( ) {
255
- match p. name . to_uppercase ( ) . as_ref ( ) {
256
- "PLIC" => {
257
- let base =
258
- TokenStream :: from_str ( & format ! ( "base 0x{:X}," , p. base_address) ) . unwrap ( ) ;
259
- let ctxs = harts
260
- . iter ( )
261
- . map ( |( name, value) | {
262
- let ctx_name = TokenStream :: from_str ( & format ! ( "ctx{value}" ) ) . unwrap ( ) ;
263
- let doc = format ! ( "[{value}](crate::interrupt::Hart::{name})" ) ;
264
- quote ! { #ctx_name = ( crate :: interrupt:: Hart :: #name, #doc) }
265
- } )
266
- . collect :: < Vec < _ > > ( ) ;
267
- let ctxs = match ctxs. len ( ) {
268
- 0 => quote ! { } ,
269
- _ => quote ! { ctxs [ #( #ctxs) , * ] , } ,
270
- } ;
216
+ if let Some ( clint) = & c. clint {
217
+ let p = peripherals. iter ( ) . find ( |& p| p. name == clint. name ) . unwrap ( ) ;
218
+ let base = TokenStream :: from_str ( & format ! ( "base 0x{:X}," , p. base_address) ) . unwrap ( ) ;
219
+ let freq = match clint. freq {
220
+ Some ( clk) => match clint. async_delay {
221
+ true => TokenStream :: from_str ( & format ! ( "freq {clk}, async_delay," ) ) . unwrap ( ) ,
222
+ false => TokenStream :: from_str ( & format ! ( "freq {clk}," ) ) . unwrap ( ) ,
223
+ } ,
224
+ None => quote ! { } ,
225
+ } ;
226
+ let mtimecmps = harts
227
+ . iter ( )
228
+ . map ( |( name, value) | {
229
+ let mtimecmp_name = TokenStream :: from_str ( & format ! ( "mtimecmp{value}" ) ) . unwrap ( ) ;
230
+ let doc = format ! ( "[{value}](crate::interrupt::Hart::{name})" ) ;
231
+ quote ! { #mtimecmp_name = ( crate :: interrupt:: Hart :: #name, #doc) }
232
+ } )
233
+ . collect :: < Vec < _ > > ( ) ;
234
+ let mtimecmps = match mtimecmps. len ( ) {
235
+ 0 => quote ! { } ,
236
+ _ => quote ! { mtimecmps [ #( #mtimecmps) , * ] , } ,
237
+ } ;
238
+ let msips = harts
239
+ . iter ( )
240
+ . map ( |( name, value) | {
241
+ let msip_name = TokenStream :: from_str ( & format ! ( "msip{value}" ) ) . unwrap ( ) ;
242
+ let doc = format ! ( "[{value}](crate::interrupt::Hart::{name})" ) ;
243
+ quote ! { #msip_name = ( crate :: interrupt:: Hart :: #name, #doc) }
244
+ } )
245
+ . collect :: < Vec < _ > > ( ) ;
246
+ let msips = match msips. len ( ) {
247
+ 0 => quote ! { } ,
248
+ _ => quote ! { msips [ #( #msips) , * ] , } ,
249
+ } ;
271
250
272
- riscv_peripherals. extend ( quote ! {
273
- riscv_peripheral:: plic_codegen!( #base #ctxs) ;
274
- } ) ;
275
- }
276
- "CLINT" => {
277
- let base =
278
- TokenStream :: from_str ( & format ! ( "base 0x{:X}," , p. base_address) ) . unwrap ( ) ;
279
- let freq = match config. riscv_clint_freq {
280
- Some ( clk) => TokenStream :: from_str ( & format ! ( "freq {clk}," ) ) . unwrap ( ) ,
281
- None => quote ! { } ,
282
- } ;
283
- let mtimecmps = harts
284
- . iter ( )
285
- . map ( |( name, value) | {
286
- let mtimecmp_name =
287
- TokenStream :: from_str ( & format ! ( "mtimecmp{value}" ) ) . unwrap ( ) ;
288
- let doc = format ! ( "[{value}](crate::interrupt::Hart::{name})" ) ;
289
- quote ! { #mtimecmp_name = ( crate :: interrupt:: Hart :: #name, #doc) }
290
- } )
291
- . collect :: < Vec < _ > > ( ) ;
292
- let mtimecmps = match mtimecmps. len ( ) {
293
- 0 => quote ! { } ,
294
- _ => quote ! { mtimecmps [ #( #mtimecmps) , * ] , } ,
295
- } ;
296
- let msips = harts
297
- . iter ( )
298
- . map ( |( name, value) | {
299
- let msip_name = TokenStream :: from_str ( & format ! ( "msip{value}" ) ) . unwrap ( ) ;
300
- let doc = format ! ( "[{value}](crate::interrupt::Hart::{name})" ) ;
301
- quote ! { #msip_name = ( crate :: interrupt:: Hart :: #name, #doc) }
302
- } )
303
- . collect :: < Vec < _ > > ( ) ;
304
- let msips = match msips. len ( ) {
305
- 0 => quote ! { } ,
306
- _ => quote ! { msips [ #( #msips) , * ] , } ,
307
- } ;
251
+ riscv_peripherals. extend ( quote ! {
252
+ riscv_peripheral:: clint_codegen!( #base #freq #mtimecmps #msips) ;
253
+ } ) ;
254
+ }
255
+ if let Some ( plic) = & c. plic {
256
+ let p = peripherals. iter ( ) . find ( |& p| & p. name == plic) . unwrap ( ) ;
257
+ let base = TokenStream :: from_str ( & format ! ( "base 0x{:X}," , p. base_address) ) . unwrap ( ) ;
258
+ let ctxs = harts
259
+ . iter ( )
260
+ . map ( |( name, value) | {
261
+ let ctx_name = TokenStream :: from_str ( & format ! ( "ctx{value}" ) ) . unwrap ( ) ;
262
+ let doc = format ! ( "[{value}](crate::interrupt::Hart::{name})" ) ;
263
+ quote ! { #ctx_name = ( crate :: interrupt:: Hart :: #name, #doc) }
264
+ } )
265
+ . collect :: < Vec < _ > > ( ) ;
266
+ let ctxs = match ctxs. len ( ) {
267
+ 0 => quote ! { } ,
268
+ _ => quote ! { ctxs [ #( #ctxs) , * ] , } ,
269
+ } ;
308
270
309
- riscv_peripherals. extend ( quote ! {
310
- riscv_peripheral:: clint_codegen!( #base #freq #mtimecmps #msips) ;
311
- } ) ;
312
- }
313
- _ => { }
314
- }
271
+ riscv_peripherals. extend ( quote ! {
272
+ riscv_peripheral:: plic_codegen!( #base #ctxs) ;
273
+ } ) ;
315
274
}
316
275
}
317
276
0 commit comments