summaryrefslogtreecommitdiffstats
path: root/cpukit/score/cpu
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2021-01-12 14:03:41 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2021-02-01 06:26:18 +0100
commit51e59d59b72ccb834c6121a844c352e146929256 (patch)
tree9a7f0161c2f0b619f89902b24798b4e29fa17e94 /cpukit/score/cpu
parentnios2: Optimize ISR dispatch variant (diff)
downloadrtems-51e59d59b72ccb834c6121a844c352e146929256.tar.bz2
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().
Diffstat (limited to 'cpukit/score/cpu')
-rw-r--r--cpukit/score/cpu/nios2/nios2-eic-il-low-level.S23
-rw-r--r--cpukit/score/cpu/nios2/nios2-eic-rsie-low-level.S166
2 files changed, 16 insertions, 173 deletions
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 1632fbb8c2..fa4d1fb8f8 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 4dd3749c45..0000000000
--- 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@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