metapac: allow runtime inspection of ir types

This commit is contained in:
xoviat 2023-09-29 18:21:03 -05:00
parent d63a20e69b
commit 23f9d9b236
3 changed files with 48 additions and 16 deletions

View File

@ -1,10 +1,12 @@
pub mod ir { pub mod ir {
#[derive(Debug, Eq, PartialEq, Clone)]
pub struct IR { pub struct IR {
pub blocks: &'static [Block], pub blocks: &'static [Block],
pub fieldsets: &'static [FieldSet], pub fieldsets: &'static [FieldSet],
pub enums: &'static [Enum], pub enums: &'static [Enum],
} }
#[derive(Debug, Eq, PartialEq, Clone)]
pub struct Block { pub struct Block {
pub name: &'static str, pub name: &'static str,
pub extends: Option<&'static str>, pub extends: Option<&'static str>,
@ -13,6 +15,7 @@ pub mod ir {
pub items: &'static [BlockItem], pub items: &'static [BlockItem],
} }
#[derive(Debug, Eq, PartialEq, Clone)]
pub struct BlockItem { pub struct BlockItem {
pub name: &'static str, pub name: &'static str,
pub description: Option<&'static str>, pub description: Option<&'static str>,
@ -23,27 +26,32 @@ pub mod ir {
pub inner: BlockItemInner, pub inner: BlockItemInner,
} }
#[derive(Debug, Eq, PartialEq, Clone)]
pub enum BlockItemInner { pub enum BlockItemInner {
Block(BlockItemBlock), Block(BlockItemBlock),
Register(Register), Register(Register),
} }
#[derive(Debug, Eq, PartialEq, Clone)]
pub struct Register { pub struct Register {
pub access: Access, pub access: Access,
pub bit_size: u32, pub bit_size: u32,
pub fieldset: Option<&'static str>, pub fieldset: Option<&'static str>,
} }
#[derive(Debug, Eq, PartialEq, Clone)]
pub struct BlockItemBlock { pub struct BlockItemBlock {
pub block: &'static str, pub block: &'static str,
} }
#[derive(Debug, Eq, PartialEq, Clone)]
pub enum Access { pub enum Access {
ReadWrite, ReadWrite,
Read, Read,
Write, Write,
} }
#[derive(Debug, Eq, PartialEq, Clone)]
pub struct FieldSet { pub struct FieldSet {
pub name: &'static str, pub name: &'static str,
pub extends: Option<&'static str>, pub extends: Option<&'static str>,
@ -53,6 +61,7 @@ pub mod ir {
pub fields: &'static [Field], pub fields: &'static [Field],
} }
#[derive(Debug, Eq, PartialEq, Clone)]
pub struct Field { pub struct Field {
pub name: &'static str, pub name: &'static str,
pub description: Option<&'static str>, pub description: Option<&'static str>,
@ -63,20 +72,24 @@ pub mod ir {
pub enumm: Option<&'static str>, pub enumm: Option<&'static str>,
} }
#[derive(Debug, Eq, PartialEq, Clone)]
pub enum Array { pub enum Array {
Regular(RegularArray), Regular(RegularArray),
Cursed(CursedArray), Cursed(CursedArray),
} }
#[derive(Debug, Eq, PartialEq, Clone)]
pub struct RegularArray { pub struct RegularArray {
pub len: u32, pub len: u32,
pub stride: u32, pub stride: u32,
} }
#[derive(Debug, Eq, PartialEq, Clone)]
pub struct CursedArray { pub struct CursedArray {
pub offsets: &'static [u32], pub offsets: &'static [u32],
} }
#[derive(Debug, Eq, PartialEq, Clone)]
pub struct Enum { pub struct Enum {
pub name: &'static str, pub name: &'static str,
pub description: Option<&'static str>, pub description: Option<&'static str>,
@ -84,6 +97,7 @@ pub mod ir {
pub variants: &'static [EnumVariant], pub variants: &'static [EnumVariant],
} }
#[derive(Debug, Eq, PartialEq, Clone)]
pub struct EnumVariant { pub struct EnumVariant {
pub name: &'static str, pub name: &'static str,
pub description: Option<&'static str>, pub description: Option<&'static str>,
@ -153,6 +167,7 @@ pub struct PeripheralRegisters {
pub kind: &'static str, pub kind: &'static str,
pub version: &'static str, pub version: &'static str,
pub block: &'static str, pub block: &'static str,
pub ir: &'static ir::IR,
} }
#[derive(Debug, Eq, PartialEq, Clone)] #[derive(Debug, Eq, PartialEq, Clone)]

View File

@ -22,7 +22,15 @@ pub mod ir {
.map(|item| BlockItem { .map(|item| BlockItem {
name: item.name.clone(), name: item.name.clone(),
description: item.description.clone(), description: item.description.clone(),
array: None, array: item.array.as_ref().map(|array| match &array {
chiptool::ir::Array::Regular(regular_array) => Array::Regular(RegularArray {
len: regular_array.len,
stride: regular_array.stride,
}),
chiptool::ir::Array::Cursed(cursed_array) => Array::Cursed(CursedArray {
offsets: cursed_array.offsets.clone(),
}),
}),
byte_offset: item.byte_offset, byte_offset: item.byte_offset,
inner: match &item.inner { inner: match &item.inner {
chiptool::ir::BlockItemInner::Block(block) => BlockItemInner::Block(BlockItemBlock { chiptool::ir::BlockItemInner::Block(block) => BlockItemInner::Block(BlockItemBlock {
@ -346,4 +354,6 @@ pub struct PeripheralRegisters {
pub kind: String, pub kind: String,
pub version: String, pub version: String,
pub block: String, pub block: String,
#[serde(default)]
pub ir: String,
} }

View File

@ -186,9 +186,9 @@ impl Gen {
write!( write!(
&mut data, &mut data,
" "
const PERIPHERALS: &'static [Peripheral] = {}; pub(crate) static PERIPHERALS: &'static [Peripheral] = {};
const INTERRUPTS: &'static [Interrupt] = {}; pub(crate) static INTERRUPTS: &'static [Interrupt] = {};
const DMA_CHANNELS: &'static [DmaChannel] = {}; pub(crate) static DMA_CHANNELS: &'static [DmaChannel] = {};
", ",
stringify(&core.peripherals), stringify(&core.peripherals),
stringify(&core.interrupts), stringify(&core.interrupts),
@ -199,6 +199,18 @@ impl Gen {
let out_dir = self.opts.out_dir.clone(); let out_dir = self.opts.out_dir.clone();
let n = self.metadata_dedup.len(); let n = self.metadata_dedup.len();
let deduped_file = self.metadata_dedup.entry(data.clone()).or_insert_with(|| { let deduped_file = self.metadata_dedup.entry(data.clone()).or_insert_with(|| {
let ir_regex = Regex::new("\":ir_for:([a-z0-9]+):\"").unwrap();
let mut data = ir_regex.replace_all(&data, "&$1::REGISTERS").to_string();
for (module, version) in &peripheral_versions {
writeln!(
&mut data,
"#[path=\"../registers/{}_{}.rs\"] pub mod {};",
module, version, module
)
.unwrap();
}
let file = format!("metadata_{:04}.rs", n); let file = format!("metadata_{:04}.rs", n);
let path = out_dir.join("src/chips").join(&file); let path = out_dir.join("src/chips").join(&file);
fs::write(path, data).unwrap(); fs::write(path, data).unwrap();
@ -206,9 +218,9 @@ impl Gen {
file file
}); });
let mut data = format!( let data = format!(
"include!(\"../{}\"); "include!(\"../{}\");
pub const METADATA: Metadata = Metadata {{ pub static METADATA: Metadata = Metadata {{
name: {:?}, name: {:?},
family: {:?}, family: {:?},
line: {:?}, line: {:?},
@ -226,15 +238,6 @@ impl Gen {
&core.nvic_priority_bits, &core.nvic_priority_bits,
); );
for (module, version) in &peripheral_versions {
writeln!(
&mut data,
"#[path=\"../../registers/{}_{}.rs\"] pub mod {};",
module, version, module
)
.unwrap();
}
let mut file = File::create(chip_dir.join("metadata.rs")).unwrap(); let mut file = File::create(chip_dir.join("metadata.rs")).unwrap();
file.write_all(data.as_bytes()).unwrap(); file.write_all(data.as_bytes()).unwrap();
@ -278,6 +281,10 @@ impl Gen {
for irq in &mut p.interrupts { for irq in &mut p.interrupts {
irq.interrupt = irq.interrupt.to_ascii_uppercase(); irq.interrupt = irq.interrupt.to_ascii_uppercase();
} }
if let Some(registers) = &mut p.registers {
registers.ir = format!(":ir_for:{}:", registers.kind);
}
} }
} }
@ -336,7 +343,7 @@ impl Gen {
&mut data, &mut data,
" "
use crate::metadata::ir::*; use crate::metadata::ir::*;
static REGISTERS: IR = {}; pub(crate) static REGISTERS: IR = {};
", ",
stringify(&ir) stringify(&ir)
.replace("Register(", "BlockItemInner::Register(") .replace("Register(", "BlockItemInner::Register(")