From 4b7d58fcccfb1b08c9ca908e98b2d9f1a280c06b Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Wed, 9 Apr 2014 12:14:38 +0200 Subject: [PATCH] hw & cortex_a9: do lazy FPU-context switch ref #1126 --- .../src/core/arndale/processor_driver.h | 8 +- .../base-hw/src/core/imx31/processor_driver.h | 10 +- .../base-hw/src/core/imx53/processor_driver.h | 8 +- repos/base-hw/src/core/kernel/kernel.cc | 15 +- repos/base-hw/src/core/kernel/processor.cc | 14 +- repos/base-hw/src/core/kernel/processor.h | 29 +- repos/base-hw/src/core/kernel/thread.cc | 8 +- .../src/core/odroid_xu/processor_driver.h | 8 +- .../base-hw/src/core/panda/processor_driver.h | 8 +- .../base-hw/src/core/pbxa9/processor_driver.h | 8 +- .../src/core/processor_driver/arm_v6.h | 21 +- .../src/core/processor_driver/arm_v7.h | 3 + .../src/core/processor_driver/cortex_a15.h | 29 +- .../src/core/processor_driver/cortex_a8.h | 27 +- .../src/core/processor_driver/cortex_a9.h | 301 +++++++++++++++++- repos/base-hw/src/core/rpi/processor_driver.h | 10 +- .../src/core/vea9x4/processor_driver.h | 9 +- 17 files changed, 431 insertions(+), 85 deletions(-) diff --git a/repos/base-hw/src/core/arndale/processor_driver.h b/repos/base-hw/src/core/arndale/processor_driver.h index 4e616f5af..44bf0872b 100644 --- a/repos/base-hw/src/core/arndale/processor_driver.h +++ b/repos/base-hw/src/core/arndale/processor_driver.h @@ -1,5 +1,5 @@ /* - * \brief CPU driver for core + * \brief Processor driver for core * \author Martin Stein * \date 2012-04-23 */ @@ -19,8 +19,10 @@ namespace Genode { + using Cortex_a15::Processor_lazy_state; + /** - * CPU driver for core + * Processor driver for core */ class Processor_driver : public Cortex_a15::Processor_driver { @@ -41,7 +43,5 @@ namespace Genode }; } -namespace Kernel { typedef Genode::Processor_driver Processor_driver; } - #endif /* _ARNDALE__PROCESSOR_DRIVER_H_ */ diff --git a/repos/base-hw/src/core/imx31/processor_driver.h b/repos/base-hw/src/core/imx31/processor_driver.h index 7833b3f3f..dbacb0ef7 100644 --- a/repos/base-hw/src/core/imx31/processor_driver.h +++ b/repos/base-hw/src/core/imx31/processor_driver.h @@ -1,5 +1,5 @@ /* - * \brief CPU driver for core + * \brief Processor driver for core * \author Martin Stein * \date 2012-04-23 */ @@ -19,13 +19,9 @@ namespace Genode { - /** - * CPU driver for core - */ - class Processor_driver : public Arm_v6::Processor_driver { }; + using Arm_v6::Processor_lazy_state; + using Arm_v6::Processor_driver; } -namespace Kernel { typedef Genode::Processor_driver Processor_driver; } - #endif /* _IMX31__PROCESSOR_DRIVER_H_ */ diff --git a/repos/base-hw/src/core/imx53/processor_driver.h b/repos/base-hw/src/core/imx53/processor_driver.h index fa0bceceb..8b228db29 100644 --- a/repos/base-hw/src/core/imx53/processor_driver.h +++ b/repos/base-hw/src/core/imx53/processor_driver.h @@ -1,5 +1,5 @@ /* - * \brief CPU driver for core + * \brief Processor driver for core * \author Martin Stein * \date 2012-12-14 */ @@ -19,8 +19,10 @@ namespace Genode { + using Cortex_a8::Processor_lazy_state; + /** - * CPU driver for core + * Processor driver for core */ class Processor_driver : public Cortex_a8::Processor_driver { @@ -38,7 +40,5 @@ namespace Genode }; } -namespace Kernel { typedef Genode::Processor_driver Processor_driver; } - #endif /* _IMX53__PROCESSOR_DRIVER_H_ */ diff --git a/repos/base-hw/src/core/kernel/kernel.cc b/repos/base-hw/src/core/kernel/kernel.cc index 691e62597..1941e3134 100644 --- a/repos/base-hw/src/core/kernel/kernel.cc +++ b/repos/base-hw/src/core/kernel/kernel.cc @@ -341,7 +341,7 @@ extern "C" void kernel() /* determine local processor scheduler */ unsigned const processor_id = Processor::executing_id(); Processor * const processor = processor_pool()->processor(processor_id); - Processor_scheduler * const scheduler = processor->scheduler(); + Scheduler * const scheduler = processor->scheduler(); /* * Request the current processor occupant without any update. While this @@ -349,17 +349,20 @@ extern "C" void kernel() * scheduling of the local activities in a way that an update would return * an occupant other than that whose exception caused the kernel entry. */ - Processor_client * const old_occupant = scheduler->occupant(); - old_occupant->exception(processor_id); + Processor_client * const old_client = scheduler->occupant(); + Processor_lazy_state * const old_state = old_client->lazy_state(); + old_client->exception(processor_id); /* * The processor local as well as remote exception-handling may have * changed the scheduling of the local activities. Hence we must update the * processor occupant. */ - Processor_client * const new_occupant = scheduler->update_occupant(); - if (old_occupant != new_occupant) { reset_scheduling_time(processor_id); } - new_occupant->proceed(processor_id); + Processor_client * const new_client = scheduler->update_occupant(); + Processor_lazy_state * const new_state = new_client->lazy_state(); + if (old_client != new_client) { reset_scheduling_time(processor_id); } + processor->prepare_proceeding(old_state, new_state); + new_client->proceed(processor_id); } diff --git a/repos/base-hw/src/core/kernel/processor.cc b/repos/base-hw/src/core/kernel/processor.cc index 431408c46..1328a126a 100644 --- a/repos/base-hw/src/core/kernel/processor.cc +++ b/repos/base-hw/src/core/kernel/processor.cc @@ -49,13 +49,13 @@ void Kernel::Processor_client::_interrupt(unsigned const processor_id) /* check wether the interrupt is a processor-scheduling timeout */ if (timer()->interrupt_id(processor_id) == irq_id) { - __processor->scheduler()->yield_occupation(); + _processor->scheduler()->yield_occupation(); timer()->clear_interrupt(processor_id); /* check wether the interrupt is our inter-processor interrupt */ } else if (ic->is_ip_interrupt(irq_id, processor_id)) { - __processor->ip_interrupt(); + _processor->ip_interrupt(); /* after all it must be a user interrupt */ } else { @@ -69,7 +69,7 @@ void Kernel::Processor_client::_interrupt(unsigned const processor_id) } -void Kernel::Processor_client::_schedule() { __processor->schedule(this); } +void Kernel::Processor_client::_schedule() { _processor->schedule(this); } void Kernel::Processor_client::tlb_to_flush(unsigned pd_id) @@ -141,15 +141,15 @@ void Kernel::Processor::schedule(Processor_client * const client) void Kernel::Processor_client::_unschedule() { - assert(__processor->id() == Processor::executing_id()); - __processor->scheduler()->remove(this); + assert(_processor->id() == Processor::executing_id()); + _processor->scheduler()->remove(this); } void Kernel::Processor_client::_yield() { - assert(__processor->id() == Processor::executing_id()); - __processor->scheduler()->yield_occupation(); + assert(_processor->id() == Processor::executing_id()); + _processor->scheduler()->yield_occupation(); } diff --git a/repos/base-hw/src/core/kernel/processor.h b/repos/base-hw/src/core/kernel/processor.h index 6b33c5eb1..3fd427f2b 100644 --- a/repos/base-hw/src/core/kernel/processor.h +++ b/repos/base-hw/src/core/kernel/processor.h @@ -23,6 +23,9 @@ namespace Kernel { + using Genode::Processor_driver; + using Genode::Processor_lazy_state; + /** * A single user of a multiplexable processor */ @@ -41,12 +44,11 @@ namespace Kernel class Kernel::Processor_client : public Processor_scheduler::Item { - private: - - Processor * __processor; - protected: + Processor * _processor; + Processor_lazy_state _lazy_state; + using List_item = Genode::List_element; List_item _flush_tlb_li; /* TLB maintainance work list item */ @@ -75,16 +77,6 @@ class Kernel::Processor_client : public Processor_scheduler::Item */ void _yield(); - - /*************** - ** Accessors ** - ***************/ - - void _processor(Processor * const processor) - { - __processor = processor; - } - public: /** @@ -122,7 +114,7 @@ class Kernel::Processor_client : public Processor_scheduler::Item Processor_client(Processor * const processor, Priority const priority) : Processor_scheduler::Item(priority), - __processor(processor), + _processor(processor), _flush_tlb_li(this) { } @@ -134,6 +126,13 @@ class Kernel::Processor_client : public Processor_scheduler::Item if (!_scheduled()) { return; } _unschedule(); } + + + /*************** + ** Accessors ** + ***************/ + + Processor_lazy_state * lazy_state() { return &_lazy_state; } }; class Kernel::Processor : public Processor_driver diff --git a/repos/base-hw/src/core/kernel/thread.cc b/repos/base-hw/src/core/kernel/thread.cc index e6941c0b3..d2a19a30d 100644 --- a/repos/base-hw/src/core/kernel/thread.cc +++ b/repos/base-hw/src/core/kernel/thread.cc @@ -167,7 +167,7 @@ void Thread::init(Processor * const processor, Pd * const pd, assert(_state == AWAITS_START) /* store thread parameters */ - Processor_client::_processor(processor); + Processor_client::_processor = processor; _utcb_phys = utcb_phys; /* join protection domain */ @@ -210,11 +210,17 @@ void Thread::exception(unsigned const processor_id) case FAST_INTERRUPT_REQUEST: _interrupt(processor_id); return; + case UNDEFINED_INSTRUCTION: + if (_processor->retry_undefined_instr(&_lazy_state)) { return; } + PWRN("undefined instruction"); + _stop(); + return; case RESET: return; default: PWRN("unknown exception"); _stop(); + return; } } diff --git a/repos/base-hw/src/core/odroid_xu/processor_driver.h b/repos/base-hw/src/core/odroid_xu/processor_driver.h index c4db794aa..e8a471c20 100644 --- a/repos/base-hw/src/core/odroid_xu/processor_driver.h +++ b/repos/base-hw/src/core/odroid_xu/processor_driver.h @@ -1,5 +1,5 @@ /* - * \brief CPU driver for core + * \brief Processor driver for core * \author Martin Stein * \date 2012-04-23 */ @@ -19,8 +19,10 @@ namespace Genode { + using Cortex_a15::Processor_lazy_state; + /** - * CPU driver for core + * Processor driver for core */ class Processor_driver : public Cortex_a15::Processor_driver { @@ -38,7 +40,5 @@ namespace Genode }; } -namespace Kernel { typedef Genode::Processor_driver Processor_driver; } - #endif /* _ODROID_XU__PROCESSOR_DRIVER_H_ */ diff --git a/repos/base-hw/src/core/panda/processor_driver.h b/repos/base-hw/src/core/panda/processor_driver.h index b067a3725..6049add7b 100644 --- a/repos/base-hw/src/core/panda/processor_driver.h +++ b/repos/base-hw/src/core/panda/processor_driver.h @@ -1,5 +1,5 @@ /* - * \brief CPU driver for core + * \brief Processor driver for core * \author Martin Stein * \date 2012-04-23 */ @@ -19,8 +19,10 @@ namespace Genode { + using Cortex_a9::Processor_lazy_state; + /** - * CPU driver for core + * Processor driver for core */ class Processor_driver : public Cortex_a9::Processor_driver { @@ -38,7 +40,5 @@ namespace Genode }; } -namespace Kernel { typedef Genode::Processor_driver Processor_driver; } - #endif /* _PANDA__PROCESSOR_DRIVER_H_ */ diff --git a/repos/base-hw/src/core/pbxa9/processor_driver.h b/repos/base-hw/src/core/pbxa9/processor_driver.h index 3f61b8b8d..b49be9a79 100644 --- a/repos/base-hw/src/core/pbxa9/processor_driver.h +++ b/repos/base-hw/src/core/pbxa9/processor_driver.h @@ -1,5 +1,5 @@ /* - * \brief CPU driver for core + * \brief Processor driver for core * \author Martin Stein * \date 2012-04-23 */ @@ -19,8 +19,10 @@ namespace Genode { + using Cortex_a9::Processor_lazy_state; + /** - * CPU driver for core + * Processor driver for core */ class Processor_driver : public Cortex_a9::Processor_driver { @@ -38,7 +40,5 @@ namespace Genode }; } -namespace Kernel { typedef Genode::Processor_driver Processor_driver; } - #endif /* _PBXA9__PROCESSOR_DRIVER_H_ */ diff --git a/repos/base-hw/src/core/processor_driver/arm_v6.h b/repos/base-hw/src/core/processor_driver/arm_v6.h index f6c1c5425..6a71d44be 100644 --- a/repos/base-hw/src/core/processor_driver/arm_v6.h +++ b/repos/base-hw/src/core/processor_driver/arm_v6.h @@ -1,5 +1,5 @@ /* - * \brief CPU driver for core + * \brief Processor driver for core * \author Norman Feske * \author Martin stein * \date 2012-08-30 @@ -27,7 +27,12 @@ namespace Arm_v6 using namespace Genode; /** - * CPU driver for core + * Part of processor state that is not switched on every mode transition + */ + class Processor_lazy_state { }; + + /** + * Processor driver for core */ struct Processor_driver : Arm::Processor_driver { @@ -213,6 +218,18 @@ namespace Arm_v6 * Return kernel name of the executing processor */ static unsigned executing_id() { return primary_id(); } + + + /** + * Prepare for the proceeding of a user + */ + static void prepare_proceeding(Processor_lazy_state *, + Processor_lazy_state *) { } + + /** + * Return wether to retry an undefined user instruction after this call + */ + bool retry_undefined_instr(Processor_lazy_state *) { return false; } }; } diff --git a/repos/base-hw/src/core/processor_driver/arm_v7.h b/repos/base-hw/src/core/processor_driver/arm_v7.h index d1b1904bc..60778d9b9 100644 --- a/repos/base-hw/src/core/processor_driver/arm_v7.h +++ b/repos/base-hw/src/core/processor_driver/arm_v7.h @@ -290,6 +290,8 @@ namespace Arm_v7 Sctlr::write(Sctlr::init_virt_kernel()); } + inline static void finish_init_phys_kernel(); + /** * Configure this module appropriately for the first kernel run */ @@ -299,6 +301,7 @@ namespace Arm_v7 Sctlr::write(Sctlr::init_phys_kernel()); Psr::write(Psr::init_kernel()); flush_tlb(); + finish_init_phys_kernel(); } /** diff --git a/repos/base-hw/src/core/processor_driver/cortex_a15.h b/repos/base-hw/src/core/processor_driver/cortex_a15.h index 78703fc8a..9588b6c7b 100644 --- a/repos/base-hw/src/core/processor_driver/cortex_a15.h +++ b/repos/base-hw/src/core/processor_driver/cortex_a15.h @@ -1,5 +1,5 @@ /* - * \brief CPU driver for core + * \brief Processor driver for core * \author Martin stein * \date 2011-11-03 */ @@ -24,21 +24,40 @@ namespace Cortex_a15 { - using namespace Genode; + /** + * Part of processor state that is not switched on every mode transition + */ + class Processor_lazy_state { }; /** - * CPU driver for core + * Processor driver for core */ struct Processor_driver : Arm_v7::Processor_driver { /** * Ensure that TLB insertions get applied - * - * Nothing to do because MMU uses caches on pagetable walks */ static void tlb_insertions() { } + + /** + * Prepare for the proceeding of a user + */ + static void prepare_proceeding(Processor_lazy_state *, + Processor_lazy_state *) { } + + /** + * Return wether to retry an undefined user instruction after this call + */ + bool retry_undefined_instr(Processor_lazy_state *) { return false; } }; } + +/****************************** + ** Arm_v7::Processor_driver ** + ******************************/ + +void Arm_v7::Processor_driver::finish_init_phys_kernel() { } + #endif /* _PROCESSOR_DRIVER__CORTEX_A15_H_ */ diff --git a/repos/base-hw/src/core/processor_driver/cortex_a8.h b/repos/base-hw/src/core/processor_driver/cortex_a8.h index b96b4c2be..957f145b0 100644 --- a/repos/base-hw/src/core/processor_driver/cortex_a8.h +++ b/repos/base-hw/src/core/processor_driver/cortex_a8.h @@ -1,5 +1,5 @@ /* - * \brief CPU driver for core + * \brief Processor driver for core * \author Martin stein * \date 2011-11-03 */ @@ -19,10 +19,13 @@ namespace Cortex_a8 { - using namespace Genode; + /** + * Part of processor state that is not switched on every mode transition + */ + class Processor_lazy_state { }; /** - * CPU driver for core + * Processor driver for core */ struct Processor_driver : Arm_v7::Processor_driver { @@ -30,8 +33,26 @@ namespace Cortex_a8 * Ensure that TLB insertions get applied */ static void tlb_insertions() { flush_tlb(); } + + /** + * Prepare for the proceeding of a user + */ + static void prepare_proceeding(Processor_lazy_state *, + Processor_lazy_state *) { } + + /** + * Return wether to retry an undefined user instruction after this call + */ + bool retry_undefined_instr(Processor_lazy_state *) { return false; } }; } + +/****************************** + ** Arm_v7::Processor_driver ** + ******************************/ + +void Arm_v7::Processor_driver::finish_init_phys_kernel() { } + #endif /* _PROCESSOR_DRIVER__CORTEX_A8_H_ */ diff --git a/repos/base-hw/src/core/processor_driver/cortex_a9.h b/repos/base-hw/src/core/processor_driver/cortex_a9.h index 07e13d731..8613c161f 100644 --- a/repos/base-hw/src/core/processor_driver/cortex_a9.h +++ b/repos/base-hw/src/core/processor_driver/cortex_a9.h @@ -1,5 +1,5 @@ /* - * \brief CPU driver for core + * \brief Processor driver for core * \author Martin stein * \date 2011-11-03 */ @@ -23,15 +23,206 @@ namespace Cortex_a9 using namespace Genode; /** - * CPU driver for core + * Part of processor state that is not switched on every mode transition */ - struct Processor_driver : Arm_v7::Processor_driver - { + class Processor_lazy_state; + + /** + * Processor driver for core + */ + class Processor_driver; +} + +class Cortex_a9::Processor_lazy_state +{ + friend class Processor_driver; + + private: + + /* advanced FP/SIMD - system registers */ + uint32_t fpscr; + uint32_t fpexc; + + /* advanced FP/SIMD - general purpose registers d0-d15 */ + uint64_t d0, d1, d2, d3, d4, d5, d6, d7; + uint64_t d8, d9, d10, d11, d12, d13, d14, d15; + + public: + + /** + * Constructor + */ + inline Processor_lazy_state(); +}; + +class Cortex_a9::Processor_driver : public Arm_v7::Processor_driver +{ + friend class Processor_lazy_state; + + private: + + /** + * Coprocessor Access Control Register + */ + struct Cpacr : Register<32> + { + struct Cp10 : Bitfield<20, 2> { }; + struct Cp11 : Bitfield<22, 2> { }; + + /** + * Read register value + */ + static access_t read() + { + access_t v; + asm volatile ("mrc p15, 0, %[v], c1, c0, 2" : [v]"=r"(v) ::); + return v; + } + + /** + * Override register value + * + * \param v write value + */ + static void write(access_t const v) + { + asm volatile ("mcr p15, 0, %[v], c1, c0, 2" :: [v]"r"(v) :); + } + }; + + /** + * Floating-point Status and Control Register + */ + struct Fpscr : Register<32> + { + /** + * Read register value + */ + static access_t read() + { + /* FIXME: See annotation 1. */ + access_t v; + asm volatile ("mrc p10, 7, %[v], cr1, cr0, 0" : [v] "=r" (v) ::); + return v; + } + + /** + * Override register value + * + * \param v write value + */ + static void write(access_t const v) + { + /* FIXME: See annotation 1. */ + asm volatile ("mcr p10, 7, %[v], cr1, cr0, 0" :: [v] "r" (v) :); + } + }; + + /** + * Floating-Point Exception Control register + */ + struct Fpexc : Register<32> + { + struct En : Bitfield<30, 1> { }; + + /** + * Read register value + */ + static access_t read() + { + /* FIXME: See annotation 1. */ + access_t v; + asm volatile ("mrc p10, 7, %[v], cr8, cr0, 0" : [v] "=r" (v) ::); + return v; + } + + /** + * Override register value + * + * \param v write value + */ + static void write(access_t const v) + { + /* FIXME: See annotation 1. */ + asm volatile ("mcr p10, 7, %[v], cr8, cr0, 0" :: [v] "r" (v) :); + } + }; + + Processor_lazy_state * _advanced_fp_simd_state; + + /** + * Enable or disable the advanced FP/SIMD extension + * + * \param enabled wether to enable or to disable advanced FP/SIMD + */ + static void _toggle_advanced_fp_simd(bool const enabled) + { + Fpexc::access_t fpexc = Fpexc::read(); + Fpexc::En::set(fpexc, enabled); + Fpexc::write(fpexc); + } + + /** + * Save state of the advanced FP/SIMD extension to memory + * + * \param state processor state to save FP/SIMD state into + */ + static void + _save_advanced_fp_simd_state(Processor_lazy_state * const state) + { + /* save system registers */ + state->fpexc = Fpexc::read(); + state->fpscr = Fpscr::read(); + + /* + * Save D0 - D15 + * + * FIXME: See annotation 2. + */ + void * const d0_d15_base = &state->d0; + asm volatile ( + "stc p11, cr0, [%[d0_d15_base]], #128" + :: [d0_d15_base] "r" (d0_d15_base) : ); + } + + /** + * Load state of the advanced FP/SIMD extension from memory + * + * \param state processor state to load FP/SIMD state out of + */ + static void + _load_advanced_fp_simd_state(Processor_lazy_state * const state) + { + /* load system registers */ + Fpexc::write(state->fpexc); + Fpscr::write(state->fpscr); + + /* + * Load D0 - D15 + * + * FIXME: See annotation 2. + */ + void * const d0_d15_base = &state->d0; + asm volatile ( + "ldc p11, cr0, [%[d0_d15_base]], #128" + :: [d0_d15_base] "r" (d0_d15_base) : ); + } + + /** + * Return wether the advanced FP/SIMD extension is enabled + */ + static bool _advanced_fp_simd_enabled() + { + Fpexc::access_t fpexc = Fpexc::read(); + return Fpexc::En::get(fpexc); + } + + public: + enum { /* common */ - CLK = Board::CORTEX_A9_CLOCK, /* CPU interface clock */ - PERIPH_CLK = CLK, /* clock for CPU internal components */ + PERIPH_CLK = Board::CORTEX_A9_CLOCK, /* interrupt controller */ PL390_DISTRIBUTOR_MMIO_BASE = Board::CORTEX_A9_PRIVATE_MEM_BASE + 0x1000, @@ -46,14 +237,104 @@ namespace Cortex_a9 PRIVATE_TIMER_CLK = PERIPH_CLK }; + /** + * Constructor + */ + Processor_driver() : _advanced_fp_simd_state(0) { } + /** * Ensure that TLB insertions get applied - * - * Nothing to do because MMU uses caches on pagetable walks */ static void tlb_insertions() { } - }; + + /** + * Initialize advanced FP/SIMD extension + */ + static void init_advanced_fp_simd() + { + Cpacr::access_t cpacr = Cpacr::read(); + Cpacr::Cp10::set(cpacr, 3); + Cpacr::Cp11::set(cpacr, 3); + Cpacr::write(cpacr); + _toggle_advanced_fp_simd(false); + } + + /** + * Prepare for the proceeding of a user + * + * \param old_state processor state of the last user + * \param new_state processor state of the next user + */ + static void prepare_proceeding(Processor_lazy_state * const old_state, + Processor_lazy_state * const new_state) + { + if (old_state == new_state) { return; } + _toggle_advanced_fp_simd(false); + } + + /** + * Return wether to retry an undefined user instruction after this call + * + * \param state processor state of the user + */ + bool retry_undefined_instr(Processor_lazy_state * const state) + { + if (_advanced_fp_simd_enabled()) { return false; } + _toggle_advanced_fp_simd(true); + if (_advanced_fp_simd_state != state) { + if (_advanced_fp_simd_state) { + _save_advanced_fp_simd_state(_advanced_fp_simd_state); + } + _load_advanced_fp_simd_state(state); + _advanced_fp_simd_state = state; + } + return true; + } +}; + + +/****************************** + ** Arm_v7::Processor_driver ** + ******************************/ + +void Arm_v7::Processor_driver::finish_init_phys_kernel() +{ + Cortex_a9::Processor_driver::init_advanced_fp_simd(); } -#endif /* _PROCESSOR_DRIVER__CORTEX_A9_H_ */ +/************************************* + ** Cortex_a9::Processor_lazy_state ** + *************************************/ + +Cortex_a9::Processor_lazy_state::Processor_lazy_state() +{ + fpexc = Processor_driver::Fpexc::En::bits(1); +} + + +/***************** + ** Annotations ** + *****************/ + +/* + * Annotation 1 + * + * According to the ARMv7 manual this should be done via vmsr/vmrs instruction + * but it seems that binutils 2.22 doesn't fully support this yet. Hence, we + * use a co-processor instruction instead. The parameters to target the + * register this way can be determined via 'sys/arm/include/vfp.h' and + * 'sys/arm/arm/vfp.c' of the FreeBSD head branch as from 2014.04.17. + */ + +/* + * Annotation 2 + * + * According to the ARMv7 manual this should be done via vldm/vstm instruction + * but it seems that binutils 2.22 doesn't fully support this yet. Hence, we + * use a co-processor instruction instead. The parameters to target the + * register this way can be determined via 'sys/arm/arm/vfp.c' of the FreeBSD + * head branch as from 2014.04.17. + */ + +#endif /* _PROCESSOR_DRIVER__CORTEX_A9_H_ */ diff --git a/repos/base-hw/src/core/rpi/processor_driver.h b/repos/base-hw/src/core/rpi/processor_driver.h index 500f4c8d5..377c04bac 100644 --- a/repos/base-hw/src/core/rpi/processor_driver.h +++ b/repos/base-hw/src/core/rpi/processor_driver.h @@ -1,5 +1,5 @@ /* - * \brief CPU definition for Raspberry Pi + * \brief Processor driver for core * \author Norman Feske * \date 2013-04-11 */ @@ -17,9 +17,11 @@ /* core includes */ #include -namespace Genode { class Processor_driver : public Arm_v6::Processor_driver { }; } - -namespace Kernel { typedef Genode::Processor_driver Processor_driver; } +namespace Genode +{ + using Arm_v6::Processor_lazy_state; + using Arm_v6::Processor_driver; +} #endif /* _RPI__PROCESSOR_DRIVER_H_ */ diff --git a/repos/base-hw/src/core/vea9x4/processor_driver.h b/repos/base-hw/src/core/vea9x4/processor_driver.h index bfa75098d..2906a22b2 100644 --- a/repos/base-hw/src/core/vea9x4/processor_driver.h +++ b/repos/base-hw/src/core/vea9x4/processor_driver.h @@ -1,5 +1,5 @@ /* - * \brief CPU driver for core + * \brief Processor driver for core * \author Martin Stein * \date 2012-04-23 */ @@ -19,8 +19,10 @@ namespace Genode { + using Cortex_a9::Processor_lazy_state; + /** - * CPU driver for core + * Processor driver for core */ class Processor_driver : public Cortex_a9::Processor_driver { @@ -38,7 +40,4 @@ namespace Genode }; } -namespace Kernel { typedef Genode::Processor_driver Processor_driver; } - #endif /* _VEA9X4__PROCESSOR_DRIVER_H_ */ -