[PATCH v1 3/5] cpukit/microblaze: Add interrupt hooks

Kinsey Moore kinsey.moore at oarcorp.com
Tue Feb 15 20:38:46 UTC 2022


Add hooks for manipulating system state before and after interrupts are
run. These hooks serve primarily to allow the MicroBlaze libdebugger
backend to prevent software breaks from occurring in interrupt context.
---
 cpukit/score/cpu/microblaze/cpu.c             | 42 +++++++++++++++++++
 cpukit/score/cpu/microblaze/cpu_asm.S         | 12 ++++++
 .../cpu/microblaze/include/rtems/score/cpu.h  | 17 ++++++++
 3 files changed, 71 insertions(+)

diff --git a/cpukit/score/cpu/microblaze/cpu.c b/cpukit/score/cpu/microblaze/cpu.c
index fe55ef5546..960ac1bfea 100644
--- a/cpukit/score/cpu/microblaze/cpu.c
+++ b/cpukit/score/cpu/microblaze/cpu.c
@@ -229,3 +229,45 @@ void _MicroBlaze_Debug_handle( CPU_Exception_frame *ef )
 
   rtems_fatal( RTEMS_FATAL_SOURCE_EXCEPTION, (rtems_fatal_code) ef );
 }
+
+MicroBlaze_Interrupt_hook installed_preint_hook = NULL;
+
+void _MicroBlaze_Pre_Interrupt_install_hook(
+  MicroBlaze_Interrupt_hook  new_hook,
+  MicroBlaze_Interrupt_hook *old_hook
+)
+{
+  if ( old_hook != NULL ) {
+    *old_hook = installed_preint_hook;
+  }
+
+  installed_preint_hook = new_hook;
+}
+
+void _MicroBlaze_Pre_Interrupt_hook()
+{
+  if ( installed_preint_hook != NULL ) {
+    installed_preint_hook();
+  }
+}
+
+MicroBlaze_Interrupt_hook installed_postint_hook = NULL;
+
+void _MicroBlaze_Post_Interrupt_install_hook(
+  MicroBlaze_Interrupt_hook  new_hook,
+  MicroBlaze_Interrupt_hook *old_hook
+)
+{
+  if ( old_hook != NULL ) {
+    *old_hook = installed_postint_hook;
+  }
+
+  installed_postint_hook = new_hook;
+}
+
+void _MicroBlaze_Post_Interrupt_hook()
+{
+  if ( installed_postint_hook != NULL ) {
+    installed_postint_hook();
+  }
+}
diff --git a/cpukit/score/cpu/microblaze/cpu_asm.S b/cpukit/score/cpu/microblaze/cpu_asm.S
index 0a2c5d8fff..6bd81eedd9 100644
--- a/cpukit/score/cpu/microblaze/cpu_asm.S
+++ b/cpukit/score/cpu/microblaze/cpu_asm.S
@@ -82,6 +82,15 @@ switch_to_interrupt_stack:
 	swi r4, r1, 0
 
 on_interrupt_stack:
+	/*
+	 * Temporarily stash param 1 into r2 which is a special register not
+	 * used by RTEMS
+	 */
+	addik r2, r5, 0
+	bralid r15, _MicroBlaze_Pre_Interrupt_hook
+	nop
+	addik r5, r2, 0
+
 	/* Add 1 to ISR_NEST_LEVEL */
 	lwi r3, r0, _Per_CPU_Information + 8
 	addik r3, r3, 1
@@ -120,6 +129,9 @@ after_stack_switch:
 	/* Fall through to quick exit */
 
 quick_exit:
+	bralid r15, _MicroBlaze_Post_Interrupt_hook
+	nop
+
 	/* Simple return from nested interrupt */
 	/* Restore registers */
 	lwi  r3, r1, MICROBLAZE_INTERRUPT_FRAME_MSR
diff --git a/cpukit/score/cpu/microblaze/include/rtems/score/cpu.h b/cpukit/score/cpu/microblaze/include/rtems/score/cpu.h
index 5ca0609e91..9c6b213e20 100644
--- a/cpukit/score/cpu/microblaze/include/rtems/score/cpu.h
+++ b/cpukit/score/cpu/microblaze/include/rtems/score/cpu.h
@@ -362,6 +362,23 @@ void _CPU_Context_switch(
   Context_Control  *heir
 );
 
+/* Interrupt hooks used by libdebugger */
+typedef void ( *MicroBlaze_Interrupt_hook )( void );
+
+void _MicroBlaze_Pre_Interrupt_install_hook(
+  MicroBlaze_Interrupt_hook  new_hook,
+  MicroBlaze_Interrupt_hook *old_hook
+);
+
+void _MicroBlaze_Pre_Interrupt_hook( void );
+
+void _MicroBlaze_Post_Interrupt_install_hook(
+  MicroBlaze_Interrupt_hook  new_hook,
+  MicroBlaze_Interrupt_hook *old_hook
+);
+
+void _MicroBlaze_Post_Interrupt_hook( void );
+
 /* Selects the appropriate resume function based on CEF state */
 RTEMS_NO_RETURN void _CPU_Exception_resume( CPU_Exception_frame *frame );
 
-- 
2.30.2



More information about the devel mailing list