foss-for-synopsys-dwc-arc-processors / embarc_osp

embARC Open Software Platform (OSP) - An embedded software distribution for IoT and other embedded applications for ARC
https://www.embarc.org/
BSD 3-Clause "New" or "Revised" License
70 stars 63 forks source link

Bug in interrupt handling without storing DSP/FPU registers #74

Closed mfarag13 closed 5 years ago

mfarag13 commented 5 years ago

Issue Summary


Bug

Development Environment

Bug Description

FPU and DSP registers are not saved during handling of interrupts and exceptions, This may lead to undefined behavior. For my case: I have a thread that has a division operation, and there is a vKernelTick which is the ISR of tick timer of freertos port. This interrupt has also a division operation in calling of board_timer_update. MW is optimizing the local variables in case of division and use the accl and acch registers, so if the tick interrupt happens after performing the division operation and before using accl or acch register, there will be a corrupted values in those registers when returning from the ISR where an exception happened and the arc_reset is called.


Enhancement

Adding the following code to INTERRUPT_PROLOGUE and EXCEPTION_PROLOGUE at arc_asm_common.h

#if ARC_FEATURE_FPU_DSP_CONTEXT
    SAVE_R58_R59
    SAVE_FPU_REGS
    SAVE_DSP_REGS
#endif

and the following to INTERRUPT_EPILOGUE and EXCEPTION_EPILOGUE

#if ARC_FEATURE_FPU_DSP_CONTEXT
    RESTORE_DSP_REGS
    RESTORE_FPU_REGS
    RESTORE_R58_R59
#endif

same as SAVE_CALLEE_REGS and RESTORE_CALLEE_REGS.

vonhust commented 5 years ago

If interrupt handlers will use DSP/FPU (which is not recommended as these operations are time consuming), these registers should be pushed and popped

at the entry and exit of interrupts, i.e, move the pop/push from SAVE_CALLEE_REGS/RESTORE_CALLEE_REGS to INTERRUPT_PROLOGUE/ INTERRUPT_EPILOGUE.

The hardware will not push&pop these regs automatically (same for ARM).

So this is not a bug, but a choice.

mfarag13 commented 5 years ago

Hi @vonhust , DSP Operation (Division) is already used in an interrupt vKernelTick at freertos port for ARC in function board_timer_update. In this case freertos port should be updated. or we can add push/pop to INTERRUPT_PROLOGUE/ INTERRUPT_EPILOGUE.