From ded302c61cfdd547c4868d8baa939c6139f712b1 Mon Sep 17 00:00:00 2001 From: Adrian-Ken Rueegsegger Date: Tue, 21 Apr 2015 23:08:13 +0200 Subject: [PATCH] hw_x86_64: Perform lazy FPU state initialization Perform lazy-initialization of FPU state when it is enabled for the first time. This assures that the FXSAVE area (including the stored MXCSR) is always properly setup and initialized to the platform default values. --- .../src/core/include/spec/x86/cpu_support.h | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/repos/base-hw/src/core/include/spec/x86/cpu_support.h b/repos/base-hw/src/core/include/spec/x86/cpu_support.h index d5e58cf29..1be0db021 100644 --- a/repos/base-hw/src/core/include/spec/x86/cpu_support.h +++ b/repos/base-hw/src/core/include/spec/x86/cpu_support.h @@ -75,26 +75,44 @@ class Genode::Cpu_lazy_state /** * Load x87 FPU State from fxsave area. */ - inline void load() { asm volatile ("fxrstor %0" : : "m" (*start)); } + inline void load() + { + if (!start) { + set_start(); + init(); + return; + } + asm volatile ("fxrstor %0" : : "m" (*start)); + } /** * Save x87 FPU State to fxsave area. */ inline void save() { asm volatile ("fxsave %0" : "=m" (*start)); } - public: + /** + * Initialize FPU without checking for pending unmasked floating-point + * exceptions. + */ + inline void init() { asm volatile ("fninit"); }; /** - * Constructor - * - * Calculate 16-byte aligned start of FXSAVE area if necessary. + * Set 16-byte aligned start of fxsave area. */ - inline Cpu_lazy_state() + inline void set_start() { start = fxsave_area; if((addr_t)start & 15) start = (char *)((addr_t)start & ~15) + 16; }; + + public: + + /** + * Constructor + */ + inline Cpu_lazy_state() : start(0) { }; + } __attribute__((aligned(16)));