1- use crate :: {
2- svd:: { Peripheral , Riscv } ,
3- util, Config ,
4- } ;
1+ use crate :: { svd:: Peripheral , util, Config } ;
52use anyhow:: Result ;
63use log:: debug;
74use proc_macro2:: TokenStream ;
85use quote:: quote;
96use std:: { collections:: HashMap , fmt:: Write , str:: FromStr } ;
107
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+ }
1317}
1418
1519/// Whole RISC-V generation
1620pub fn render (
17- r : Option < & Riscv > ,
1821 peripherals : & [ Peripheral ] ,
1922 device_x : & mut String ,
2023 config : & Config ,
2124) -> Result < TokenStream > {
2225 let mut mod_items = TokenStream :: new ( ) ;
2326
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 ( ) {
2629 debug ! ( "Rendering target-specific core interrupts" ) ;
2730 writeln ! ( device_x, "/* Core interrupt sources and trap handlers */" ) ?;
2831 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 ( ) ;
4236
4337 writeln ! ( device_x, "PROVIDE({name} = DefaultHandler);" ) ?;
4438 writeln ! (
@@ -64,23 +58,14 @@ pub fn render(
6458 mod_items. extend ( quote ! { pub use riscv:: interrupt:: Interrupt as CoreInterrupt ; } ) ;
6559 }
6660
67- if !r . exceptions . is_empty ( ) {
61+ if let Some ( e ) = c . exceptions . as_ref ( ) {
6862 debug ! ( "Rendering target-specific exceptions" ) ;
6963 writeln ! ( device_x, "/* Exception sources */" ) ?;
7064 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 ( ) ;
8469
8570 writeln ! ( device_x, "PROVIDE({name} = ExceptionHandler);" ) ?;
8671
@@ -102,21 +87,12 @@ pub fn render(
10287 mod_items. extend ( quote ! { pub use riscv:: interrupt:: Exception ; } ) ;
10388 }
10489
105- if !r . priorities . is_empty ( ) {
90+ if let Some ( p ) = c . priorities . as_ref ( ) {
10691 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 ( ) ;
12096
12197 quote ! {
12298 #[ doc = #description]
@@ -133,21 +109,12 @@ pub fn render(
133109 } ) ;
134110 }
135111
136- if !r . harts . is_empty ( ) {
112+ if let Some ( h ) = c . harts . as_ref ( ) {
137113 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 ( ) ;
151118
152119 quote ! {
153120 #[ doc = #description]
@@ -238,80 +205,72 @@ pub fn render(
238205 }
239206
240207 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
245211 . 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 ) )
251213 . collect :: < Vec < _ > > ( ) ,
252214 None => vec ! [ ] ,
253215 } ;
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+ } ;
271250
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+ } ;
308270
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+ } ) ;
315274 }
316275 }
317276
0 commit comments