Linux Audio

Check our new training course

Buildroot integration, development and maintenance

Need a Buildroot system for your embedded project?
Loading...
Note: File does not exist in v3.5.6.
  1/* SPDX-License-Identifier: GPL-2.0 */
  2/*
  3 * Author: Huacai Chen <chenhuacai@loongson.cn>
  4 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
  5 */
  6#ifndef _ASM_FPU_H
  7#define _ASM_FPU_H
  8
  9#include <linux/sched.h>
 10#include <linux/sched/task_stack.h>
 11#include <linux/ptrace.h>
 12#include <linux/thread_info.h>
 13#include <linux/bitops.h>
 14
 15#include <asm/cpu.h>
 16#include <asm/cpu-features.h>
 17#include <asm/current.h>
 18#include <asm/loongarch.h>
 19#include <asm/processor.h>
 20#include <asm/ptrace.h>
 21
 22struct sigcontext;
 23
 24extern void _init_fpu(unsigned int);
 25extern void _save_fp(struct loongarch_fpu *);
 26extern void _restore_fp(struct loongarch_fpu *);
 27
 28/*
 29 * Mask the FCSR Cause bits according to the Enable bits, observing
 30 * that Unimplemented is always enabled.
 31 */
 32static inline unsigned long mask_fcsr_x(unsigned long fcsr)
 33{
 34	return fcsr & ((fcsr & FPU_CSR_ALL_E) <<
 35			(ffs(FPU_CSR_ALL_X) - ffs(FPU_CSR_ALL_E)));
 36}
 37
 38static inline int is_fp_enabled(void)
 39{
 40	return (csr_read32(LOONGARCH_CSR_EUEN) & CSR_EUEN_FPEN) ?
 41		1 : 0;
 42}
 43
 44#define enable_fpu()		set_csr_euen(CSR_EUEN_FPEN)
 45
 46#define disable_fpu()		clear_csr_euen(CSR_EUEN_FPEN)
 47
 48#define clear_fpu_owner()	clear_thread_flag(TIF_USEDFPU)
 49
 50static inline int is_fpu_owner(void)
 51{
 52	return test_thread_flag(TIF_USEDFPU);
 53}
 54
 55static inline void __own_fpu(void)
 56{
 57	enable_fpu();
 58	set_thread_flag(TIF_USEDFPU);
 59	KSTK_EUEN(current) |= CSR_EUEN_FPEN;
 60}
 61
 62static inline void own_fpu_inatomic(int restore)
 63{
 64	if (cpu_has_fpu && !is_fpu_owner()) {
 65		__own_fpu();
 66		if (restore)
 67			_restore_fp(&current->thread.fpu);
 68	}
 69}
 70
 71static inline void own_fpu(int restore)
 72{
 73	preempt_disable();
 74	own_fpu_inatomic(restore);
 75	preempt_enable();
 76}
 77
 78static inline void lose_fpu_inatomic(int save, struct task_struct *tsk)
 79{
 80	if (is_fpu_owner()) {
 81		if (save)
 82			_save_fp(&tsk->thread.fpu);
 83		disable_fpu();
 84		clear_tsk_thread_flag(tsk, TIF_USEDFPU);
 85	}
 86	KSTK_EUEN(tsk) &= ~(CSR_EUEN_FPEN | CSR_EUEN_LSXEN | CSR_EUEN_LASXEN);
 87}
 88
 89static inline void lose_fpu(int save)
 90{
 91	preempt_disable();
 92	lose_fpu_inatomic(save, current);
 93	preempt_enable();
 94}
 95
 96static inline void init_fpu(void)
 97{
 98	unsigned int fcsr = current->thread.fpu.fcsr;
 99
100	__own_fpu();
101	_init_fpu(fcsr);
102	set_used_math();
103}
104
105static inline void save_fp(struct task_struct *tsk)
106{
107	if (cpu_has_fpu)
108		_save_fp(&tsk->thread.fpu);
109}
110
111static inline void restore_fp(struct task_struct *tsk)
112{
113	if (cpu_has_fpu)
114		_restore_fp(&tsk->thread.fpu);
115}
116
117static inline union fpureg *get_fpu_regs(struct task_struct *tsk)
118{
119	if (tsk == current) {
120		preempt_disable();
121		if (is_fpu_owner())
122			_save_fp(&current->thread.fpu);
123		preempt_enable();
124	}
125
126	return tsk->thread.fpu.fpr;
127}
128
129#endif /* _ASM_FPU_H */