summaryrefslogtreecommitdiff
path: root/chip/stm32/fpu.c
blob: 2bf0a0b803eb781ad8821e6239624093c42f710d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/* Copyright 2022 The ChromiumOS Authors
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "hooks.h"
#include "registers.h"
#include "task.h"

static void fpu_init(void)
{
	task_enable_irq(STM32_IRQ_FPU);
}
DECLARE_HOOK(HOOK_INIT, fpu_init, HOOK_PRIO_DEFAULT);

__attribute__((naked)) void IRQ_HANDLER(STM32_IRQ_FPU)(void)
{
	/* Naked call so we can extract raw LR and SP */
	asm volatile("mov r0, lr\n"
		     "mov r1, sp\n"
		     /*
		      * By default Floating-point context control register
		      * (FPCCR) have ASPEN and LSPEN bits enabled (see reset
		      * value in PM0214, 4.6.2 Floating-point context control
		      * register (FPCCR)). This means that lazy floating-point
		      * context save and restore is enabled. To save context on
		      * stack it's necessary to perform read access from FPU
		      * (see PM0214 4.6.7 Enabling and clearing FPU exception
		      * interrupts).
		      */
		     "vmrs r2, fpscr\n"
		     /*
		      * Must push registers in pairs to keep 64-bit aligned
		      * stack for ARM EABI.
		      */
		     "push {r0, lr}\n"
		     "bl fpu_irq\n"
		     "pop {r0, pc}\n");
}
const struct irq_priority __keep IRQ_PRIORITY(STM32_IRQ_FPU)
	__attribute__((section(".rodata.irqprio"))) = { STM32_IRQ_FPU,
							0 }; /* highest priority
							      */