aboutsummaryrefslogtreecommitdiff
path: root/cortex-m-semihosting/src/debug.rs
diff options
context:
space:
mode:
authorGravatar bors[bot] <26634292+bors[bot]@users.noreply.github.com> 2020-10-13 23:32:15 +0000
committerGravatar GitHub <noreply@github.com> 2020-10-13 23:32:15 +0000
commit432e5f527430394570d1d07454e26cc41d5b2936 (patch)
treed3cde25a18eabfc5f0342dbf2d31ab767f21bab9 /cortex-m-semihosting/src/debug.rs
parentf77d64a2d1505335e4a170d03a40993bb066fd02 (diff)
parentb51178fae6373d8dae95f2fb661e0635359e8bc0 (diff)
downloadcortex-m-432e5f527430394570d1d07454e26cc41d5b2936.tar.gz
cortex-m-432e5f527430394570d1d07454e26cc41d5b2936.tar.zst
cortex-m-432e5f527430394570d1d07454e26cc41d5b2936.zip
263: Import cortex-m-semihosting and panic-semihosting into this repo r=adamgreig a=jonas-schievink Motivation: * Allows writing QEMU tests for `cortex-m`'s functionality that use semihosting to control QEMU. Previously these crates would pull in another cortex-m version, which doesn't work. Now they have a `path` dependency on the root crate. * Lets us share the outline-inline-assembly setup and `cargo-xtask` in general. * Lets us share CI and bot setup between more crates. * 2 fewer repos to triage and keep track of (I'll transfer their issues after this is merged). I also want to import cortex-m-rt, but I'll do that in a later PR. CI was updated to build-test all crates with all or most feature combinations, like it did before. Co-authored-by: Jonas Schievink <jonasschievink@gmail.com>
Diffstat (limited to 'cortex-m-semihosting/src/debug.rs')
-rw-r--r--cortex-m-semihosting/src/debug.rs96
1 files changed, 96 insertions, 0 deletions
diff --git a/cortex-m-semihosting/src/debug.rs b/cortex-m-semihosting/src/debug.rs
new file mode 100644
index 0000000..a4fa6d8
--- /dev/null
+++ b/cortex-m-semihosting/src/debug.rs
@@ -0,0 +1,96 @@
+//! Interacting with debugging agent
+//!
+//! # Example
+//!
+//! This example will show how to terminate the QEMU session. The program
+//! should be running under QEMU with semihosting enabled
+//! (use `-semihosting` flag).
+//!
+//! Target program:
+//!
+//! ```no_run
+//! use cortex_m_semihosting::debug::{self, EXIT_SUCCESS, EXIT_FAILURE};
+//!
+//! fn main() {
+//! if 2 == 2 {
+//! // report success
+//! debug::exit(EXIT_SUCCESS);
+//! } else {
+//! // report failure
+//! debug::exit(EXIT_FAILURE);
+//! }
+//! }
+//!
+
+/// This values are taken from section 5.5.2 of
+/// ADS Debug Target Guide (DUI0058).
+// TODO document
+#[allow(missing_docs)]
+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,
+}
+
+/// Status enum for `exit` syscall.
+pub type ExitStatus = Result<(), ()>;
+
+/// Successful execution of a program.
+pub const EXIT_SUCCESS: ExitStatus = Ok(());
+
+/// Unsuccessful execution of a program.
+pub const EXIT_FAILURE: ExitStatus = Err(());
+
+/// Reports to the debugger that the execution has completed.
+///
+/// This call can be used to terminate QEMU session and report back success
+/// or failure. If you need to pass more than one type of error, consider
+/// using `report_exception` syscall instead.
+///
+/// This call should not return. However, it is possible for the debugger
+/// to request that the application continue. In that case this call
+/// returns normally.
+///
+pub fn exit(status: ExitStatus) {
+ match status {
+ EXIT_SUCCESS => report_exception(Exception::ApplicationExit),
+ EXIT_FAILURE => report_exception(Exception::RunTimeErrorUnknown),
+ }
+}
+
+/// Report an exception to the debugger directly.
+///
+/// Exception handlers can use this SWI at the end of handler chains
+/// as the default action, to indicate that the exception has not been handled.
+///
+/// This call should not return. However, it is possible for the debugger
+/// to request that the application continue. In that case this call
+/// returns normally.
+///
+/// # Arguments
+///
+/// * `reason` - A reason code reported back to the debugger.
+///
+pub fn report_exception(reason: Exception) {
+ let code = reason as usize;
+ unsafe {
+ syscall1!(REPORT_EXCEPTION, code);
+ }
+}