@ -1,4 +1,5 @@
|
||||
use super::{LendResult, ScalarResult, Service};
|
||||
use crate::xous::Memory;
|
||||
use std::io::Write;
|
||||
|
||||
enum LogLendOpcode {
|
||||
@ -9,11 +10,54 @@ enum LogLendOpcode {
|
||||
StandardError = 2,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
enum LogSendOpcode {
|
||||
/// A panic occurred, and a panic log is forthcoming
|
||||
PanicStarted = 1000,
|
||||
|
||||
/// Log messages of varying size
|
||||
PanicMessage0 = 1100,
|
||||
PanicMessage1 = 1101,
|
||||
PanicMessage2 = 1102,
|
||||
PanicMessage3 = 1103,
|
||||
PanicMessage4 = 1104,
|
||||
PanicMessage5 = 1105,
|
||||
PanicMessage6 = 1106,
|
||||
PanicMessage7 = 1107,
|
||||
PanicMessage8 = 1108,
|
||||
PanicMessage9 = 1109,
|
||||
PanicMessage10 = 1110,
|
||||
PanicMessage11 = 1111,
|
||||
PanicMessage12 = 1112,
|
||||
PanicMessage13 = 1113,
|
||||
PanicMessage14 = 1114,
|
||||
PanicMessage15 = 1115,
|
||||
PanicMessage16 = 1116,
|
||||
PanicMessage17 = 1117,
|
||||
PanicMessage18 = 1118,
|
||||
PanicMessage19 = 1119,
|
||||
PanicMessage20 = 1120,
|
||||
PanicMessage21 = 1121,
|
||||
PanicMessage22 = 1122,
|
||||
PanicMessage23 = 1123,
|
||||
PanicMessage24 = 1124,
|
||||
PanicMessage25 = 1125,
|
||||
PanicMessage26 = 1126,
|
||||
PanicMessage27 = 1127,
|
||||
PanicMessage28 = 1128,
|
||||
PanicMessage29 = 1129,
|
||||
PanicMessage30 = 1130,
|
||||
PanicMessage31 = 1131,
|
||||
PanicMessage32 = 1132,
|
||||
|
||||
/// End of a panic
|
||||
PanicFinished = 1200,
|
||||
}
|
||||
|
||||
pub struct Log {}
|
||||
|
||||
impl Log {
|
||||
pub fn new() -> Self {
|
||||
// println!("Constructing a log server");
|
||||
Log {}
|
||||
}
|
||||
}
|
||||
@ -25,16 +69,64 @@ impl Default for Log {
|
||||
}
|
||||
|
||||
impl Service for Log {
|
||||
fn scalar(&mut self, sender: u32, opcode: u32, args: [u32; 4]) {
|
||||
println!("Log scalar {}: {} {:x?}", sender, opcode, args);
|
||||
fn scalar(&mut self, _memory: &mut Memory, sender: u32, opcode: u32, args: [u32; 4]) {
|
||||
let message_bytes = if opcode >= LogSendOpcode::PanicMessage0 as u32
|
||||
&& opcode <= LogSendOpcode::PanicMessage32 as u32
|
||||
{
|
||||
Some(opcode - LogSendOpcode::PanicMessage0 as u32)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if LogSendOpcode::PanicStarted as u32 == opcode {
|
||||
println!("Panic started");
|
||||
} else if LogSendOpcode::PanicFinished as u32 == opcode {
|
||||
println!();
|
||||
println!("Panic finished");
|
||||
} else if let Some(message_bytes) = message_bytes {
|
||||
let mut output_bfr = [0u8; core::mem::size_of::<u32>() * 4 /*args.len()*/];
|
||||
// let mut output_iter = output_bfr.iter_mut();
|
||||
|
||||
// Combine the four arguments to form a single
|
||||
// contiguous buffer. Note: The buffer size will change
|
||||
// depending on the platfor's `usize` length.
|
||||
for (src, dest) in args.iter().zip(output_bfr.chunks_mut(4)) {
|
||||
dest.copy_from_slice(src.to_le_bytes().as_ref());
|
||||
// for src in word.to_le_bytes().iter() {
|
||||
// *(output_iter.next().unwrap()) = *src;
|
||||
// }
|
||||
}
|
||||
print!(
|
||||
"{}",
|
||||
std::str::from_utf8(&output_bfr[0..message_bytes as usize]).unwrap_or("<invalid>")
|
||||
);
|
||||
} else {
|
||||
println!("Log scalar {}: {} {:x?}", sender, opcode, args);
|
||||
}
|
||||
}
|
||||
|
||||
fn blocking_scalar(&mut self, sender: u32, opcode: u32, args: [u32; 4]) -> ScalarResult {
|
||||
println!("Log blocking_scalar {}: {} {:x?}", sender, opcode, args);
|
||||
fn blocking_scalar(
|
||||
&mut self,
|
||||
_memory: &mut Memory,
|
||||
sender: u32,
|
||||
opcode: u32,
|
||||
args: [u32; 4],
|
||||
) -> ScalarResult {
|
||||
println!(
|
||||
"Unhandled log blocking_scalar {}: {} {:x?}",
|
||||
sender, opcode, args
|
||||
);
|
||||
ScalarResult::Scalar1(0)
|
||||
}
|
||||
|
||||
fn lend(&mut self, sender: u32, opcode: u32, buf: &[u8], extra: [u32; 2]) -> LendResult {
|
||||
fn lend(
|
||||
&mut self,
|
||||
_memory: &mut Memory,
|
||||
sender: u32,
|
||||
opcode: u32,
|
||||
buf: &[u8],
|
||||
extra: [u32; 2],
|
||||
) -> LendResult {
|
||||
if opcode == LogLendOpcode::StandardOutput as u32 {
|
||||
let print_buffer = &buf[0..extra[1] as usize];
|
||||
// println!("Log stdout:");
|
||||
@ -46,23 +138,31 @@ impl Service for Log {
|
||||
std::io::stderr().write_all(print_buffer).unwrap();
|
||||
std::io::stderr().flush().unwrap();
|
||||
} else {
|
||||
panic!("Log lend {}: {} {:x?}", sender, opcode, buf);
|
||||
panic!("Unhandled log lend {}: {} {:x?}", sender, opcode, buf);
|
||||
}
|
||||
LendResult::MemoryReturned([0, 0])
|
||||
}
|
||||
|
||||
fn lend_mut(
|
||||
&mut self,
|
||||
_memory: &mut Memory,
|
||||
sender: u32,
|
||||
opcode: u32,
|
||||
_buf: &mut [u8],
|
||||
extra: [u32; 2],
|
||||
) -> LendResult {
|
||||
println!("Log lend_mut {}: {} {:x?}", sender, opcode, extra);
|
||||
println!("Unhandled log lend_mut {}: {} {:x?}", sender, opcode, extra);
|
||||
LendResult::MemoryReturned([0, 0])
|
||||
}
|
||||
|
||||
fn send(&mut self, sender: u32, opcode: u32, _buf: &[u8], extra: [u32; 2]) {
|
||||
println!("Log send {}: {} {:x?}", sender, opcode, extra);
|
||||
fn send(
|
||||
&mut self,
|
||||
_memory: &mut Memory,
|
||||
sender: u32,
|
||||
opcode: u32,
|
||||
_buf: &[u8],
|
||||
extra: [u32; 2],
|
||||
) {
|
||||
println!("Unhandled log send {}: {} {:x?}", sender, opcode, extra);
|
||||
}
|
||||
}
|
||||
|
179
src/xous/services/name.rs
Normal file
179
src/xous/services/name.rs
Normal file
@ -0,0 +1,179 @@
|
||||
use crate::xous::Memory;
|
||||
|
||||
use super::{LendResult, ScalarResult, Service};
|
||||
|
||||
#[allow(dead_code)]
|
||||
enum NameLendOpcode {
|
||||
/// Create a new server with the given name and return its SID.
|
||||
Register = 0,
|
||||
|
||||
/// Create a connection to the target server.
|
||||
Lookup = 1,
|
||||
|
||||
/// Create an authenticated connection to the target server.
|
||||
AuthenticatedLookup = 2,
|
||||
|
||||
/// unregister a server, given its cryptographically unique SID.
|
||||
Unregister = 3,
|
||||
|
||||
/// disconnect, given a server name and a cryptographically unique, one-time use token
|
||||
Disconnect = 4,
|
||||
|
||||
/// indicates if all inherently trusted slots have been occupied. Should not run untrusted code until this is the case.
|
||||
TrustedInitDone = 5,
|
||||
|
||||
/// Connect to a Server, blocking if the Server does not exist. When the Server is started,
|
||||
/// return with either the CID or an AuthenticationRequest
|
||||
///
|
||||
/// # Message Types
|
||||
///
|
||||
/// * MutableLend
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// The memory being pointed to should be a &str, and the length of the string should
|
||||
/// be specified in the `valid` field.
|
||||
///
|
||||
/// # Return Values
|
||||
///
|
||||
/// Memory is overwritten to contain a return value. This return value can be defined
|
||||
/// as the following enum:
|
||||
///
|
||||
/// ```rust
|
||||
/// #[repr(C)]
|
||||
/// #[non_exhaustive]
|
||||
/// enum ConnectResult {
|
||||
/// Success(xous::CID /* connection ID */, [u32; 4] /* Disconnection token */),
|
||||
/// Error(u32 /* error code */),
|
||||
/// Unhandled, /* Catchall for future Results */
|
||||
/// }
|
||||
/// ```
|
||||
BlockingConnect = 6,
|
||||
|
||||
/// Connect to a Server, returning the connection ID or an authentication request if
|
||||
/// it exists, and returning ServerNotFound if it does not exist.
|
||||
///
|
||||
/// # Message Types
|
||||
///
|
||||
/// * MutableLend
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// The memory being pointed to should be a &str, and the length of the string should
|
||||
/// be specified in the `valid` field.
|
||||
///
|
||||
/// # Return Values
|
||||
///
|
||||
/// Memory is overwritten to contain a return value. This return value can be defined
|
||||
/// as the following enum:
|
||||
///
|
||||
/// ```rust
|
||||
/// #[repr(C)]
|
||||
/// #[non_exhaustive]
|
||||
/// enum ConnectResult {
|
||||
/// Success(xous::CID /* connection ID */, [u32; 4] /* Disconnection token */),
|
||||
/// Error(u32 /* error code */),
|
||||
/// Unhandled, /* Catchall for future Results */
|
||||
/// }
|
||||
/// ```
|
||||
TryConnect = 7,
|
||||
}
|
||||
|
||||
pub struct Name {}
|
||||
|
||||
impl Name {
|
||||
pub fn new() -> Self {
|
||||
Name {}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Name {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Service for Name {
|
||||
fn scalar(&mut self, _memory: &mut Memory, sender: u32, opcode: u32, args: [u32; 4]) {
|
||||
panic!("Unhandled name scalar {}: {} {:x?}", sender, opcode, args);
|
||||
}
|
||||
|
||||
fn blocking_scalar(
|
||||
&mut self,
|
||||
_memory: &mut Memory,
|
||||
sender: u32,
|
||||
opcode: u32,
|
||||
args: [u32; 4],
|
||||
) -> ScalarResult {
|
||||
panic!(
|
||||
"Unhandled name blocking_scalar {}: {} {:x?}",
|
||||
sender, opcode, args
|
||||
);
|
||||
// ScalarResult::Scalar1(0)
|
||||
}
|
||||
|
||||
fn lend(
|
||||
&mut self,
|
||||
_memory: &mut Memory,
|
||||
sender: u32,
|
||||
opcode: u32,
|
||||
buf: &[u8],
|
||||
extra: [u32; 2],
|
||||
) -> LendResult {
|
||||
panic!(
|
||||
"Unhandled name lend {}: {} {:x?} {:x?}",
|
||||
sender, opcode, buf, extra
|
||||
);
|
||||
// LendResult::MemoryReturned([0, 0])
|
||||
}
|
||||
|
||||
fn lend_mut(
|
||||
&mut self,
|
||||
memory: &mut Memory,
|
||||
sender: u32,
|
||||
opcode: u32,
|
||||
buf: &mut [u8],
|
||||
extra: [u32; 2],
|
||||
) -> LendResult {
|
||||
if opcode == NameLendOpcode::Register as u32 {
|
||||
panic!("Register opcode unimplemented");
|
||||
} else if opcode == NameLendOpcode::TryConnect as u32
|
||||
|| opcode == NameLendOpcode::BlockingConnect as u32
|
||||
{
|
||||
let buf_len = buf.len().min(extra[1] as usize);
|
||||
let name = std::str::from_utf8(&buf[0..buf_len]).unwrap_or("<invalid>");
|
||||
println!("Registering name {}", name);
|
||||
|
||||
let service = Box::new(if name == "panic-to-screen!" {
|
||||
println!("Panic-to-screen registered");
|
||||
super::panic_to_screen::PanicToScreen::new()
|
||||
} else {
|
||||
panic!("Unrecognized service name {}", name);
|
||||
});
|
||||
|
||||
let connection_id = memory.connections.len() as u32 + 1;
|
||||
memory.connections.insert(connection_id, service);
|
||||
|
||||
buf[0..4].copy_from_slice(&0u32.to_le_bytes());
|
||||
buf[4..8].copy_from_slice(&connection_id.to_le_bytes());
|
||||
LendResult::MemoryReturned([0, 0])
|
||||
} else {
|
||||
panic!(
|
||||
"Unhandled name lend_mut {}: {} {:x?}",
|
||||
sender, opcode, extra
|
||||
);
|
||||
}
|
||||
//
|
||||
}
|
||||
|
||||
fn send(
|
||||
&mut self,
|
||||
_memory: &mut Memory,
|
||||
sender: u32,
|
||||
opcode: u32,
|
||||
_buf: &[u8],
|
||||
extra: [u32; 2],
|
||||
) {
|
||||
panic!("Unhandled name send {}: {} {:x?}", sender, opcode, extra);
|
||||
}
|
||||
}
|
39
src/xous/services/panic_to_screen.rs
Normal file
39
src/xous/services/panic_to_screen.rs
Normal file
@ -0,0 +1,39 @@
|
||||
use super::{LendResult, Service};
|
||||
use crate::xous::Memory;
|
||||
|
||||
enum PanicToScreenLendMutOpcode {
|
||||
AppendPanicText = 0,
|
||||
}
|
||||
|
||||
pub struct PanicToScreen {}
|
||||
|
||||
impl PanicToScreen {
|
||||
pub fn new() -> Self {
|
||||
PanicToScreen {}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for PanicToScreen {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Service for PanicToScreen {
|
||||
fn lend_mut(
|
||||
&mut self,
|
||||
_memory: &mut Memory,
|
||||
_sender: u32,
|
||||
opcode: u32,
|
||||
buf: &mut [u8],
|
||||
extra: [u32; 2],
|
||||
) -> LendResult {
|
||||
if opcode != PanicToScreenLendMutOpcode::AppendPanicText as _ {
|
||||
panic!("Unhandled panic-to-screen opcode {}", opcode);
|
||||
}
|
||||
|
||||
let panic_str = std::str::from_utf8(&buf[0..extra[1] as usize]).unwrap_or("<invalid>");
|
||||
println!("Panic to screen: {}", panic_str);
|
||||
LendResult::MemoryReturned([0, 0])
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ use std::{
|
||||
};
|
||||
|
||||
use super::LendResult;
|
||||
use crate::xous::Memory;
|
||||
|
||||
pub struct Ticktimer {
|
||||
start: std::time::SystemTime,
|
||||
@ -35,16 +36,24 @@ impl Default for Ticktimer {
|
||||
}
|
||||
|
||||
impl super::Service for Ticktimer {
|
||||
fn scalar(&mut self, _sender: u32, opcode: u32, args: [u32; 4]) {
|
||||
fn scalar(&mut self, _memory: &mut Memory, _sender: u32, opcode: u32, args: [u32; 4]) {
|
||||
if opcode == ScalarOpcode::FreeCondition as u32 {
|
||||
let condition_index = args[0] as usize;
|
||||
if let Some(condvar) = self.condvars.remove(&condition_index) {
|
||||
assert!(condvar.1.load(std::sync::atomic::Ordering::Relaxed) == 0);
|
||||
}
|
||||
} else {
|
||||
println!("Unhandled scalar: {}", opcode);
|
||||
}
|
||||
}
|
||||
|
||||
fn blocking_scalar(&mut self, sender: u32, opcode: u32, args: [u32; 4]) -> super::ScalarResult {
|
||||
fn blocking_scalar(
|
||||
&mut self,
|
||||
_memory: &mut Memory,
|
||||
sender: u32,
|
||||
opcode: u32,
|
||||
args: [u32; 4],
|
||||
) -> super::ScalarResult {
|
||||
if opcode == ScalarOpcode::ElapsedMs as u32 {
|
||||
let elapsed_ms = std::time::SystemTime::now()
|
||||
.duration_since(self.start)
|
||||
@ -118,19 +127,27 @@ impl super::Service for Ticktimer {
|
||||
super::ScalarResult::Scalar1(notify_count as u32)
|
||||
} else {
|
||||
panic!(
|
||||
"Ticktimer blocking_scalar {}: {} {:x?}",
|
||||
"Ticktimer unhandled blocking_scalar {}: {} {:x?}",
|
||||
sender, opcode, args
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn lend(&mut self, sender: u32, opcode: u32, _buf: &[u8], extra: [u32; 2]) -> LendResult {
|
||||
fn lend(
|
||||
&mut self,
|
||||
_memory: &mut Memory,
|
||||
sender: u32,
|
||||
opcode: u32,
|
||||
_buf: &[u8],
|
||||
extra: [u32; 2],
|
||||
) -> LendResult {
|
||||
println!("Ticktimer lend {}: {} {:x?}", sender, opcode, extra);
|
||||
LendResult::MemoryReturned([0, 0])
|
||||
}
|
||||
|
||||
fn lend_mut(
|
||||
&mut self,
|
||||
_memory: &mut Memory,
|
||||
sender: u32,
|
||||
opcode: u32,
|
||||
_buf: &mut [u8],
|
||||
@ -140,7 +157,14 @@ impl super::Service for Ticktimer {
|
||||
LendResult::MemoryReturned([0, 0])
|
||||
}
|
||||
|
||||
fn send(&mut self, sender: u32, opcode: u32, _buf: &[u8], extra: [u32; 2]) {
|
||||
fn send(
|
||||
&mut self,
|
||||
_memory: &mut Memory,
|
||||
sender: u32,
|
||||
opcode: u32,
|
||||
_buf: &[u8],
|
||||
extra: [u32; 2],
|
||||
) {
|
||||
println!("Ticktimer send {}: {} {:x?}", sender, opcode, extra);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user