mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 17:07:46 +00:00
Kernel/riscv64: Implement {load,store}_fpu_state
This commit adds two functions which save/restore the entire FPU state. On RISC-V, you only need to save the floating pointer registers themselves and the fcsr CSR, which contains the entire state of the F/D extensions.
This commit is contained in:
parent
cd389833d4
commit
1429c83942
2 changed files with 85 additions and 0 deletions
|
@ -16,6 +16,7 @@ namespace Kernel {
|
||||||
// This struct will get pushed on the stack by the signal handling code.
|
// This struct will get pushed on the stack by the signal handling code.
|
||||||
// Therefore, it has to be aligned to a 16-byte boundary.
|
// Therefore, it has to be aligned to a 16-byte boundary.
|
||||||
struct [[gnu::aligned(16)]] FPUState {
|
struct [[gnu::aligned(16)]] FPUState {
|
||||||
|
// FIXME: Add support for the Q extension.
|
||||||
u64 f[32];
|
u64 f[32];
|
||||||
u64 fcsr;
|
u64 fcsr;
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,6 +17,88 @@ namespace Kernel {
|
||||||
|
|
||||||
Processor* g_current_processor;
|
Processor* g_current_processor;
|
||||||
|
|
||||||
|
static void store_fpu_state(FPUState* fpu_state)
|
||||||
|
{
|
||||||
|
asm volatile(
|
||||||
|
"fsd f0, 0*8(%0) \n"
|
||||||
|
"fsd f1, 1*8(%0) \n"
|
||||||
|
"fsd f2, 2*8(%0) \n"
|
||||||
|
"fsd f3, 3*8(%0) \n"
|
||||||
|
"fsd f4, 4*8(%0) \n"
|
||||||
|
"fsd f5, 5*8(%0) \n"
|
||||||
|
"fsd f6, 6*8(%0) \n"
|
||||||
|
"fsd f7, 7*8(%0) \n"
|
||||||
|
"fsd f8, 8*8(%0) \n"
|
||||||
|
"fsd f9, 9*8(%0) \n"
|
||||||
|
"fsd f10, 10*8(%0) \n"
|
||||||
|
"fsd f11, 11*8(%0) \n"
|
||||||
|
"fsd f12, 12*8(%0) \n"
|
||||||
|
"fsd f13, 13*8(%0) \n"
|
||||||
|
"fsd f14, 14*8(%0) \n"
|
||||||
|
"fsd f15, 15*8(%0) \n"
|
||||||
|
"fsd f16, 16*8(%0) \n"
|
||||||
|
"fsd f17, 17*8(%0) \n"
|
||||||
|
"fsd f18, 18*8(%0) \n"
|
||||||
|
"fsd f19, 19*8(%0) \n"
|
||||||
|
"fsd f20, 20*8(%0) \n"
|
||||||
|
"fsd f21, 21*8(%0) \n"
|
||||||
|
"fsd f22, 22*8(%0) \n"
|
||||||
|
"fsd f23, 23*8(%0) \n"
|
||||||
|
"fsd f24, 24*8(%0) \n"
|
||||||
|
"fsd f25, 25*8(%0) \n"
|
||||||
|
"fsd f26, 26*8(%0) \n"
|
||||||
|
"fsd f27, 27*8(%0) \n"
|
||||||
|
"fsd f28, 28*8(%0) \n"
|
||||||
|
"fsd f29, 29*8(%0) \n"
|
||||||
|
"fsd f30, 30*8(%0) \n"
|
||||||
|
"fsd f31, 31*8(%0) \n"
|
||||||
|
|
||||||
|
"csrr t0, fcsr \n"
|
||||||
|
"sd t0, 32*8(%0) \n" ::"r"(fpu_state)
|
||||||
|
: "t0", "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] static void load_fpu_state(FPUState* fpu_state)
|
||||||
|
{
|
||||||
|
asm volatile(
|
||||||
|
"fld f0, 0*8(%0) \n"
|
||||||
|
"fld f1, 1*8(%0) \n"
|
||||||
|
"fld f2, 2*8(%0) \n"
|
||||||
|
"fld f3, 3*8(%0) \n"
|
||||||
|
"fld f4, 4*8(%0) \n"
|
||||||
|
"fld f5, 5*8(%0) \n"
|
||||||
|
"fld f6, 6*8(%0) \n"
|
||||||
|
"fld f7, 7*8(%0) \n"
|
||||||
|
"fld f8, 8*8(%0) \n"
|
||||||
|
"fld f9, 9*8(%0) \n"
|
||||||
|
"fld f10, 10*8(%0) \n"
|
||||||
|
"fld f11, 11*8(%0) \n"
|
||||||
|
"fld f12, 12*8(%0) \n"
|
||||||
|
"fld f13, 13*8(%0) \n"
|
||||||
|
"fld f14, 14*8(%0) \n"
|
||||||
|
"fld f15, 15*8(%0) \n"
|
||||||
|
"fld f16, 16*8(%0) \n"
|
||||||
|
"fld f17, 17*8(%0) \n"
|
||||||
|
"fld f18, 18*8(%0) \n"
|
||||||
|
"fld f19, 19*8(%0) \n"
|
||||||
|
"fld f20, 20*8(%0) \n"
|
||||||
|
"fld f21, 21*8(%0) \n"
|
||||||
|
"fld f22, 22*8(%0) \n"
|
||||||
|
"fld f23, 23*8(%0) \n"
|
||||||
|
"fld f24, 24*8(%0) \n"
|
||||||
|
"fld f25, 25*8(%0) \n"
|
||||||
|
"fld f26, 26*8(%0) \n"
|
||||||
|
"fld f27, 27*8(%0) \n"
|
||||||
|
"fld f28, 28*8(%0) \n"
|
||||||
|
"fld f29, 29*8(%0) \n"
|
||||||
|
"fld f30, 30*8(%0) \n"
|
||||||
|
"fld f31, 31*8(%0) \n"
|
||||||
|
|
||||||
|
"ld t0, 32*8(%0) \n"
|
||||||
|
"csrw fcsr, t0 \n" ::"r"(fpu_state)
|
||||||
|
: "t0", "memory");
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void ProcessorBase<T>::early_initialize(u32 cpu)
|
void ProcessorBase<T>::early_initialize(u32 cpu)
|
||||||
{
|
{
|
||||||
|
@ -36,6 +118,8 @@ void ProcessorBase<T>::initialize(u32)
|
||||||
sstatus.FS = RISCV64::CSR::SSTATUS::FloatingPointStatus::Initial;
|
sstatus.FS = RISCV64::CSR::SSTATUS::FloatingPointStatus::Initial;
|
||||||
RISCV64::CSR::SSTATUS::write(sstatus);
|
RISCV64::CSR::SSTATUS::write(sstatus);
|
||||||
|
|
||||||
|
store_fpu_state(&s_clean_fpu_state);
|
||||||
|
|
||||||
initialize_interrupts();
|
initialize_interrupts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue