diff --git a/eepy-sys/src/syscall/mod.rs b/eepy-sys/src/syscall/mod.rs index a6bfd6d..96c22ca 100644 --- a/eepy-sys/src/syscall/mod.rs +++ b/eepy-sys/src/syscall/mod.rs @@ -1,24 +1,82 @@ +#[repr(u8)] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum SyscallNumber { + Misc = 0, + Image = 1, + Input = 2, + Usb = 3, +} + +impl TryFrom for SyscallNumber { + type Error = (); + + fn try_from(value: u8) -> Result { + match value { + x if x == SyscallNumber::Misc as u8 => Ok(SyscallNumber::Misc), + x if x == SyscallNumber::Image as u8 => Ok(SyscallNumber::Image), + x if x == SyscallNumber::Input as u8 => Ok(SyscallNumber::Input), + x if x == SyscallNumber::Usb as u8 => Ok(SyscallNumber::Usb), + _ => Err(()), + } + } +} + +#[repr(usize)] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum MiscSyscall { + GetSerial = 0, +} + +impl TryFrom for MiscSyscall { + type Error = (); + + fn try_from(value: usize) -> Result { + match value { + x if x == MiscSyscall::GetSerial as usize => Ok(MiscSyscall::GetSerial), + _ => Err(()), + } + } +} + + /// Perform a raw system call. #[macro_export] macro_rules! syscall { ( $syscall_num:expr, - $( out $r0out:ident )? $( in $r0in:expr )?, - $( out $r1out:ident )? $( in $r1in:expr )?, - $( out $r2out:ident )? $( in $r2in:expr )?, - $( out $r3out:ident )? $( in $r3in:expr )?, + $( out $r0out:ident )? $( in $r0in:expr )? $(, + $( out $r1out:ident )? $( in $r1in:expr )? $(, + $( out $r2out:ident )? $( in $r2in:expr )? $(, + $( out $r3out:ident )? $( in $r3in:expr )? $(,)? + )? + )? + )? ) => { - asm!( + ::core::arch::asm!( "svc #{syscall_num}", - $( in("r0") $r0in, )? + $( in("r0") $r0in as usize, )? $( lateout("r0") $r0out, )? - $( in("r1") $r1in, )? - $( lateout("r1") $r1out, )? - $( in("r2") $r2in, )? - $( lateout("r2") $r2out, )? - $( in("r3") $r3in, )? - $( lateout("r3") $r3out, )? - syscall_num = const $syscall_num, - ); + $( + $( in("r1") $r1in as usize, )? + $( lateout("r1") $r1out, )? + $( + $( in("r2") $r2in as usize, )? + $( lateout("r2") $r2out, )? + $( + $( in("r3") $r3in as usize, )? + $( lateout("r3") $r3out, )? + )? + )? + )? + syscall_num = const $syscall_num as u8, + ) } } + +pub fn get_serial() -> &'static str { + let mut ptr: *const [u8; 16]; + unsafe { syscall!(SyscallNumber::Misc, out ptr in MiscSyscall::GetSerial) }; + unsafe { core::str::from_utf8_unchecked(&*ptr) } +} \ No newline at end of file diff --git a/eepy/src/main.rs b/eepy/src/main.rs index b5d007c..5fc6085 100644 --- a/eepy/src/main.rs +++ b/eepy/src/main.rs @@ -15,7 +15,7 @@ use defmt_rtt as _; use core::cell::RefCell; use critical_section::Mutex; -use defmt::{debug, info, trace, warn}; +use defmt::{debug, info, println, trace, warn}; use embedded_hal::delay::DelayNs; use embedded_hal::digital::OutputPin; use embedded_hal::i2c::I2c; @@ -39,7 +39,7 @@ use fw16_epd_bsp::hal::timer::{Alarm, Alarm0}; use fw16_epd_bsp::pac::I2C0; use fw16_epd_bsp::pac::interrupt; use eepy_gui::draw_target::EpdDrawTarget; -use eepy_sys::{syscall as do_syscall, Event, RefreshBlockMode, SafeOption, TouchEvent, TouchEventType}; +use eepy_sys::{Event, RefreshBlockMode, SafeOption, TouchEvent, TouchEventType}; use tp370pgh01::rp2040::{Rp2040PervasiveSpiDelays, IoPin}; use tp370pgh01::{Tp370pgh01, IMAGE_BYTES}; use crate::ringbuffer::RingBuffer; @@ -329,20 +329,7 @@ fn main() -> ! { }*/ // Test syscall - unsafe { - let mut r0: usize; - let mut r1: usize; - let mut r2: usize; - let mut r3: usize; - do_syscall!( - 31, - out r0 in 0, - out r1 in 1, - out r2 in 2, - out r3 in 3, - ); - debug!("{} {} {} {}", r0, r1, r2, r3); - } + println!("{}", eepy_sys::syscall::get_serial()); let draw_target = EpdDrawTarget::new(write_image, refresh); gui::gui_main(draw_target); diff --git a/eepy/src/syscall.rs b/eepy/src/syscall.rs index 32a8413..db3dd19 100644 --- a/eepy/src/syscall.rs +++ b/eepy/src/syscall.rs @@ -1,6 +1,9 @@ use core::arch::{asm, global_asm}; use cortex_m_rt::exception; use defmt::debug; +use defmt::export::panic; +use eepy_sys::syscall::{MiscSyscall, SyscallNumber}; +use crate::SERIAL_NUMBER; global_asm!(include_str!("syscall.s")); @@ -18,11 +21,16 @@ global_asm!(include_str!("syscall.s")); extern "C" fn syscall(sp: *mut usize) { // Stack contains R0, R1, R2, R3, R12, LR, ReturnAddress, xPSR let stack_values = unsafe { core::slice::from_raw_parts_mut(sp, 8) }; - let svc_operand = unsafe { (stack_values[6] as *const u8).sub(2).read() }; - debug!("{:x}", svc_operand); + let syscall_num = unsafe { (stack_values[6] as *const u8).sub(2).read() }; - // Increase the value of R0-R3 by 1 - for i in 0..4 { - stack_values[i] += 1; + match SyscallNumber::try_from(syscall_num) { + Ok(SyscallNumber::Misc) => match MiscSyscall::try_from(stack_values[0]) { + Ok(MiscSyscall::GetSerial) => { + let serial = SERIAL_NUMBER.get().unwrap(); + stack_values[0] = (&raw const *serial) as usize; + }, + _ => panic!("illegal syscall"), + }, + _ => panic!("illegal syscall"), } } \ No newline at end of file