[rtems commit] nios2: Allow ISR nesting in dispatch variant

Sebastian Huber sebh at rtems.org
Mon Feb 1 06:20:12 UTC 2021


Module:    rtems
Branch:    master
Commit:    51e59d59b72ccb834c6121a844c352e146929256
Changeset: http://git.rtems.org/rtems/commit/?id=51e59d59b72ccb834c6121a844c352e146929256

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Tue Jan 12 14:03:41 2021 +0100

nios2: Allow ISR nesting in dispatch variant

Rename _Nios2_ISR_Dispatch_with_shadow_non_preemptive() in
_Nios2_ISR_Dispatch_with_shadow_register_set().  Remove
_Nios2_ISR_Dispatch_with_shadow_preemptive().

---

 cpukit/Makefile.am                                |   1 -
 cpukit/score/cpu/nios2/nios2-eic-il-low-level.S   |  23 ++-
 cpukit/score/cpu/nios2/nios2-eic-rsie-low-level.S | 166 ----------------------
 spec/build/cpukit/cpunios2.yml                    |   1 -
 4 files changed, 16 insertions(+), 175 deletions(-)

diff --git a/cpukit/Makefile.am b/cpukit/Makefile.am
index 71bbaea..565aa66 100644
--- a/cpukit/Makefile.am
+++ b/cpukit/Makefile.am
@@ -1677,7 +1677,6 @@ librtemscpu_a_SOURCES += score/cpu/nios2/nios2-context-switch.S
 librtemscpu_a_SOURCES += score/cpu/nios2/nios2-context-validate.S
 librtemscpu_a_SOURCES += score/cpu/nios2/nios2-context-volatile-clobber.S
 librtemscpu_a_SOURCES += score/cpu/nios2/nios2-eic-il-low-level.S
-librtemscpu_a_SOURCES += score/cpu/nios2/nios2-eic-rsie-low-level.S
 librtemscpu_a_SOURCES += score/cpu/nios2/nios2-exception-frame-print.c
 librtemscpu_a_SOURCES += score/cpu/nios2/nios2-fatal-halt.c
 librtemscpu_a_SOURCES += score/cpu/nios2/nios2-iic-low-level.S
diff --git a/cpukit/score/cpu/nios2/nios2-eic-il-low-level.S b/cpukit/score/cpu/nios2/nios2-eic-il-low-level.S
index 1632fbb..fa4d1fb 100644
--- a/cpukit/score/cpu/nios2/nios2-eic-il-low-level.S
+++ b/cpukit/score/cpu/nios2/nios2-eic-il-low-level.S
@@ -43,13 +43,16 @@
 	.extern	_Per_CPU_Information
 	.extern	_Nios2_ISR_Status_interrupts_disabled
 
-	.globl	_Nios2_ISR_Dispatch_with_shadow_non_preemptive
+	.globl	_Nios2_ISR_Dispatch_with_shadow_register_set
 
-_Nios2_ISR_Dispatch_with_shadow_non_preemptive:
+_Nios2_ISR_Dispatch_with_shadow_register_set:
 
 	/* Load thread dispatch disable level */
 	ldw	r16, %gprel(_Per_CPU_Information + PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL)(gp)
 
+	/* Read status */
+	rdctl	r18, status
+
 	/* Load high level handler address and argument */
 	ldw	r8, 4(et)
 	ldw	r4, 8(et)
@@ -58,6 +61,15 @@ _Nios2_ISR_Dispatch_with_shadow_non_preemptive:
 	addi	r17, r16, 1
 	stw	r17, %gprel(_Per_CPU_Information + PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL)(gp)
 
+	/*
+	 * Enable higher level interrupts.  This is safe since status.RSIE is
+	 * always 0 and thread dispatching is disabled right above.  Higher
+	 * priority interrupts shall not share shadow register sets with lower
+	 * priority interrupts.
+	 */
+	ori	r5, r18, 1
+	wrctl	status, r5
+
 	/* Call high level handler with argument */
 	callr	r8
 
@@ -67,9 +79,6 @@ _Nios2_ISR_Dispatch_with_shadow_non_preemptive:
 	/* Load the thread dispatch after ISR disable indicator */
 	ldw	r13, %gprel(_Per_CPU_Information + PER_CPU_ISR_DISPATCH_DISABLE)(gp)
 
-	/* Read status */
-	rdctl	r14, status
-
 	/* Fix return address */
 	subi	ea, ea, 4
 
@@ -84,10 +93,10 @@ _Nios2_ISR_Dispatch_with_shadow_non_preemptive:
 	or	r15, r12, r16
 
 	/*
-	 * Get the previous register set from r14.  If it is zero, then this is
+	 * Get the previous register set from r18.  If it is zero, then this is
 	 * the outermost interrupt.  Or it to the thread dispatch status (r15).
 	 */
-	andhi	r12, r14, 0x3f
+	andhi	r12, r18, 0x3f
 	or	r15, r12, r15
 
 	/*
diff --git a/cpukit/score/cpu/nios2/nios2-eic-rsie-low-level.S b/cpukit/score/cpu/nios2/nios2-eic-rsie-low-level.S
deleted file mode 100644
index 4dd3749..0000000
--- a/cpukit/score/cpu/nios2/nios2-eic-rsie-low-level.S
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (c) 2011 embedded brains GmbH.  All rights reserved.
- *
- *  embedded brains GmbH
- *  Obere Lagerstr. 30
- *  82178 Puchheim
- *  Germany
- *  <rtems at embedded-brains.de>
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#include <rtems/score/percpu.h>
-
-#define FRAME_OFFSET_AT 0
-#define FRAME_OFFSET_R2 4
-#define FRAME_OFFSET_R3 8
-#define FRAME_OFFSET_R4 12
-#define FRAME_OFFSET_R5 16
-#define FRAME_OFFSET_R6 20
-#define FRAME_OFFSET_R7 24
-#define FRAME_OFFSET_R8 28
-#define FRAME_OFFSET_R9 32
-#define FRAME_OFFSET_R10 36
-#define FRAME_OFFSET_R11 40
-#define FRAME_OFFSET_R12 44
-#define FRAME_OFFSET_R13 48
-#define FRAME_OFFSET_R14 52
-#define FRAME_OFFSET_R15 56
-#define FRAME_OFFSET_RA  60
-#define FRAME_OFFSET_EA  64
-#define FRAME_OFFSET_ESTATUS 68
-#define FRAME_OFFSET_R16 72
-
-#define FRAME_SIZE (FRAME_OFFSET_R16 + 4)
-
-	.set	noat
-	.section	.text
-
-	.extern	_Per_CPU_Information
-
-	.globl	_Nios2_ISR_Dispatch_with_shadow_preemptive
-
-_Nios2_ISR_Dispatch_with_shadow_preemptive:
-
-	/* Obtain stack frame */
-	subi	sp, sp, FRAME_SIZE
-
-	/* Save volatile registers */
-	stw	at, FRAME_OFFSET_AT(sp)
-	stw	r2, FRAME_OFFSET_R2(sp)
-	stw	r3, FRAME_OFFSET_R3(sp)
-	stw	r4, FRAME_OFFSET_R4(sp)
-	stw	r5, FRAME_OFFSET_R5(sp)
-	stw	r6, FRAME_OFFSET_R6(sp)
-	stw	r7, FRAME_OFFSET_R7(sp)
-	stw	r8, FRAME_OFFSET_R8(sp)
-	stw	r9, FRAME_OFFSET_R9(sp)
-	stw	r10, FRAME_OFFSET_R10(sp)
-	stw	r11, FRAME_OFFSET_R11(sp)
-	stw	r12, FRAME_OFFSET_R12(sp)
-	stw	r13, FRAME_OFFSET_R13(sp)
-	stw	r14, FRAME_OFFSET_R14(sp)
-	stw	r15, FRAME_OFFSET_R15(sp)
-
-	/* Save context */
-	rdctl	r2, estatus
-	subi	ea, ea, 4
-	stw	ra, FRAME_OFFSET_RA(sp)
-	stw	ea, FRAME_OFFSET_EA(sp)
-	stw	r2, FRAME_OFFSET_ESTATUS(sp)
-
-	/* Save one non-volatile register for further usage */
-	stw	r16, FRAME_OFFSET_R16(sp)
-
-	/* Save stack pointer */
-	mov	r16, sp
-
-	/* Increment ISR nest level and thread dispatch disable level */
-	ldw	r9, %gprel(_Per_CPU_Information + PER_CPU_ISR_NEST_LEVEL)(gp)
-	ldw	r10, %gprel(_Per_CPU_Information + PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL)(gp)
-	addi	r11, r9, 1
-	addi	r10, r10, 1
-	stw	r11, %gprel(_Per_CPU_Information + PER_CPU_ISR_NEST_LEVEL)(gp)
-	stw	r10, %gprel(_Per_CPU_Information + PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL)(gp)
-
-	/* Switch to interrupt stack if necessary */
-	bne	r9, zero, switch_to_interrupt_stack_done
-	ldw	sp, %gprel(_Per_CPU_Information + PER_CPU_INTERRUPT_STACK_HIGH)(gp)
-
-switch_to_interrupt_stack_done:
-
-	/* Load high level handler address and argument */
-	ldw	r12, 4(et)
-	ldw	r4, 8(et)
-
-	/* Enable interrupts */
-	rdctl	r13, status
-	orhi	r13, r13, 0x0080
-	wrctl	status, r13
-
-	/* Call high level handler with argument */
-	callr	r12
-
-	/* Disable interrupts */
-	rdctl	r12, status
-	movhi	r13, 0xff80
-	subi	r13, r13, 1
-	and	r12, r12, r13
-	wrctl	status, r12
-
-	/* Decrement ISR nest level and thread dispatch disable level */
-	ldw	r9, %gprel(_Per_CPU_Information + PER_CPU_ISR_NEST_LEVEL)(gp)
-	ldw	r10, %gprel(_Per_CPU_Information + PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL)(gp)
-	subi	r9, r9, 1
-	subi	r10, r10, 1
-	stw	r9, %gprel(_Per_CPU_Information + PER_CPU_ISR_NEST_LEVEL)(gp)
-	stw	r10, %gprel(_Per_CPU_Information + PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL)(gp)
-
-	/*
-	 * Restore stack pointer.  If the ISR nest level is greater than one,
-	 * then this is a nop, else we switch back to the thread stack.
-	 */
-	mov	sp, r16
-
-	/* Thread dispatch */
-	bne	r10, zero, thread_dispatch_done
-	call	_Thread_Dispatch
-
-thread_dispatch_done:
-
-	/* Restore volatile registers */
-	ldw	at, FRAME_OFFSET_AT(sp)
-	ldw	r2, FRAME_OFFSET_R2(sp)
-	ldw	r3, FRAME_OFFSET_R3(sp)
-	ldw	r4, FRAME_OFFSET_R4(sp)
-	ldw	r5, FRAME_OFFSET_R5(sp)
-	ldw	r6, FRAME_OFFSET_R6(sp)
-	ldw	r7, FRAME_OFFSET_R7(sp)
-	ldw	r8, FRAME_OFFSET_R8(sp)
-	ldw	r9, FRAME_OFFSET_R9(sp)
-	ldw	r10, FRAME_OFFSET_R10(sp)
-	ldw	r11, FRAME_OFFSET_R11(sp)
-	ldw	r12, FRAME_OFFSET_R12(sp)
-	ldw	r13, FRAME_OFFSET_R13(sp)
-	ldw	r14, FRAME_OFFSET_R14(sp)
-	ldw	r15, FRAME_OFFSET_R15(sp)
-
-	/* Restore context */
-	ldw	ra, FRAME_OFFSET_RA(sp)
-	ldw	ea, FRAME_OFFSET_EA(sp)
-	ldw	et, FRAME_OFFSET_ESTATUS(sp)
-
-	/* Restore the non-volatile register */
-	ldw	r16, FRAME_OFFSET_R16(sp)
-
-	/* Release stack frame */
-	addi	sp, sp, FRAME_SIZE
-
-	/* Restore context */
-	wrctl	estatus, et
-
-	/* Return */
-	eret
diff --git a/spec/build/cpukit/cpunios2.yml b/spec/build/cpukit/cpunios2.yml
index 4b43f85..40201dc 100644
--- a/spec/build/cpukit/cpunios2.yml
+++ b/spec/build/cpukit/cpunios2.yml
@@ -31,7 +31,6 @@ source:
 - cpukit/score/cpu/nios2/nios2-context-validate.S
 - cpukit/score/cpu/nios2/nios2-context-volatile-clobber.S
 - cpukit/score/cpu/nios2/nios2-eic-il-low-level.S
-- cpukit/score/cpu/nios2/nios2-eic-rsie-low-level.S
 - cpukit/score/cpu/nios2/nios2-exception-frame-print.c
 - cpukit/score/cpu/nios2/nios2-fatal-halt.c
 - cpukit/score/cpu/nios2/nios2-iic-irq.c



More information about the vc mailing list