Aarch32, FPU: Init fpexc with FPU enabled
On 32-bit ARM the fpexc system register is set by loadFpuState, which includes the FPU enable/disable bit FPEXC_EN_BIT. This register is part of the usercontext and needs to be initialised correctly, otherwise the FPU will be disabled by loadFpuState. Before, this bug was hidden because the FPU was enabled lazily after a trap. This bug just caused one extra FPU trap at first FPU use for each task: The first handleFPUFault would fail to enable the FPU, causing another FPU trap when user space gets restarted. On the second FPU fault, switchLocalFpuOwner calls enableFpu first and then calls saveFpuState because ksActiveFPUState is set to the current task's FPU state. Then it gets saved with FPEXC_EN_BIT set and the task can continue with the FPU actually enabled. This also means that with the old code, the initial FPEXC state of each task was equal to the previous active FPU task's. Signed-off-by: Indan Zupancic <indan@nul.nu>
This commit is contained in:
parent
504f1ccf00
commit
77f5fab0a0
2 changed files with 8 additions and 10 deletions
|
|
@ -24,16 +24,6 @@
|
|||
#define FPSID_SW_BIT 23
|
||||
#define FPSID_SUBARCH_SHIFT_POS 16
|
||||
|
||||
#define FPEXC_EX_BIT 31
|
||||
#define FPEXC_EN_BIT 30
|
||||
|
||||
#if defined(CONFIG_ARM_CORTEX_A7) || defined(CONFIG_ARM_CORTEX_A9)
|
||||
#define FPEXC_DEX_BIT 29
|
||||
#endif
|
||||
|
||||
#define FPEXC_DEX_BIT 29
|
||||
#define FPEXC_FP2V_BIT 28
|
||||
|
||||
static void clearEnFPEXC(void)
|
||||
{
|
||||
word_t fpexc;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,11 @@
|
|||
| PMODE_IDLE \
|
||||
| CPSR_EXTRA_FLAGS )
|
||||
|
||||
#define FPEXC_EX_BIT 31
|
||||
#define FPEXC_EN_BIT 30
|
||||
#define FPEXC_DEX_BIT 29
|
||||
#define FPEXC_FP2V_BIT 28
|
||||
|
||||
/* Offsets within the user context, these need to match the order in
|
||||
* register_t below */
|
||||
#define PT_SP (13 * 4)
|
||||
|
|
@ -245,6 +250,9 @@ void Arch_initBreakpointContext(user_context_t *context);
|
|||
static inline void Arch_initContext(user_context_t *context)
|
||||
{
|
||||
context->registers[CPSR] = CPSR_USER;
|
||||
#ifdef CONFIG_HAVE_FPU
|
||||
context->fpuState.fpexc = BIT(FPEXC_EN_BIT);
|
||||
#endif
|
||||
#ifdef ARM_BASE_CP14_SAVE_AND_RESTORE
|
||||
Arch_initBreakpointContext(context);
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in a new issue