Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Linux/PA-RISC Project (http://www.parisc-linux.org/)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Floating-point emulation code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *  Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *  linux/arch/math-emu/driver.c.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  *	decodes and dispatches unimplemented FPU instructions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  *  Copyright (C) 1999, 2000  Philipp Rumpf <prumpf@tux.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  *  Copyright (C) 2001	      Hewlett-Packard <bame@debian.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/sched/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include "float.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include "math-emu.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define fptpos 31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define fpr1pos 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define extru(r,pos,len) (((r) >> (31-(pos))) & (( 1 << (len)) - 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define FPUDEBUG 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) /* Format of the floating-point exception registers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) struct exc_reg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	unsigned int exception : 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	unsigned int ei : 26;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) /* Macros for grabbing bits of the instruction format from the 'ei'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)    field above. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) /* Major opcode 0c and 0e */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define FP0CE_UID(i) (((i) >> 6) & 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define FP0CE_CLASS(i) (((i) >> 9) & 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define FP0CE_SUBOP(i) (((i) >> 13) & 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #define FP0CE_SUBOP1(i) (((i) >> 15) & 7) /* Class 1 subopcode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #define FP0C_FORMAT(i) (((i) >> 11) & 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #define FP0E_FORMAT(i) (((i) >> 11) & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) /* Major opcode 0c, uid 2 (performance monitoring) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define FPPM_SUBOP(i) (((i) >> 9) & 0x1f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) /* Major opcode 2e (fused operations).   */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #define FP2E_SUBOP(i)  (((i) >> 5) & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #define FP2E_FORMAT(i) (((i) >> 11) & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) /* Major opcode 26 (FMPYSUB) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) /* Major opcode 06 (FMPYADD) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #define FPx6_FORMAT(i) ((i) & 0x1f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) /* Flags and enable bits of the status word. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define FPSW_FLAGS(w) ((w) >> 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #define FPSW_ENABLE(w) ((w) & 0x1f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) #define FPSW_V (1<<4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) #define FPSW_Z (1<<3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) #define FPSW_O (1<<2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) #define FPSW_U (1<<1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) #define FPSW_I (1<<0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) /* Handle a floating point exception.  Return zero if the faulting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)    instruction can be completed successfully. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) handle_fpe(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	extern void printbinary(unsigned long x, int nbits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	unsigned int orig_sw, sw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	int signalcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	/* need an intermediate copy of float regs because FPU emulation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	 * code expects an artificial last entry which contains zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	 * also, the passed in fr registers contain one word that defines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	 * the fpu type. the fpu type information is constructed 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	 * inside the emulation code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	__u64 frcopy[36];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	memcpy(frcopy, regs->fr, sizeof regs->fr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	frcopy[32] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	memcpy(&orig_sw, frcopy, sizeof(orig_sw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	if (FPUDEBUG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		printk(KERN_DEBUG "FP VZOUICxxxxCQCQCQCQCQCRMxxTDVZOUI ->\n   ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		printbinary(orig_sw, 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		printk(KERN_DEBUG "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	signalcode = decode_fpu(frcopy, 0x666);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	/* Status word = FR0L. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	memcpy(&sw, frcopy, sizeof(sw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	if (FPUDEBUG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		printk(KERN_DEBUG "VZOUICxxxxCQCQCQCQCQCRMxxTDVZOUI decode_fpu returns %d|0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 			signalcode >> 24, signalcode & 0xffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		printbinary(sw, 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		printk(KERN_DEBUG "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	memcpy(regs->fr, frcopy, sizeof regs->fr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	if (signalcode != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	    force_sig_fault(signalcode >> 24, signalcode & 0xffffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 			    (void __user *) regs->iaoq[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	    return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	return signalcode ? -1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }