Using ARM/Neon fp hardware with libc

Martin Stein martin.stein at ...1...
Wed Oct 7 10:09:08 CEST 2015

Hi Bob,

On 06.10.2015 14:23, robjsstewart at ...9... wrote:> Stefan,
> So, implementing the Cpu_lazy_state in cpu.h in the core spec for the
> Cortex A9 into cpu.h for the Cortex A8 spec is all that is required?

The FPU support for Cortex-A9 in base-hw works as follows:

Initially, the FPU is turned off by the Kernel, regardless of whether an
FPU is supported. So, if a thread issues an FPU instruction, it always
traps to the Kernel with an 'UNDEFINED_INSTRUCTION' exception first.
'Thread::exception' in [1] then asks the CPU-specific code whether to
retry the unknown instruction. On most CPUs, the questioned code does
nothing more then returning "no". But on Cortex-A9 CPUs that have the
FP/SIMD extensions, the method 'Cpu::retry_undefined_instr' in [2] does
more. First, it toggles the FPU on. Then, it checks who was the last
user of the FPU. If the last user was another one than the thread that
now triggered the 'UNDEFINED_INSTRUCTION', the FPU context has to be
switched. The FPU context is part of the so-called "lazy CPU state".
This state is part of every thread and is called "lazy" because, in
contrast to the common CPU state of a thread (r0-r12,ip,sp,...), it
isn't necessarily switched on every thread-switch. At the end of
'Cpu::retry_undefined_instr', the Kernel denotes which is the new user
and tells 'Thread::exception' to let the application retry its last
instruction. Now that the FPU is on and contains the correct context,
the instruction succeeds. However, the context of the thread remains in
the FPU. To enable other threads to use the FPU in parallel, the Kernel
has to ensure that it gets the opportunity to switch the context again
when necessary. Thus, it disables the FPU again as soon as the thread
that enabled it, gets scheduled away. The hook for this is the
CPU-specific method 'Cpu::prepare_proceeding' [2] that is called on
every Kernel pass in 'Cpu::exception' [3].

In a nutshell, the FPU is turned on only on an FPU instruction and
turned off again as soon as the thread that called the FPU instruction
looses the scheduling focus. The FPU context is switched only on an FPU
instruction that is issued by another thread than the one that issued
the last FPU instruction.

To enable FPU support for Cortex A8, you would have to implement
'Arm_v7::finish_init_phys_kernel' (initialize but toggle off FPU),
'Genode::Cpu_lazy_state', 'Cpu::retry_undefined_instr', and
'Cpu::prepare_proceeding'. All in [4].

If you have further question, don't hesitate to ask ;)


[1] repos/base-hw/src/core/spec/arm/kernel/
[2] repos/base-hw/src/core/include/spec/cortex_a9/cpu.h
[3] repos/base-hw/src/core/kernel/
[4] repos/base-hw/src/core/include/spec/cortex_a8/cpu.h

More information about the users mailing list