summaryrefslogtreecommitdiffstats
path: root/cpukit/score/cpu/nios2
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2011-08-09 11:11:30 +0000
committerSebastian Huber <sebastian.huber@embedded-brains.de>2011-08-09 11:11:30 +0000
commit3ee5a2e29b8e96239256130447374eef55d74970 (patch)
tree5117bde76246c4ed74cde6e324c6325d05bdf27c /cpukit/score/cpu/nios2
parent2011-08-09 Sebastian Huber <sebastian.huber@embedded-brains.de> (diff)
downloadrtems-3ee5a2e29b8e96239256130447374eef55d74970.tar.bz2
2011-08-09 Sebastian Huber <sebastian.huber@embedded-brains.de>
* nios2-iic-low-level.S: New file. * cpu_asm.S: Moved low-level interrupt handling into new file. * Makefile.am: Reflect change from above.
Diffstat (limited to 'cpukit/score/cpu/nios2')
-rw-r--r--cpukit/score/cpu/nios2/ChangeLog6
-rw-r--r--cpukit/score/cpu/nios2/Makefile.am5
-rw-r--r--cpukit/score/cpu/nios2/cpu_asm.S299
-rw-r--r--cpukit/score/cpu/nios2/nios2-iic-low-level.S321
4 files changed, 331 insertions, 300 deletions
diff --git a/cpukit/score/cpu/nios2/ChangeLog b/cpukit/score/cpu/nios2/ChangeLog
index 158de7ebe2..61d1bb4b92 100644
--- a/cpukit/score/cpu/nios2/ChangeLog
+++ b/cpukit/score/cpu/nios2/ChangeLog
@@ -1,5 +1,11 @@
2011-08-09 Sebastian Huber <sebastian.huber@embedded-brains.de>
+ * nios2-iic-low-level.S: New file.
+ * cpu_asm.S: Moved low-level interrupt handling into new file.
+ * Makefile.am: Reflect change from above.
+
+2011-08-09 Sebastian Huber <sebastian.huber@embedded-brains.de>
+
* cpu_asm.S, rtems/score/cpu.h: There is no need to save the global
pointer (gp) in the thread register context since it is a system wide
constant and set-up with the C runtime environment.
diff --git a/cpukit/score/cpu/nios2/Makefile.am b/cpukit/score/cpu/nios2/Makefile.am
index 2004daa2f3..2921813434 100644
--- a/cpukit/score/cpu/nios2/Makefile.am
+++ b/cpukit/score/cpu/nios2/Makefile.am
@@ -17,7 +17,10 @@ include_rtems_score_HEADERS += rtems/score/cpu_asm.h
include_rtems_score_HEADERS += rtems/score/types.h
noinst_LIBRARIES = libscorecpu.a
-libscorecpu_a_SOURCES = cpu.c irq.c cpu_asm.S
+libscorecpu_a_SOURCES = cpu.c \
+ irq.c \
+ nios2-iic-low-level.S \
+ cpu_asm.S
libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
all-local: $(PREINSTALL_FILES)
diff --git a/cpukit/score/cpu/nios2/cpu_asm.S b/cpukit/score/cpu/nios2/cpu_asm.S
index c0f6a082f1..985e8b3e90 100644
--- a/cpukit/score/cpu/nios2/cpu_asm.S
+++ b/cpukit/score/cpu/nios2/cpu_asm.S
@@ -83,302 +83,3 @@ _CPU_Context_restore:
/* Copy first to second arg, then re-use 2nd half of Context_switch */
mov r5, r4
br _CPU_Context_switch_restore
-
-
-/* ===================================================================== */
-
- .globl _exception_vector
-
-_exception_vector:
-
- /*
- * First, re-wind so we're pointed to the instruction where the exception
- * occurred.
- */
-
- addi ea, ea, -4
-
- /*
- * Now test to determine the cause of the exception.
- */
-
- /* TODO: Look at [ea] if there was an unknown/trap instruction */
-
- /* If interrupts are globally disabled, it certainly was no interrupt */
- rdctl et, estatus
- andi et, et, 1
- beq et, zero, _Exception_Handler
-
- /* If no interrupts are pending, it was a software exception */
- rdctl et, ipending
- beq et, zero, _Exception_Handler
-
- /*
- * Falling through to here means that this was a hardware interrupt.
- */
-
- br _ISR_Handler
-
-/* =====================================================================
- * Exception handler:
- * Responsible for unimplemented instructions and other software
- * exceptions. Not responsible for hardware interrupts. Currently,
- * software exceptions are regarded as error conditions, and the
- * handling isn't perfect. */
-
-_Exception_Handler:
-
- /* stw et, 108(sp') => stw et, -20(sp) */
- stw et, -20(sp)
- mov et, sp
- addi sp, sp, -128
-
- stw r1, 0(sp)
- stw r2, 4(sp)
- stw r3, 8(sp)
-
- rdctl r1, estatus
- rdctl r2, ienable
- rdctl r3, ipending
-
- stw r4, 12(sp)
- stw r5, 16(sp)
- stw r6, 20(sp)
- stw r7, 24(sp)
- stw r8, 28(sp)
- stw r9, 32(sp)
- stw r10, 36(sp)
- stw r11, 40(sp)
- stw r12, 44(sp)
- stw r13, 48(sp)
- stw r14, 52(sp)
- stw r15, 56(sp)
- stw r16, 60(sp)
- stw r17, 64(sp)
- stw r18, 68(sp)
- stw r19, 72(sp)
- stw r20, 76(sp)
- stw r21, 80(sp)
- stw r22, 84(sp)
- stw r23, 88(sp)
- stw gp, 92(sp)
- stw fp, 96(sp)
- /* sp */
- stw et, 100(sp)
- stw ra, 104(sp)
- /* stw et, 108(sp) */
- stw ea, 112(sp)
-
- /* status */
- stw r1, 116(sp)
- /* ienable */
- stw r2, 120(sp)
- /* ipending */
- stw r3, 124(sp)
-
- /*
- * Restore the global pointer.
- */
-
- movhi gp, %hiadj(_gp)
- addi gp, gp, %lo(_gp)
-
- /*
- * Pass a pointer to the stack frame as the input argument of the
- * exception handler (CPU_Exception_frame *).
- */
-
- mov r4, sp
-
- /*
- * Call the exception handler.
- */
-
- .extern __Exception_Handler
- call __Exception_Handler
-
-stuck_in_exception:
- br stuck_in_exception
-
- /*
- * Restore the saved registers, so that all general purpose registers
- * have been restored to their state at the time the interrupt occured.
- */
-
- ldw r1, 0(sp)
- ldw r2, 4(sp)
- ldw r3, 8(sp)
- ldw r4, 12(sp)
- ldw r5, 16(sp)
- ldw r6, 20(sp)
- ldw r7, 24(sp)
- ldw r8, 28(sp)
- ldw r9, 32(sp)
- ldw r10, 36(sp)
- ldw r11, 40(sp)
- ldw r12, 44(sp)
- ldw r13, 48(sp)
- ldw r14, 52(sp)
- ldw r15, 56(sp)
- ldw r16, 60(sp)
- ldw r17, 64(sp)
- ldw r18, 68(sp)
- ldw r19, 72(sp)
- ldw r20, 76(sp)
- ldw r21, 80(sp)
- ldw r22, 84(sp)
- ldw r23, 88(sp)
- ldw gp, 92(sp)
- ldw fp, 96(sp)
- ldw ra, 104(sp)
-
- /* Disable interrupts */
- wrctl status, r0
-
- ldw ea, 112(sp)
- ldw et, 116(sp)
-
- /* FIXME: Enable interrupts after exception processing */
- ori et, et, 1
- wrctl estatus, et
- ldw et, 108(sp)
-
- /* Restore stack pointer */
- ldw sp, 100(sp)
-
- eret
-
-/* ===================================================================== */
-
- .section .text
-
-_ISR_Handler:
-
- /*
- * Process an external hardware interrupt.
- *
- * First, preserve all callee saved registers on
- * the stack. (See the Nios2 ABI documentation for details).
- *
- * Do we really need to save all?
- *
- * If this is interrupting a task (and not another interrupt),
- * everything is saved into the task's stack, thus putting us
- * in a situation similar to when the task calls a subroutine
- * (and only the CPU_Context_Control subset needs to be changed)
- */
-
- rdctl et, estatus
-
- /* Keep this in the same order as CPU_Interrupt_frame: */
-
- addi sp, sp, -76
- stw r1, 0(sp)
- stw r2, 4(sp)
- stw r3, 8(sp)
- stw r4, 12(sp)
- stw r5, 16(sp)
- stw r6, 20(sp)
- stw r7, 24(sp)
- stw r8, 28(sp)
- stw r9, 32(sp)
- stw r10, 36(sp)
- stw r11, 40(sp)
- stw r12, 44(sp)
- stw r13, 48(sp)
- stw r14, 52(sp)
- stw r15, 56(sp)
- stw ra, 60(sp)
- stw gp, 64(sp)
- /* et contains status */
- stw et, 68(sp)
- stw ea, 72(sp)
-
- /*
- * Obtain a bitlist of the pending interrupts.
- */
-
- rdctl et, ipending
-
- /*
- * Restore the global pointer to the expected value.
- */
-
- movhi gp, %hiadj(_gp)
- addi gp, gp, %lo(_gp)
-
- /*
- * Search through the bit list stored in r24(et) to find the first enabled
- * bit. The offset of this bit is the index of the interrupt that is
- * to be handled.
- */
-
- mov r4, zero
-6:
- andi r3, r24, 1
- bne r3, zero, 7f
- addi r4, r4, 1
- srli r24, r24, 1
- br 6b
-7:
-
- /*
- * Having located the interrupt source, r4 contains the index of the
- * interrupt to be handled. r5, the 2nd argument to the function,
- * will point to the CPU_Interrupt_frame.
- */
-
- mov r5, sp
-
- .extern __ISR_Handler
- call __ISR_Handler
-
- /*
- * Now that the interrupt processing is complete, prepare to return to
- * the interrupted code.
- */
-
- /*
- * Restore the saved registers, so that all general purpose registers
- * have been restored to their state at the time the interrupt occured.
- */
-
- ldw r1, 0(sp)
- ldw r2, 4(sp)
- ldw r3, 8(sp)
- ldw r4, 12(sp)
- ldw r5, 16(sp)
- ldw r6, 20(sp)
- ldw r7, 24(sp)
- ldw r8, 28(sp)
- ldw r9, 32(sp)
- ldw r10, 36(sp)
- ldw r11, 40(sp)
- ldw r12, 44(sp)
- ldw r13, 48(sp)
- ldw r14, 52(sp)
- ldw r15, 56(sp)
- ldw ra, 60(sp)
- ldw gp, 64(sp)
-
- /* Disable interrupts */
- wrctl status, r0
-
- /* Restore the exception registers */
-
- /* load saved ea into ea */
- ldw ea, 72(sp)
- /* load saved estatus into et */
- ldw et, 68(sp)
- /* Always have interrupts enabled when we return from interrupt */
- ori et, et, 1
- wrctl estatus, et
- /* Restore the stack pointer */
- addi sp, sp, 76
-
- /*
- * Return to the interrupted instruction.
- */
- eret
-
-
diff --git a/cpukit/score/cpu/nios2/nios2-iic-low-level.S b/cpukit/score/cpu/nios2/nios2-iic-low-level.S
new file mode 100644
index 0000000000..7a5d24ca59
--- /dev/null
+++ b/cpukit/score/cpu/nios2/nios2-iic-low-level.S
@@ -0,0 +1,321 @@
+/*
+ * $Id$
+ *
+ * This file contains all assembly code for the
+ * NIOS2 implementation of RTEMS.
+ *
+ * Copyright (c) 2006 Kolja Waschk (rtemsdev/ixo.de)
+ *
+ * Derived from no_cpu/cpu_asm.S, copyright (c) 1989-1999,
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/asm.h>
+#include <rtems/score/cpu_asm.h>
+
+ .set noat
+
+ .globl _exception_vector
+
+_exception_vector:
+
+ /*
+ * First, re-wind so we're pointed to the instruction where the exception
+ * occurred.
+ */
+
+ addi ea, ea, -4
+
+ /*
+ * Now test to determine the cause of the exception.
+ */
+
+ /* TODO: Look at [ea] if there was an unknown/trap instruction */
+
+ /* If interrupts are globally disabled, it certainly was no interrupt */
+ rdctl et, estatus
+ andi et, et, 1
+ beq et, zero, _Exception_Handler
+
+ /* If no interrupts are pending, it was a software exception */
+ rdctl et, ipending
+ beq et, zero, _Exception_Handler
+
+ /*
+ * Falling through to here means that this was a hardware interrupt.
+ */
+
+ br _ISR_Handler
+
+/* =====================================================================
+ * Exception handler:
+ * Responsible for unimplemented instructions and other software
+ * exceptions. Not responsible for hardware interrupts. Currently,
+ * software exceptions are regarded as error conditions, and the
+ * handling isn't perfect. */
+
+_Exception_Handler:
+
+ /* stw et, 108(sp') => stw et, -20(sp) */
+ stw et, -20(sp)
+ mov et, sp
+ addi sp, sp, -128
+
+ stw r1, 0(sp)
+ stw r2, 4(sp)
+ stw r3, 8(sp)
+
+ rdctl r1, estatus
+ rdctl r2, ienable
+ rdctl r3, ipending
+
+ stw r4, 12(sp)
+ stw r5, 16(sp)
+ stw r6, 20(sp)
+ stw r7, 24(sp)
+ stw r8, 28(sp)
+ stw r9, 32(sp)
+ stw r10, 36(sp)
+ stw r11, 40(sp)
+ stw r12, 44(sp)
+ stw r13, 48(sp)
+ stw r14, 52(sp)
+ stw r15, 56(sp)
+ stw r16, 60(sp)
+ stw r17, 64(sp)
+ stw r18, 68(sp)
+ stw r19, 72(sp)
+ stw r20, 76(sp)
+ stw r21, 80(sp)
+ stw r22, 84(sp)
+ stw r23, 88(sp)
+ stw gp, 92(sp)
+ stw fp, 96(sp)
+ /* sp */
+ stw et, 100(sp)
+ stw ra, 104(sp)
+ /* stw et, 108(sp) */
+ stw ea, 112(sp)
+
+ /* status */
+ stw r1, 116(sp)
+ /* ienable */
+ stw r2, 120(sp)
+ /* ipending */
+ stw r3, 124(sp)
+
+ /*
+ * Restore the global pointer.
+ */
+
+ movhi gp, %hiadj(_gp)
+ addi gp, gp, %lo(_gp)
+
+ /*
+ * Pass a pointer to the stack frame as the input argument of the
+ * exception handler (CPU_Exception_frame *).
+ */
+
+ mov r4, sp
+
+ /*
+ * Call the exception handler.
+ */
+
+ .extern __Exception_Handler
+ call __Exception_Handler
+
+stuck_in_exception:
+ br stuck_in_exception
+
+ /*
+ * Restore the saved registers, so that all general purpose registers
+ * have been restored to their state at the time the interrupt occured.
+ */
+
+ ldw r1, 0(sp)
+ ldw r2, 4(sp)
+ ldw r3, 8(sp)
+ ldw r4, 12(sp)
+ ldw r5, 16(sp)
+ ldw r6, 20(sp)
+ ldw r7, 24(sp)
+ ldw r8, 28(sp)
+ ldw r9, 32(sp)
+ ldw r10, 36(sp)
+ ldw r11, 40(sp)
+ ldw r12, 44(sp)
+ ldw r13, 48(sp)
+ ldw r14, 52(sp)
+ ldw r15, 56(sp)
+ ldw r16, 60(sp)
+ ldw r17, 64(sp)
+ ldw r18, 68(sp)
+ ldw r19, 72(sp)
+ ldw r20, 76(sp)
+ ldw r21, 80(sp)
+ ldw r22, 84(sp)
+ ldw r23, 88(sp)
+ ldw gp, 92(sp)
+ ldw fp, 96(sp)
+ ldw ra, 104(sp)
+
+ /* Disable interrupts */
+ wrctl status, r0
+
+ ldw ea, 112(sp)
+ ldw et, 116(sp)
+
+ /* FIXME: Enable interrupts after exception processing */
+ ori et, et, 1
+ wrctl estatus, et
+ ldw et, 108(sp)
+
+ /* Restore stack pointer */
+ ldw sp, 100(sp)
+
+ eret
+
+/* ===================================================================== */
+
+ .section .text
+
+_ISR_Handler:
+
+ /*
+ * Process an external hardware interrupt.
+ *
+ * First, preserve all callee saved registers on
+ * the stack. (See the Nios2 ABI documentation for details).
+ *
+ * Do we really need to save all?
+ *
+ * If this is interrupting a task (and not another interrupt),
+ * everything is saved into the task's stack, thus putting us
+ * in a situation similar to when the task calls a subroutine
+ * (and only the CPU_Context_Control subset needs to be changed)
+ */
+
+ rdctl et, estatus
+
+ /* Keep this in the same order as CPU_Interrupt_frame: */
+
+ addi sp, sp, -76
+ stw r1, 0(sp)
+ stw r2, 4(sp)
+ stw r3, 8(sp)
+ stw r4, 12(sp)
+ stw r5, 16(sp)
+ stw r6, 20(sp)
+ stw r7, 24(sp)
+ stw r8, 28(sp)
+ stw r9, 32(sp)
+ stw r10, 36(sp)
+ stw r11, 40(sp)
+ stw r12, 44(sp)
+ stw r13, 48(sp)
+ stw r14, 52(sp)
+ stw r15, 56(sp)
+ stw ra, 60(sp)
+ stw gp, 64(sp)
+ /* et contains status */
+ stw et, 68(sp)
+ stw ea, 72(sp)
+
+ /*
+ * Obtain a bitlist of the pending interrupts.
+ */
+
+ rdctl et, ipending
+
+ /*
+ * Restore the global pointer to the expected value.
+ */
+
+ movhi gp, %hiadj(_gp)
+ addi gp, gp, %lo(_gp)
+
+ /*
+ * Search through the bit list stored in r24(et) to find the first enabled
+ * bit. The offset of this bit is the index of the interrupt that is
+ * to be handled.
+ */
+
+ mov r4, zero
+6:
+ andi r3, r24, 1
+ bne r3, zero, 7f
+ addi r4, r4, 1
+ srli r24, r24, 1
+ br 6b
+7:
+
+ /*
+ * Having located the interrupt source, r4 contains the index of the
+ * interrupt to be handled. r5, the 2nd argument to the function,
+ * will point to the CPU_Interrupt_frame.
+ */
+
+ mov r5, sp
+
+ .extern __ISR_Handler
+ call __ISR_Handler
+
+ /*
+ * Now that the interrupt processing is complete, prepare to return to
+ * the interrupted code.
+ */
+
+ /*
+ * Restore the saved registers, so that all general purpose registers
+ * have been restored to their state at the time the interrupt occured.
+ */
+
+ ldw r1, 0(sp)
+ ldw r2, 4(sp)
+ ldw r3, 8(sp)
+ ldw r4, 12(sp)
+ ldw r5, 16(sp)
+ ldw r6, 20(sp)
+ ldw r7, 24(sp)
+ ldw r8, 28(sp)
+ ldw r9, 32(sp)
+ ldw r10, 36(sp)
+ ldw r11, 40(sp)
+ ldw r12, 44(sp)
+ ldw r13, 48(sp)
+ ldw r14, 52(sp)
+ ldw r15, 56(sp)
+ ldw ra, 60(sp)
+ ldw gp, 64(sp)
+
+ /* Disable interrupts */
+ wrctl status, r0
+
+ /* Restore the exception registers */
+
+ /* load saved ea into ea */
+ ldw ea, 72(sp)
+ /* load saved estatus into et */
+ ldw et, 68(sp)
+ /* Always have interrupts enabled when we return from interrupt */
+ ori et, et, 1
+ wrctl estatus, et
+ /* Restore the stack pointer */
+ addi sp, sp, 76
+
+ /*
+ * Return to the interrupted instruction.
+ */
+ eret
+
+