cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

fpu.S (3715B)


      1/* SPDX-License-Identifier: GPL-2.0-or-later */
      2/*
      3 *  FPU support code, moved here from head.S so that it can be used
      4 *  by chips which use other head-whatever.S files.
      5 *
      6 *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
      7 *    Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
      8 *    Copyright (C) 1996 Paul Mackerras.
      9 *    Copyright (C) 1997 Dan Malek (dmalek@jlc.net).
     10 */
     11
     12#include <asm/reg.h>
     13#include <asm/page.h>
     14#include <asm/mmu.h>
     15#include <asm/cputable.h>
     16#include <asm/cache.h>
     17#include <asm/thread_info.h>
     18#include <asm/ppc_asm.h>
     19#include <asm/asm-offsets.h>
     20#include <asm/ptrace.h>
     21#include <asm/export.h>
     22#include <asm/asm-compat.h>
     23#include <asm/feature-fixups.h>
     24
     25#ifdef CONFIG_VSX
     26#define __REST_32FPVSRS(n,c,base)					\
     27BEGIN_FTR_SECTION							\
     28	b	2f;							\
     29END_FTR_SECTION_IFSET(CPU_FTR_VSX);					\
     30	REST_32FPRS(n,base);						\
     31	b	3f;							\
     322:	REST_32VSRS(n,c,base);						\
     333:
     34
     35#define __SAVE_32FPVSRS(n,c,base)					\
     36BEGIN_FTR_SECTION							\
     37	b	2f;							\
     38END_FTR_SECTION_IFSET(CPU_FTR_VSX);					\
     39	SAVE_32FPRS(n,base);						\
     40	b	3f;							\
     412:	SAVE_32VSRS(n,c,base);						\
     423:
     43#else
     44#define __REST_32FPVSRS(n,b,base)	REST_32FPRS(n, base)
     45#define __SAVE_32FPVSRS(n,b,base)	SAVE_32FPRS(n, base)
     46#endif
     47#define REST_32FPVSRS(n,c,base) __REST_32FPVSRS(n,__REG_##c,__REG_##base)
     48#define SAVE_32FPVSRS(n,c,base) __SAVE_32FPVSRS(n,__REG_##c,__REG_##base)
     49
     50/*
     51 * Load state from memory into FP registers including FPSCR.
     52 * Assumes the caller has enabled FP in the MSR.
     53 */
     54_GLOBAL(load_fp_state)
     55	lfd	fr0,FPSTATE_FPSCR(r3)
     56	MTFSF_L(fr0)
     57	REST_32FPVSRS(0, R4, R3)
     58	blr
     59EXPORT_SYMBOL(load_fp_state)
     60_ASM_NOKPROBE_SYMBOL(load_fp_state); /* used by restore_math */
     61
     62/*
     63 * Store FP state into memory, including FPSCR
     64 * Assumes the caller has enabled FP in the MSR.
     65 */
     66_GLOBAL(store_fp_state)
     67	SAVE_32FPVSRS(0, R4, R3)
     68	mffs	fr0
     69	stfd	fr0,FPSTATE_FPSCR(r3)
     70	blr
     71EXPORT_SYMBOL(store_fp_state)
     72
     73/*
     74 * This task wants to use the FPU now.
     75 * On UP, disable FP for the task which had the FPU previously,
     76 * and save its floating-point registers in its thread_struct.
     77 * Load up this task's FP registers from its thread_struct,
     78 * enable the FPU for the current task and return to the task.
     79 * Note that on 32-bit this can only use registers that will be
     80 * restored by fast_exception_return, i.e. r3 - r6, r10 and r11.
     81 */
     82_GLOBAL(load_up_fpu)
     83	mfmsr	r5
     84#ifdef CONFIG_PPC_BOOK3S_64
     85	/* interrupt doesn't set MSR[RI] and HPT can fault on current access */
     86	ori	r5,r5,MSR_FP|MSR_RI
     87#else
     88	ori	r5,r5,MSR_FP
     89#endif
     90#ifdef CONFIG_VSX
     91BEGIN_FTR_SECTION
     92	oris	r5,r5,MSR_VSX@h
     93END_FTR_SECTION_IFSET(CPU_FTR_VSX)
     94#endif
     95	MTMSRD(r5)			/* enable use of fpu now */
     96	isync
     97	/* enable use of FP after return */
     98#ifdef CONFIG_PPC32
     99	addi	r5,r2,THREAD
    100	lwz	r4,THREAD_FPEXC_MODE(r5)
    101	ori	r9,r9,MSR_FP		/* enable FP for current */
    102	or	r9,r9,r4
    103#else
    104	ld	r4,PACACURRENT(r13)
    105	addi	r5,r4,THREAD		/* Get THREAD */
    106	lwz	r4,THREAD_FPEXC_MODE(r5)
    107	ori	r12,r12,MSR_FP
    108	or	r12,r12,r4
    109	std	r12,_MSR(r1)
    110#ifdef CONFIG_PPC_BOOK3S_64
    111	li	r4,0
    112	stb	r4,PACASRR_VALID(r13)
    113#endif
    114#endif
    115	li	r4,1
    116	stb	r4,THREAD_LOAD_FP(r5)
    117	addi	r10,r5,THREAD_FPSTATE
    118	lfd	fr0,FPSTATE_FPSCR(r10)
    119	MTFSF_L(fr0)
    120	REST_32FPVSRS(0, R4, R10)
    121	/* restore registers and return */
    122	/* we haven't used ctr or xer or lr */
    123	blr
    124_ASM_NOKPROBE_SYMBOL(load_up_fpu)
    125
    126/*
    127 * save_fpu(tsk)
    128 * Save the floating-point registers in its thread_struct.
    129 * Enables the FPU for use in the kernel on return.
    130 */
    131_GLOBAL(save_fpu)
    132	addi	r3,r3,THREAD	        /* want THREAD of task */
    133	PPC_LL	r6,THREAD_FPSAVEAREA(r3)
    134	PPC_LL	r5,PT_REGS(r3)
    135	PPC_LCMPI	0,r6,0
    136	bne	2f
    137	addi	r6,r3,THREAD_FPSTATE
    1382:	SAVE_32FPVSRS(0, R4, R6)
    139	mffs	fr0
    140	stfd	fr0,FPSTATE_FPSCR(r6)
    141	blr