forked from Imagelibrary/rtems
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.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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) );
|
||||
|
||||
Reference in New Issue
Block a user