genode/repos/base-hw/src/core/spec/x86_64/fpu.h
Sebastian Sumpf da17f2cbd3 hw: eager FPU switching for x86_64
Since gcc 8.3.0 generates SSE instructions into kernel code, the
kernel itself may raise FPU exceptions and/or corrupt user level FPU
contexts thereby. Both things are not feasible, and therefore, lazy FPU
switching becomes a no go for base-hw because we cannot avoid FPU
instructions because of the entanglement of base-hw, base, and the tool
chain (libgcc_eh.a).

issue #3365
2019-05-27 14:53:32 +02:00

65 lines
1.3 KiB
C++

/*
* \brief x86_64 FPU context
* \author Sebastian Sumpf
* \date 2019-05-23
*/
/*
* Copyright (C) 2019 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _CORE__SPEC__X86_64__FPU_H_
#define _CORE__SPEC__X86_64__FPU_H_
/* Genode includes */
#include <util/misc_math.h>
#include <util/mmio.h>
#include <util/string.h>
namespace Genode { class Fpu_context; }
class Genode::Fpu_context
{
addr_t _fxsave_addr { 0 };
/*
* FXSAVE area providing storage for x87 FPU, MMX, XMM,
* and MXCSR registers.
*
* For further details see Intel SDM Vol. 2A,
* 'FXSAVE instruction'.
*/
char _fxsave_area[527];
struct Context : Mmio
{
struct Fcw : Register<0, 16> { };
struct Mxcsr : Register<24, 32> { };
Context(addr_t const base) : Mmio(base)
{
memset((void *)base, 0, 512);
write<Fcw>(0x37f); /* mask exceptions SysV ABI */
write<Mxcsr>(0x1f80);
}
};
public:
Fpu_context()
{
/* align to 16 byte boundary */
_fxsave_addr = align_addr((addr_t)_fxsave_area, 4);
/* set fcw/mxcsr */
Context init(_fxsave_addr);
}
addr_t fpu_context() const { return _fxsave_addr; }
};
#endif /* _CORE__SPEC__X86_64__FPU_H_ */