diff --git a/zmu_cortex_m/src/core/exception.rs b/zmu_cortex_m/src/core/exception.rs index c2e9952..69bace2 100644 --- a/zmu_cortex_m/src/core/exception.rs +++ b/zmu_cortex_m/src/core/exception.rs @@ -355,11 +355,29 @@ impl ExceptionHandling for Processor { let mut highestpri: i16 = 256; let mut boostedpri: i16 = 256; let subgroupshift = self.aircr.get_bits(8..11); - let groupvalue = 2 << subgroupshift; + let mut groupvalue = 2 << subgroupshift; for (_, exp) in self.exceptions.iter().filter(|&(_, e)| e.active) { if exp.priority < highestpri { highestpri = exp.priority; + + /* + ARMV7-M Arch Reference Manual. Version E. Page B1-527 + Priority Grouping. The group priority for Reset, NMI + and HardFault are -3, -2 and -1 respectively, regardless + of the value of PRIGROUP. Note that we dont check reset because + after setting the reset pending flag, the simulator resets the + processor. + */ + + if exp.exception_number == Exception::NMI.into() { + groupvalue = -2; + } + + if exp.exception_number == Exception::HardFault.into() { + groupvalue = -1; + } + let subgroupvalue = highestpri % groupvalue; highestpri -= subgroupvalue; } @@ -645,6 +663,24 @@ mod tests { assert!(core.exception_active(Exception::BusFault)); } + #[test] + fn test_get_execution_priority() { + let mut p = Processor::new(); + + p.reset().unwrap(); + p.msp = 0x2000_0400; + p.set_exception_pending(Exception::HardFault); + p.check_exceptions(); + + assert_eq!(p.get_execution_priority(), -1); + + p.reset().unwrap(); + p.msp = 0x2000_0400; + p.set_exception_pending(Exception::NMI); + p.check_exceptions(); + assert_eq!(p.get_execution_priority(), -2); + } + #[test] fn test_exception_priority() { // Arrange