wip for susres extensions

This commit is contained in:
bunnie 2021-04-26 14:55:45 +08:00
parent f86f295fa5
commit 836c836aec

View file

@ -1,7 +1,7 @@
use quick_xml::events::Event;
use quick_xml::Reader;
use std::io::{BufRead, BufReader, Read, Write};
use convert_case::{Case, Casing};
#[derive(Debug)]
pub enum ParseError {
UnexpectedTag,
@ -477,6 +477,7 @@ fn parse_vendor_extensions<T: BufRead>(
fn print_header<U: Write>(out: &mut U) -> std::io::Result<()> {
let s = r####"
#![allow(dead_code)]
use core::convert::TryInto;
pub struct Register {
/// Offset of this register within this CSR
@ -549,6 +550,7 @@ impl Field {
}
}
}
#[derive(Debug, Copy, Clone)]
pub struct CSR<T> {
pub base: *mut T,
}
@ -676,10 +678,116 @@ fn print_peripherals<U: Write>(peripherals: &[Peripheral], out: &mut U) -> std::
}
writeln!(out)?;
writeln!(out, "pub mod utra {{")?;
let s = r####"
pub mod utra {
pub enum Error {
OutOfMemory,
}
#[derive(Debug, Copy, Clone)]
pub struct ManagedReg<T> {
pub offset: T,
pub mask: usize,
pub value: usize,
}
//#[derive(Debug)]
pub struct SusResRegManager<T, const N: usize> {
pub csr: crate::CSR<u32>,
pub registers: [Option<ManagedReg<T>>; N],
pub sus_prologue: Option<fn(&mut Self)>,
pub sus_epilogue: Option<fn(&mut Self)>,
pub res_prologue: Option<fn(&mut Self)>,
pub res_epilogue: Option<fn(&mut Self)>,
}
impl<T, const N: usize> SusResRegManager::<T, N> where ManagedReg<T>: core::marker::Copy {
pub fn new(reg_base: *mut u32) -> SusResRegManager<T, N> {
SusResRegManager::<T, N> {
csr: crate::CSR::new(reg_base),
registers: [None; N],
sus_prologue: None,
sus_epilogue: None,
res_prologue: None,
res_epilogue: None,
}
}
}
pub trait SusResReg<T> {
fn push(&mut self, mr: ManagedReg<T>) -> Result<(), Error>;
fn suspend(&mut self);
fn resume(&mut self);
}
impl<T, const N: usize> SusResReg<T> for SusResRegManager<T, N> where T: core::convert::Into<usize> + Copy {
// push registers into the manager in the order you want them suspended
fn push(&mut self, mr: ManagedReg<T>) -> Result<(), Error> {
for entry in self.registers.iter_mut() {
if entry.is_none() {
*entry = Some(mr);
return Ok(())
}
}
Err(Error::OutOfMemory)
}
fn suspend(&mut self) {
if let Some(sp) = self.sus_prologue {
sp(self);
}
for entry in self.registers.iter_mut() {
if let Some(reg) = entry {
// masking is done on the write side
reg.value = self.csr.r(crate::Register{offset: reg.offset.into()}) as usize;
}
}
if let Some(se) = self.sus_epilogue {
se(self);
}
}
fn resume(&mut self) {
if let Some(rp) = self.res_prologue {
rp(self);
}
for entry in self.registers.iter().rev() { // this is in reverse order to the suspend
if let Some(reg) = entry {
self.csr.wo(crate::Register{offset: reg.offset.into()}, (reg.value & reg.mask) as u32);
}
}
if let Some(re) = self.res_epilogue {
re(self);
}
}
}
/*
pub struct ManagedMem<const N: usize> {
pub mem: xous::MemoryRange,
pub backing: [u32; N],
}
pub trait SusResMem {
fn suspend(&mut self) {
let src = self.mem.as_ptr() as *const u32;
for words in 0..self.mem.len() {
self.backing[words] = unsafe{src.add(words).read_volatile()};
}
}
fn resume(&mut self) {
let dst = self.mem.as_ptr() as *mut u32;
for words in 0..self.mem.len() {
unsafe{dst.add(words).write_volatile(self.backing[words])};
}
}
}
*/
"####;
out.write_all(s.as_bytes())?;
for peripheral in peripherals {
writeln!(out)?;
writeln!(out, " pub mod {} {{", peripheral.name.to_lowercase())?;
writeln!(out, " #[derive(Debug, Copy, Clone)]")?;
writeln!(out, " pub enum {}Offset {{", peripheral.name.to_case(Case::UpperCamel))?;
for register in &peripheral.registers {
writeln!(out, " {} = {},", register.name.to_case(Case::UpperCamel), register.offset / 4)?;
}
writeln!(out, " }}")?;
writeln!(out, " pub const {}_NUMREGS: usize = {};", peripheral.name.to_uppercase(), peripheral.registers.len())?;
for register in &peripheral.registers {
writeln!(out)?;
if let Some(description) = &register.description {