source: rtems/cpukit/score/cpu/nios2/nios2-eic-rsie-low-level.S @ 98c95d1

Last change on this file since 98c95d1 was 98c95d1, checked in by Sebastian Huber <sebastian.huber@…>, on Jan 5, 2021 at 9:53:35 AM

nios2: Fix ISR dispatch variants

The thread dispatch disabled level moved to _Per_CPU_Information some
time ago.

  • Property mode set to 100644
File size: 4.2 KB
Line 
1/*
2 * Copyright (c) 2011 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Obere Lagerstr. 30
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.org/license/LICENSE.
13 */
14
15#include <rtems/score/percpu.h>
16
17#define FRAME_OFFSET_AT 0
18#define FRAME_OFFSET_R2 4
19#define FRAME_OFFSET_R3 8
20#define FRAME_OFFSET_R4 12
21#define FRAME_OFFSET_R5 16
22#define FRAME_OFFSET_R6 20
23#define FRAME_OFFSET_R7 24
24#define FRAME_OFFSET_R8 28
25#define FRAME_OFFSET_R9 32
26#define FRAME_OFFSET_R10 36
27#define FRAME_OFFSET_R11 40
28#define FRAME_OFFSET_R12 44
29#define FRAME_OFFSET_R13 48
30#define FRAME_OFFSET_R14 52
31#define FRAME_OFFSET_R15 56
32#define FRAME_OFFSET_RA  60
33#define FRAME_OFFSET_EA  64
34#define FRAME_OFFSET_ESTATUS 68
35#define FRAME_OFFSET_R16 72
36
37#define FRAME_SIZE (FRAME_OFFSET_R16 + 4)
38
39        .set    noat
40        .section        .text
41
42        .extern _Per_CPU_Information
43
44        .globl  _Nios2_ISR_Dispatch_with_shadow_preemptive
45
46_Nios2_ISR_Dispatch_with_shadow_preemptive:
47
48        /* Obtain stack frame */
49        subi    sp, sp, FRAME_SIZE
50
51        /* Save volatile registers */
52        stw     at, FRAME_OFFSET_AT(sp)
53        stw     r2, FRAME_OFFSET_R2(sp)
54        stw     r3, FRAME_OFFSET_R3(sp)
55        stw     r4, FRAME_OFFSET_R4(sp)
56        stw     r5, FRAME_OFFSET_R5(sp)
57        stw     r6, FRAME_OFFSET_R6(sp)
58        stw     r7, FRAME_OFFSET_R7(sp)
59        stw     r8, FRAME_OFFSET_R8(sp)
60        stw     r9, FRAME_OFFSET_R9(sp)
61        stw     r10, FRAME_OFFSET_R10(sp)
62        stw     r11, FRAME_OFFSET_R11(sp)
63        stw     r12, FRAME_OFFSET_R12(sp)
64        stw     r13, FRAME_OFFSET_R13(sp)
65        stw     r14, FRAME_OFFSET_R14(sp)
66        stw     r15, FRAME_OFFSET_R15(sp)
67
68        /* Save context */
69        rdctl   r2, estatus
70        subi    ea, ea, 4
71        stw     ra, FRAME_OFFSET_RA(sp)
72        stw     ea, FRAME_OFFSET_EA(sp)
73        stw     r2, FRAME_OFFSET_ESTATUS(sp)
74
75        /* Save one non-volatile register for further usage */
76        stw     r16, FRAME_OFFSET_R16(sp)
77
78        /* Save stack pointer */
79        mov     r16, sp
80
81        /* Increment ISR nest level and thread dispatch disable level */
82        ldw     r9, %gprel(_Per_CPU_Information + PER_CPU_ISR_NEST_LEVEL)(gp)
83        ldw     r10, %gprel(_Per_CPU_Information + PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL)(gp)
84        addi    r11, r9, 1
85        addi    r10, r10, 1
86        stw     r11, %gprel(_Per_CPU_Information + PER_CPU_ISR_NEST_LEVEL)(gp)
87        stw     r10, %gprel(_Per_CPU_Information + PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL)(gp)
88
89        /* Switch to interrupt stack if necessary */
90        bne     r9, zero, switch_to_interrupt_stack_done
91        ldw     sp, %gprel(_Per_CPU_Information + PER_CPU_INTERRUPT_STACK_HIGH)(gp)
92
93switch_to_interrupt_stack_done:
94
95        /* Load high level handler address and argument */
96        ldw     r12, 4(et)
97        ldw     r4, 8(et)
98
99        /* Enable interrupts */
100        rdctl   r13, status
101        orhi    r13, r13, 0x0080
102        wrctl   status, r13
103
104        /* Call high level handler with argument */
105        callr   r12
106
107        /* Disable interrupts */
108        rdctl   r12, status
109        movhi   r13, 0xff80
110        subi    r13, r13, 1
111        and     r12, r12, r13
112        wrctl   status, r12
113
114        /* Decrement ISR nest level and thread dispatch disable level */
115        ldw     r9, %gprel(_Per_CPU_Information + PER_CPU_ISR_NEST_LEVEL)(gp)
116        ldw     r10, %gprel(_Per_CPU_Information + PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL)(gp)
117        subi    r9, r9, 1
118        subi    r10, r10, 1
119        stw     r9, %gprel(_Per_CPU_Information + PER_CPU_ISR_NEST_LEVEL)(gp)
120        stw     r10, %gprel(_Per_CPU_Information + PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL)(gp)
121
122        /*
123         * Restore stack pointer.  If the ISR nest level is greater than one,
124         * then this is a nop, else we switch back to the thread stack.
125         */
126        mov     sp, r16
127
128        /* Thread dispatch */
129        bne     r10, zero, thread_dispatch_done
130        call    _Thread_Dispatch
131
132thread_dispatch_done:
133
134        /* Restore volatile registers */
135        ldw     at, FRAME_OFFSET_AT(sp)
136        ldw     r2, FRAME_OFFSET_R2(sp)
137        ldw     r3, FRAME_OFFSET_R3(sp)
138        ldw     r4, FRAME_OFFSET_R4(sp)
139        ldw     r5, FRAME_OFFSET_R5(sp)
140        ldw     r6, FRAME_OFFSET_R6(sp)
141        ldw     r7, FRAME_OFFSET_R7(sp)
142        ldw     r8, FRAME_OFFSET_R8(sp)
143        ldw     r9, FRAME_OFFSET_R9(sp)
144        ldw     r10, FRAME_OFFSET_R10(sp)
145        ldw     r11, FRAME_OFFSET_R11(sp)
146        ldw     r12, FRAME_OFFSET_R12(sp)
147        ldw     r13, FRAME_OFFSET_R13(sp)
148        ldw     r14, FRAME_OFFSET_R14(sp)
149        ldw     r15, FRAME_OFFSET_R15(sp)
150
151        /* Restore context */
152        ldw     ra, FRAME_OFFSET_RA(sp)
153        ldw     ea, FRAME_OFFSET_EA(sp)
154        ldw     et, FRAME_OFFSET_ESTATUS(sp)
155
156        /* Restore the non-volatile register */
157        ldw     r16, FRAME_OFFSET_R16(sp)
158
159        /* Release stack frame */
160        addi    sp, sp, FRAME_SIZE
161
162        /* Restore context */
163        wrctl   estatus, et
164
165        /* Return */
166        eret
Note: See TracBrowser for help on using the repository browser.