From 51e59d59b72ccb834c6121a844c352e146929256 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Tue, 12 Jan 2021 14:03:41 +0100 Subject: 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/score/cpu/nios2/nios2-eic-il-low-level.S | 23 ++- cpukit/score/cpu/nios2/nios2-eic-rsie-low-level.S | 166 ---------------------- 2 files changed, 16 insertions(+), 173 deletions(-) delete mode 100644 cpukit/score/cpu/nios2/nios2-eic-rsie-low-level.S (limited to 'cpukit/score/cpu') 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 - * - * - * 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 - -#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 -- cgit v1.2.3