mirror of
https://github.com/saymrwulf/xous-core.git
synced 2026-11-15 08:30:02 +00:00
wip for susres extensions
This commit is contained in:
parent
f86f295fa5
commit
836c836aec
1 changed files with 110 additions and 2 deletions
|
|
@ -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) = ®ister.description {
|
||||
|
|
|
|||
Loading…
Reference in a new issue