arm64: Save/restore FPU state when handling IRQ or syscall
Change-Id: I8b2a36d57f410c0d06ca5ce90d1b997494072c94 Reviewed-on: https://review.haiku-os.org/c/haiku/+/7510 Reviewed-by: waddlesplash <[email protected]> Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
committed by
Fredrik Holmqvist
parent
b6fd30b0ed
commit
06fae14eb9
@@ -138,6 +138,9 @@ struct iframe {
|
|||||||
// exception info
|
// exception info
|
||||||
uint64 esr;
|
uint64 esr;
|
||||||
uint64 far;
|
uint64 far;
|
||||||
|
|
||||||
|
// fpu
|
||||||
|
struct aarch64_fpu_state fpu;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,11 @@
|
|||||||
// threads yet.
|
// threads yet.
|
||||||
struct iframe_stack gBootFrameStack;
|
struct iframe_stack gBootFrameStack;
|
||||||
|
|
||||||
|
// In order to avoid store/restore of large FPU state, it is assumed that
|
||||||
|
// this code and page fault handling doesn't use FPU.
|
||||||
|
// Instead this is called manually when handling IRQ or syscall.
|
||||||
|
extern "C" void _fp_save(aarch64_fpu_state *fpu);
|
||||||
|
extern "C" void _fp_restore(aarch64_fpu_state *fpu);
|
||||||
|
|
||||||
void
|
void
|
||||||
arch_int_enable_io_interrupt(int32 irq)
|
arch_int_enable_io_interrupt(int32 irq)
|
||||||
@@ -340,6 +345,8 @@ do_sync_handler(iframe * frame)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_fp_save(&frame->fpu);
|
||||||
|
|
||||||
thread_at_kernel_entry(system_time());
|
thread_at_kernel_entry(system_time());
|
||||||
|
|
||||||
enable_interrupts();
|
enable_interrupts();
|
||||||
@@ -362,6 +369,8 @@ do_sync_handler(iframe * frame)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_fp_restore(&frame->fpu);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -393,11 +402,15 @@ do_irq_handler(iframe * frame)
|
|||||||
|
|
||||||
IFrameScope scope(frame);
|
IFrameScope scope(frame);
|
||||||
|
|
||||||
|
_fp_save(&frame->fpu);
|
||||||
|
|
||||||
InterruptController *ic = InterruptController::Get();
|
InterruptController *ic = InterruptController::Get();
|
||||||
if (ic != NULL)
|
if (ic != NULL)
|
||||||
ic->HandleInterrupt();
|
ic->HandleInterrupt();
|
||||||
|
|
||||||
after_exception();
|
after_exception();
|
||||||
|
|
||||||
|
_fp_restore(&frame->fpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user