nios2: implement fiberRtnValueSet()
The return value of _Swap() is often treated as a "don't care" value and thus often ignored. However, there are cases when it is desirable to have a meaningful return value. This meaningful value can be assigned via fiberRtnValueSet(). To that end, a new field has been added to the coop register struct to store this value for when _Swap() needs to return that meaningful value. Change-Id: Ic4967fa7d602850c09ebde18e8bfd4c97cda9ec8 Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
885e9084a8
commit
8a8a2928e5
3 changed files with 15 additions and 6 deletions
|
@ -55,6 +55,7 @@ GEN_OFFSET_SYM(t_coop, r28);
|
||||||
GEN_OFFSET_SYM(t_coop, ra);
|
GEN_OFFSET_SYM(t_coop, ra);
|
||||||
GEN_OFFSET_SYM(t_coop, sp);
|
GEN_OFFSET_SYM(t_coop, sp);
|
||||||
GEN_OFFSET_SYM(t_coop, key);
|
GEN_OFFSET_SYM(t_coop, key);
|
||||||
|
GEN_OFFSET_SYM(t_coop, retval);
|
||||||
|
|
||||||
/* size of the struct tcs structure sans save area for floating point regs */
|
/* size of the struct tcs structure sans save area for floating point regs */
|
||||||
GEN_ABSOLUTE_SYM(__tTCS_NOFLOAT_SIZEOF, sizeof(tTCS));
|
GEN_ABSOLUTE_SYM(__tTCS_NOFLOAT_SIZEOF, sizeof(tTCS));
|
||||||
|
|
|
@ -93,15 +93,24 @@ BRANCH_LABEL(next_chosen)
|
||||||
ldw ra, __tTCS_coopReg_OFFSET + __t_coop_ra_OFFSET(r11)
|
ldw ra, __tTCS_coopReg_OFFSET + __t_coop_ra_OFFSET(r11)
|
||||||
ldw sp, __tTCS_coopReg_OFFSET + __t_coop_sp_OFFSET(r11)
|
ldw sp, __tTCS_coopReg_OFFSET + __t_coop_sp_OFFSET(r11)
|
||||||
|
|
||||||
/* Restore interrupt state in status.PIE */
|
/* Load return value into r2 (return value register). garbage
|
||||||
ldw r2, __tTCS_coopReg_OFFSET + __t_coop_key_OFFSET(r11)
|
* unless someone previously called fiberRtnValueSet(). Do this
|
||||||
andi r3, r2, NIOS2_STATUS_PIE_MSK
|
* before we potentially unlock interrupts.
|
||||||
|
*/
|
||||||
|
ldw r2, __tTCS_coopReg_OFFSET + __t_coop_retval_OFFSET(r11)
|
||||||
|
|
||||||
|
/* irq_unlock(fiber->coopReg.key);
|
||||||
|
* key was supplied as argument to _Swap()
|
||||||
|
*/
|
||||||
|
ldw r3, __tTCS_coopReg_OFFSET + __t_coop_key_OFFSET(r11)
|
||||||
|
andi r3, r3, NIOS2_STATUS_PIE_MSK
|
||||||
beq r3, zero, no_unlock
|
beq r3, zero, no_unlock
|
||||||
rdctl r3, status
|
rdctl r3, status
|
||||||
ori r3, r3, NIOS2_STATUS_PIE_MSK
|
ori r3, r3, NIOS2_STATUS_PIE_MSK
|
||||||
wrctl status, r3
|
wrctl status, r3
|
||||||
|
|
||||||
BRANCH_LABEL(no_unlock)
|
BRANCH_LABEL(no_unlock)
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -91,6 +91,7 @@ struct s_coop {
|
||||||
uint32_t ra; /* Return address */
|
uint32_t ra; /* Return address */
|
||||||
uint32_t sp; /* Stack pointer */
|
uint32_t sp; /* Stack pointer */
|
||||||
uint32_t key; /* IRQ status before irq_lock() and call to _Swap() */
|
uint32_t key; /* IRQ status before irq_lock() and call to _Swap() */
|
||||||
|
uint32_t retval; /* Return value of _Swap() */
|
||||||
};
|
};
|
||||||
typedef struct s_coop t_coop;
|
typedef struct s_coop t_coop;
|
||||||
|
|
||||||
|
@ -170,9 +171,7 @@ static ALWAYS_INLINE void nanoArchInit(void)
|
||||||
static ALWAYS_INLINE void fiberRtnValueSet(struct tcs *fiber,
|
static ALWAYS_INLINE void fiberRtnValueSet(struct tcs *fiber,
|
||||||
unsigned int value)
|
unsigned int value)
|
||||||
{
|
{
|
||||||
ARG_UNUSED(fiber);
|
fiber->coopReg.retval = value;
|
||||||
ARG_UNUSED(value);
|
|
||||||
/* STUB */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void _IntLibInit(void)
|
static inline void _IntLibInit(void)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue