// Okay, now that we're confident we came from a task, we need to deal with // the case where the fault occurred while stacking an SVC exception frame. // In this case, the SVC exception will still be set as pending, which means // when we try to return to the supervisor to handle this fault, it'll // generate a spurious SVC. Even in the best of cases, this breaks the // supervisor. // // It would be super great if there were, say, a register in the System // Control Block that would tell us that SVC is pended, wouldn't it? Perhaps // it could be called the System Handler Control and State Register. In // fact, if you read the ARMv6-M ARM, you will find a register with such a // name, and might be tempted to use it! // // BEWARE. // // In a _different section_ of that manual, there is a throwaway footnote // that reads: // // > The DWT, BPU, ROM table, DCB, and the SHCSR and DFSR registers are // > accessible through the DAP interface. Access from the processor is // > IMPLEMENTATION DEFINED. // // On the Cortex-M0+, this very attractive register works great from the // debugger but _reads as zero from the kernel._ Ugh. // // Instead, we are using the always-active ICSR register, which lets us // _detect_ the pending SVC _but not clear it._ To clear it, we use the // mitigation mechanism defined over in syscalls.rs. // // The case where an SVC is pending in ICSR uniquely identifies a task // having faulted during SVC, because a hardfault _in the kernel_ during // processing of an SVC would not have made it here (see above). {