mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-20 10:44:23 +08:00
Merge master.kernel.org:/home/rmk/linux-2.6-arm
This commit is contained in:
commit
194d0710e1
@ -104,6 +104,7 @@ logo_*.c
|
||||
logo_*_clut224.c
|
||||
logo_*_mono.c
|
||||
lxdialog
|
||||
mach-types
|
||||
mach-types.h
|
||||
make_times_h
|
||||
map
|
||||
|
@ -61,7 +61,7 @@ static struct plat_serial8250_port coyote_uart_data[] = {
|
||||
.mapbase = IXP4XX_UART2_BASE_PHYS,
|
||||
.membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
|
||||
.irq = IRQ_IXP4XX_UART2,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
|
||||
.iotype = UPIO_MEM,
|
||||
.regshift = 2,
|
||||
.uartclk = IXP4XX_UART_XTAL,
|
||||
|
@ -83,7 +83,7 @@ static struct plat_serial8250_port gtwx5715_uart_platform_data[] = {
|
||||
.mapbase = IXP4XX_UART2_BASE_PHYS,
|
||||
.membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
|
||||
.irq = IRQ_IXP4XX_UART2,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
|
||||
.iotype = UPIO_MEM,
|
||||
.regshift = 2,
|
||||
.uartclk = IXP4XX_UART_XTAL,
|
||||
|
@ -82,7 +82,7 @@ static struct plat_serial8250_port ixdp425_uart_data[] = {
|
||||
.mapbase = IXP4XX_UART1_BASE_PHYS,
|
||||
.membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET,
|
||||
.irq = IRQ_IXP4XX_UART1,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
|
||||
.iotype = UPIO_MEM,
|
||||
.regshift = 2,
|
||||
.uartclk = IXP4XX_UART_XTAL,
|
||||
@ -91,7 +91,7 @@ static struct plat_serial8250_port ixdp425_uart_data[] = {
|
||||
.mapbase = IXP4XX_UART2_BASE_PHYS,
|
||||
.membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
|
||||
.irq = IRQ_IXP4XX_UART1,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
|
||||
.iotype = UPIO_MEM,
|
||||
.regshift = 2,
|
||||
.uartclk = IXP4XX_UART_XTAL,
|
||||
|
@ -30,6 +30,7 @@
|
||||
* 28-Jun-2005 BJD Moved pm functionality out to common code
|
||||
* 17-Jul-2005 BJD Changed to platform device for SuperIO 16550s
|
||||
* 25-Jul-2005 BJD Removed ASIX static mappings
|
||||
* 27-Jul-2005 BJD Ensure maximum frequency of i2c bus
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
@ -60,6 +61,7 @@
|
||||
#include <asm/arch/regs-mem.h>
|
||||
#include <asm/arch/regs-lcd.h>
|
||||
#include <asm/arch/nand.h>
|
||||
#include <asm/arch/iic.h>
|
||||
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/nand.h>
|
||||
@ -304,7 +306,7 @@ static void bast_nand_select(struct s3c2410_nand_set *set, int slot)
|
||||
}
|
||||
|
||||
static struct s3c2410_platform_nand bast_nand_info = {
|
||||
.tacls = 80,
|
||||
.tacls = 40,
|
||||
.twrph0 = 80,
|
||||
.twrph1 = 80,
|
||||
.nr_sets = ARRAY_SIZE(bast_nand_sets),
|
||||
@ -385,6 +387,17 @@ static struct platform_device bast_sio = {
|
||||
},
|
||||
};
|
||||
|
||||
/* we have devices on the bus which cannot work much over the
|
||||
* standard 100KHz i2c bus frequency
|
||||
*/
|
||||
|
||||
static struct s3c2410_platform_i2c bast_i2c_info = {
|
||||
.flags = 0,
|
||||
.slave_addr = 0x10,
|
||||
.bus_freq = 100*1000,
|
||||
.max_freq = 130*1000,
|
||||
};
|
||||
|
||||
/* Standard BAST devices */
|
||||
|
||||
static struct platform_device *bast_devices[] __initdata = {
|
||||
@ -431,6 +444,7 @@ void __init bast_map_io(void)
|
||||
s3c24xx_uclk.parent = &s3c24xx_clkout1;
|
||||
|
||||
s3c_device_nand.dev.platform_data = &bast_nand_info;
|
||||
s3c_device_i2c.dev.platform_data = &bast_i2c_info;
|
||||
|
||||
s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc));
|
||||
s3c24xx_init_clocks(0);
|
||||
|
@ -370,142 +370,6 @@ ENTRY(cpu_xscale_dcache_clean_area)
|
||||
bhi 1b
|
||||
mov pc, lr
|
||||
|
||||
/* ================================ CACHE LOCKING============================
|
||||
*
|
||||
* The XScale MicroArchitecture implements support for locking entries into
|
||||
* the data and instruction cache. The following functions implement the core
|
||||
* low level instructions needed to accomplish the locking. The developer's
|
||||
* manual states that the code that performs the locking must be in non-cached
|
||||
* memory. To accomplish this, the code in xscale-cache-lock.c copies the
|
||||
* following functions from the cache into a non-cached memory region that
|
||||
* is allocated through consistent_alloc().
|
||||
*
|
||||
*/
|
||||
.align 5
|
||||
/*
|
||||
* xscale_icache_lock
|
||||
*
|
||||
* r0: starting address to lock
|
||||
* r1: end address to lock
|
||||
*/
|
||||
ENTRY(xscale_icache_lock)
|
||||
|
||||
iLockLoop:
|
||||
bic r0, r0, #CACHELINESIZE - 1
|
||||
mcr p15, 0, r0, c9, c1, 0 @ lock into cache
|
||||
cmp r0, r1 @ are we done?
|
||||
add r0, r0, #CACHELINESIZE @ advance to next cache line
|
||||
bls iLockLoop
|
||||
mov pc, lr
|
||||
|
||||
/*
|
||||
* xscale_icache_unlock
|
||||
*/
|
||||
ENTRY(xscale_icache_unlock)
|
||||
mcr p15, 0, r0, c9, c1, 1 @ Unlock icache
|
||||
mov pc, lr
|
||||
|
||||
/*
|
||||
* xscale_dcache_lock
|
||||
*
|
||||
* r0: starting address to lock
|
||||
* r1: end address to lock
|
||||
*/
|
||||
ENTRY(xscale_dcache_lock)
|
||||
mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
|
||||
mov r2, #1
|
||||
mcr p15, 0, r2, c9, c2, 0 @ Put dcache in lock mode
|
||||
cpwait ip @ Wait for completion
|
||||
|
||||
mrs r2, cpsr
|
||||
orr r3, r2, #PSR_F_BIT | PSR_I_BIT
|
||||
dLockLoop:
|
||||
msr cpsr_c, r3
|
||||
mcr p15, 0, r0, c7, c10, 1 @ Write back line if it is dirty
|
||||
mcr p15, 0, r0, c7, c6, 1 @ Flush/invalidate line
|
||||
msr cpsr_c, r2
|
||||
ldr ip, [r0], #CACHELINESIZE @ Preload 32 bytes into cache from
|
||||
@ location [r0]. Post-increment
|
||||
@ r3 to next cache line
|
||||
cmp r0, r1 @ Are we done?
|
||||
bls dLockLoop
|
||||
|
||||
mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
|
||||
mov r2, #0
|
||||
mcr p15, 0, r2, c9, c2, 0 @ Get out of lock mode
|
||||
cpwait_ret lr, ip
|
||||
|
||||
/*
|
||||
* xscale_dcache_unlock
|
||||
*/
|
||||
ENTRY(xscale_dcache_unlock)
|
||||
mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
|
||||
mcr p15, 0, ip, c9, c2, 1 @ Unlock cache
|
||||
mov pc, lr
|
||||
|
||||
/*
|
||||
* Needed to determine the length of the code that needs to be copied.
|
||||
*/
|
||||
.align 5
|
||||
ENTRY(xscale_cache_dummy)
|
||||
mov pc, lr
|
||||
|
||||
/* ================================ TLB LOCKING==============================
|
||||
*
|
||||
* The XScale MicroArchitecture implements support for locking entries into
|
||||
* the Instruction and Data TLBs. The following functions provide the
|
||||
* low level support for supporting these under Linux. xscale-lock.c
|
||||
* implements some higher level management code. Most of the following
|
||||
* is taken straight out of the Developer's Manual.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Lock I-TLB entry
|
||||
*
|
||||
* r0: Virtual address to translate and lock
|
||||
*/
|
||||
.align 5
|
||||
ENTRY(xscale_itlb_lock)
|
||||
mrs r2, cpsr
|
||||
orr r3, r2, #PSR_F_BIT | PSR_I_BIT
|
||||
msr cpsr_c, r3 @ Disable interrupts
|
||||
mcr p15, 0, r0, c8, c5, 1 @ Invalidate I-TLB entry
|
||||
mcr p15, 0, r0, c10, c4, 0 @ Translate and lock
|
||||
msr cpsr_c, r2 @ Restore interrupts
|
||||
cpwait_ret lr, ip
|
||||
|
||||
/*
|
||||
* Lock D-TLB entry
|
||||
*
|
||||
* r0: Virtual address to translate and lock
|
||||
*/
|
||||
.align 5
|
||||
ENTRY(xscale_dtlb_lock)
|
||||
mrs r2, cpsr
|
||||
orr r3, r2, #PSR_F_BIT | PSR_I_BIT
|
||||
msr cpsr_c, r3 @ Disable interrupts
|
||||
mcr p15, 0, r0, c8, c6, 1 @ Invalidate D-TLB entry
|
||||
mcr p15, 0, r0, c10, c8, 0 @ Translate and lock
|
||||
msr cpsr_c, r2 @ Restore interrupts
|
||||
cpwait_ret lr, ip
|
||||
|
||||
/*
|
||||
* Unlock all I-TLB entries
|
||||
*/
|
||||
.align 5
|
||||
ENTRY(xscale_itlb_unlock)
|
||||
mcr p15, 0, ip, c10, c4, 1 @ Unlock I-TLB
|
||||
mcr p15, 0, ip, c8, c5, 0 @ Invalidate I-TLB
|
||||
cpwait_ret lr, ip
|
||||
|
||||
/*
|
||||
* Unlock all D-TLB entries
|
||||
*/
|
||||
ENTRY(xscale_dtlb_unlock)
|
||||
mcr p15, 0, ip, c10, c8, 1 @ Unlock D-TBL
|
||||
mcr p15, 0, ip, c8, c6, 0 @ Invalidate D-TLB
|
||||
cpwait_ret lr, ip
|
||||
|
||||
/* =============================== PageTable ============================== */
|
||||
|
||||
#define PTE_CACHE_WRITE_ALLOCATE 0
|
||||
|
@ -40,17 +40,17 @@ float64 float64_arccos(float64 rFm);
|
||||
float64 float64_pow(float64 rFn, float64 rFm);
|
||||
float64 float64_pol(float64 rFn, float64 rFm);
|
||||
|
||||
static float64 float64_rsf(float64 rFn, float64 rFm)
|
||||
static float64 float64_rsf(struct roundingData *roundData, float64 rFn, float64 rFm)
|
||||
{
|
||||
return float64_sub(rFm, rFn);
|
||||
return float64_sub(roundData, rFm, rFn);
|
||||
}
|
||||
|
||||
static float64 float64_rdv(float64 rFn, float64 rFm)
|
||||
static float64 float64_rdv(struct roundingData *roundData, float64 rFn, float64 rFm)
|
||||
{
|
||||
return float64_div(rFm, rFn);
|
||||
return float64_div(roundData, rFm, rFn);
|
||||
}
|
||||
|
||||
static float64 (*const dyadic_double[16])(float64 rFn, float64 rFm) = {
|
||||
static float64 (*const dyadic_double[16])(struct roundingData*, float64 rFn, float64 rFm) = {
|
||||
[ADF_CODE >> 20] = float64_add,
|
||||
[MUF_CODE >> 20] = float64_mul,
|
||||
[SUF_CODE >> 20] = float64_sub,
|
||||
@ -65,12 +65,12 @@ static float64 (*const dyadic_double[16])(float64 rFn, float64 rFm) = {
|
||||
[FRD_CODE >> 20] = float64_rdv,
|
||||
};
|
||||
|
||||
static float64 float64_mvf(float64 rFm)
|
||||
static float64 float64_mvf(struct roundingData *roundData,float64 rFm)
|
||||
{
|
||||
return rFm;
|
||||
}
|
||||
|
||||
static float64 float64_mnf(float64 rFm)
|
||||
static float64 float64_mnf(struct roundingData *roundData,float64 rFm)
|
||||
{
|
||||
union float64_components u;
|
||||
|
||||
@ -84,7 +84,7 @@ static float64 float64_mnf(float64 rFm)
|
||||
return u.f64;
|
||||
}
|
||||
|
||||
static float64 float64_abs(float64 rFm)
|
||||
static float64 float64_abs(struct roundingData *roundData,float64 rFm)
|
||||
{
|
||||
union float64_components u;
|
||||
|
||||
@ -98,7 +98,7 @@ static float64 float64_abs(float64 rFm)
|
||||
return u.f64;
|
||||
}
|
||||
|
||||
static float64 (*const monadic_double[16])(float64 rFm) = {
|
||||
static float64 (*const monadic_double[16])(struct roundingData *, float64 rFm) = {
|
||||
[MVF_CODE >> 20] = float64_mvf,
|
||||
[MNF_CODE >> 20] = float64_mnf,
|
||||
[ABS_CODE >> 20] = float64_abs,
|
||||
@ -108,7 +108,7 @@ static float64 (*const monadic_double[16])(float64 rFm) = {
|
||||
[NRM_CODE >> 20] = float64_mvf,
|
||||
};
|
||||
|
||||
unsigned int DoubleCPDO(const unsigned int opcode, FPREG * rFd)
|
||||
unsigned int DoubleCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd)
|
||||
{
|
||||
FPA11 *fpa11 = GET_FPA11();
|
||||
float64 rFm;
|
||||
@ -151,13 +151,13 @@ unsigned int DoubleCPDO(const unsigned int opcode, FPREG * rFd)
|
||||
}
|
||||
|
||||
if (dyadic_double[opc_mask_shift]) {
|
||||
rFd->fDouble = dyadic_double[opc_mask_shift](rFn, rFm);
|
||||
rFd->fDouble = dyadic_double[opc_mask_shift](roundData, rFn, rFm);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (monadic_double[opc_mask_shift]) {
|
||||
rFd->fDouble = monadic_double[opc_mask_shift](rFm);
|
||||
rFd->fDouble = monadic_double[opc_mask_shift](roundData, rFm);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
@ -35,17 +35,17 @@ floatx80 floatx80_arccos(floatx80 rFm);
|
||||
floatx80 floatx80_pow(floatx80 rFn, floatx80 rFm);
|
||||
floatx80 floatx80_pol(floatx80 rFn, floatx80 rFm);
|
||||
|
||||
static floatx80 floatx80_rsf(floatx80 rFn, floatx80 rFm)
|
||||
static floatx80 floatx80_rsf(struct roundingData *roundData, floatx80 rFn, floatx80 rFm)
|
||||
{
|
||||
return floatx80_sub(rFm, rFn);
|
||||
return floatx80_sub(roundData, rFm, rFn);
|
||||
}
|
||||
|
||||
static floatx80 floatx80_rdv(floatx80 rFn, floatx80 rFm)
|
||||
static floatx80 floatx80_rdv(struct roundingData *roundData, floatx80 rFn, floatx80 rFm)
|
||||
{
|
||||
return floatx80_div(rFm, rFn);
|
||||
return floatx80_div(roundData, rFm, rFn);
|
||||
}
|
||||
|
||||
static floatx80 (*const dyadic_extended[16])(floatx80 rFn, floatx80 rFm) = {
|
||||
static floatx80 (*const dyadic_extended[16])(struct roundingData*, floatx80 rFn, floatx80 rFm) = {
|
||||
[ADF_CODE >> 20] = floatx80_add,
|
||||
[MUF_CODE >> 20] = floatx80_mul,
|
||||
[SUF_CODE >> 20] = floatx80_sub,
|
||||
@ -60,24 +60,24 @@ static floatx80 (*const dyadic_extended[16])(floatx80 rFn, floatx80 rFm) = {
|
||||
[FRD_CODE >> 20] = floatx80_rdv,
|
||||
};
|
||||
|
||||
static floatx80 floatx80_mvf(floatx80 rFm)
|
||||
static floatx80 floatx80_mvf(struct roundingData *roundData, floatx80 rFm)
|
||||
{
|
||||
return rFm;
|
||||
}
|
||||
|
||||
static floatx80 floatx80_mnf(floatx80 rFm)
|
||||
static floatx80 floatx80_mnf(struct roundingData *roundData, floatx80 rFm)
|
||||
{
|
||||
rFm.high ^= 0x8000;
|
||||
return rFm;
|
||||
}
|
||||
|
||||
static floatx80 floatx80_abs(floatx80 rFm)
|
||||
static floatx80 floatx80_abs(struct roundingData *roundData, floatx80 rFm)
|
||||
{
|
||||
rFm.high &= 0x7fff;
|
||||
return rFm;
|
||||
}
|
||||
|
||||
static floatx80 (*const monadic_extended[16])(floatx80 rFm) = {
|
||||
static floatx80 (*const monadic_extended[16])(struct roundingData*, floatx80 rFm) = {
|
||||
[MVF_CODE >> 20] = floatx80_mvf,
|
||||
[MNF_CODE >> 20] = floatx80_mnf,
|
||||
[ABS_CODE >> 20] = floatx80_abs,
|
||||
@ -87,7 +87,7 @@ static floatx80 (*const monadic_extended[16])(floatx80 rFm) = {
|
||||
[NRM_CODE >> 20] = floatx80_mvf,
|
||||
};
|
||||
|
||||
unsigned int ExtendedCPDO(const unsigned int opcode, FPREG * rFd)
|
||||
unsigned int ExtendedCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd)
|
||||
{
|
||||
FPA11 *fpa11 = GET_FPA11();
|
||||
floatx80 rFm;
|
||||
@ -138,13 +138,13 @@ unsigned int ExtendedCPDO(const unsigned int opcode, FPREG * rFd)
|
||||
}
|
||||
|
||||
if (dyadic_extended[opc_mask_shift]) {
|
||||
rFd->fExtended = dyadic_extended[opc_mask_shift](rFn, rFm);
|
||||
rFd->fExtended = dyadic_extended[opc_mask_shift](roundData, rFn, rFm);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (monadic_extended[opc_mask_shift]) {
|
||||
rFd->fExtended = monadic_extended[opc_mask_shift](rFm);
|
||||
rFd->fExtended = monadic_extended[opc_mask_shift](roundData, rFm);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
@ -51,48 +51,42 @@ static void resetFPA11(void)
|
||||
fpa11->fpsr = FP_EMULATOR | BIT_AC;
|
||||
}
|
||||
|
||||
void SetRoundingMode(const unsigned int opcode)
|
||||
int8 SetRoundingMode(const unsigned int opcode)
|
||||
{
|
||||
switch (opcode & MASK_ROUNDING_MODE) {
|
||||
default:
|
||||
case ROUND_TO_NEAREST:
|
||||
float_rounding_mode = float_round_nearest_even;
|
||||
break;
|
||||
return float_round_nearest_even;
|
||||
|
||||
case ROUND_TO_PLUS_INFINITY:
|
||||
float_rounding_mode = float_round_up;
|
||||
break;
|
||||
return float_round_up;
|
||||
|
||||
case ROUND_TO_MINUS_INFINITY:
|
||||
float_rounding_mode = float_round_down;
|
||||
break;
|
||||
return float_round_down;
|
||||
|
||||
case ROUND_TO_ZERO:
|
||||
float_rounding_mode = float_round_to_zero;
|
||||
break;
|
||||
return float_round_to_zero;
|
||||
}
|
||||
}
|
||||
|
||||
void SetRoundingPrecision(const unsigned int opcode)
|
||||
int8 SetRoundingPrecision(const unsigned int opcode)
|
||||
{
|
||||
#ifdef CONFIG_FPE_NWFPE_XP
|
||||
switch (opcode & MASK_ROUNDING_PRECISION) {
|
||||
case ROUND_SINGLE:
|
||||
floatx80_rounding_precision = 32;
|
||||
break;
|
||||
return 32;
|
||||
|
||||
case ROUND_DOUBLE:
|
||||
floatx80_rounding_precision = 64;
|
||||
break;
|
||||
return 64;
|
||||
|
||||
case ROUND_EXTENDED:
|
||||
floatx80_rounding_precision = 80;
|
||||
break;
|
||||
return 80;
|
||||
|
||||
default:
|
||||
floatx80_rounding_precision = 80;
|
||||
return 80;
|
||||
}
|
||||
#endif
|
||||
return 80;
|
||||
}
|
||||
|
||||
void nwfpe_init_fpa(union fp_state *fp)
|
||||
@ -103,8 +97,6 @@ void nwfpe_init_fpa(union fp_state *fp)
|
||||
#endif
|
||||
memset(fpa11, 0, sizeof(FPA11));
|
||||
resetFPA11();
|
||||
SetRoundingMode(ROUND_TO_NEAREST);
|
||||
SetRoundingPrecision(ROUND_EXTENDED);
|
||||
fpa11->initflag = 1;
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,13 @@
|
||||
/* includes */
|
||||
#include "fpsr.h" /* FP control and status register definitions */
|
||||
#include "milieu.h"
|
||||
|
||||
struct roundingData {
|
||||
int8 mode;
|
||||
int8 precision;
|
||||
signed char exception;
|
||||
};
|
||||
|
||||
#include "softfloat.h"
|
||||
|
||||
#define typeNone 0x00
|
||||
@ -84,8 +91,8 @@ typedef struct tagFPA11 {
|
||||
initialised. */
|
||||
} FPA11;
|
||||
|
||||
extern void SetRoundingMode(const unsigned int);
|
||||
extern void SetRoundingPrecision(const unsigned int);
|
||||
extern int8 SetRoundingMode(const unsigned int);
|
||||
extern int8 SetRoundingPrecision(const unsigned int);
|
||||
extern void nwfpe_init_fpa(union fp_state *fp);
|
||||
|
||||
#endif
|
||||
|
@ -24,15 +24,16 @@
|
||||
#include "fpa11.h"
|
||||
#include "fpopcode.h"
|
||||
|
||||
unsigned int SingleCPDO(const unsigned int opcode, FPREG * rFd);
|
||||
unsigned int DoubleCPDO(const unsigned int opcode, FPREG * rFd);
|
||||
unsigned int ExtendedCPDO(const unsigned int opcode, FPREG * rFd);
|
||||
unsigned int SingleCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd);
|
||||
unsigned int DoubleCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd);
|
||||
unsigned int ExtendedCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd);
|
||||
|
||||
unsigned int EmulateCPDO(const unsigned int opcode)
|
||||
{
|
||||
FPA11 *fpa11 = GET_FPA11();
|
||||
FPREG *rFd;
|
||||
unsigned int nType, nDest, nRc;
|
||||
struct roundingData roundData;
|
||||
|
||||
/* Get the destination size. If not valid let Linux perform
|
||||
an invalid instruction trap. */
|
||||
@ -40,7 +41,9 @@ unsigned int EmulateCPDO(const unsigned int opcode)
|
||||
if (typeNone == nDest)
|
||||
return 0;
|
||||
|
||||
SetRoundingMode(opcode);
|
||||
roundData.mode = SetRoundingMode(opcode);
|
||||
roundData.precision = SetRoundingPrecision(opcode);
|
||||
roundData.exception = 0;
|
||||
|
||||
/* Compare the size of the operands in Fn and Fm.
|
||||
Choose the largest size and perform operations in that size,
|
||||
@ -63,14 +66,14 @@ unsigned int EmulateCPDO(const unsigned int opcode)
|
||||
|
||||
switch (nType) {
|
||||
case typeSingle:
|
||||
nRc = SingleCPDO(opcode, rFd);
|
||||
nRc = SingleCPDO(&roundData, opcode, rFd);
|
||||
break;
|
||||
case typeDouble:
|
||||
nRc = DoubleCPDO(opcode, rFd);
|
||||
nRc = DoubleCPDO(&roundData, opcode, rFd);
|
||||
break;
|
||||
#ifdef CONFIG_FPE_NWFPE_XP
|
||||
case typeExtended:
|
||||
nRc = ExtendedCPDO(opcode, rFd);
|
||||
nRc = ExtendedCPDO(&roundData, opcode, rFd);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
@ -93,9 +96,9 @@ unsigned int EmulateCPDO(const unsigned int opcode)
|
||||
case typeSingle:
|
||||
{
|
||||
if (typeDouble == nType)
|
||||
rFd->fSingle = float64_to_float32(rFd->fDouble);
|
||||
rFd->fSingle = float64_to_float32(&roundData, rFd->fDouble);
|
||||
else
|
||||
rFd->fSingle = floatx80_to_float32(rFd->fExtended);
|
||||
rFd->fSingle = floatx80_to_float32(&roundData, rFd->fExtended);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -104,7 +107,7 @@ unsigned int EmulateCPDO(const unsigned int opcode)
|
||||
if (typeSingle == nType)
|
||||
rFd->fDouble = float32_to_float64(rFd->fSingle);
|
||||
else
|
||||
rFd->fDouble = floatx80_to_float64(rFd->fExtended);
|
||||
rFd->fDouble = floatx80_to_float64(&roundData, rFd->fExtended);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -121,12 +124,15 @@ unsigned int EmulateCPDO(const unsigned int opcode)
|
||||
#else
|
||||
if (nDest != nType) {
|
||||
if (nDest == typeSingle)
|
||||
rFd->fSingle = float64_to_float32(rFd->fDouble);
|
||||
rFd->fSingle = float64_to_float32(&roundData, rFd->fDouble);
|
||||
else
|
||||
rFd->fDouble = float32_to_float64(rFd->fSingle);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (roundData.exception)
|
||||
float_raise(roundData.exception);
|
||||
|
||||
return nRc;
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ static inline void loadMultiple(const unsigned int Fn, const unsigned int __user
|
||||
}
|
||||
}
|
||||
|
||||
static inline void storeSingle(const unsigned int Fn, unsigned int __user *pMem)
|
||||
static inline void storeSingle(struct roundingData *roundData, const unsigned int Fn, unsigned int __user *pMem)
|
||||
{
|
||||
FPA11 *fpa11 = GET_FPA11();
|
||||
union {
|
||||
@ -106,12 +106,12 @@ static inline void storeSingle(const unsigned int Fn, unsigned int __user *pMem)
|
||||
|
||||
switch (fpa11->fType[Fn]) {
|
||||
case typeDouble:
|
||||
val.f = float64_to_float32(fpa11->fpreg[Fn].fDouble);
|
||||
val.f = float64_to_float32(roundData, fpa11->fpreg[Fn].fDouble);
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_FPE_NWFPE_XP
|
||||
case typeExtended:
|
||||
val.f = floatx80_to_float32(fpa11->fpreg[Fn].fExtended);
|
||||
val.f = floatx80_to_float32(roundData, fpa11->fpreg[Fn].fExtended);
|
||||
break;
|
||||
#endif
|
||||
|
||||
@ -122,7 +122,7 @@ static inline void storeSingle(const unsigned int Fn, unsigned int __user *pMem)
|
||||
put_user(val.i[0], pMem);
|
||||
}
|
||||
|
||||
static inline void storeDouble(const unsigned int Fn, unsigned int __user *pMem)
|
||||
static inline void storeDouble(struct roundingData *roundData, const unsigned int Fn, unsigned int __user *pMem)
|
||||
{
|
||||
FPA11 *fpa11 = GET_FPA11();
|
||||
union {
|
||||
@ -137,7 +137,7 @@ static inline void storeDouble(const unsigned int Fn, unsigned int __user *pMem)
|
||||
|
||||
#ifdef CONFIG_FPE_NWFPE_XP
|
||||
case typeExtended:
|
||||
val.f = floatx80_to_float64(fpa11->fpreg[Fn].fExtended);
|
||||
val.f = floatx80_to_float64(roundData, fpa11->fpreg[Fn].fExtended);
|
||||
break;
|
||||
#endif
|
||||
|
||||
@ -259,8 +259,11 @@ unsigned int PerformSTF(const unsigned int opcode)
|
||||
{
|
||||
unsigned int __user *pBase, *pAddress, *pFinal;
|
||||
unsigned int nRc = 1, write_back = WRITE_BACK(opcode);
|
||||
struct roundingData roundData;
|
||||
|
||||
SetRoundingMode(ROUND_TO_NEAREST);
|
||||
roundData.mode = SetRoundingMode(opcode);
|
||||
roundData.precision = SetRoundingPrecision(opcode);
|
||||
roundData.exception = 0;
|
||||
|
||||
pBase = (unsigned int __user *) readRegister(getRn(opcode));
|
||||
if (REG_PC == getRn(opcode)) {
|
||||
@ -281,10 +284,10 @@ unsigned int PerformSTF(const unsigned int opcode)
|
||||
|
||||
switch (opcode & MASK_TRANSFER_LENGTH) {
|
||||
case TRANSFER_SINGLE:
|
||||
storeSingle(getFd(opcode), pAddress);
|
||||
storeSingle(&roundData, getFd(opcode), pAddress);
|
||||
break;
|
||||
case TRANSFER_DOUBLE:
|
||||
storeDouble(getFd(opcode), pAddress);
|
||||
storeDouble(&roundData, getFd(opcode), pAddress);
|
||||
break;
|
||||
#ifdef CONFIG_FPE_NWFPE_XP
|
||||
case TRANSFER_EXTENDED:
|
||||
@ -295,6 +298,9 @@ unsigned int PerformSTF(const unsigned int opcode)
|
||||
nRc = 0;
|
||||
}
|
||||
|
||||
if (roundData.exception)
|
||||
float_raise(roundData.exception);
|
||||
|
||||
if (write_back)
|
||||
writeRegister(getRn(opcode), (unsigned long) pFinal);
|
||||
return nRc;
|
||||
|
@ -33,8 +33,6 @@ extern flag floatx80_is_nan(floatx80);
|
||||
extern flag float64_is_nan(float64);
|
||||
extern flag float32_is_nan(float32);
|
||||
|
||||
void SetRoundingMode(const unsigned int opcode);
|
||||
|
||||
unsigned int PerformFLT(const unsigned int opcode);
|
||||
unsigned int PerformFIX(const unsigned int opcode);
|
||||
|
||||
@ -77,14 +75,17 @@ unsigned int EmulateCPRT(const unsigned int opcode)
|
||||
unsigned int PerformFLT(const unsigned int opcode)
|
||||
{
|
||||
FPA11 *fpa11 = GET_FPA11();
|
||||
SetRoundingMode(opcode);
|
||||
SetRoundingPrecision(opcode);
|
||||
struct roundingData roundData;
|
||||
|
||||
roundData.mode = SetRoundingMode(opcode);
|
||||
roundData.precision = SetRoundingPrecision(opcode);
|
||||
roundData.exception = 0;
|
||||
|
||||
switch (opcode & MASK_ROUNDING_PRECISION) {
|
||||
case ROUND_SINGLE:
|
||||
{
|
||||
fpa11->fType[getFn(opcode)] = typeSingle;
|
||||
fpa11->fpreg[getFn(opcode)].fSingle = int32_to_float32(readRegister(getRd(opcode)));
|
||||
fpa11->fpreg[getFn(opcode)].fSingle = int32_to_float32(&roundData, readRegister(getRd(opcode)));
|
||||
}
|
||||
break;
|
||||
|
||||
@ -108,6 +109,9 @@ unsigned int PerformFLT(const unsigned int opcode)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (roundData.exception)
|
||||
float_raise(roundData.exception);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -115,26 +119,29 @@ unsigned int PerformFIX(const unsigned int opcode)
|
||||
{
|
||||
FPA11 *fpa11 = GET_FPA11();
|
||||
unsigned int Fn = getFm(opcode);
|
||||
struct roundingData roundData;
|
||||
|
||||
SetRoundingMode(opcode);
|
||||
roundData.mode = SetRoundingMode(opcode);
|
||||
roundData.precision = SetRoundingPrecision(opcode);
|
||||
roundData.exception = 0;
|
||||
|
||||
switch (fpa11->fType[Fn]) {
|
||||
case typeSingle:
|
||||
{
|
||||
writeRegister(getRd(opcode), float32_to_int32(fpa11->fpreg[Fn].fSingle));
|
||||
writeRegister(getRd(opcode), float32_to_int32(&roundData, fpa11->fpreg[Fn].fSingle));
|
||||
}
|
||||
break;
|
||||
|
||||
case typeDouble:
|
||||
{
|
||||
writeRegister(getRd(opcode), float64_to_int32(fpa11->fpreg[Fn].fDouble));
|
||||
writeRegister(getRd(opcode), float64_to_int32(&roundData, fpa11->fpreg[Fn].fDouble));
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_FPE_NWFPE_XP
|
||||
case typeExtended:
|
||||
{
|
||||
writeRegister(getRd(opcode), floatx80_to_int32(fpa11->fpreg[Fn].fExtended));
|
||||
writeRegister(getRd(opcode), floatx80_to_int32(&roundData, fpa11->fpreg[Fn].fExtended));
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
@ -143,6 +150,9 @@ unsigned int PerformFIX(const unsigned int opcode)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (roundData.exception)
|
||||
float_raise(roundData.exception);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -116,8 +116,6 @@ fpmodule.c to integrate with the NetBSD kernel (I hope!).
|
||||
code to access data in user space in some other source files at the
|
||||
moment (grep for get_user / put_user calls). --philb]
|
||||
|
||||
float_exception_flags is a global variable in SoftFloat.
|
||||
|
||||
This function is called by the SoftFloat routines to raise a floating
|
||||
point exception. We check the trap enable byte in the FPSR, and raise
|
||||
a SIGFPE exception if necessary. If not the relevant bits in the
|
||||
@ -129,15 +127,14 @@ void float_raise(signed char flags)
|
||||
register unsigned int fpsr, cumulativeTraps;
|
||||
|
||||
#ifdef CONFIG_DEBUG_USER
|
||||
printk(KERN_DEBUG
|
||||
"NWFPE: %s[%d] takes exception %08x at %p from %08lx\n",
|
||||
current->comm, current->pid, flags,
|
||||
__builtin_return_address(0), GET_USERREG()->ARM_pc);
|
||||
/* Ignore inexact errors as there are far too many of them to log */
|
||||
if (flags & ~BIT_IXC)
|
||||
printk(KERN_DEBUG
|
||||
"NWFPE: %s[%d] takes exception %08x at %p from %08lx\n",
|
||||
current->comm, current->pid, flags,
|
||||
__builtin_return_address(0), GET_USERREG()->ARM_pc);
|
||||
#endif
|
||||
|
||||
/* Keep SoftFloat exception flags up to date. */
|
||||
float_exception_flags |= flags;
|
||||
|
||||
/* Read fpsr and initialize the cumulativeTraps. */
|
||||
fpsr = readFPSR();
|
||||
cumulativeTraps = 0;
|
||||
|
@ -36,17 +36,17 @@ float32 float32_arccos(float32 rFm);
|
||||
float32 float32_pow(float32 rFn, float32 rFm);
|
||||
float32 float32_pol(float32 rFn, float32 rFm);
|
||||
|
||||
static float32 float32_rsf(float32 rFn, float32 rFm)
|
||||
static float32 float32_rsf(struct roundingData *roundData, float32 rFn, float32 rFm)
|
||||
{
|
||||
return float32_sub(rFm, rFn);
|
||||
return float32_sub(roundData, rFm, rFn);
|
||||
}
|
||||
|
||||
static float32 float32_rdv(float32 rFn, float32 rFm)
|
||||
static float32 float32_rdv(struct roundingData *roundData, float32 rFn, float32 rFm)
|
||||
{
|
||||
return float32_div(rFm, rFn);
|
||||
return float32_div(roundData, rFm, rFn);
|
||||
}
|
||||
|
||||
static float32 (*const dyadic_single[16])(float32 rFn, float32 rFm) = {
|
||||
static float32 (*const dyadic_single[16])(struct roundingData *, float32 rFn, float32 rFm) = {
|
||||
[ADF_CODE >> 20] = float32_add,
|
||||
[MUF_CODE >> 20] = float32_mul,
|
||||
[SUF_CODE >> 20] = float32_sub,
|
||||
@ -60,22 +60,22 @@ static float32 (*const dyadic_single[16])(float32 rFn, float32 rFm) = {
|
||||
[FRD_CODE >> 20] = float32_rdv,
|
||||
};
|
||||
|
||||
static float32 float32_mvf(float32 rFm)
|
||||
static float32 float32_mvf(struct roundingData *roundData, float32 rFm)
|
||||
{
|
||||
return rFm;
|
||||
}
|
||||
|
||||
static float32 float32_mnf(float32 rFm)
|
||||
static float32 float32_mnf(struct roundingData *roundData, float32 rFm)
|
||||
{
|
||||
return rFm ^ 0x80000000;
|
||||
}
|
||||
|
||||
static float32 float32_abs(float32 rFm)
|
||||
static float32 float32_abs(struct roundingData *roundData, float32 rFm)
|
||||
{
|
||||
return rFm & 0x7fffffff;
|
||||
}
|
||||
|
||||
static float32 (*const monadic_single[16])(float32 rFm) = {
|
||||
static float32 (*const monadic_single[16])(struct roundingData*, float32 rFm) = {
|
||||
[MVF_CODE >> 20] = float32_mvf,
|
||||
[MNF_CODE >> 20] = float32_mnf,
|
||||
[ABS_CODE >> 20] = float32_abs,
|
||||
@ -85,7 +85,7 @@ static float32 (*const monadic_single[16])(float32 rFm) = {
|
||||
[NRM_CODE >> 20] = float32_mvf,
|
||||
};
|
||||
|
||||
unsigned int SingleCPDO(const unsigned int opcode, FPREG * rFd)
|
||||
unsigned int SingleCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd)
|
||||
{
|
||||
FPA11 *fpa11 = GET_FPA11();
|
||||
float32 rFm;
|
||||
@ -108,13 +108,13 @@ unsigned int SingleCPDO(const unsigned int opcode, FPREG * rFd)
|
||||
if (fpa11->fType[Fn] == typeSingle &&
|
||||
dyadic_single[opc_mask_shift]) {
|
||||
rFn = fpa11->fpreg[Fn].fSingle;
|
||||
rFd->fSingle = dyadic_single[opc_mask_shift](rFn, rFm);
|
||||
rFd->fSingle = dyadic_single[opc_mask_shift](roundData, rFn, rFm);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (monadic_single[opc_mask_shift]) {
|
||||
rFd->fSingle = monadic_single[opc_mask_shift](rFm);
|
||||
rFd->fSingle = monadic_single[opc_mask_shift](roundData, rFm);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -74,7 +74,7 @@ enum {
|
||||
Software IEC/IEEE floating-point rounding mode.
|
||||
-------------------------------------------------------------------------------
|
||||
*/
|
||||
extern signed char float_rounding_mode;
|
||||
//extern int8 float_rounding_mode;
|
||||
enum {
|
||||
float_round_nearest_even = 0,
|
||||
float_round_to_zero = 1,
|
||||
@ -86,7 +86,6 @@ enum {
|
||||
-------------------------------------------------------------------------------
|
||||
Software IEC/IEEE floating-point exception flags.
|
||||
-------------------------------------------------------------------------------
|
||||
extern signed char float_exception_flags;
|
||||
enum {
|
||||
float_flag_inexact = 1,
|
||||
float_flag_underflow = 2,
|
||||
@ -99,7 +98,6 @@ ScottB: November 4, 1998
|
||||
Changed the enumeration to match the bit order in the FPA11.
|
||||
*/
|
||||
|
||||
extern signed char float_exception_flags;
|
||||
enum {
|
||||
float_flag_invalid = 1,
|
||||
float_flag_divbyzero = 2,
|
||||
@ -121,7 +119,7 @@ void float_raise( signed char );
|
||||
Software IEC/IEEE integer-to-floating-point conversion routines.
|
||||
-------------------------------------------------------------------------------
|
||||
*/
|
||||
float32 int32_to_float32( signed int );
|
||||
float32 int32_to_float32( struct roundingData *, signed int );
|
||||
float64 int32_to_float64( signed int );
|
||||
#ifdef FLOATX80
|
||||
floatx80 int32_to_floatx80( signed int );
|
||||
@ -132,7 +130,7 @@ floatx80 int32_to_floatx80( signed int );
|
||||
Software IEC/IEEE single-precision conversion routines.
|
||||
-------------------------------------------------------------------------------
|
||||
*/
|
||||
signed int float32_to_int32( float32 );
|
||||
signed int float32_to_int32( struct roundingData *, float32 );
|
||||
signed int float32_to_int32_round_to_zero( float32 );
|
||||
float64 float32_to_float64( float32 );
|
||||
#ifdef FLOATX80
|
||||
@ -144,13 +142,13 @@ floatx80 float32_to_floatx80( float32 );
|
||||
Software IEC/IEEE single-precision operations.
|
||||
-------------------------------------------------------------------------------
|
||||
*/
|
||||
float32 float32_round_to_int( float32 );
|
||||
float32 float32_add( float32, float32 );
|
||||
float32 float32_sub( float32, float32 );
|
||||
float32 float32_mul( float32, float32 );
|
||||
float32 float32_div( float32, float32 );
|
||||
float32 float32_rem( float32, float32 );
|
||||
float32 float32_sqrt( float32 );
|
||||
float32 float32_round_to_int( struct roundingData*, float32 );
|
||||
float32 float32_add( struct roundingData *, float32, float32 );
|
||||
float32 float32_sub( struct roundingData *, float32, float32 );
|
||||
float32 float32_mul( struct roundingData *, float32, float32 );
|
||||
float32 float32_div( struct roundingData *, float32, float32 );
|
||||
float32 float32_rem( struct roundingData *, float32, float32 );
|
||||
float32 float32_sqrt( struct roundingData*, float32 );
|
||||
char float32_eq( float32, float32 );
|
||||
char float32_le( float32, float32 );
|
||||
char float32_lt( float32, float32 );
|
||||
@ -164,9 +162,9 @@ char float32_is_signaling_nan( float32 );
|
||||
Software IEC/IEEE double-precision conversion routines.
|
||||
-------------------------------------------------------------------------------
|
||||
*/
|
||||
signed int float64_to_int32( float64 );
|
||||
signed int float64_to_int32( struct roundingData *, float64 );
|
||||
signed int float64_to_int32_round_to_zero( float64 );
|
||||
float32 float64_to_float32( float64 );
|
||||
float32 float64_to_float32( struct roundingData *, float64 );
|
||||
#ifdef FLOATX80
|
||||
floatx80 float64_to_floatx80( float64 );
|
||||
#endif
|
||||
@ -176,13 +174,13 @@ floatx80 float64_to_floatx80( float64 );
|
||||
Software IEC/IEEE double-precision operations.
|
||||
-------------------------------------------------------------------------------
|
||||
*/
|
||||
float64 float64_round_to_int( float64 );
|
||||
float64 float64_add( float64, float64 );
|
||||
float64 float64_sub( float64, float64 );
|
||||
float64 float64_mul( float64, float64 );
|
||||
float64 float64_div( float64, float64 );
|
||||
float64 float64_rem( float64, float64 );
|
||||
float64 float64_sqrt( float64 );
|
||||
float64 float64_round_to_int( struct roundingData *, float64 );
|
||||
float64 float64_add( struct roundingData *, float64, float64 );
|
||||
float64 float64_sub( struct roundingData *, float64, float64 );
|
||||
float64 float64_mul( struct roundingData *, float64, float64 );
|
||||
float64 float64_div( struct roundingData *, float64, float64 );
|
||||
float64 float64_rem( struct roundingData *, float64, float64 );
|
||||
float64 float64_sqrt( struct roundingData *, float64 );
|
||||
char float64_eq( float64, float64 );
|
||||
char float64_le( float64, float64 );
|
||||
char float64_lt( float64, float64 );
|
||||
@ -198,31 +196,23 @@ char float64_is_signaling_nan( float64 );
|
||||
Software IEC/IEEE extended double-precision conversion routines.
|
||||
-------------------------------------------------------------------------------
|
||||
*/
|
||||
signed int floatx80_to_int32( floatx80 );
|
||||
signed int floatx80_to_int32( struct roundingData *, floatx80 );
|
||||
signed int floatx80_to_int32_round_to_zero( floatx80 );
|
||||
float32 floatx80_to_float32( floatx80 );
|
||||
float64 floatx80_to_float64( floatx80 );
|
||||
|
||||
/*
|
||||
-------------------------------------------------------------------------------
|
||||
Software IEC/IEEE extended double-precision rounding precision. Valid
|
||||
values are 32, 64, and 80.
|
||||
-------------------------------------------------------------------------------
|
||||
*/
|
||||
extern signed char floatx80_rounding_precision;
|
||||
float32 floatx80_to_float32( struct roundingData *, floatx80 );
|
||||
float64 floatx80_to_float64( struct roundingData *, floatx80 );
|
||||
|
||||
/*
|
||||
-------------------------------------------------------------------------------
|
||||
Software IEC/IEEE extended double-precision operations.
|
||||
-------------------------------------------------------------------------------
|
||||
*/
|
||||
floatx80 floatx80_round_to_int( floatx80 );
|
||||
floatx80 floatx80_add( floatx80, floatx80 );
|
||||
floatx80 floatx80_sub( floatx80, floatx80 );
|
||||
floatx80 floatx80_mul( floatx80, floatx80 );
|
||||
floatx80 floatx80_div( floatx80, floatx80 );
|
||||
floatx80 floatx80_rem( floatx80, floatx80 );
|
||||
floatx80 floatx80_sqrt( floatx80 );
|
||||
floatx80 floatx80_round_to_int( struct roundingData *, floatx80 );
|
||||
floatx80 floatx80_add( struct roundingData *, floatx80, floatx80 );
|
||||
floatx80 floatx80_sub( struct roundingData *, floatx80, floatx80 );
|
||||
floatx80 floatx80_mul( struct roundingData *, floatx80, floatx80 );
|
||||
floatx80 floatx80_div( struct roundingData *, floatx80, floatx80 );
|
||||
floatx80 floatx80_rem( struct roundingData *, floatx80, floatx80 );
|
||||
floatx80 floatx80_sqrt( struct roundingData *, floatx80 );
|
||||
char floatx80_eq( floatx80, floatx80 );
|
||||
char floatx80_le( floatx80, floatx80 );
|
||||
char floatx80_lt( floatx80, floatx80 );
|
||||
|
@ -770,6 +770,9 @@ vfp_double_add(struct vfp_double *vdd, struct vfp_double *vdn,
|
||||
if ((s64)m_sig < 0) {
|
||||
vdd->sign = vfp_sign_negate(vdd->sign);
|
||||
m_sig = -m_sig;
|
||||
} else if (m_sig == 0) {
|
||||
vdd->sign = (fpscr & FPSCR_RMODE_MASK) ==
|
||||
FPSCR_ROUND_MINUSINF ? 0x8000 : 0;
|
||||
}
|
||||
} else {
|
||||
m_sig += vdn->significand;
|
||||
|
@ -36,13 +36,10 @@
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#define OSCR_FREQ CLOCK_TICK_RATE
|
||||
#define SA1100_CLOSE_MAGIC (0x5afc4453)
|
||||
|
||||
static unsigned long sa1100wdt_users;
|
||||
static int expect_close;
|
||||
static int pre_margin;
|
||||
static int boot_status;
|
||||
static int nowayout = WATCHDOG_NOWAYOUT;
|
||||
|
||||
/*
|
||||
* Allow only one person to hold it open
|
||||
@ -62,55 +59,33 @@ static int sa1100dog_open(struct inode *inode, struct file *file)
|
||||
}
|
||||
|
||||
/*
|
||||
* Shut off the timer.
|
||||
* Lock it in if it's a module and we defined ...NOWAYOUT
|
||||
* Oddly, the watchdog can only be enabled, but we can turn off
|
||||
* the interrupt, which appears to prevent the watchdog timing out.
|
||||
* The watchdog cannot be disabled.
|
||||
*
|
||||
* Previous comments suggested that turning off the interrupt by
|
||||
* clearing OIER[E3] would prevent the watchdog timing out but this
|
||||
* does not appear to be true (at least on the PXA255).
|
||||
*/
|
||||
static int sa1100dog_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
OSMR3 = OSCR + pre_margin;
|
||||
|
||||
if (expect_close == SA1100_CLOSE_MAGIC) {
|
||||
OIER &= ~OIER_E3;
|
||||
} else {
|
||||
printk(KERN_CRIT "WATCHDOG: WDT device closed unexpectedly. WDT will not stop!\n");
|
||||
}
|
||||
printk(KERN_CRIT "WATCHDOG: Device closed - timer will not stop\n");
|
||||
|
||||
clear_bit(1, &sa1100wdt_users);
|
||||
expect_close = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t sa1100dog_write(struct file *file, const char *data, size_t len, loff_t *ppos)
|
||||
{
|
||||
if (len) {
|
||||
if (!nowayout) {
|
||||
size_t i;
|
||||
|
||||
expect_close = 0;
|
||||
|
||||
for (i = 0; i != len; i++) {
|
||||
char c;
|
||||
|
||||
if (get_user(c, data + i))
|
||||
return -EFAULT;
|
||||
if (c == 'V')
|
||||
expect_close = SA1100_CLOSE_MAGIC;
|
||||
}
|
||||
}
|
||||
if (len)
|
||||
/* Refresh OSMR3 timer. */
|
||||
OSMR3 = OSCR + pre_margin;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static struct watchdog_info ident = {
|
||||
.options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE |
|
||||
WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
|
||||
.identity = "SA1100 Watchdog",
|
||||
.options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
|
||||
.identity = "SA1100/PXA255 Watchdog",
|
||||
};
|
||||
|
||||
static int sa1100dog_ioctl(struct inode *inode, struct file *file,
|
||||
@ -172,7 +147,7 @@ static struct file_operations sa1100dog_fops =
|
||||
static struct miscdevice sa1100dog_miscdev =
|
||||
{
|
||||
.minor = WATCHDOG_MINOR,
|
||||
.name = "SA1100/PXA2xx watchdog",
|
||||
.name = "watchdog",
|
||||
.fops = &sa1100dog_fops,
|
||||
};
|
||||
|
||||
@ -194,7 +169,6 @@ static int __init sa1100dog_init(void)
|
||||
if (ret == 0)
|
||||
printk("SA1100/PXA2xx Watchdog Timer: timer margin %d sec\n",
|
||||
margin);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -212,8 +186,5 @@ MODULE_DESCRIPTION("SA1100/PXA2xx Watchdog");
|
||||
module_param(margin, int, 0);
|
||||
MODULE_PARM_DESC(margin, "Watchdog margin in seconds (default 60s)");
|
||||
|
||||
module_param(nowayout, int, 0);
|
||||
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started");
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
|
||||
|
Loading…
Reference in New Issue
Block a user