summaryrefslogtreecommitdiffstats
path: root/cpukit/score/cpu/nios2
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2011-08-18 09:00:14 +0000
committerChris Johns <chrisj@rtems.org>2011-08-18 09:00:14 +0000
commita3854892811dbf4e8d36fb6666c19e472d10d787 (patch)
tree8e135e5a7c0329b79a6865a956f893449c7926e2 /cpukit/score/cpu/nios2
parent2011-08-18 Sebastian Huber <sebastian.huber@embedded-brains.de> (diff)
downloadrtems-a3854892811dbf4e8d36fb6666c19e472d10d787.tar.bz2
2011-08-18 Chris Johns <chrisj@rtems.org>
* cpu.c: Fix the ISR get level for the IIC. Make _CPU_Context_Initialize a function rather than inlined. * cpu_asm.S: Do not enable interrupt on return, rather resume the state on entry to the ISR. * irq.c, nios2/nios2-iic-low-level.S: Change the ISR handler so the ipending decoding is in C and within the interrupt context. This is usable with the Altera HAL directly. * rtems/score/cpu.h: Add ienable and ipending interfaces. Add some comments. Remove _CPU_Context_Initialize.
Diffstat (limited to 'cpukit/score/cpu/nios2')
-rw-r--r--cpukit/score/cpu/nios2/ChangeLog12
-rw-r--r--cpukit/score/cpu/nios2/cpu.c32
-rw-r--r--cpukit/score/cpu/nios2/cpu_asm.S2
-rw-r--r--cpukit/score/cpu/nios2/irq.c36
-rw-r--r--cpukit/score/cpu/nios2/nios2-iic-low-level.S4
-rw-r--r--cpukit/score/cpu/nios2/rtems/score/cpu.h85
6 files changed, 119 insertions, 52 deletions
diff --git a/cpukit/score/cpu/nios2/ChangeLog b/cpukit/score/cpu/nios2/ChangeLog
index 94ca8ec29d..95bbe3c451 100644
--- a/cpukit/score/cpu/nios2/ChangeLog
+++ b/cpukit/score/cpu/nios2/ChangeLog
@@ -1,3 +1,15 @@
+2011-08-18 Chris Johns <chrisj@rtems.org>
+
+ * cpu.c: Fix the ISR get level for the IIC. Make
+ _CPU_Context_Initialize a function rather than inlined.
+ * cpu_asm.S: Do not enable interrupt on return, rather resume the
+ state on entry to the ISR.
+ * irq.c, nios2/nios2-iic-low-level.S: Change the ISR handler so
+ the ipending decoding is in C and within the interrupt
+ context. This is usable with the Altera HAL directly.
+ * rtems/score/cpu.h: Add ienable and ipending interfaces. Add some
+ comments. Remove _CPU_Context_Initialize.
+
2011-08-14 Chris Johns <chrisj@rtems.org>
* rtems/score/cpu.h: Clear the vector table for simple vectored
diff --git a/cpukit/score/cpu/nios2/cpu.c b/cpukit/score/cpu/nios2/cpu.c
index 536e5e8cf8..6686426c5c 100644
--- a/cpukit/score/cpu/nios2/cpu.c
+++ b/cpukit/score/cpu/nios2/cpu.c
@@ -19,6 +19,8 @@
#include <rtems/score/isr.h>
#include <rtems/score/wkspace.h>
+#include <rtems/score/nios2.h>
+
/* _CPU_Initialize
*
* This routine performs processor dependent initialization.
@@ -44,19 +46,33 @@ void _CPU_Initialize(void)
/*
* _CPU_ISR_Get_level
- *
- * NO_CPU Specific Information:
- *
- * XXX document implementation including references if appropriate
*/
uint32_t _CPU_ISR_Get_level( void )
{
- /*
- * This routine returns the current interrupt level.
- */
+ /* @todo Add EIC support. */
+ uint32_t status = __builtin_rdctl(0);
+ return status & 1 ? 0 : 1;
+}
- return 0;
+/*
+ * FIXME: Evaluate interrupt level.
+ */
+void _CPU_Context_Initialize(
+ Context_Control *the_context,
+ uint32_t *stack_base,
+ uint32_t size,
+ uint32_t new_level,
+ void *entry_point,
+ bool is_fp
+)
+{
+ uint32_t stack = (uint32_t)stack_base + size - 4;
+ the_context->fp = stack;
+ the_context->sp = stack;
+ the_context->ra = (intptr_t) entry_point;
+ /* @todo Add EIC support. */
+ the_context->status = new_level ? 0 : 1;
}
/*
diff --git a/cpukit/score/cpu/nios2/cpu_asm.S b/cpukit/score/cpu/nios2/cpu_asm.S
index 985e8b3e90..41ef5b2273 100644
--- a/cpukit/score/cpu/nios2/cpu_asm.S
+++ b/cpukit/score/cpu/nios2/cpu_asm.S
@@ -70,8 +70,6 @@ _CPU_Context_switch_restore:
ldw ea, 40(r5)
ldw at, 44(r5)
- /* FIXME: Always have interrupts enabled when we return from Context_switch */
- ori at, at, 1
wrctl estatus, at
eret
diff --git a/cpukit/score/cpu/nios2/irq.c b/cpukit/score/cpu/nios2/irq.c
index abfbeca0fb..ffca00fece 100644
--- a/cpukit/score/cpu/nios2/irq.c
+++ b/cpukit/score/cpu/nios2/irq.c
@@ -34,19 +34,6 @@
register unsigned long *stack_ptr __asm__ ("sp");
-RTEMS_INLINE_ROUTINE void
-__Dipatch_interrupt_vector(uint32_t vector, proc_ptr pp)
-{
- if ( _ISR_Vector_table[ vector] )
- {
- (*_ISR_Vector_table[ vector ])(vector, pp);
- };
-}
-
-#if (RTEMS_NIOS_USE_ALT_HAL == TRUE)
-
-#include <bsp/alt/nios2.h>
-
RTEMS_INLINE_ROUTINE void __IIC_Handler(void)
{
uint32_t active;
@@ -56,7 +43,7 @@ RTEMS_INLINE_ROUTINE void __IIC_Handler(void)
/*
* Obtain from the interrupt controller a bit list of pending interrupts,
* and then process the highest priority interrupt. This process loops,
- * loading the active interrupt list on each pass until alt_irq_pending()
+ * loading the active interrupt list on each pass until ipending
* return zero.
*
* The maximum interrupt latency for the highest priority interrupt is
@@ -66,7 +53,7 @@ RTEMS_INLINE_ROUTINE void __IIC_Handler(void)
* this is the case.
*/
- NIOS2_READ_IPENDING (active);
+ _CPU_read_ipending (active);
while (active)
{
@@ -75,34 +62,29 @@ RTEMS_INLINE_ROUTINE void __IIC_Handler(void)
/*
* Test each bit in turn looking for an active interrupt. Once one is
- * found, the interrupt handler asigned by a call to alt_irq_register() is
- * called to clear the interrupt condition.
+ * found call it to clear the interrupt condition.
*/
while (active)
{
if (active & mask)
{
- __Dipatch_interrupt_vector(vector, NULL);
+ if ( _ISR_Vector_table[ vector] )
+ (*_ISR_Vector_table[ vector ])(vector, NULL);
active &= ~mask;
}
mask <<= 1;
++vector;
};
- NIOS2_READ_IPENDING (active);
+ _CPU_read_ipending (active);
}
}
-#endif
-#if (RTEMS_NIOS_USE_ALT_HAL == TRUE)
void __ISR_Handler(void)
-#else
-void __ISR_Handler(uint32_t vector, CPU_Interrupt_frame *ifr)
-#endif
{
- register uint32_t level;
+ register uint32_t level;
/* Interrupts are disabled upon entry to this Handler */
@@ -118,11 +100,7 @@ void __ISR_Handler(uint32_t vector, CPU_Interrupt_frame *ifr)
_Thread_Dispatch_increment_disable_level();
-#if (RTEMS_NIOS_USE_ALT_HAL == TRUE)
__IIC_Handler();
-#else
- __Dipatch_interrupt_vector(vector, ifr);
-#endif
/* Make sure that interrupts are disabled again */
_CPU_ISR_Disable( level );
diff --git a/cpukit/score/cpu/nios2/nios2-iic-low-level.S b/cpukit/score/cpu/nios2/nios2-iic-low-level.S
index 7a5d24ca59..0196cf98e3 100644
--- a/cpukit/score/cpu/nios2/nios2-iic-low-level.S
+++ b/cpukit/score/cpu/nios2/nios2-iic-low-level.S
@@ -231,6 +231,7 @@ _ISR_Handler:
stw et, 68(sp)
stw ea, 72(sp)
+#if REMOVED_BY_CCJ
/*
* Obtain a bitlist of the pending interrupts.
*/
@@ -266,7 +267,8 @@ _ISR_Handler:
*/
mov r5, sp
-
+#endif
+
.extern __ISR_Handler
call __ISR_Handler
diff --git a/cpukit/score/cpu/nios2/rtems/score/cpu.h b/cpukit/score/cpu/nios2/rtems/score/cpu.h
index 61a1b421b8..32a5107e6f 100644
--- a/cpukit/score/cpu/nios2/rtems/score/cpu.h
+++ b/cpukit/score/cpu/nios2/rtems/score/cpu.h
@@ -189,40 +189,101 @@ typedef struct {
#define _CPU_Initialize_vectors()
#endif
+/**
+ * @brief Read the ienable register.
+ */
+#define _CPU_read_ienable( value ) \
+ do { value = __builtin_rdctl(3); } while (0)
+
+/**
+ * @brief Write the ienable register.
+ */
+#define _CPU_write_ienable( value ) \
+ do { __builtin_wrctl(3, value); } while (0)
+
+/**
+ * @brief Read the ipending register.
+ */
+#define _CPU_read_ipending( value ) \
+ do { value = __builtin_rdctl(4); } while (0)
+
+/**
+ * Disable all interrupts for a critical section. The previous
+ * level is returned in _level.
+ */
#define _CPU_ISR_Disable( _isr_cookie ) \
do { \
_isr_cookie = __builtin_rdctl( 0 ); \
__builtin_wrctl( 0, 0 ); \
} while ( 0 )
+/**
+ * Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
+ * This indicates the end of a critical section. The parameter
+ * _level is not modified.
+ */
#define _CPU_ISR_Enable( _isr_cookie ) \
do { \
__builtin_wrctl( 0, (int) _isr_cookie ); \
} while ( 0 )
+/**
+ * This temporarily restores the interrupt to _level before immediately
+ * disabling them again. This is used to divide long critical
+ * sections into two or more parts. The parameter _level is not
+ * modified.
+ */
#define _CPU_ISR_Flash( _isr_cookie ) \
do { \
__builtin_wrctl( 0, (int) _isr_cookie ); \
__builtin_wrctl( 0, 0 ); \
} while ( 0 )
-#define _CPU_ISR_Set_level( new_level ) \
+/**
+ * Map interrupt level in task mode onto the hardware that the CPU
+ * actually provides. Currently, interrupt levels which do not
+ * map onto the CPU in a straight fashion are undefined.
+ */
+#define _CPU_ISR_Set_level( new_level ) \
_CPU_ISR_Enable( new_level == 0 ? 1 : 0 );
+/**
+ * @brief Obtain the Current Interrupt Disable Level
+ *
+ * This method is invoked to return the current interrupt disable level.
+ *
+ * @return This method returns the current interrupt disable level.
+ */
uint32_t _CPU_ISR_Get_level( void );
-/*
- * FIXME: Evaluate interrupt level.
+/**
+ * Initialize the context to a state suitable for starting a
+ * task after a context restore operation. Generally, this
+ * involves:
+ *
+ * - setting a starting address
+ * - preparing the stack
+ * - preparing the stack and frame pointers
+ * - setting the proper interrupt level in the context
+ * - initializing the floating point context
+ *
+ * @param[in] the_context points to the context area
+ * @param[in] stack_base is the low address of the allocated stack area
+ * @param[in] size is the size of the stack area in bytes
+ * @param[in] new_level is the interrupt level for the task
+ * @param[in] entry_point is the task's entry point
+ * @param[in] is_fp is set to TRUE if the task is a floating point task
+ *
+ * @note Implemented as a subroutine for the NIOS2 port.
*/
-#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
- _isr, _entry_point, _is_fp ) \
- do { \
- uint32_t _stack = (uint32_t)(_stack_base) + (_size) - 4; \
- (_the_context)->fp = (void *)_stack; \
- (_the_context)->sp = (void *)_stack; \
- (_the_context)->ra = (void *)(_entry_point); \
- (_the_context)->status = 0x1; /* IRQs enabled */ \
- } while ( 0 )
+void _CPU_Context_Initialize(
+ Context_Control *the_context,
+ uint32_t *stack_base,
+ uint32_t size,
+ uint32_t new_level,
+ void *entry_point,
+ bool is_fp
+);
#define _CPU_Context_Restart_self( _the_context ) \
_CPU_Context_restore( (_the_context) );