diff options
author | Chris Johns <chrisj@rtems.org> | 2011-08-18 09:00:14 +0000 |
---|---|---|
committer | Chris Johns <chrisj@rtems.org> | 2011-08-18 09:00:14 +0000 |
commit | a3854892811dbf4e8d36fb6666c19e472d10d787 (patch) | |
tree | 8e135e5a7c0329b79a6865a956f893449c7926e2 /cpukit/score/cpu | |
parent | 2011-08-18 Sebastian Huber <sebastian.huber@embedded-brains.de> (diff) | |
download | rtems-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')
-rw-r--r-- | cpukit/score/cpu/nios2/ChangeLog | 12 | ||||
-rw-r--r-- | cpukit/score/cpu/nios2/cpu.c | 32 | ||||
-rw-r--r-- | cpukit/score/cpu/nios2/cpu_asm.S | 2 | ||||
-rw-r--r-- | cpukit/score/cpu/nios2/irq.c | 36 | ||||
-rw-r--r-- | cpukit/score/cpu/nios2/nios2-iic-low-level.S | 4 | ||||
-rw-r--r-- | cpukit/score/cpu/nios2/rtems/score/cpu.h | 85 |
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) ); |