Commit 893c4d2f authored by Linus Torvalds's avatar Linus Torvalds

Import 1.1.18

parent 9ec7e58c
VERSION = 1 VERSION = 1
PATCHLEVEL = 1 PATCHLEVEL = 1
SUBLEVEL = 17 SUBLEVEL = 18
all: Version zImage all: Version zImage
......
...@@ -5,14 +5,13 @@ ...@@ -5,14 +5,13 @@
#DEBUG = -DDEBUGGING #DEBUG = -DDEBUGGING
DEBUG = DEBUG =
PARANOID = -DPARANOID PARANOID = -DPARANOID
REENTRANT = -DREENTRANT_FPU
CFLAGS := $(CFLAGS) $(PARANOID) $(DEBUG) -fno-builtin CFLAGS := $(CFLAGS) $(PARANOID) $(DEBUG) -fno-builtin
.c.o: .c.o:
$(CC) $(CFLAGS) $(MATH_EMULATION) -c $< $(CC) $(CFLAGS) $(MATH_EMULATION) -c $<
.S.o: .S.o:
$(CC) -D__ASSEMBLER__ $(PARANOID) $(REENTRANT) -c $< $(CC) -D__ASSEMBLER__ $(PARANOID) -c $<
.s.o: .s.o:
$(CC) -c $< $(CC) -c $<
......
...@@ -47,7 +47,7 @@ Please report bugs, etc to me at: ...@@ -47,7 +47,7 @@ Please report bugs, etc to me at:
--Bill Metzenthen --Bill Metzenthen
March 1994 June 1994
----------------------- Internals of wm-FPU-emu ----------------------- ----------------------- Internals of wm-FPU-emu -----------------------
...@@ -80,20 +80,24 @@ emulate each FPU instruction to completion without interruption. ...@@ -80,20 +80,24 @@ emulate each FPU instruction to completion without interruption.
However, it may happen that when the emulator is accessing the user However, it may happen that when the emulator is accessing the user
memory space, swapping may be needed. In this case the emulator may be memory space, swapping may be needed. In this case the emulator may be
temporarily suspended while disk i/o takes place. During this time temporarily suspended while disk i/o takes place. During this time
another process may use the emulator, thereby changing some static another process may use the emulator, thereby perhaps changing static
variables (eg FPU_st0_ptr, etc). The code which accesses user memory variables. The code which accesses user memory is confined to five
is confined to five files: files:
fpu_entry.c fpu_entry.c
reg_ld_str.c reg_ld_str.c
load_store.c load_store.c
get_address.c get_address.c
errors.c errors.c
As from version 1.12 of the emulator, no static variables are used
(apart from those in the kernel's per-process tables). The emulator is
therefore now fully re-entrant, rather than having just the restricted
form of re-entrancy which is required by the Linux kernel.
----------------------- Limitations of wm-FPU-emu ----------------------- ----------------------- Limitations of wm-FPU-emu -----------------------
There are a number of differences between the current wm-FPU-emu There are a number of differences between the current wm-FPU-emu
(version beta 1.11) and the 80486 FPU (apart from bugs). Some of the (version 1.12) and the 80486 FPU (apart from bugs). Some of the more
more important differences are listed below: important differences are listed below:
The Roundup flag does not have much meaning for the transcendental The Roundup flag does not have much meaning for the transcendental
functions and its 80486 value with these functions is likely to differ functions and its 80486 value with these functions is likely to differ
...@@ -154,6 +158,11 @@ crashes dosemu under Linux and also brings Windows down with a general ...@@ -154,6 +158,11 @@ crashes dosemu under Linux and also brings Windows down with a general
protection fault message when run under the MS-DOS prompt of Windows protection fault message when run under the MS-DOS prompt of Windows
3.1. (The program simply reads data from a valid address). 3.1. (The program simply reads data from a valid address).
The emulator supports 16-bit protected mode, with one difference from
an 80486DX. A 80486DX will allow some floating point instructions to
write a few bytes below the lowest address of the stack. The emulator
will not allow this in 16-bit protected mode: no instructions are
allowed to write outside the bounds set by the protection.
----------------------- Performance of wm-FPU-emu ----------------------- ----------------------- Performance of wm-FPU-emu -----------------------
...@@ -322,6 +331,7 @@ Hamish Coleman, t933093@minyos.xx.rmit.oz.au ...@@ -322,6 +331,7 @@ Hamish Coleman, t933093@minyos.xx.rmit.oz.au
Bruce Evans, bde@kralizec.zeta.org.au Bruce Evans, bde@kralizec.zeta.org.au
Timo Korvola, Timo.Korvola@hut.fi Timo Korvola, Timo.Korvola@hut.fi
Rick Lyons, rick@razorback.brisnet.org.au Rick Lyons, rick@razorback.brisnet.org.au
Rick, jrs@world.std.com
...and numerous others who responded to my request for help with ...and numerous others who responded to my request for help with
a real 80486. a real 80486.
......
...@@ -42,20 +42,28 @@ void Un_impl(void) ...@@ -42,20 +42,28 @@ void Un_impl(void)
RE_ENTRANT_CHECK_OFF; RE_ENTRANT_CHECK_OFF;
/* No need to verify_area(), we have previously fetched these bytes. */ /* No need to verify_area(), we have previously fetched these bytes. */
printk("Unimplemented FPU Opcode at eip=%p : ", (void *) address); printk("Unimplemented FPU Opcode at eip=%p : ", (void *) address);
while ( 1 ) if ( FPU_CS == USER_CS )
{ {
byte1 = get_fs_byte((unsigned char *) address); while ( 1 )
if ( (byte1 & 0xf8) == 0xd8 ) break; {
printk("[%02x]", byte1); byte1 = get_fs_byte((unsigned char *) address);
address++; if ( (byte1 & 0xf8) == 0xd8 ) break;
printk("[%02x]", byte1);
address++;
}
printk("%02x ", byte1);
FPU_modrm = get_fs_byte(1 + (unsigned char *) address);
if (FPU_modrm >= 0300)
printk("%02x (%02x+%d)\n", FPU_modrm, FPU_modrm & 0xf8, FPU_modrm & 7);
else
printk("/%d\n", (FPU_modrm >> 3) & 7);
} }
printk("%02x ", byte1);
FPU_modrm = get_fs_byte(1 + (unsigned char *) address);
if (FPU_modrm >= 0300)
printk("%02x (%02x+%d)\n", FPU_modrm, FPU_modrm & 0xf8, FPU_modrm & 7);
else else
printk("/%d\n", (FPU_modrm >> 3) & 7); {
printk("cs selector = %04x\n", FPU_CS);
}
RE_ENTRANT_CHECK_ON; RE_ENTRANT_CHECK_ON;
EXCEPTION(EX_Invalid); EXCEPTION(EX_Invalid);
...@@ -85,29 +93,36 @@ void emu_printall() ...@@ -85,29 +93,36 @@ void emu_printall()
RE_ENTRANT_CHECK_OFF; RE_ENTRANT_CHECK_OFF;
/* No need to verify_area(), we have previously fetched these bytes. */ /* No need to verify_area(), we have previously fetched these bytes. */
printk("At %p:", (void *) address); printk("At %p:", (void *) address);
#define MAX_PRINTED_BYTES 20 if ( FPU_CS == USER_CS )
for ( i = 0; i < MAX_PRINTED_BYTES; i++ )
{ {
byte1 = get_fs_byte((unsigned char *) address); #define MAX_PRINTED_BYTES 20
if ( (byte1 & 0xf8) == 0xd8 ) for ( i = 0; i < MAX_PRINTED_BYTES; i++ )
{ {
printk(" %02x", byte1); byte1 = get_fs_byte((unsigned char *) address);
break; if ( (byte1 & 0xf8) == 0xd8 )
{
printk(" %02x", byte1);
break;
}
printk(" [%02x]", byte1);
address++;
}
if ( i == MAX_PRINTED_BYTES )
printk(" [more..]\n");
else
{
FPU_modrm = get_fs_byte(1 + (unsigned char *) address);
if (FPU_modrm >= 0300)
printk(" %02x (%02x+%d)\n", FPU_modrm, FPU_modrm & 0xf8, FPU_modrm & 7);
else
printk(" /%d, mod=%d rm=%d\n",
(FPU_modrm >> 3) & 7, (FPU_modrm >> 6) & 3, FPU_modrm & 7);
} }
printk(" [%02x]", byte1);
address++;
} }
if ( i == MAX_PRINTED_BYTES )
printk(" [more..]\n");
else else
{ {
FPU_modrm = get_fs_byte(1 + (unsigned char *) address); printk("%04x\n", FPU_CS);
if (FPU_modrm >= 0300)
printk(" %02x (%02x+%d)\n", FPU_modrm, FPU_modrm & 0xf8, FPU_modrm & 7);
else
printk(" /%d, mod=%d rm=%d\n",
(FPU_modrm >> 3) & 7, (FPU_modrm >> 6) & 3, FPU_modrm & 7);
} }
partial_status = status_word(); partial_status = status_word();
...@@ -181,6 +196,7 @@ printk(" CW: ic=%d rc=%ld%ld pc=%ld%ld iem=%d ef=%d%d%d%d%d%d\n", ...@@ -181,6 +196,7 @@ printk(" CW: ic=%d rc=%ld%ld pc=%ld%ld iem=%d ef=%d%d%d%d%d%d\n",
printk("%s\n", tag_desc[(int) (unsigned) r->tag]); printk("%s\n", tag_desc[(int) (unsigned) r->tag]);
} }
#ifdef OBSOLETE
printk("[data] %c .%04lx %04lx %04lx %04lx e%+-6ld ", printk("[data] %c .%04lx %04lx %04lx %04lx e%+-6ld ",
FPU_loaded_data.sign ? '-' : '+', FPU_loaded_data.sign ? '-' : '+',
(long)(FPU_loaded_data.sigh >> 16), (long)(FPU_loaded_data.sigh >> 16),
...@@ -189,6 +205,7 @@ printk(" CW: ic=%d rc=%ld%ld pc=%ld%ld iem=%d ef=%d%d%d%d%d%d\n", ...@@ -189,6 +205,7 @@ printk(" CW: ic=%d rc=%ld%ld pc=%ld%ld iem=%d ef=%d%d%d%d%d%d\n",
(long)(FPU_loaded_data.sigl & 0xFFFF), (long)(FPU_loaded_data.sigl & 0xFFFF),
FPU_loaded_data.exp - EXP_BIAS + 1); FPU_loaded_data.exp - EXP_BIAS + 1);
printk("%s\n", tag_desc[(int) (unsigned) FPU_loaded_data.tag]); printk("%s\n", tag_desc[(int) (unsigned) FPU_loaded_data.tag]);
#endif OBSOLETE
RE_ENTRANT_CHECK_ON; RE_ENTRANT_CHECK_ON;
} }
...@@ -214,7 +231,6 @@ static struct { ...@@ -214,7 +231,6 @@ static struct {
error was detected. error was detected.
Internal error types: Internal error types:
0 in load_store.c
0x14 in fpu_etc.c 0x14 in fpu_etc.c
0x1nn in a *.c file: 0x1nn in a *.c file:
0x101 in reg_add_sub.c 0x101 in reg_add_sub.c
...@@ -244,7 +260,13 @@ static struct { ...@@ -244,7 +260,13 @@ static struct {
0x126 in fpu_entry.c 0x126 in fpu_entry.c
0x127 in poly_2xm1.c 0x127 in poly_2xm1.c
0x128 in fpu_entry.c 0x128 in fpu_entry.c
0x129 in fpu_entry.c
0x130 in get_address.c 0x130 in get_address.c
0x131 in get_address.c
0x132 in get_address.c
0x133 in get_address.c
0x140 in load_store.c
0x141 in load_store.c
0x2nn in an *.S file: 0x2nn in an *.S file:
0x201 in reg_u_add.S 0x201 in reg_u_add.S
0x202 in reg_u_div.S 0x202 in reg_u_div.S
...@@ -583,7 +605,7 @@ void stack_overflow(void) ...@@ -583,7 +605,7 @@ void stack_overflow(void)
{ {
/* The masked response */ /* The masked response */
top--; top--;
reg_move(&CONST_QNaN, FPU_st0_ptr = &st(0)); reg_move(&CONST_QNaN, &st(0));
} }
EXCEPTION(EX_StackOver); EXCEPTION(EX_StackOver);
...@@ -599,7 +621,7 @@ void stack_underflow(void) ...@@ -599,7 +621,7 @@ void stack_underflow(void)
if ( control_word & CW_Invalid ) if ( control_word & CW_Invalid )
{ {
/* The masked response */ /* The masked response */
reg_move(&CONST_QNaN, FPU_st0_ptr); reg_move(&CONST_QNaN, &st(0));
} }
EXCEPTION(EX_StackUnder); EXCEPTION(EX_StackUnder);
......
...@@ -20,7 +20,7 @@ void fadd__() ...@@ -20,7 +20,7 @@ void fadd__()
{ {
/* fadd st,st(i) */ /* fadd st,st(i) */
clear_C1(); clear_C1();
reg_add(FPU_st0_ptr, &st(FPU_rm), FPU_st0_ptr, control_word); reg_add(&st(0), &st(FPU_rm), &st(0), control_word);
} }
...@@ -28,7 +28,7 @@ void fmul__() ...@@ -28,7 +28,7 @@ void fmul__()
{ {
/* fmul st,st(i) */ /* fmul st,st(i) */
clear_C1(); clear_C1();
reg_mul(FPU_st0_ptr, &st(FPU_rm), FPU_st0_ptr, control_word); reg_mul(&st(0), &st(FPU_rm), &st(0), control_word);
} }
...@@ -37,7 +37,7 @@ void fsub__() ...@@ -37,7 +37,7 @@ void fsub__()
{ {
/* fsub st,st(i) */ /* fsub st,st(i) */
clear_C1(); clear_C1();
reg_sub(FPU_st0_ptr, &st(FPU_rm), FPU_st0_ptr, control_word); reg_sub(&st(0), &st(FPU_rm), &st(0), control_word);
} }
...@@ -45,7 +45,7 @@ void fsubr_() ...@@ -45,7 +45,7 @@ void fsubr_()
{ {
/* fsubr st,st(i) */ /* fsubr st,st(i) */
clear_C1(); clear_C1();
reg_sub(&st(FPU_rm), FPU_st0_ptr, FPU_st0_ptr, control_word); reg_sub(&st(FPU_rm), &st(0), &st(0), control_word);
} }
...@@ -53,7 +53,7 @@ void fdiv__() ...@@ -53,7 +53,7 @@ void fdiv__()
{ {
/* fdiv st,st(i) */ /* fdiv st,st(i) */
clear_C1(); clear_C1();
reg_div(FPU_st0_ptr, &st(FPU_rm), FPU_st0_ptr, control_word); reg_div(&st(0), &st(FPU_rm), &st(0), control_word);
} }
...@@ -61,7 +61,7 @@ void fdivr_() ...@@ -61,7 +61,7 @@ void fdivr_()
{ {
/* fdivr st,st(i) */ /* fdivr st,st(i) */
clear_C1(); clear_C1();
reg_div(&st(FPU_rm), FPU_st0_ptr, FPU_st0_ptr, control_word); reg_div(&st(FPU_rm), &st(0), &st(0), control_word);
} }
...@@ -70,7 +70,7 @@ void fadd_i() ...@@ -70,7 +70,7 @@ void fadd_i()
{ {
/* fadd st(i),st */ /* fadd st(i),st */
clear_C1(); clear_C1();
reg_add(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word); reg_add(&st(0), &st(FPU_rm), &st(FPU_rm), control_word);
} }
...@@ -78,7 +78,7 @@ void fmul_i() ...@@ -78,7 +78,7 @@ void fmul_i()
{ {
/* fmul st(i),st */ /* fmul st(i),st */
clear_C1(); clear_C1();
reg_mul(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word); reg_mul(&st(0), &st(FPU_rm), &st(FPU_rm), control_word);
} }
...@@ -86,9 +86,9 @@ void fsubri() ...@@ -86,9 +86,9 @@ void fsubri()
{ {
/* fsubr st(i),st */ /* fsubr st(i),st */
/* This is the sense of the 80486 manual /* This is the sense of the 80486 manual
reg_sub(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm), control_word); */ reg_sub(&st(FPU_rm), &st(0), &st(FPU_rm), control_word); */
clear_C1(); clear_C1();
reg_sub(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word); reg_sub(&st(0), &st(FPU_rm), &st(FPU_rm), control_word);
} }
...@@ -96,9 +96,9 @@ void fsub_i() ...@@ -96,9 +96,9 @@ void fsub_i()
{ {
/* fsub st(i),st */ /* fsub st(i),st */
/* This is the sense of the 80486 manual /* This is the sense of the 80486 manual
reg_sub(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word); */ reg_sub(&st(0), &st(FPU_rm), &st(FPU_rm), control_word); */
clear_C1(); clear_C1();
reg_sub(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm), control_word); reg_sub(&st(FPU_rm), &st(0), &st(FPU_rm), control_word);
} }
...@@ -106,7 +106,7 @@ void fdivri() ...@@ -106,7 +106,7 @@ void fdivri()
{ {
/* fdivr st(i),st */ /* fdivr st(i),st */
clear_C1(); clear_C1();
reg_div(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word); reg_div(&st(0), &st(FPU_rm), &st(FPU_rm), control_word);
} }
...@@ -114,7 +114,7 @@ void fdiv_i() ...@@ -114,7 +114,7 @@ void fdiv_i()
{ {
/* fdiv st(i),st */ /* fdiv st(i),st */
clear_C1(); clear_C1();
reg_div(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm), control_word); reg_div(&st(FPU_rm), &st(0), &st(FPU_rm), control_word);
} }
...@@ -123,7 +123,7 @@ void faddp_() ...@@ -123,7 +123,7 @@ void faddp_()
{ {
/* faddp st(i),st */ /* faddp st(i),st */
clear_C1(); clear_C1();
if ( !reg_add(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word) ) if ( !reg_add(&st(0), &st(FPU_rm), &st(FPU_rm), control_word) )
pop(); pop();
} }
...@@ -132,7 +132,7 @@ void fmulp_() ...@@ -132,7 +132,7 @@ void fmulp_()
{ {
/* fmulp st(i),st */ /* fmulp st(i),st */
clear_C1(); clear_C1();
if ( !reg_mul(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word) ) if ( !reg_mul(&st(0), &st(FPU_rm), &st(FPU_rm), control_word) )
pop(); pop();
} }
...@@ -142,9 +142,9 @@ void fsubrp() ...@@ -142,9 +142,9 @@ void fsubrp()
{ {
/* fsubrp st(i),st */ /* fsubrp st(i),st */
/* This is the sense of the 80486 manual /* This is the sense of the 80486 manual
reg_sub(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm), control_word); */ reg_sub(&st(FPU_rm), &st(0), &st(FPU_rm), control_word); */
clear_C1(); clear_C1();
if ( !reg_sub(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word) ) if ( !reg_sub(&st(0), &st(FPU_rm), &st(FPU_rm), control_word) )
pop(); pop();
} }
...@@ -153,9 +153,9 @@ void fsubp_() ...@@ -153,9 +153,9 @@ void fsubp_()
{ {
/* fsubp st(i),st */ /* fsubp st(i),st */
/* This is the sense of the 80486 manual /* This is the sense of the 80486 manual
reg_sub(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word); */ reg_sub(&st(0), &st(FPU_rm), &st(FPU_rm), control_word); */
clear_C1(); clear_C1();
if ( !reg_sub(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm), control_word) ) if ( !reg_sub(&st(FPU_rm), &st(0), &st(FPU_rm), control_word) )
pop(); pop();
} }
...@@ -164,7 +164,7 @@ void fdivrp() ...@@ -164,7 +164,7 @@ void fdivrp()
{ {
/* fdivrp st(i),st */ /* fdivrp st(i),st */
clear_C1(); clear_C1();
if ( !reg_div(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word) ) if ( !reg_div(&st(0), &st(FPU_rm), &st(FPU_rm), control_word) )
pop(); pop();
} }
...@@ -173,7 +173,7 @@ void fdivp_() ...@@ -173,7 +173,7 @@ void fdivp_()
{ {
/* fdivp st(i),st */ /* fdivp st(i),st */
clear_C1(); clear_C1();
if ( !reg_div(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm), control_word) ) if ( !reg_div(&st(FPU_rm), &st(0), &st(FPU_rm), control_word) )
pop(); pop();
} }
...@@ -26,8 +26,7 @@ void fclex(void) ...@@ -26,8 +26,7 @@ void fclex(void)
partial_status &= ~(SW_Backward|SW_Summary|SW_Stack_Fault|SW_Precision| partial_status &= ~(SW_Backward|SW_Summary|SW_Stack_Fault|SW_Precision|
SW_Underflow|SW_Overflow|SW_Zero_Div|SW_Denorm_Op| SW_Underflow|SW_Overflow|SW_Zero_Div|SW_Denorm_Op|
SW_Invalid); SW_Invalid);
NO_NET_DATA_EFFECT; no_ip_update = 1;
FPU_entry_eip = ip_offset; /* We want no net effect */
} }
/* Needs to be externally visible */ /* Needs to be externally visible */
...@@ -43,11 +42,12 @@ void finit() ...@@ -43,11 +42,12 @@ void finit()
} }
/* The behaviour is different to that detailed in /* The behaviour is different to that detailed in
Section 15.1.6 of the Intel manual */ Section 15.1.6 of the Intel manual */
data_operand_offset = 0; operand_address.offset = 0;
operand_selector = 0; operand_address.selector = 0;
NO_NET_DATA_EFFECT; instruction_address.offset = 0;
FPU_entry_op_cs = 0; instruction_address.selector = 0;
FPU_entry_eip = ip_offset = 0; instruction_address.opcode = 0;
no_ip_update = 1;
} }
/* /*
...@@ -71,7 +71,7 @@ void finit_() ...@@ -71,7 +71,7 @@ void finit_()
static void fstsw_ax(void) static void fstsw_ax(void)
{ {
*(short *) &FPU_EAX = status_word(); *(short *) &FPU_EAX = status_word();
NO_NET_INSTR_EFFECT; no_ip_update = 1;
} }
static FUNC const fstsw_table[] = { static FUNC const fstsw_table[] = {
...@@ -108,10 +108,9 @@ void fld_i_() ...@@ -108,10 +108,9 @@ void fld_i_()
{ reg_move(&st(FPU_rm), st_new_ptr); push(); } { reg_move(&st(FPU_rm), st_new_ptr); push(); }
else else
{ {
if ( control_word & EX_Invalid ) if ( control_word & CW_Invalid )
{ {
/* The masked response */ /* The masked response */
push();
stack_underflow(); stack_underflow();
} }
else else
...@@ -125,9 +124,9 @@ void fxch_i() ...@@ -125,9 +124,9 @@ void fxch_i()
{ {
/* fxch st(i) */ /* fxch st(i) */
FPU_REG t; FPU_REG t;
register FPU_REG *sti_ptr = &st(FPU_rm); register FPU_REG *sti_ptr = &st(FPU_rm), *st0_ptr = &st(0);
if ( FPU_st0_tag == TW_Empty ) if ( st0_ptr->tag == TW_Empty )
{ {
if ( sti_ptr->tag == TW_Empty ) if ( sti_ptr->tag == TW_Empty )
{ {
...@@ -136,20 +135,20 @@ void fxch_i() ...@@ -136,20 +135,20 @@ void fxch_i()
return; return;
} }
if ( control_word & CW_Invalid ) if ( control_word & CW_Invalid )
reg_move(sti_ptr, FPU_st0_ptr); /* Masked response */ reg_move(sti_ptr, st0_ptr); /* Masked response */
stack_underflow_i(FPU_rm); stack_underflow_i(FPU_rm);
return; return;
} }
if ( sti_ptr->tag == TW_Empty ) if ( sti_ptr->tag == TW_Empty )
{ {
if ( control_word & CW_Invalid ) if ( control_word & CW_Invalid )
reg_move(FPU_st0_ptr, sti_ptr); /* Masked response */ reg_move(st0_ptr, sti_ptr); /* Masked response */
stack_underflow(); stack_underflow();
return; return;
} }
clear_C1(); clear_C1();
reg_move(FPU_st0_ptr, &t); reg_move(st0_ptr, &t);
reg_move(sti_ptr, FPU_st0_ptr); reg_move(sti_ptr, st0_ptr);
reg_move(&t, sti_ptr); reg_move(&t, sti_ptr);
} }
...@@ -172,14 +171,14 @@ void ffreep() ...@@ -172,14 +171,14 @@ void ffreep()
void fst_i_() void fst_i_()
{ {
/* fst st(i) */ /* fst st(i) */
reg_move(FPU_st0_ptr, &st(FPU_rm)); reg_move(&st(0), &st(FPU_rm));
} }
void fstp_i() void fstp_i()
{ {
/* fstp st(i) */ /* fstp st(i) */
reg_move(FPU_st0_ptr, &st(FPU_rm)); reg_move(&st(0), &st(FPU_rm));
pop(); pop();
} }
...@@ -60,14 +60,18 @@ ...@@ -60,14 +60,18 @@
#include <linux/math_emu.h> #include <linux/math_emu.h>
#include <linux/linkage.h> #include <linux/linkage.h>
#ifdef PARANOID /*
#define RE_ENTRANT_CHECKING
*/
#ifdef RE_ENTRANT_CHECKING
extern char emulating; extern char emulating;
# define RE_ENTRANT_CHECK_OFF emulating = 0 # define RE_ENTRANT_CHECK_OFF emulating = 0
# define RE_ENTRANT_CHECK_ON emulating = 1 # define RE_ENTRANT_CHECK_ON emulating = 1
#else #else
# define RE_ENTRANT_CHECK_OFF # define RE_ENTRANT_CHECK_OFF
# define RE_ENTRANT_CHECK_ON # define RE_ENTRANT_CHECK_ON
#endif PARANOID #endif RE_ENTRANT_CHECKING
#define FWAIT_OPCODE 0x9b #define FWAIT_OPCODE 0x9b
#define OP_SIZE_PREFIX 0x66 #define OP_SIZE_PREFIX 0x66
...@@ -89,46 +93,43 @@ extern char emulating; ...@@ -89,46 +93,43 @@ extern char emulating;
#define PREFIX_SS_ 6 #define PREFIX_SS_ 6
#define PREFIX_DEFAULT 7 #define PREFIX_DEFAULT 7
/* These are to defeat the default action, giving the instruction struct address {
no net effect: */ unsigned int offset;
#define NO_NET_DATA_EFFECT \ unsigned int selector:16;
{ FPU_data_address = (void *)data_operand_offset; \ unsigned int opcode:11;
FPU_data_selector = operand_selector; } unsigned int empty:5;
#define NO_NET_INSTR_EFFECT \ };
{ FPU_entry_eip = ip_offset; \
FPU_entry_op_cs = cs_selector; }
typedef void (*FUNC)(void); typedef void (*FUNC)(void);
typedef struct fpu_reg FPU_REG; typedef struct fpu_reg FPU_REG;
typedef void (*FUNC_ST0)(FPU_REG *st0_ptr);
typedef struct { unsigned char address_size, operand_size, segment; } typedef struct { unsigned char address_size, operand_size, segment; }
overrides; overrides;
/* This structure is 48 bits: */ /* This structure is 32 bits: */
typedef struct { overrides override; typedef struct { overrides override;
unsigned char mode16, vm86, p286; } fpu_addr_modes; unsigned char default_mode; } fpu_addr_modes;
/* PROTECTED has a restricted meaning in the emulator; it is used
to signal that the emulator needs to do special things to ensure
that protection is respected in a segmented model. */
#define PROTECTED 4
#define SIXTEEN 1 /* We rely upon this being 1 (true) */
#define VM86 SIXTEEN
#define PM16 (SIXTEEN | PROTECTED)
#define SEG32 PROTECTED
extern unsigned char const data_sizes_16[32];
#define st(x) ( regs[((top+x) &7 )] ) #define st(x) ( regs[((top+x) &7 )] )
#define STACK_OVERFLOW (st_new_ptr = &st(-1), st_new_ptr->tag != TW_Empty) #define STACK_OVERFLOW (st_new_ptr = &st(-1), st_new_ptr->tag != TW_Empty)
#define NOT_EMPTY(i) (st(i).tag != TW_Empty) #define NOT_EMPTY(i) (st(i).tag != TW_Empty)
#define NOT_EMPTY_0 (FPU_st0_tag ^ TW_Empty) #define NOT_EMPTY_ST0 (st0_tag ^ TW_Empty)
extern unsigned char FPU_rm;
extern char FPU_st0_tag;
extern FPU_REG *FPU_st0_ptr;
/* ###### These need to be shifted to somewhere safe. */
/* extern void *FPU_data_address; has been shifted */
extern unsigned short FPU_data_selector;
extern unsigned long FPU_entry_op_cs;
extern FPU_REG FPU_loaded_data;
#define pop() { FPU_st0_ptr->tag = TW_Empty; top++; } #define pop() { regs[(top++ & 7 )].tag = TW_Empty; }
#define poppop() { regs[((top + 1) & 7 )].tag \
= regs[(top & 7 )].tag = TW_Empty; \
top += 2; }
/* push() does not affect the tags */ /* push() does not affect the tags */
#define push() { top--; FPU_st0_ptr = st_new_ptr; } #define push() { top--; }
#define reg_move(x, y) { \ #define reg_move(x, y) { \
......
This diff is collapsed.
...@@ -17,22 +17,22 @@ ...@@ -17,22 +17,22 @@
#include "reg_constant.h" #include "reg_constant.h"
static void fchs(void) static void fchs(FPU_REG *st0_ptr)
{ {
if ( NOT_EMPTY_0 ) if ( st0_ptr->tag ^ TW_Empty )
{ {
FPU_st0_ptr->sign ^= SIGN_POS^SIGN_NEG; st0_ptr->sign ^= SIGN_POS^SIGN_NEG;
clear_C1(); clear_C1();
} }
else else
stack_underflow(); stack_underflow();
} }
static void fabs(void) static void fabs(FPU_REG *st0_ptr)
{ {
if ( FPU_st0_tag ^ TW_Empty ) if ( st0_ptr->tag ^ TW_Empty )
{ {
FPU_st0_ptr->sign = SIGN_POS; st0_ptr->sign = SIGN_POS;
clear_C1(); clear_C1();
} }
else else
...@@ -40,25 +40,25 @@ static void fabs(void) ...@@ -40,25 +40,25 @@ static void fabs(void)
} }
static void ftst_(void) static void ftst_(FPU_REG *st0_ptr)
{ {
switch (FPU_st0_tag) switch (st0_ptr->tag)
{ {
case TW_Zero: case TW_Zero:
setcc(SW_C3); setcc(SW_C3);
break; break;
case TW_Valid: case TW_Valid:
if (FPU_st0_ptr->sign == SIGN_POS) if (st0_ptr->sign == SIGN_POS)
setcc(0); setcc(0);
else else
setcc(SW_C0); setcc(SW_C0);
#ifdef DENORM_OPERAND #ifdef DENORM_OPERAND
if ( (FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()) ) if ( (st0_ptr->exp <= EXP_UNDER) && (denormal_operand()) )
{ {
#ifdef PECULIAR_486 #ifdef PECULIAR_486
/* This is wierd! */ /* This is wierd! */
if (FPU_st0_ptr->sign == SIGN_POS) if (st0_ptr->sign == SIGN_POS)
setcc(SW_C3); setcc(SW_C3);
#endif PECULIAR_486 #endif PECULIAR_486
return; return;
...@@ -71,7 +71,7 @@ static void ftst_(void) ...@@ -71,7 +71,7 @@ static void ftst_(void)
EXCEPTION(EX_Invalid); EXCEPTION(EX_Invalid);
break; break;
case TW_Infinity: case TW_Infinity:
if (FPU_st0_ptr->sign == SIGN_POS) if (st0_ptr->sign == SIGN_POS)
setcc(0); setcc(0);
else else
setcc(SW_C0); setcc(SW_C0);
...@@ -87,10 +87,10 @@ static void ftst_(void) ...@@ -87,10 +87,10 @@ static void ftst_(void)
} }
} }
static void fxam(void) static void fxam(FPU_REG *st0_ptr)
{ {
int c=0; int c=0;
switch (FPU_st0_tag) switch (st0_ptr->tag)
{ {
case TW_Empty: case TW_Empty:
c = SW_C3|SW_C0; c = SW_C3|SW_C0;
...@@ -100,7 +100,7 @@ static void fxam(void) ...@@ -100,7 +100,7 @@ static void fxam(void)
break; break;
case TW_Valid: case TW_Valid:
/* This will need to be changed if TW_Denormal is ever used. */ /* This will need to be changed if TW_Denormal is ever used. */
if ( FPU_st0_ptr->exp <= EXP_UNDER ) if ( st0_ptr->exp <= EXP_UNDER )
c = SW_C2|SW_C3; /* Denormal */ c = SW_C2|SW_C3; /* Denormal */
else else
c = SW_C2; c = SW_C2;
...@@ -112,16 +112,18 @@ static void fxam(void) ...@@ -112,16 +112,18 @@ static void fxam(void)
c = SW_C2|SW_C0; c = SW_C2|SW_C0;
break; break;
} }
if (FPU_st0_ptr->sign == SIGN_NEG) if (st0_ptr->sign == SIGN_NEG)
c |= SW_C1; c |= SW_C1;
setcc(c); setcc(c);
} }
static FUNC const fp_etc_table[] = {
fchs, fabs, FPU_illegal, FPU_illegal, ftst_, fxam, FPU_illegal, FPU_illegal static FUNC_ST0 const fp_etc_table[] = {
fchs, fabs, (FUNC_ST0)FPU_illegal, (FUNC_ST0)FPU_illegal,
ftst_, fxam, (FUNC_ST0)FPU_illegal, (FUNC_ST0)FPU_illegal
}; };
void fp_etc() void fp_etc()
{ {
(fp_etc_table[FPU_rm])(); (fp_etc_table[FPU_rm])(&st(0));
} }
...@@ -63,13 +63,16 @@ extern void trig_a(void); ...@@ -63,13 +63,16 @@ extern void trig_a(void);
extern void trig_b(void); extern void trig_b(void);
/* get_address.c */ /* get_address.c */
extern void get_address(unsigned char FPU_modrm, unsigned long *fpu_eip, extern void *get_address(unsigned char FPU_modrm, unsigned long *fpu_eip,
fpu_addr_modes); struct address *addr,
extern void get_address_16(unsigned char FPU_modrm, unsigned long *fpu_eip, fpu_addr_modes);
fpu_addr_modes); extern void *get_address_16(unsigned char FPU_modrm, unsigned long *fpu_eip,
struct address *addr,
fpu_addr_modes);
/* load_store.c */ /* load_store.c */
extern void load_store_instr(char type, fpu_addr_modes addr_modes); extern int load_store_instr(unsigned char type, fpu_addr_modes addr_modes,
void *address);
/* poly_2xm1.c */ /* poly_2xm1.c */
extern int poly_2xm1(FPU_REG const *arg, FPU_REG *result); extern int poly_2xm1(FPU_REG const *arg, FPU_REG *result);
...@@ -96,7 +99,7 @@ extern int reg_sub(FPU_REG const *a, FPU_REG const *b, ...@@ -96,7 +99,7 @@ extern int reg_sub(FPU_REG const *a, FPU_REG const *b,
/* reg_compare.c */ /* reg_compare.c */
extern int compare(FPU_REG const *b); extern int compare(FPU_REG const *b);
extern int compare_st_data(void); extern int compare_st_data(FPU_REG const *b);
extern void fcom_st(void); extern void fcom_st(void);
extern void fcompst(void); extern void fcompst(void);
extern void fcompp(void); extern void fcompp(void);
...@@ -108,26 +111,26 @@ extern void fucompp(void); ...@@ -108,26 +111,26 @@ extern void fucompp(void);
extern void fconst(void); extern void fconst(void);
/* reg_ld_str.c */ /* reg_ld_str.c */
extern int reg_load_extended(void); extern int reg_load_extended(long double *addr, FPU_REG *loaded_data);
extern int reg_load_double(void); extern int reg_load_double(double *dfloat, FPU_REG *loaded_data);
extern int reg_load_single(void); extern int reg_load_single(float *single, FPU_REG *loaded_data);
extern void reg_load_int64(void); extern void reg_load_int64(long long *_s, FPU_REG *loaded_data);
extern void reg_load_int32(void); extern void reg_load_int32(long *_s, FPU_REG *loaded_data);
extern void reg_load_int16(void); extern void reg_load_int16(short *_s, FPU_REG *loaded_data);
extern void reg_load_bcd(void); extern void reg_load_bcd(char *s, FPU_REG *loaded_data);
extern int reg_store_extended(void); extern int reg_store_extended(long double *d, FPU_REG *st0_ptr);
extern int reg_store_double(void); extern int reg_store_double(double *dfloat, FPU_REG *st0_ptr);
extern int reg_store_single(void); extern int reg_store_single(float *single, FPU_REG *st0_ptr);
extern int reg_store_int64(void); extern int reg_store_int64(long long *d, FPU_REG *st0_ptr);
extern int reg_store_int32(void); extern int reg_store_int32(long *d, FPU_REG *st0_ptr);
extern int reg_store_int16(void); extern int reg_store_int16(short *d, FPU_REG *st0_ptr);
extern int reg_store_bcd(void); extern int reg_store_bcd(char *d, FPU_REG *st0_ptr);
extern int round_to_int(FPU_REG *r); extern int round_to_int(FPU_REG *r);
extern char *fldenv(fpu_addr_modes addr_modes); extern char *fldenv(fpu_addr_modes addr_modes, char *address);
extern void frstor(fpu_addr_modes addr_modes); extern void frstor(fpu_addr_modes addr_modes, char *address);
extern unsigned short tag_word(void); extern unsigned short tag_word(void);
extern char *fstenv(fpu_addr_modes addr_modes); extern char *fstenv(fpu_addr_modes addr_modes, char *address);
extern void fsave(fpu_addr_modes addr_modes); extern void fsave(fpu_addr_modes addr_modes, char *address);
/* reg_mul.c */ /* reg_mul.c */
extern int reg_mul(FPU_REG const *a, FPU_REG const *b, extern int reg_mul(FPU_REG const *a, FPU_REG const *b,
......
...@@ -19,6 +19,19 @@ ...@@ -19,6 +19,19 @@
of the stack frame of math_emulate() */ of the stack frame of math_emulate() */
#define SETUP_DATA_AREA(arg) FPU_info = (struct info *) &arg #define SETUP_DATA_AREA(arg) FPU_info = (struct info *) &arg
#define LDT_DESCRIPTOR(s) (current->ldt[(s) >> 3])
#define SEG_D_SIZE(x) ((x).b & (3 << 21))
#define SEG_G_BIT(x) ((x).b & (1 << 23))
#define SEG_GRANULARITY(x) (((x).b & (1 << 23)) ? 4096 : 1)
#define SEG_286_MODE(x) ((x).b & ( 0xff000000 | 0xf0000 | (1 << 23)))
#define SEG_BASE_ADDR(s) (((s).b & 0xff000000) \
| (((s).b & 0xff) << 16) | ((s).a >> 16))
#define SEG_LIMIT(s) (((s).b & 0xff0000) | ((s).a & 0xffff))
#define SEG_EXECUTE_ONLY(s) (((s).b & ((1 << 11) | (1 << 9))) == (1 << 11))
#define SEG_WRITE_PERM(s) (((s).b & ((1 << 11) | (1 << 9))) == (1 << 9))
#define SEG_EXPAND_DOWN(s) (((s).b & ((1 << 11) | (1 << 10))) \
== (1 << 10))
#define I387 (current->tss.i387) #define I387 (current->tss.i387)
#define FPU_info (I387.soft.info) #define FPU_info (I387.soft.info)
...@@ -30,22 +43,24 @@ ...@@ -30,22 +43,24 @@
#define FPU_EIP (FPU_info->___eip) #define FPU_EIP (FPU_info->___eip)
#define FPU_ORIG_EIP (FPU_info->___orig_eip) #define FPU_ORIG_EIP (FPU_info->___orig_eip)
#define LDT_BASE_ADDR(s) ((current->ldt[(s) >> 3].b & 0xff000000) \
| ((current->ldt[(s) >> 3].b & 0xff) << 16) \
| (current->ldt[(s) >> 3].a >> 16))
#define FPU_lookahead (I387.soft.lookahead) #define FPU_lookahead (I387.soft.lookahead)
#define FPU_entry_eip (I387.soft.entry_eip)
/* nz if ip_offset and cs_selector are not to be set for the current
instruction. */
#define no_ip_update (((char *)&(I387.soft.twd))[0])
#define FPU_rm (((unsigned char *)&(I387.soft.twd))[1])
/* Number of bytes of data which can be legally accessed by the current
instruction. This only needs to hold a number <= 108, so a byte will do. */
#define access_limit (((unsigned char *)&(I387.soft.twd))[2])
#define partial_status (I387.soft.swd) #define partial_status (I387.soft.swd)
#define control_word (I387.soft.cwd) #define control_word (I387.soft.cwd)
#define regs (I387.soft.regs) #define regs (I387.soft.regs)
#define top (I387.soft.top) #define top (I387.soft.top)
#define ip_offset (I387.soft.fip) #define instruction_address (*(struct address *)&I387.soft.fip)
#define cs_selector (I387.soft.fcs) #define operand_address (*(struct address *)&I387.soft.foo)
#define data_operand_offset (I387.soft.foo)
#define operand_selector (I387.soft.fos)
#define FPU_verify_area(x,y,z) if ( verify_area(x,y,z) ) \ #define FPU_verify_area(x,y,z) if ( verify_area(x,y,z) ) \
math_abort(FPU_info,SIGSEGV) math_abort(FPU_info,SIGSEGV)
...@@ -64,7 +79,4 @@ ...@@ -64,7 +79,4 @@
#define FPU_code_verify_area(z) FPU_verify_area(VERIFY_READ,(void *)FPU_EIP,z) #define FPU_code_verify_area(z) FPU_verify_area(VERIFY_READ,(void *)FPU_EIP,z)
#endif #endif
/* ######## temporary and ugly ;-) */
#define FPU_data_address ((void *)(I387.soft.twd))
#endif #endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -187,16 +187,8 @@ void poly_add_1(FPU_REG *src) ...@@ -187,16 +187,8 @@ void poly_add_1(FPU_REG *src)
for the use of this function in poly_atan. Simple truncation for the use of this function in poly_atan. Simple truncation
is used here instead of round-to-nearest. */ is used here instead of round-to-nearest. */
#ifdef OBSOLETE
char round = (src->sigl & 3) == 3;
#endif OBSOLETE
shrx(&src->sigl, 1); shrx(&src->sigl, 1);
#ifdef OBSOLETE
if ( round ) significand(src)++; /* Round to even */
#endif OBSOLETE
src->sigh |= 0x80000000; src->sigh |= 0x80000000;
src->exp = EXP_BIAS; src->exp = EXP_BIAS;
......
...@@ -24,10 +24,15 @@ ...@@ -24,10 +24,15 @@
int compare(FPU_REG const *b) int compare(FPU_REG const *b)
{ {
int diff; int diff;
char st0_tag;
FPU_REG *st0_ptr;
if ( FPU_st0_ptr->tag | b->tag ) st0_ptr = &st(0);
st0_tag = st0_ptr->tag;
if ( st0_tag | b->tag )
{ {
if ( FPU_st0_ptr->tag == TW_Zero ) if ( st0_tag == TW_Zero )
{ {
if ( b->tag == TW_Zero ) return COMP_A_eq_B; if ( b->tag == TW_Zero ) return COMP_A_eq_B;
if ( b->tag == TW_Valid ) if ( b->tag == TW_Valid )
...@@ -42,23 +47,23 @@ int compare(FPU_REG const *b) ...@@ -42,23 +47,23 @@ int compare(FPU_REG const *b)
} }
else if ( b->tag == TW_Zero ) else if ( b->tag == TW_Zero )
{ {
if ( FPU_st0_ptr->tag == TW_Valid ) if ( st0_tag == TW_Valid )
{ {
return ((FPU_st0_ptr->sign == SIGN_POS) ? COMP_A_gt_B return ((st0_ptr->sign == SIGN_POS) ? COMP_A_gt_B
: COMP_A_lt_B) : COMP_A_lt_B)
#ifdef DENORM_OPERAND #ifdef DENORM_OPERAND
| ((FPU_st0_ptr->exp <= EXP_UNDER ) | ((st0_ptr->exp <= EXP_UNDER )
? COMP_Denormal : 0 ) ? COMP_Denormal : 0 )
#endif DENORM_OPERAND #endif DENORM_OPERAND
; ;
} }
} }
if ( FPU_st0_ptr->tag == TW_Infinity ) if ( st0_tag == TW_Infinity )
{ {
if ( (b->tag == TW_Valid) || (b->tag == TW_Zero) ) if ( (b->tag == TW_Valid) || (b->tag == TW_Zero) )
{ {
return ((FPU_st0_ptr->sign == SIGN_POS) ? COMP_A_gt_B return ((st0_ptr->sign == SIGN_POS) ? COMP_A_gt_B
: COMP_A_lt_B) : COMP_A_lt_B)
#ifdef DENORM_OPERAND #ifdef DENORM_OPERAND
| (((b->tag == TW_Valid) && (b->exp <= EXP_UNDER)) ? | (((b->tag == TW_Valid) && (b->exp <= EXP_UNDER)) ?
...@@ -69,19 +74,19 @@ int compare(FPU_REG const *b) ...@@ -69,19 +74,19 @@ int compare(FPU_REG const *b)
else if ( b->tag == TW_Infinity ) else if ( b->tag == TW_Infinity )
{ {
/* The 80486 book says that infinities can be equal! */ /* The 80486 book says that infinities can be equal! */
return (FPU_st0_ptr->sign == b->sign) ? COMP_A_eq_B : return (st0_ptr->sign == b->sign) ? COMP_A_eq_B :
((FPU_st0_ptr->sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B); ((st0_ptr->sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B);
} }
/* Fall through to the NaN code */ /* Fall through to the NaN code */
} }
else if ( b->tag == TW_Infinity ) else if ( b->tag == TW_Infinity )
{ {
if ( (FPU_st0_ptr->tag == TW_Valid) || (FPU_st0_ptr->tag == TW_Zero) ) if ( (st0_tag == TW_Valid) || (st0_tag == TW_Zero) )
{ {
return ((b->sign == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B) return ((b->sign == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B)
#ifdef DENORM_OPERAND #ifdef DENORM_OPERAND
| (((FPU_st0_ptr->tag == TW_Valid) | (((st0_tag == TW_Valid)
&& (FPU_st0_ptr->exp <= EXP_UNDER)) ? && (st0_ptr->exp <= EXP_UNDER)) ?
COMP_Denormal : 0) COMP_Denormal : 0)
#endif DENORM_OPERAND #endif DENORM_OPERAND
; ;
...@@ -91,9 +96,9 @@ int compare(FPU_REG const *b) ...@@ -91,9 +96,9 @@ int compare(FPU_REG const *b)
/* The only possibility now should be that one of the arguments /* The only possibility now should be that one of the arguments
is a NaN */ is a NaN */
if ( (FPU_st0_ptr->tag == TW_NaN) || (b->tag == TW_NaN) ) if ( (st0_tag == TW_NaN) || (b->tag == TW_NaN) )
{ {
if ( ((FPU_st0_ptr->tag == TW_NaN) && !(FPU_st0_ptr->sigh & 0x40000000)) if ( ((st0_tag == TW_NaN) && !(st0_ptr->sigh & 0x40000000))
|| ((b->tag == TW_NaN) && !(b->sigh & 0x40000000)) ) || ((b->tag == TW_NaN) && !(b->sigh & 0x40000000)) )
/* At least one arg is a signaling NaN */ /* At least one arg is a signaling NaN */
return COMP_No_Comp | COMP_SNaN | COMP_NaN; return COMP_No_Comp | COMP_SNaN | COMP_NaN;
...@@ -106,51 +111,51 @@ int compare(FPU_REG const *b) ...@@ -106,51 +111,51 @@ int compare(FPU_REG const *b)
} }
#ifdef PARANOID #ifdef PARANOID
if (!(FPU_st0_ptr->sigh & 0x80000000)) EXCEPTION(EX_Invalid); if (!(st0_ptr->sigh & 0x80000000)) EXCEPTION(EX_Invalid);
if (!(b->sigh & 0x80000000)) EXCEPTION(EX_Invalid); if (!(b->sigh & 0x80000000)) EXCEPTION(EX_Invalid);
#endif PARANOID #endif PARANOID
if (FPU_st0_ptr->sign != b->sign) if (st0_ptr->sign != b->sign)
{ {
return ((FPU_st0_ptr->sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B) return ((st0_ptr->sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B)
#ifdef DENORM_OPERAND #ifdef DENORM_OPERAND
| |
( ((FPU_st0_ptr->exp <= EXP_UNDER) || (b->exp <= EXP_UNDER)) ? ( ((st0_ptr->exp <= EXP_UNDER) || (b->exp <= EXP_UNDER)) ?
COMP_Denormal : 0) COMP_Denormal : 0)
#endif DENORM_OPERAND #endif DENORM_OPERAND
; ;
} }
diff = FPU_st0_ptr->exp - b->exp; diff = st0_ptr->exp - b->exp;
if ( diff == 0 ) if ( diff == 0 )
{ {
diff = FPU_st0_ptr->sigh - b->sigh; /* Works only if ms bits are diff = st0_ptr->sigh - b->sigh; /* Works only if ms bits are
identical */ identical */
if ( diff == 0 ) if ( diff == 0 )
{ {
diff = FPU_st0_ptr->sigl > b->sigl; diff = st0_ptr->sigl > b->sigl;
if ( diff == 0 ) if ( diff == 0 )
diff = -(FPU_st0_ptr->sigl < b->sigl); diff = -(st0_ptr->sigl < b->sigl);
} }
} }
if ( diff > 0 ) if ( diff > 0 )
{ {
return ((FPU_st0_ptr->sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B) return ((st0_ptr->sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B)
#ifdef DENORM_OPERAND #ifdef DENORM_OPERAND
| |
( ((FPU_st0_ptr->exp <= EXP_UNDER) || (b->exp <= EXP_UNDER)) ? ( ((st0_ptr->exp <= EXP_UNDER) || (b->exp <= EXP_UNDER)) ?
COMP_Denormal : 0) COMP_Denormal : 0)
#endif DENORM_OPERAND #endif DENORM_OPERAND
; ;
} }
if ( diff < 0 ) if ( diff < 0 )
{ {
return ((FPU_st0_ptr->sign == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B) return ((st0_ptr->sign == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B)
#ifdef DENORM_OPERAND #ifdef DENORM_OPERAND
| |
( ((FPU_st0_ptr->exp <= EXP_UNDER) || (b->exp <= EXP_UNDER)) ? ( ((st0_ptr->exp <= EXP_UNDER) || (b->exp <= EXP_UNDER)) ?
COMP_Denormal : 0) COMP_Denormal : 0)
#endif DENORM_OPERAND #endif DENORM_OPERAND
; ;
...@@ -159,7 +164,7 @@ int compare(FPU_REG const *b) ...@@ -159,7 +164,7 @@ int compare(FPU_REG const *b)
return COMP_A_eq_B return COMP_A_eq_B
#ifdef DENORM_OPERAND #ifdef DENORM_OPERAND
| |
( ((FPU_st0_ptr->exp <= EXP_UNDER) || (b->exp <= EXP_UNDER)) ? ( ((st0_ptr->exp <= EXP_UNDER) || (b->exp <= EXP_UNDER)) ?
COMP_Denormal : 0) COMP_Denormal : 0)
#endif DENORM_OPERAND #endif DENORM_OPERAND
; ;
...@@ -168,11 +173,11 @@ int compare(FPU_REG const *b) ...@@ -168,11 +173,11 @@ int compare(FPU_REG const *b)
/* This function requires that st(0) is not empty */ /* This function requires that st(0) is not empty */
int compare_st_data(void) int compare_st_data(FPU_REG const *loaded_data)
{ {
int f, c; int f, c;
c = compare(&FPU_loaded_data); c = compare(loaded_data);
if (c & COMP_NaN) if (c & COMP_NaN)
{ {
...@@ -214,7 +219,7 @@ static int compare_st_st(int nr) ...@@ -214,7 +219,7 @@ static int compare_st_st(int nr)
{ {
int f, c; int f, c;
if ( !NOT_EMPTY_0 || !NOT_EMPTY(nr) ) if ( !NOT_EMPTY(0) || !NOT_EMPTY(nr) )
{ {
setcc(SW_C3 | SW_C2 | SW_C0); setcc(SW_C3 | SW_C2 | SW_C0);
/* Stack fault */ /* Stack fault */
...@@ -264,7 +269,7 @@ static int compare_u_st_st(int nr) ...@@ -264,7 +269,7 @@ static int compare_u_st_st(int nr)
{ {
int f, c; int f, c;
if ( !NOT_EMPTY_0 || !NOT_EMPTY(nr) ) if ( !NOT_EMPTY(0) || !NOT_EMPTY(nr) )
{ {
setcc(SW_C3 | SW_C2 | SW_C0); setcc(SW_C3 | SW_C2 | SW_C0);
/* Stack fault */ /* Stack fault */
...@@ -340,10 +345,7 @@ void fcompp() ...@@ -340,10 +345,7 @@ void fcompp()
return; return;
} }
if ( !compare_st_st(1) ) if ( !compare_st_st(1) )
{ poppop();
pop(); FPU_st0_ptr = &st(0);
pop();
}
} }
...@@ -369,10 +371,7 @@ void fucompp() ...@@ -369,10 +371,7 @@ void fucompp()
if (FPU_rm == 1) if (FPU_rm == 1)
{ {
if ( !compare_u_st_st(1) ) if ( !compare_u_st_st(1) )
{ poppop();
pop(); FPU_st0_ptr = &st(0);
pop();
}
} }
else else
FPU_illegal(); FPU_illegal();
......
...@@ -66,7 +66,7 @@ static void fld_const(FPU_REG const *c) ...@@ -66,7 +66,7 @@ static void fld_const(FPU_REG const *c)
return; return;
} }
push(); push();
reg_move(c, FPU_st0_ptr); reg_move(c, st_new_ptr);
clear_C1(); clear_C1();
} }
......
...@@ -25,9 +25,9 @@ ...@@ -25,9 +25,9 @@
_reg_div: _reg_div:
pushl %ebp pushl %ebp
movl %esp,%ebp movl %esp,%ebp
#ifdef REENTRANT_FPU #ifndef NON_REENTRANT_FPU
subl $28,%esp /* Needed by divide_kernel */ subl $28,%esp /* Needed by divide_kernel */
#endif REENTRANT_FPU #endif NON_REENTRANT_FPU
pushl %esi pushl %esi
pushl %edi pushl %edi
...@@ -214,11 +214,11 @@ LDiv_negative_result: ...@@ -214,11 +214,11 @@ LDiv_negative_result:
xorl %eax,%eax /* Valid result */ xorl %eax,%eax /* Valid result */
LDiv_exit: LDiv_exit:
#ifdef REENTRANT_FPU #ifndef NON_REENTRANT_FPU
leal -40(%ebp),%esp leal -40(%ebp),%esp
#else #else
leal -12(%ebp),%esp leal -12(%ebp),%esp
#endif REENTRANT_FPU #endif NON_REENTRANT_FPU
popl %ebx popl %ebx
popl %edi popl %edi
......
This diff is collapsed.
...@@ -82,7 +82,7 @@ ...@@ -82,7 +82,7 @@
#define UNMASKED_UNDERFLOW $2 #define UNMASKED_UNDERFLOW $2
#ifdef REENTRANT_FPU #ifndef NON_REENTRANT_FPU
/* Make the code re-entrant by putting /* Make the code re-entrant by putting
local storage on the stack: */ local storage on the stack: */
#define FPU_bits_lost (%esp) #define FPU_bits_lost (%esp)
...@@ -97,7 +97,7 @@ FPU_bits_lost: ...@@ -97,7 +97,7 @@ FPU_bits_lost:
.byte 0 .byte 0
FPU_denormal: FPU_denormal:
.byte 0 .byte 0
#endif REENTRANT_FPU #endif NON_REENTRANT_FPU
.text .text
...@@ -127,9 +127,9 @@ fpu_reg_round: /* Normal entry point */ ...@@ -127,9 +127,9 @@ fpu_reg_round: /* Normal entry point */
fpu_reg_round_sqrt: /* Entry point from wm_sqrt.S */ fpu_reg_round_sqrt: /* Entry point from wm_sqrt.S */
#ifdef REENTRANT_FPU #ifndef NON_REENTRANT_FPU
pushl %ebx /* adjust the stack pointer */ pushl %ebx /* adjust the stack pointer */
#endif REENTRANT_FPU #endif NON_REENTRANT_FPU
#ifdef PARANOID #ifdef PARANOID
/* Cannot use this here yet */ /* Cannot use this here yet */
...@@ -417,9 +417,9 @@ xL_Store_significand: ...@@ -417,9 +417,9 @@ xL_Store_significand:
jge L_overflow jge L_overflow
fpu_reg_round_exit: fpu_reg_round_exit:
#ifdef REENTRANT_FPU #ifndef NON_REENTRANT_FPU
popl %ebx /* adjust the stack pointer */ popl %ebx /* adjust the stack pointer */
#endif REENTRANT_FPU #endif NON_REENTRANT_FPU
fpu_Arith_exit: fpu_Arith_exit:
popl %ebx popl %ebx
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
/* #define dSIGH(x) 4(x) */ /* #define dSIGH(x) 4(x) */
#ifdef REENTRANT_FPU #ifndef NON_REENTRANT_FPU
/* /*
Local storage on the stack: Local storage on the stack:
Result: FPU_accum_3:FPU_accum_2:FPU_accum_1:FPU_accum_0 Result: FPU_accum_3:FPU_accum_2:FPU_accum_1:FPU_accum_0
...@@ -65,7 +65,7 @@ FPU_result_2: ...@@ -65,7 +65,7 @@ FPU_result_2:
.long 0 .long 0
FPU_ovfl_flag: FPU_ovfl_flag:
.byte 0 .byte 0
#endif REENTRANT_FPU #endif NON_REENTRANT_FPU
.text .text
...@@ -78,9 +78,9 @@ FPU_ovfl_flag: ...@@ -78,9 +78,9 @@ FPU_ovfl_flag:
_reg_u_div: _reg_u_div:
pushl %ebp pushl %ebp
movl %esp,%ebp movl %esp,%ebp
#ifdef REENTRANT_FPU #ifndef NON_REENTRANT_FPU
subl $28,%esp subl $28,%esp
#endif REENTRANT_FPU #endif NON_REENTRANT_FPU
pushl %esi pushl %esi
pushl %edi pushl %edi
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#ifdef REENTRANT_FPU #ifndef NON_REENTRANT_FPU
/* Local storage on the stack: */ /* Local storage on the stack: */
#define FPU_accum_0 -4(%ebp) /* ms word */ #define FPU_accum_0 -4(%ebp) /* ms word */
#define FPU_accum_1 -8(%ebp) #define FPU_accum_1 -8(%ebp)
...@@ -40,7 +40,7 @@ FPU_accum_0: ...@@ -40,7 +40,7 @@ FPU_accum_0:
.long 0 .long 0
FPU_accum_1: FPU_accum_1:
.long 0 .long 0
#endif REENTRANT_FPU #endif NON_REENTRANT_FPU
.text .text
...@@ -50,9 +50,9 @@ FPU_accum_1: ...@@ -50,9 +50,9 @@ FPU_accum_1:
_reg_u_mul: _reg_u_mul:
pushl %ebp pushl %ebp
movl %esp,%ebp movl %esp,%ebp
#ifdef REENTRANT_FPU #ifndef NON_REENTRANT_FPU
subl $8,%esp subl $8,%esp
#endif REENTRANT_FPU #endif NON_REENTRANT_FPU
pushl %esi pushl %esi
pushl %edi pushl %edi
......
...@@ -9,5 +9,4 @@ ...@@ -9,5 +9,4 @@
| | | |
+---------------------------------------------------------------------------*/ +---------------------------------------------------------------------------*/
#define FPU_VERSION "wm-FPU-emu version Beta 1.11" #define FPU_VERSION "wm-FPU-emu version 1.12"
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#include "fpu_asm.h" #include "fpu_asm.h"
#ifdef REENTRANT_FPU #ifndef NON_REENTRANT_FPU
/* Local storage on the stack: */ /* Local storage on the stack: */
#define FPU_accum_3 -4(%ebp) /* ms word */ #define FPU_accum_3 -4(%ebp) /* ms word */
#define FPU_accum_2 -8(%ebp) #define FPU_accum_2 -8(%ebp)
...@@ -70,7 +70,7 @@ FPU_fsqrt_arg_1: ...@@ -70,7 +70,7 @@ FPU_fsqrt_arg_1:
.long 0 .long 0
FPU_fsqrt_arg_0: FPU_fsqrt_arg_0:
.long 0 /* ls word, at most the ms bit is set */ .long 0 /* ls word, at most the ms bit is set */
#endif REENTRANT_FPU #endif NON_REENTRANT_FPU
.text .text
...@@ -80,9 +80,9 @@ FPU_fsqrt_arg_0: ...@@ -80,9 +80,9 @@ FPU_fsqrt_arg_0:
_wm_sqrt: _wm_sqrt:
pushl %ebp pushl %ebp
movl %esp,%ebp movl %esp,%ebp
#ifdef REENTRANT_FPU #ifndef NON_REENTRANT_FPU
subl $28,%esp subl $28,%esp
#endif REENTRANT_FPU #endif NON_REENTRANT_FPU
pushl %esi pushl %esi
pushl %edi pushl %edi
pushl %ebx pushl %ebx
......
This diff is collapsed.
...@@ -82,6 +82,9 @@ extern int * blksize_size[MAX_BLKDEV]; ...@@ -82,6 +82,9 @@ extern int * blksize_size[MAX_BLKDEV];
extern unsigned long hd_init(unsigned long mem_start, unsigned long mem_end); extern unsigned long hd_init(unsigned long mem_start, unsigned long mem_end);
extern unsigned long cdu31a_init(unsigned long mem_start, unsigned long mem_end); extern unsigned long cdu31a_init(unsigned long mem_start, unsigned long mem_end);
extern unsigned long mcd_init(unsigned long mem_start, unsigned long mem_end); extern unsigned long mcd_init(unsigned long mem_start, unsigned long mem_end);
#ifdef CONFIG_SBPCD
extern unsigned long sbpcd_init(unsigned long, unsigned long);
#endif CONFIG_SBPCD
extern int is_read_only(int dev); extern int is_read_only(int dev);
extern void set_device_ro(int dev,int flag); extern void set_device_ro(int dev,int flag);
......
...@@ -19,10 +19,6 @@ ...@@ -19,10 +19,6 @@
#include "blk.h" #include "blk.h"
#ifdef CONFIG_SBPCD
extern u_long sbpcd_init(u_long, u_long);
#endif CONFIG_SBPCD
/* /*
* The request-struct contains all necessary data * The request-struct contains all necessary data
* to load a nr of sectors into memory * to load a nr of sectors into memory
......
This diff is collapsed.
...@@ -281,6 +281,14 @@ static struct device ppp0_dev = { ...@@ -281,6 +281,14 @@ static struct device ppp0_dev = {
#define NEXT_DEV (&ppp0_dev) #define NEXT_DEV (&ppp0_dev)
#endif /* PPP */ #endif /* PPP */
#ifdef CONFIG_DUMMY
extern int dummy_init(struct device *dev);
static struct device dummy_dev = {
"dummy", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, dummy_init, };
# undef NEXT_DEV
# define NEXT_DEV (&dummy_dev)
#endif
#ifdef LOOPBACK #ifdef LOOPBACK
extern int loopback_init(struct device *dev); extern int loopback_init(struct device *dev);
static struct device loopback_dev = { static struct device loopback_dev = {
......
...@@ -94,6 +94,7 @@ static char ppp_warning[] = KERN_WARNING "PPP: ALERT! not INUSE! %d\n"; ...@@ -94,6 +94,7 @@ static char ppp_warning[] = KERN_WARNING "PPP: ALERT! not INUSE! %d\n";
int ppp_init(struct device *); int ppp_init(struct device *);
static void ppp_init_ctrl_blk(struct ppp *); static void ppp_init_ctrl_blk(struct ppp *);
static int ppp_dev_open(struct device *); static int ppp_dev_open(struct device *);
static int ppp_dev_ioctl(struct device *dev, struct ifreq *ifr);
static int ppp_dev_close(struct device *); static int ppp_dev_close(struct device *);
static void ppp_kick_tty(struct ppp *); static void ppp_kick_tty(struct ppp *);
...@@ -264,6 +265,7 @@ ppp_init(struct device *dev) ...@@ -264,6 +265,7 @@ ppp_init(struct device *dev)
dev->mtu = PPP_MTU; dev->mtu = PPP_MTU;
dev->hard_start_xmit = ppp_xmit; dev->hard_start_xmit = ppp_xmit;
dev->open = ppp_dev_open; dev->open = ppp_dev_open;
dev->do_ioctl = ppp_dev_ioctl;
dev->stop = ppp_dev_close; dev->stop = ppp_dev_close;
dev->get_stats = ppp_get_stats; dev->get_stats = ppp_get_stats;
dev->hard_header = ppp_header; dev->hard_header = ppp_header;
...@@ -601,6 +603,32 @@ ppp_dev_close(struct device *dev) ...@@ -601,6 +603,32 @@ ppp_dev_close(struct device *dev)
return 0; return 0;
} }
static int ppp_dev_ioctl(struct device *dev, struct ifreq *ifr)
{
struct ppp *ppp = &ppp_ctrl[dev->base_addr];
int error;
struct stats
{
struct ppp_stats ppp_stats;
struct slcompress slhc;
} *result;
error = verify_area (VERIFY_READ,
ifr->ifr_ifru.ifru_data,
sizeof (struct stats));
if (error == 0) {
result = (struct stats *) ifr->ifr_ifru.ifru_data;
memcpy_tofs (&result->ppp_stats, &ppp->stats, sizeof (struct ppp_stats));
if (ppp->slcomp)
memcpy_tofs (&result->slhc, ppp->slcomp, sizeof (struct slcompress));
}
return error;
}
/************************************************************* /*************************************************************
* TTY OUTPUT * TTY OUTPUT
* The following function delivers a fully-formed PPP * The following function delivers a fully-formed PPP
...@@ -882,6 +910,8 @@ static void ppp_receive_buf(struct tty_struct *tty, unsigned char *cp, ...@@ -882,6 +910,8 @@ static void ppp_receive_buf(struct tty_struct *tty, unsigned char *cp,
if (ppp_debug >= 5) { if (ppp_debug >= 5) {
ppp_print_buffer ("receive buffer", cp, count, KERNEL_DS); ppp_print_buffer ("receive buffer", cp, count, KERNEL_DS);
} }
ppp->stats.rbytes += count;
while (count-- > 0) { while (count-- > 0) {
c = *cp++; c = *cp++;
...@@ -1367,7 +1397,7 @@ ppp_ioctl(struct tty_struct *tty, struct file *file, unsigned int i, ...@@ -1367,7 +1397,7 @@ ppp_ioctl(struct tty_struct *tty, struct file *file, unsigned int i,
PRINTKN (3,(KERN_INFO "ppp_ioctl: set mru to %x\n", temp_i)); PRINTKN (3,(KERN_INFO "ppp_ioctl: set mru to %x\n", temp_i));
temp_i = (int) get_fs_long (l); temp_i = (int) get_fs_long (l);
if (ppp->mru != temp_i) if (ppp->mru != temp_i)
ppp_changedmtu (ppp, ppp->mtu, temp_i); ppp_changedmtu (ppp, ppp->dev->mtu, temp_i);
} }
break; break;
......
...@@ -562,7 +562,6 @@ int buslogic_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) ...@@ -562,7 +562,6 @@ int buslogic_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
if (bufflen != sizeof SCpnt->sense_buffer) { if (bufflen != sizeof SCpnt->sense_buffer) {
buslogic_printk("Wrong buffer length supplied for request sense (%d)\n", buslogic_printk("Wrong buffer length supplied for request sense (%d)\n",
bufflen); bufflen);
panic("buslogic.c: wrong buffer length for request sense");
} }
#endif #endif
SCpnt->result = 0; SCpnt->result = 0;
...@@ -781,6 +780,7 @@ static int setup_mailboxes(unsigned int base, struct Scsi_Host *SHpnt) ...@@ -781,6 +780,7 @@ static int setup_mailboxes(unsigned int base, struct Scsi_Host *SHpnt)
buslogic_printk("buslogic_detect: failed setting up mailboxes\n"); buslogic_printk("buslogic_detect: failed setting up mailboxes\n");
} }
ok = TRUE; ok = TRUE;
return ok;
must_be_adaptec: must_be_adaptec:
INTR_RESET(base); INTR_RESET(base);
printk("- must be Adaptec\n"); /* So that the adaptec detect looks clean */ printk("- must be Adaptec\n"); /* So that the adaptec detect looks clean */
...@@ -888,7 +888,6 @@ static int getconfig(unsigned int base, unsigned char *irq, ...@@ -888,7 +888,6 @@ static int getconfig(unsigned int base, unsigned char *irq,
/* Query the board to find out the model. */ /* Query the board to find out the model. */
static int buslogic_query(unsigned int base, int *trans) static int buslogic_query(unsigned int base, int *trans)
{ {
#if 0
unsigned const char inquiry_cmd[] = { CMD_INQUIRY }; unsigned const char inquiry_cmd[] = { CMD_INQUIRY };
unsigned char inquiry_result[4]; unsigned char inquiry_result[4];
int i; int i;
...@@ -899,14 +898,18 @@ static int buslogic_query(unsigned int base, int *trans) ...@@ -899,14 +898,18 @@ static int buslogic_query(unsigned int base, int *trans)
buslogic_out(base, inquiry_cmd, sizeof inquiry_cmd); buslogic_out(base, inquiry_cmd, sizeof inquiry_cmd);
buslogic_in(base, inquiry_result, 4); buslogic_in(base, inquiry_result, 4);
WAIT_UNTIL(INTERRUPT(base), CMDC); WAIT_UNTIL(INTERRUPT(base), CMDC);
INTR_RESET(base);
buslogic_printk("Inquiry Bytes: %X %X %X %X\n",
inquiry_result[0],inquiry_result[1],
inquiry_result[2],inquiry_result[3]);
while (0) { while (0) {
fail: fail:
buslogic_printk("buslogic_detect: query card type\n"); buslogic_printk("buslogic_query: query board settings\n");
return TRUE;
} }
INTR_RESET(base);
#endif
*trans = BIOS_TRANSLATION_6432; /* Default case */ *trans = BIOS_TRANSLATION_6432; /* Default case */
return FALSE; return FALSE;
} }
...@@ -1018,8 +1021,13 @@ int buslogic_detect(int hostnum) ...@@ -1018,8 +1021,13 @@ int buslogic_detect(int hostnum)
host[irq - 9] = SHpnt; host[irq - 9] = SHpnt;
SHpnt->this_id = id; SHpnt->this_id = id;
#ifdef CONFIG_NO_BUGGY_BUSLOGIC
/* Only type 'A' (AT/ISA) bus adapters use unchecked DMA. */ /* Only type 'A' (AT/ISA) bus adapters use unchecked DMA. */
SHpnt->unchecked_isa_dma = (bus_type == 'A'); SHpnt->unchecked_isa_dma = (bus_type == 'A');
#else
/* bugs in the firmware with 16M+. Gaah */
SHpnt->unchecked_isa_dma = 1;
#endif
SHpnt->sg_tablesize = max_sg; SHpnt->sg_tablesize = max_sg;
if (SHpnt->sg_tablesize > BUSLOGIC_MAX_SG) if (SHpnt->sg_tablesize > BUSLOGIC_MAX_SG)
SHpnt->sg_tablesize = BUSLOGIC_MAX_SG; SHpnt->sg_tablesize = BUSLOGIC_MAX_SG;
......
...@@ -44,6 +44,9 @@ extern int check_cdu31a_media_change(int, int); ...@@ -44,6 +44,9 @@ extern int check_cdu31a_media_change(int, int);
#ifdef CONFIG_MCD #ifdef CONFIG_MCD
extern int check_mcd_media_change(int, int); extern int check_mcd_media_change(int, int);
#endif #endif
#ifdef CONFIG_SBPCD
extern int check_sbpcd_media_change(int, int);
#endif
#define NR_SIZES 4 #define NR_SIZES 4
static char buffersize_index[9] = {-1, 0, 1, -1, 2, -1, -1, -1, 3}; static char buffersize_index[9] = {-1, 0, 1, -1, 2, -1, -1, -1, 3};
...@@ -334,6 +337,12 @@ void check_disk_change(dev_t dev) ...@@ -334,6 +337,12 @@ void check_disk_change(dev_t dev)
break; break;
#endif #endif
#if defined(CONFIG_SBPCD)
case MATSUSHITA_CDROM_MAJOR:
i = check_sbpcd_media_change(dev, 0);
break;
#endif
default: default:
return; return;
}; };
......
This diff is collapsed.
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
OBJS = sched.o sys_call.o traps.o irq.o dma.o fork.o \ OBJS = sched.o sys_call.o traps.o irq.o dma.o fork.o \
panic.o printk.o vsprintf.o sys.o module.o ksyms.o exit.o \ panic.o printk.o vsprintf.o sys.o module.o ksyms.o exit.o \
signal.o mktime.o ptrace.o ioport.o itimer.o \ signal.o ptrace.o ioport.o itimer.o \
info.o ldt.o time.o tqueue.o vm86.o info.o ldt.o time.o tqueue.o vm86.o
all: kernel.o all: kernel.o
......
...@@ -517,6 +517,8 @@ static void second_overflow(void) ...@@ -517,6 +517,8 @@ static void second_overflow(void)
if (xtime.tv_sec > last_rtc_update + 660) if (xtime.tv_sec > last_rtc_update + 660)
if (set_rtc_mmss(xtime.tv_sec) == 0) if (set_rtc_mmss(xtime.tv_sec) == 0)
last_rtc_update = xtime.tv_sec; last_rtc_update = xtime.tv_sec;
else
last_rtc_update = xtime.tv_sec - 600; /* do it again in one min */
} }
/* /*
......
This diff is collapsed.
...@@ -46,6 +46,13 @@ ...@@ -46,6 +46,13 @@
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/mman.h> #include <linux/mman.h>
/*
* Define this if things work differently on a i386 and a i486:
* it will (on a i486) warn about kernel memory accesses that are
* done without a 'verify_area(VERIFY_WRITE,..)'
*/
#undef CONFIG_TEST_VERIFY_AREA
unsigned long high_memory = 0; unsigned long high_memory = 0;
extern unsigned long pg0[1024]; /* page table for 0-4MB for everybody */ extern unsigned long pg0[1024]; /* page table for 0-4MB for everybody */
...@@ -902,10 +909,15 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) ...@@ -902,10 +909,15 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
} else } else
user_esp = regs->esp; user_esp = regs->esp;
} }
if (error_code & PAGE_PRESENT) if (error_code & PAGE_PRESENT) {
#ifdef CONFIG_TEST_VERIFY_AREA
if (regs->cs == KERNEL_CS)
printk("WP fault at %08x\n", regs->eip);
#endif
do_wp_page(error_code, address, current, user_esp); do_wp_page(error_code, address, current, user_esp);
else } else {
do_no_page(error_code, address, current, user_esp); do_no_page(error_code, address, current, user_esp);
}
return; return;
} }
address -= TASK_SIZE; address -= TASK_SIZE;
...@@ -1124,6 +1136,9 @@ void mem_init(unsigned long start_low_mem, ...@@ -1124,6 +1136,9 @@ void mem_init(unsigned long start_low_mem,
invalidate(); invalidate();
if (wp_works_ok < 0) if (wp_works_ok < 0)
wp_works_ok = 0; wp_works_ok = 0;
#ifdef CONFIG_TEST_VERIFY_AREA
wp_works_ok = 0;
#endif
return; return;
} }
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment