source: rtems/cpukit/score/cpu/nios2/nios2-eic-il-low-level.S @ 00acca28

5
Last change on this file since 00acca28 was 99a1f122, checked in by Sebastian Huber <sebastian.huber@…>, on 01/13/15 at 07:24:36

nios2: Disable assembler warning

Close #2232.

  • Property mode set to 100644
File size: 5.5 KB
Line 
1/*
2 * Copyright (c) 2011-2015 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Dornierstr. 4
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#include <rtems/score/nios2-utility.h>
17
18#define FRAME_OFFSET_RA 0
19#define FRAME_OFFSET_AT 4
20#define FRAME_OFFSET_R2 8
21#define FRAME_OFFSET_R3 12
22#define FRAME_OFFSET_R4 16
23#define FRAME_OFFSET_R5 20
24#define FRAME_OFFSET_R6 24
25#define FRAME_OFFSET_R7 28
26#define FRAME_OFFSET_R8 32
27#define FRAME_OFFSET_R9 36
28#define FRAME_OFFSET_R10 40
29#define FRAME_OFFSET_R11 44
30#define FRAME_OFFSET_R12 48
31#define FRAME_OFFSET_R13 52
32#define FRAME_OFFSET_R14 56
33#define FRAME_OFFSET_R15 60
34#define FRAME_OFFSET_STATUS 64
35#define FRAME_OFFSET_EA  68
36
37#define FRAME_SIZE (FRAME_OFFSET_EA + 4)
38
39        .set    noat
40        .set    nobreak
41        .section        .text
42
43        .extern _Per_CPU_Information
44        .extern _Thread_Dispatch_disable_level
45        .extern _Nios2_Thread_dispatch_disabled
46        .extern _Nios2_ISR_Status_interrupts_disabled
47
48        .globl  _Nios2_ISR_Dispatch_with_shadow_non_preemptive
49
50_Nios2_ISR_Dispatch_with_shadow_non_preemptive:
51
52        /* Load thread dispatch disable level */
53        ldw     r16, %gprel(_Thread_Dispatch_disable_level)(gp)
54
55        /* Load high level handler address and argument */
56        ldw     r8, 4(et)
57        ldw     r4, 8(et)
58
59        /* Increment and store thread dispatch disable level */
60        addi    r9, r16, 1
61        stw     r9, %gprel(_Thread_Dispatch_disable_level)(gp)
62
63        /* Call high level handler with argument */
64        callr   r8
65
66        /* Load thread dispatch necessary */
67        ldb     r12, %gprel(_Per_CPU_Information + PER_CPU_DISPATCH_NEEDED)(gp)
68
69        /* Load Nios II specific thread dispatch disabled */
70        ldw     r13, %gprel(_Nios2_Thread_dispatch_disabled)(gp)
71
72        /* Read status */
73        rdctl   r14, status
74
75        /* Fix return address */
76        subi    ea, ea, 4
77
78        /*
79         * Restore the thread dispatch disable level.  We must do this before
80         * we return to the normal register set, because otherwise we have
81         * problems if someone deletes or restarts the interrupted thread while
82         * we are in the thread dispatch helper.
83         */
84        stw     r16, %gprel(_Thread_Dispatch_disable_level)(gp)
85
86        /* Is thread dispatch allowed? */
87        bne     r16, zero, no_thread_dispatch
88
89        /* Is thread dispatch necessary? */
90        beq     r12, zero, no_thread_dispatch
91
92        /* Is outermost interrupt? */
93        andhi   r14, r14, 0x3f
94        bne     r14, zero, no_thread_dispatch
95
96        /* Is Nios II specific thread dispatch allowed? */
97        bne     r13, zero, no_thread_dispatch
98
99        /* Obtain stack frame in normal register set */
100        rdprs   r15, sp, -FRAME_SIZE
101
102        /* Disable Nios II specific thread dispatch */
103        stw     r12, %gprel(_Nios2_Thread_dispatch_disabled)(gp)
104
105        /* Save context */
106        stw     sstatus, FRAME_OFFSET_STATUS(r15)
107        stw     ea, FRAME_OFFSET_EA(r15)
108
109        /* Set thread dispatch helper address */
110        movhi   ea, %hiadj(thread_dispatch_helper)
111        addi    ea, ea, %lo(thread_dispatch_helper)
112
113        /* Update stack pointer in normal register set */
114        wrprs   sp, r15
115
116no_thread_dispatch:
117
118        /*
119         * Return to thread dispatch helper, interrupted thread or interrupted
120         * lower level interrupt service routine.
121         */
122        eret
123
124thread_dispatch_helper:
125
126        /* This code executes in the context of the interrupted thread */
127
128        /* Save volatile registers */
129        stw     ra, FRAME_OFFSET_RA(sp)
130        stw     at, FRAME_OFFSET_AT(sp)
131        stw     r2, FRAME_OFFSET_R2(sp)
132        stw     r3, FRAME_OFFSET_R3(sp)
133        stw     r4, FRAME_OFFSET_R4(sp)
134        stw     r5, FRAME_OFFSET_R5(sp)
135        stw     r6, FRAME_OFFSET_R6(sp)
136        stw     r7, FRAME_OFFSET_R7(sp)
137        stw     r8, FRAME_OFFSET_R8(sp)
138        stw     r9, FRAME_OFFSET_R9(sp)
139        stw     r10, FRAME_OFFSET_R10(sp)
140        stw     r11, FRAME_OFFSET_R11(sp)
141        stw     r12, FRAME_OFFSET_R12(sp)
142        stw     r13, FRAME_OFFSET_R13(sp)
143        stw     r14, FRAME_OFFSET_R14(sp)
144        stw     r15, FRAME_OFFSET_R15(sp)
145
146do_thread_dispatch:
147
148        call    _Thread_Dispatch
149
150        /* Restore some volatile registers */
151        ldw     ra, FRAME_OFFSET_RA(sp)
152        ldw     at, FRAME_OFFSET_AT(sp)
153        ldw     r2, FRAME_OFFSET_R2(sp)
154        ldw     r3, FRAME_OFFSET_R3(sp)
155        ldw     r4, FRAME_OFFSET_R4(sp)
156        ldw     r5, FRAME_OFFSET_R5(sp)
157        ldw     r6, FRAME_OFFSET_R6(sp)
158        ldw     r7, FRAME_OFFSET_R7(sp)
159        ldw     r8, FRAME_OFFSET_R8(sp)
160        ldw     r9, FRAME_OFFSET_R9(sp)
161        ldw     r10, FRAME_OFFSET_R10(sp)
162        ldw     r11, FRAME_OFFSET_R11(sp)
163        ldw     r12, FRAME_OFFSET_R12(sp)
164
165        /*
166         * Disable interrupts.
167         *
168         * We have the following invariants:
169         *   1. status.RSIE == 0: thread context initialization
170         *   2. status.CRS == 0: thread context initialization
171         *   3. status.PRS: arbitrary
172         *   4. status.IL < interrupt disable IL: else we would not be here
173         *   5. status.IH == 0: thread context initialization
174         *   6. status.U == 0: thread context initialization
175         *   7. status.PIE == 1: thread context initialization
176         * Thus we can use a constant to disable interrupts.
177         */
178        rdctl   r14, status
179        movi    r15, %lo(_Nios2_ISR_Status_interrupts_disabled)
180        wrctl   status, r15
181
182        /* Load thread dispatch necessary */
183        ldb     r13, %gprel(_Per_CPU_Information + PER_CPU_DISPATCH_NEEDED)(gp)
184
185        /* Is thread dispatch necessary? */
186        bne     r13, zero, enable_interrupts_before_thread_dispatch
187
188        /* Enable Nios II specific thread dispatch */
189        stw     zero, %gprel(_Nios2_Thread_dispatch_disabled)(gp)
190
191        /* Restore remaining volatile register */
192        ldw     r13, FRAME_OFFSET_R13(sp)
193        ldw     r14, FRAME_OFFSET_R14(sp)
194        ldw     r15, FRAME_OFFSET_R15(sp)
195
196        /* Restore context */
197        ldw     et, FRAME_OFFSET_STATUS(sp)
198        ldw     ea, FRAME_OFFSET_EA(sp)
199
200        /* Release stack frame */
201        addi    sp, sp, FRAME_SIZE
202
203        /* Restore context */
204        wrctl   estatus, et
205
206        /* Return to interrupted thread */
207        eret
208
209enable_interrupts_before_thread_dispatch:
210
211        /* Restore status */
212        wrctl   status, r14
213
214        br      do_thread_dispatch
Note: See TracBrowser for help on using the repository browser.