summaryrefslogtreecommitdiffstats
path: root/kernel/arch/parisc/math-emu/driver.c
blob: 09ef4136c6935ec8c45b0f43151ce9beb1eac566 (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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*
 * Linux/PA-RISC Project (http://www.parisc-linux.org/)
 *
 * Floating-point emulation code
 *  Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
 *
 *    This program is free software; you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation; either version 2, or (at your option)
 *    any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
/*
 *  linux/arch/math-emu/driver.c.c
 *
 *	decodes and dispatches unimplemented FPU instructions
 *
 *  Copyright (C) 1999, 2000  Philipp Rumpf <prumpf@tux.org>
 *  Copyright (C) 2001	      Hewlett-Packard <bame@debian.org>
 */

#include <linux/sched.h>
#include "float.h"
#include "math-emu.h"


#define fptpos 31
#define fpr1pos 10
#define extru(r,pos,len) (((r) >> (31-(pos))) & (( 1 << (len)) - 1))

#define FPUDEBUG 0

/* Format of the floating-point exception registers. */
struct exc_reg {
	unsigned int exception : 6;
	unsigned int ei : 26;
};

/* Macros for grabbing bits of the instruction format from the 'ei'
   field above. */
/* Major opcode 0c and 0e */
#define FP0CE_UID(i) (((i) >> 6) & 3)
#define FP0CE_CLASS(i) (((i) >> 9) & 3)
#define FP0CE_SUBOP(i) (((i) >> 13) & 7)
#define FP0CE_SUBOP1(i) (((i) >> 15) & 7) /* Class 1 subopcode */
#define FP0C_FORMAT(i) (((i) >> 11) & 3)
#define FP0E_FORMAT(i) (((i) >> 11) & 1)

/* Major opcode 0c, uid 2 (performance monitoring) */
#define FPPM_SUBOP(i) (((i) >> 9) & 0x1f)

/* Major opcode 2e (fused operations).   */
#define FP2E_SUBOP(i)  (((i) >> 5) & 1)
#define FP2E_FORMAT(i) (((i) >> 11) & 1)

/* Major opcode 26 (FMPYSUB) */
/* Major opcode 06 (FMPYADD) */
#define FPx6_FORMAT(i) ((i) & 0x1f)

/* Flags and enable bits of the status word. */
#define FPSW_FLAGS(w) ((w) >> 27)
#define FPSW_ENABLE(w) ((w) & 0x1f)
#define FPSW_V (1<<4)
#define FPSW_Z (1<<3)
#define FPSW_O (1<<2)
#define FPSW_U (1<<1)
#define FPSW_I (1<<0)

/* Handle a floating point exception.  Return zero if the faulting
   instruction can be completed successfully. */
int
handle_fpe(struct pt_regs *regs)
{
	extern void printbinary(unsigned long x, int nbits);
	struct siginfo si;
	unsigned int orig_sw, sw;
	int signalcode;
	/* need an intermediate copy of float regs because FPU emulation
	 * code expects an artificial last entry which contains zero
	 *
	 * also, the passed in fr registers contain one word that defines
	 * the fpu type. the fpu type information is constructed 
	 * inside the emulation code
	 */
	__u64 frcopy[36];

	memcpy(frcopy, regs->fr, sizeof regs->fr);
	frcopy[32] = 0;

	memcpy(&orig_sw, frcopy, sizeof(orig_sw));

	if (FPUDEBUG) {
		printk(KERN_DEBUG "FP VZOUICxxxxCQCQCQCQCQCRMxxTDVZOUI ->\n   ");
		printbinary(orig_sw, 32);
		printk(KERN_DEBUG "\n");
	}

	signalcode = decode_fpu(frcopy, 0x666);

	/* Status word = FR0L. */
	memcpy(&sw, frcopy, sizeof(sw));
	if (FPUDEBUG) {
		printk(KERN_DEBUG "VZOUICxxxxCQCQCQCQCQCRMxxTDVZOUI decode_fpu returns %d|0x%x\n",
			signalcode >> 24, signalcode & 0xffffff);
		printbinary(sw, 32);
		printk(KERN_DEBUG "\n");
	}

	memcpy(regs->fr, frcopy, sizeof regs->fr);
	if (signalcode != 0) {
	    si.si_signo = signalcode >> 24;
	    si.si_errno = 0;
	    si.si_code = signalcode & 0xffffff;
	    si.si_addr = (void __user *) regs->iaoq[0];
	    force_sig_info(si.si_signo, &si, current);
	    return -1;
	}

	return signalcode ? -1 : 0;
}
production systems, because userland can easily disable the thermal policy by simply flooding this sysfs node with low temperature values. config IMX_THERMAL tristate "Temperature sensor driver for Freescale i.MX SoCs" depends on CPU_THERMAL depends on MFD_SYSCON depends on OF help Support for Temperature Monitor (TEMPMON) found on Freescale i.MX SoCs. It supports one critical trip point and one passive trip point. The cpufreq is used as the cooling device to throttle CPUs when the passive trip is crossed. config SPEAR_THERMAL bool "SPEAr thermal sensor driver" depends on PLAT_SPEAR depends on OF help Enable this to plug the SPEAr thermal sensor driver into the Linux thermal framework. config ROCKCHIP_THERMAL tristate "Rockchip thermal driver" depends on ARCH_ROCKCHIP depends on RESET_CONTROLLER help Rockchip thermal driver provides support for Temperature sensor ADC (TS-ADC) found on Rockchip SoCs. It supports one critical trip point. Cpufreq is used as the cooling device and will throttle CPUs when the Temperature crosses the passive trip point. config RCAR_THERMAL tristate "Renesas R-Car thermal driver" depends on ARCH_SHMOBILE || COMPILE_TEST depends on HAS_IOMEM help Enable this to plug the R-Car thermal sensor driver into the Linux thermal framework. config KIRKWOOD_THERMAL tristate "Temperature sensor on Marvell Kirkwood SoCs" depends on MACH_KIRKWOOD depends on OF help Support for the Kirkwood thermal sensor driver into the Linux thermal framework. Only kirkwood 88F6282 and 88F6283 have this sensor. config DOVE_THERMAL tristate "Temperature sensor on Marvell Dove SoCs" depends on ARCH_DOVE || MACH_DOVE depends on OF help Support for the Dove thermal sensor driver in the Linux thermal framework. config DB8500_THERMAL bool "DB8500 thermal management" depends on ARCH_U8500 default y help Adds DB8500 thermal management implementation according to the thermal management framework. A thermal zone with several trip points will be created. Cooling devices can be bound to the trip points to cool this thermal zone if trip points reached. config ARMADA_THERMAL tristate "Armada 370/XP thermal management" depends on ARCH_MVEBU depends on OF help Enable this option if you want to have support for thermal management controller present in Armada 370 and Armada XP SoC. config TEGRA_SOCTHERM tristate "Tegra SOCTHERM thermal management" depends on ARCH_TEGRA help Enable this option for integrated thermal management support on NVIDIA Tegra124 systems-on-chip. The driver supports four thermal zones (CPU, GPU, MEM, PLLX). Cooling devices can be bound to the thermal zones to manage temperatures. This option is also required for the emergency thermal reset (thermtrip) feature to function. config DB8500_CPUFREQ_COOLING tristate "DB8500 cpufreq cooling" depends on ARCH_U8500 depends on CPU_THERMAL default y help Adds DB8500 cpufreq cooling devices, and these cooling devices can be bound to thermal zone trip points. When a trip point reached, the bound cpufreq cooling device turns active to set CPU frequency low to cool down the CPU. config INTEL_POWERCLAMP tristate "Intel PowerClamp idle injection driver" depends on THERMAL depends on X86 depends on CPU_SUP_INTEL help Enable this to enable Intel PowerClamp idle injection driver. This enforce idle time which results in more package C-state residency. The user interface is exposed via generic thermal framework. config X86_PKG_TEMP_THERMAL tristate "X86 package temperature thermal driver" depends on X86_THERMAL_VECTOR select THERMAL_GOV_USER_SPACE default m help Enable this to register CPU digital sensor for package temperature as thermal zone. Each package will have its own thermal zone. There are two trip points which can be set by user to get notifications via thermal notification methods. config INTEL_SOC_DTS_THERMAL tristate "Intel SoCs DTS thermal driver" depends on X86 && IOSF_MBI help Enable this to register Intel SoCs (e.g. Bay Trail) platform digital temperature sensor (DTS). These SoCs have two additional DTSs in addition to DTSs on CPU cores. Each DTS will be registered as a thermal zone. There are two trip points. One of the trip point can be set by user mode programs to get notifications via Linux thermal notification methods.The other trip is a critical trip point, which was set by the driver based on the TJ MAX temperature. config INT340X_THERMAL tristate "ACPI INT340X thermal drivers" depends on X86 && ACPI select THERMAL_GOV_USER_SPACE select ACPI_THERMAL_REL select ACPI_FAN help Newer laptops and tablets that use ACPI may have thermal sensors and other devices with thermal control capabilities outside the core CPU/SOC, for thermal safety reasons. They are exposed for the OS to use via the INT3400 ACPI device object as the master, and INT3401~INT340B ACPI device objects as the slaves. Enable this to expose the temperature information and cooling ability from these objects to userspace via the normal thermal framework. This means that a wide range of applications and GUI widgets can show the information to the user or use this information for making decisions. For example, the Intel Thermal Daemon can use this information to allow the user to select his laptop to run without turning on the fans. config ACPI_THERMAL_REL tristate depends on ACPI menu "Texas Instruments thermal drivers" source "drivers/thermal/ti-soc-thermal/Kconfig" endmenu menu "Samsung thermal drivers" depends on ARCH_EXYNOS source "drivers/thermal/samsung/Kconfig" endmenu menu "STMicroelectronics thermal drivers" depends on ARCH_STI && OF source "drivers/thermal/st/Kconfig" endmenu endif