From 55aa179f21ac81d850a2dfc8410c17d8b2a94be7 Mon Sep 17 00:00:00 2001 From: Diego Asanza Date: Tue, 7 Jan 2025 20:35:28 +0100 Subject: [PATCH 1/2] Fix execution priority. This commit implements the execution priority as defined in the armv7-m architecture reference manual. There was a bug where the group priority for reset, nmi and hardfault was not being ignored as specified in the ARMV7-M Arch Reference Manual. Version E. Page B1-157. Here it is defined that the group priority for Hardfault, NMI and Reset is -1, -2 and -3 respectively, regardles of the value of PRIGROUP. Signed-off-by: Diego Asanza --- zmu_cortex_m/src/core/exception.rs | 38 +++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/zmu_cortex_m/src/core/exception.rs b/zmu_cortex_m/src/core/exception.rs index c2e9952..ac562fd 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-157 + 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 From 0bdfd4e21ecf680dbc334919a98ab0bdc3d389fd Mon Sep 17 00:00:00 2001 From: Diego Asanza Date: Wed, 8 Jan 2025 18:17:33 +0100 Subject: [PATCH 2/2] apply suggestions from code review. Signed-off-by: Diego Asanza --- zmu_cortex_m/src/core/exception.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zmu_cortex_m/src/core/exception.rs b/zmu_cortex_m/src/core/exception.rs index ac562fd..69bace2 100644 --- a/zmu_cortex_m/src/core/exception.rs +++ b/zmu_cortex_m/src/core/exception.rs @@ -362,7 +362,7 @@ impl ExceptionHandling for Processor { highestpri = exp.priority; /* - ARMV7-M Arch Reference Manual. Version E. Page B1-157 + 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