Browse Source

add `exit` and `report_exception` syscalls

Vadzim Dambrouski 8 years ago
parent
commit
02cb500a5a
4 changed files with 61 additions and 3 deletions
  1. 52 0
      src/debug.rs
  2. 3 2
      src/lib.rs
  3. 4 1
      src/macros.rs
  4. 2 0
      src/nr.rs

+ 52 - 0
src/debug.rs

@@ -0,0 +1,52 @@
+//! Interacting with debugging agent
+
+pub enum Exception {
+    // Hardware reason codes
+    BranchThroughZero = 0x20000,
+    UndefinedInstr = 0x20001,
+    SoftwareInterrupt = 0x20002,
+    PrefetchAbort = 0x20003,
+    DataAbort = 0x20004,
+    AddressException = 0x20005,
+    IRQ = 0x20006,
+    FIQ = 0x20007,
+    // Software reason codes
+    BreakPoint = 0x20020,
+    WatchPoint = 0x20021,
+    StepComplete = 0x20022,
+    RunTimeErrorUnknown = 0x20023,
+    InternalError = 0x20024,
+    UserInterruption = 0x20025,
+    ApplicationExit = 0x20026,
+    StackOverflow = 0x20027,
+    DivisionByZero = 0x20028,
+    OSSpecific = 0x20029,
+}
+
+/// Reports to the debugger that the execution has completed.
+///
+/// If `status` is not 0 then an error is reported.
+/// This call may not return.
+///
+pub fn exit(status: i8) {
+    if status == 0 {
+        report_exception(Exception::ApplicationExit);
+    } else {
+        report_exception(Exception::RunTimeErrorUnknown);
+    }
+}
+
+/// Report an exception to the debugger directly.
+///
+/// This call may not return.
+///
+/// # Arguments
+///
+/// * `reason` - A reason code reported back to the debugger
+///
+pub fn report_exception(reason: Exception) {
+    let code = reason as usize;
+    unsafe {
+        syscall!(REPORT_EXCEPTION, code);
+    }
+}

+ 3 - 2
src/lib.rs

@@ -110,11 +110,12 @@ mod macros;
 
 pub mod io;
 pub mod nr;
+pub mod debug;
 
 /// Performs a semihosting operation
 #[inline(always)]
 #[cfg(target_arch = "arm")]
-pub unsafe fn syscall<T>(mut nr: usize, arg: &T) -> usize {
+pub unsafe fn syscall<T: Sized>(mut nr: usize, arg: T) -> usize {
     asm!("bkpt 0xAB"
          : "+{r0}"(nr)
          : "{r1}"(arg)
@@ -124,6 +125,6 @@ pub unsafe fn syscall<T>(mut nr: usize, arg: &T) -> usize {
 }
 
 #[cfg(not(target_arch = "arm"))]
-pub unsafe fn syscall<T>(_nr: usize, _arg: &T) -> usize {
+pub unsafe fn syscall<T: Sized>(_nr: usize, _arg: T) -> usize {
     0
 }

+ 4 - 1
src/macros.rs

@@ -1,8 +1,11 @@
 /// Variable argument version of `syscall`
 #[macro_export]
 macro_rules! syscall {
+    ($nr:ident) => {
+        $crate::syscall($crate::nr::$nr, 0usize)
+    };
     ($nr:ident, $a1:expr) => {
-        $crate::syscall($crate::nr::$nr, &($a1 as usize))
+        $crate::syscall($crate::nr::$nr, $a1 as usize)
     };
     ($nr:ident, $a1:expr, $a2:expr) => {
         $crate::syscall($crate::nr::$nr, &[$a1 as usize, $a2 as usize])

+ 2 - 0
src/nr.rs

@@ -22,3 +22,5 @@ pub const TMPNAM: usize = 0x0d;
 pub const WRITE0: usize = 0x04;
 pub const WRITE: usize = 0x05;
 pub const WRITEC: usize = 0x03;
+pub const ENTER_SVC: usize = 0x17;
+pub const REPORT_EXCEPTION: usize = 0x18;