mirror of
https://github.com/saymrwulf/xous-core.git
synced 2026-11-08 04:56:43 +00:00
push of spinor changes to validate l2cache
This commit is contained in:
parent
79ce51c32c
commit
1b5d4bd79b
9 changed files with 259 additions and 11 deletions
8
Cargo.lock
generated
8
Cargo.lock
generated
|
|
@ -1237,18 +1237,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ptr_meta"
|
||||
version = "0.1.1"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aad980f4bb4053abd4733b1680024a8c71ffde345f6e584c6af9eb6f0067a198"
|
||||
checksum = "7424255320182a46c403331afed6f95e0259a7c578f9da54a27e262ef3b60118"
|
||||
dependencies = [
|
||||
"ptr_meta_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ptr_meta_derive"
|
||||
version = "0.1.1"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7bcd6232fa7d7fcd15703da5c07c9f10d203ee4fdf6ecf6d7ac5056db78089a3"
|
||||
checksum = "53005b9863728f508d3f23ae37e03d60986a01b65f7ae8397dcebaa1d5e54e10"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.8",
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ default-members = [
|
|||
"services/engine-25519",
|
||||
"services/aes",
|
||||
"services/test-stub",
|
||||
#"services/spinor",
|
||||
]
|
||||
members = [
|
||||
"xous-ipc",
|
||||
|
|
@ -69,6 +70,7 @@ members = [
|
|||
"services/engine-25519",
|
||||
"services/aes",
|
||||
"services/test-stub",
|
||||
#"services/spinor",
|
||||
]
|
||||
resolver = "2"
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<device schemaVersion="1.1" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="CMSIS-SVD.xsd" >
|
||||
<vendor>litex</vendor>
|
||||
<name>SOC</name>
|
||||
<description><![CDATA[Litex SoC 2021-07-03 18:21:53]]></description>
|
||||
<description><![CDATA[Litex SoC 2021-07-04 02:16:46]]></description>
|
||||
|
||||
<addressUnitBits>8</addressUnitBits>
|
||||
<width>32</width>
|
||||
|
|
@ -1222,10 +1222,10 @@ register to disable individual events.]]></description>
|
|||
<register>
|
||||
<name>GIT_GITREV</name>
|
||||
<description><![CDATA[First 32-bits of the git revision. This documentation was built from git rev
|
||||
``977355ba``, so this value is 2540918202, which should be enough to check out
|
||||
``27ddfe4b``, so this value is 668859979, which should be enough to check out
|
||||
the exact git version used to build this firmware.]]></description>
|
||||
<addressOffset>0x0014</addressOffset>
|
||||
<resetValue>0x977355ba</resetValue>
|
||||
<resetValue>0x27ddfe4b</resetValue>
|
||||
<size>32</size>
|
||||
<fields>
|
||||
<field>
|
||||
|
|
@ -1242,7 +1242,7 @@ the exact git version used to build this firmware.]]></description>
|
|||
is ``1``, then the repository this was built from has one additional commit
|
||||
beyond the tag indicated in `MAJOR`, `MINOR`, and `REVISION`.]]></description>
|
||||
<addressOffset>0x0018</addressOffset>
|
||||
<resetValue>0x26</resetValue>
|
||||
<resetValue>0x28</resetValue>
|
||||
<size>32</size>
|
||||
<fields>
|
||||
<field>
|
||||
|
|
@ -3467,7 +3467,7 @@ inject too fast.]]></description>
|
|||
<name>SEED1</name>
|
||||
<description><![CDATA[Bits 32-63 of `SEED_SEED`. Seed used for the build]]></description>
|
||||
<addressOffset>0x0000</addressOffset>
|
||||
<resetValue>0x698bb704</resetValue>
|
||||
<resetValue>0x6a034505</resetValue>
|
||||
<size>32</size>
|
||||
<fields>
|
||||
<field>
|
||||
|
|
@ -3482,7 +3482,7 @@ inject too fast.]]></description>
|
|||
<name>SEED0</name>
|
||||
<description><![CDATA[Bits 0-31 of `SEED_SEED`.]]></description>
|
||||
<addressOffset>0x0004</addressOffset>
|
||||
<resetValue>0x5d2ea7df</resetValue>
|
||||
<resetValue>0x6ebb0afe</resetValue>
|
||||
<size>32</size>
|
||||
<fields>
|
||||
<field>
|
||||
|
|
@ -3535,10 +3535,40 @@ inject too fast.]]></description>
|
|||
</field>
|
||||
</fields>
|
||||
</register>
|
||||
<register>
|
||||
<name>LOCKADDR</name>
|
||||
<description><![CDATA[address of the word to lock. Address locked on write, and cannot be undone.]]></description>
|
||||
<addressOffset>0x0008</addressOffset>
|
||||
<resetValue>0x00</resetValue>
|
||||
<size>32</size>
|
||||
<fields>
|
||||
<field>
|
||||
<name>lockaddr</name>
|
||||
<msb>7</msb>
|
||||
<bitRange>[7:0]</bitRange>
|
||||
<lsb>0</lsb>
|
||||
</field>
|
||||
</fields>
|
||||
</register>
|
||||
<register>
|
||||
<name>LOCKSTAT</name>
|
||||
<description><![CDATA[If set, the requested address word is locked and will always return 0.]]></description>
|
||||
<addressOffset>0x000c</addressOffset>
|
||||
<resetValue>0x00</resetValue>
|
||||
<size>32</size>
|
||||
<fields>
|
||||
<field>
|
||||
<name>lockstat</name>
|
||||
<msb>0</msb>
|
||||
<bitRange>[0:0]</bitRange>
|
||||
<lsb>0</lsb>
|
||||
</field>
|
||||
</fields>
|
||||
</register>
|
||||
</registers>
|
||||
<addressBlock>
|
||||
<offset>0</offset>
|
||||
<size>0x8</size>
|
||||
<size>0x10</size>
|
||||
<usage>registers</usage>
|
||||
</addressBlock>
|
||||
</peripheral>
|
||||
|
|
|
|||
Binary file not shown.
23
services/spinor/Cargo.toml
Normal file
23
services/spinor/Cargo.toml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
[package]
|
||||
name = "spinor"
|
||||
version = "0.1.0"
|
||||
authors = ["bunnie <bunnie@kosagi.com>"]
|
||||
edition = "2018"
|
||||
description = "SPINOR ROM operations server"
|
||||
|
||||
[dependencies]
|
||||
xous = { path = "../../xous-rs" }
|
||||
log-server = { path = "../log-server" }
|
||||
ticktimer-server = { path = "../ticktimer-server" }
|
||||
xous-names = { path = "../xous-names" }
|
||||
log = "0.4"
|
||||
num-derive = {version = "0.3", default-features = false}
|
||||
num-traits = {version = "0.2", default-features = false}
|
||||
susres = {path = "../susres"}
|
||||
rkyv = {version = "0.6.7", default-features = false, features = ["const_generics"]}
|
||||
|
||||
[target.'cfg(not(any(windows,unix)))'.dependencies]
|
||||
utralib = { path = "../../utralib"}
|
||||
|
||||
[features]
|
||||
default = []
|
||||
32
services/spinor/src/api.rs
Normal file
32
services/spinor/src/api.rs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
pub(crate) const SERVER_NAME_SPINOR: &str = "_SPINOR Hardware Interface Server_";
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(num_derive::FromPrimitive, num_derive::ToPrimitive, Debug)]
|
||||
pub(crate) enum Opcode {
|
||||
/// erase a region
|
||||
EraseRegion,
|
||||
|
||||
/// program a region
|
||||
WriteRegion,
|
||||
|
||||
/// Suspend/resume callback
|
||||
SuspendResume,
|
||||
}
|
||||
|
||||
#[derive(Debug, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize, Clone, Copy)]
|
||||
pub struct EraseRegion {
|
||||
/// start location for the erase
|
||||
pub start: u32,
|
||||
/// length of the region to erase
|
||||
pub len: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize, Clone, Copy)]
|
||||
pub struct WriteRegion<const N: usize> { // wait...can we do const generics with rkyv??
|
||||
/// start location for the write
|
||||
pub start: u32,
|
||||
/// if true, erase the region to write if not already erased; otherwise, if not erased, the routine will error out
|
||||
pub autoerase: bool,
|
||||
/// data to write
|
||||
pub sector: [u8; N],
|
||||
}
|
||||
33
services/spinor/src/lib.rs
Normal file
33
services/spinor/src/lib.rs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#![cfg_attr(target_os = "none", no_std)]
|
||||
|
||||
pub mod api;
|
||||
use xous::{CID, send_message};
|
||||
use num_traits::ToPrimitive;
|
||||
|
||||
pub struct Spinor {
|
||||
conn: CID,
|
||||
}
|
||||
impl Spinor {
|
||||
pub fn new(xns: &xous_names::XousNames) -> Result<Self, xous::Error> {
|
||||
REFCOUNT.store(REFCOUNT.load(Ordering::Relaxed) + 1, Ordering::Relaxed);
|
||||
let conn = xns.request_connection_blocking(api::SERVER_NAME_SPINOR).expect("Can't connect to Spinor server");
|
||||
Ok(Spinor {
|
||||
conn
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
use core::sync::atomic::{AtomicU32, Ordering};
|
||||
static REFCOUNT: AtomicU32 = AtomicU32::new(0);
|
||||
impl Drop for Spinor {
|
||||
fn drop(&mut self) {
|
||||
// the connection to the server side must be reference counted, so that multiple instances of this object within
|
||||
// a single process do not end up de-allocating the CID on other threads before they go out of scope.
|
||||
// Note to future me: you want this. Don't get rid of it because you think, "nah, nobody will ever make more than one copy of this object".
|
||||
if REFCOUNT.load(Ordering::Relaxed) == 0 {
|
||||
unsafe{xous::disconnect(self.conn).unwrap();}
|
||||
}
|
||||
// if there was object-specific state (such as a one-time use server for async callbacks, specific to the object instance),
|
||||
// de-allocate those items here. They don't need a reference count because they are object-specific
|
||||
}
|
||||
}
|
||||
127
services/spinor/src/main.rs
Normal file
127
services/spinor/src/main.rs
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
#![cfg_attr(target_os = "none", no_std)]
|
||||
#![cfg_attr(target_os = "none", no_main)]
|
||||
|
||||
mod api;
|
||||
|
||||
use num_traits::FromPrimitive;
|
||||
|
||||
use log::info;
|
||||
|
||||
|
||||
#[cfg(target_os = "none")]
|
||||
mod implementation {
|
||||
use utralib::generated::*;
|
||||
// use crate::api::*;
|
||||
use log::info;
|
||||
use susres::{RegManager, RegOrField, SuspendResume};
|
||||
|
||||
pub struct Spinor {
|
||||
csr: utralib::CSR<u32>,
|
||||
fifo: xous::MemoryRange,
|
||||
susres_manager: RegManager::<{utra::audio::AUDIO_NUMREGS}>,
|
||||
}
|
||||
|
||||
impl Spinor {
|
||||
pub fn new() -> Spinor {
|
||||
let csr = xous::syscall::map_memory(
|
||||
xous::MemoryAddress::new(utra::audio::HW_AUDIO_BASE),
|
||||
None,
|
||||
4096,
|
||||
xous::MemoryFlags::R | xous::MemoryFlags::W,
|
||||
)
|
||||
.expect("couldn't map Audio CSR range");
|
||||
let fifo = xous::syscall::map_memory(
|
||||
xous::MemoryAddress::new(utralib::HW_AUDIO_MEM),
|
||||
None,
|
||||
utralib::HW_AUDIO_MEM_LEN,
|
||||
xous::MemoryFlags::R | xous::MemoryFlags::W,
|
||||
)
|
||||
.expect("couldn't map Audio CSR range");
|
||||
|
||||
let mut spinor = Spinor {
|
||||
csr: CSR::new(csr.as_mut_ptr() as *mut u32),
|
||||
susres_manager: RegManager::new(csr.as_mut_ptr() as *mut u32),
|
||||
fifo,
|
||||
};
|
||||
|
||||
spinor
|
||||
}
|
||||
|
||||
pub fn suspend(&mut self) {
|
||||
self.susres_manager.suspend();
|
||||
}
|
||||
pub fn resume(&mut self) {
|
||||
self.susres_manager.resume();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// a stub to try to avoid breaking hosted mode for as long as possible.
|
||||
#[cfg(not(target_os = "none"))]
|
||||
mod implementation {
|
||||
use log::info;
|
||||
|
||||
pub struct Spinor {
|
||||
}
|
||||
|
||||
impl Spinor {
|
||||
pub fn new() -> Spinor {
|
||||
Spinor {
|
||||
}
|
||||
}
|
||||
pub fn suspend(&self) {
|
||||
}
|
||||
pub fn resume(&self) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[xous::xous_main]
|
||||
fn xmain() -> ! {
|
||||
use crate::implementation::Spinor;
|
||||
|
||||
log_server::init_wait().unwrap();
|
||||
log::set_max_level(log::LevelFilter::Info);
|
||||
info!("my PID is {}", xous::process::id());
|
||||
|
||||
let xns = xous_names::XousNames::new().unwrap();
|
||||
/*
|
||||
Very important to track who has access to the SPINOR server, and limit access. Access to this server is essential for persistent rootkits.
|
||||
Here is the list of servers allowed to access, and why:
|
||||
- shellchat (for testing ONLY, remove once done)
|
||||
- PDDB (not yet written)
|
||||
- keystore (not yet written)
|
||||
*/
|
||||
let spinor_sid = xns.register_name(api::SERVER_NAME_SPINOR, Some(1)).expect("can't register server");
|
||||
log::trace!("registered with NS -- {:?}", spinor_sid);
|
||||
|
||||
let mut spinor = Spinor::new();
|
||||
|
||||
log::trace!("ready to accept requests");
|
||||
|
||||
// register a suspend/resume listener
|
||||
let sr_cid = xous::connect(spinor_sid).expect("couldn't create suspend callback connection");
|
||||
let mut susres = susres::Susres::new(&xns, api::Opcode::SuspendResume as u32, sr_cid).expect("couldn't create suspend/resume object");
|
||||
|
||||
loop {
|
||||
let msg = xous::receive_message(spinor_sid).unwrap();
|
||||
match FromPrimitive::from_usize(msg.body.id()) {
|
||||
Some(api::Opcode::SuspendResume) => xous::msg_scalar_unpack!(msg, token, _, _, _, {
|
||||
spinor.suspend();
|
||||
susres.suspend_until_resume(token).expect("couldn't execute suspend/resume");
|
||||
spinor.resume();
|
||||
}),
|
||||
None => {
|
||||
log::error!("couldn't convert opcode");
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
// clean up our program
|
||||
log::trace!("main loop exit, destroying servers");
|
||||
xns.unregister_server(spinor_sid).unwrap();
|
||||
xous::destroy_server(spinor_sid).unwrap();
|
||||
log::trace!("quitting");
|
||||
xous::terminate_process(0)
|
||||
}
|
||||
|
|
@ -55,6 +55,7 @@ fn try_main() -> Result<(), DynError> {
|
|||
"codec",
|
||||
"engine-sha512",
|
||||
"engine-25519",
|
||||
//"spinor",
|
||||
];
|
||||
let benchmark_pkgs = [
|
||||
"benchmark",
|
||||
|
|
|
|||
Loading…
Reference in a new issue