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

Import 1.1.18

parent 9ec7e58c
VERSION = 1
PATCHLEVEL = 1
SUBLEVEL = 17
SUBLEVEL = 18
all: Version zImage
......
......@@ -5,14 +5,13 @@
#DEBUG = -DDEBUGGING
DEBUG =
PARANOID = -DPARANOID
REENTRANT = -DREENTRANT_FPU
CFLAGS := $(CFLAGS) $(PARANOID) $(DEBUG) -fno-builtin
.c.o:
$(CC) $(CFLAGS) $(MATH_EMULATION) -c $<
.S.o:
$(CC) -D__ASSEMBLER__ $(PARANOID) $(REENTRANT) -c $<
$(CC) -D__ASSEMBLER__ $(PARANOID) -c $<
.s.o:
$(CC) -c $<
......
......@@ -47,7 +47,7 @@ Please report bugs, etc to me at:
--Bill Metzenthen
March 1994
June 1994
----------------------- Internals of wm-FPU-emu -----------------------
......@@ -80,20 +80,24 @@ emulate each FPU instruction to completion without interruption.
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
temporarily suspended while disk i/o takes place. During this time
another process may use the emulator, thereby changing some static
variables (eg FPU_st0_ptr, etc). The code which accesses user memory
is confined to five files:
another process may use the emulator, thereby perhaps changing static
variables. The code which accesses user memory is confined to five
files:
fpu_entry.c
reg_ld_str.c
load_store.c
get_address.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 -----------------------
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
more important differences are listed below:
(version 1.12) and the 80486 FPU (apart from bugs). Some of the more
important differences are listed below:
The Roundup flag does not have much meaning for the transcendental
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
protection fault message when run under the MS-DOS prompt of Windows
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 -----------------------
......@@ -322,6 +331,7 @@ Hamish Coleman, t933093@minyos.xx.rmit.oz.au
Bruce Evans, bde@kralizec.zeta.org.au
Timo Korvola, Timo.Korvola@hut.fi
Rick Lyons, rick@razorback.brisnet.org.au
Rick, jrs@world.std.com
...and numerous others who responded to my request for help with
a real 80486.
......
......@@ -42,20 +42,28 @@ void Un_impl(void)
RE_ENTRANT_CHECK_OFF;
/* No need to verify_area(), we have previously fetched these bytes. */
printk("Unimplemented FPU Opcode at eip=%p : ", (void *) address);
while ( 1 )
if ( FPU_CS == USER_CS )
{
byte1 = get_fs_byte((unsigned char *) address);
if ( (byte1 & 0xf8) == 0xd8 ) break;
printk("[%02x]", byte1);
address++;
while ( 1 )
{
byte1 = get_fs_byte((unsigned char *) 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
printk("/%d\n", (FPU_modrm >> 3) & 7);
{
printk("cs selector = %04x\n", FPU_CS);
}
RE_ENTRANT_CHECK_ON;
EXCEPTION(EX_Invalid);
......@@ -85,29 +93,36 @@ void emu_printall()
RE_ENTRANT_CHECK_OFF;
/* No need to verify_area(), we have previously fetched these bytes. */
printk("At %p:", (void *) address);
#define MAX_PRINTED_BYTES 20
for ( i = 0; i < MAX_PRINTED_BYTES; i++ )
if ( FPU_CS == USER_CS )
{
byte1 = get_fs_byte((unsigned char *) address);
if ( (byte1 & 0xf8) == 0xd8 )
#define MAX_PRINTED_BYTES 20
for ( i = 0; i < MAX_PRINTED_BYTES; i++ )
{
printk(" %02x", byte1);
break;
byte1 = get_fs_byte((unsigned char *) address);
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
{
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("%04x\n", FPU_CS);
}
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",
printk("%s\n", tag_desc[(int) (unsigned) r->tag]);
}
#ifdef OBSOLETE
printk("[data] %c .%04lx %04lx %04lx %04lx e%+-6ld ",
FPU_loaded_data.sign ? '-' : '+',
(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",
(long)(FPU_loaded_data.sigl & 0xFFFF),
FPU_loaded_data.exp - EXP_BIAS + 1);
printk("%s\n", tag_desc[(int) (unsigned) FPU_loaded_data.tag]);
#endif OBSOLETE
RE_ENTRANT_CHECK_ON;
}
......@@ -214,7 +231,6 @@ static struct {
error was detected.
Internal error types:
0 in load_store.c
0x14 in fpu_etc.c
0x1nn in a *.c file:
0x101 in reg_add_sub.c
......@@ -244,7 +260,13 @@ static struct {
0x126 in fpu_entry.c
0x127 in poly_2xm1.c
0x128 in fpu_entry.c
0x129 in fpu_entry.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:
0x201 in reg_u_add.S
0x202 in reg_u_div.S
......@@ -583,7 +605,7 @@ void stack_overflow(void)
{
/* The masked response */
top--;
reg_move(&CONST_QNaN, FPU_st0_ptr = &st(0));
reg_move(&CONST_QNaN, &st(0));
}
EXCEPTION(EX_StackOver);
......@@ -599,7 +621,7 @@ void stack_underflow(void)
if ( control_word & CW_Invalid )
{
/* The masked response */
reg_move(&CONST_QNaN, FPU_st0_ptr);
reg_move(&CONST_QNaN, &st(0));
}
EXCEPTION(EX_StackUnder);
......
......@@ -20,7 +20,7 @@ void fadd__()
{
/* fadd st,st(i) */
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__()
{
/* fmul st,st(i) */
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__()
{
/* fsub st,st(i) */
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_()
{
/* fsubr st,st(i) */
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__()
{
/* fdiv st,st(i) */
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_()
{
/* fdivr st,st(i) */
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()
{
/* fadd st(i),st */
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()
{
/* fmul st(i),st */
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()
{
/* fsubr st(i),st */
/* 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();
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()
{
/* fsub st(i),st */
/* 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();
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()
{
/* fdivr st(i),st */
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()
{
/* fdiv st(i),st */
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_()
{
/* faddp st(i),st */
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();
}
......@@ -132,7 +132,7 @@ void fmulp_()
{
/* fmulp st(i),st */
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();
}
......@@ -142,9 +142,9 @@ void fsubrp()
{
/* fsubrp st(i),st */
/* 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();
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();
}
......@@ -153,9 +153,9 @@ void fsubp_()
{
/* fsubp st(i),st */
/* 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();
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();
}
......@@ -164,7 +164,7 @@ void fdivrp()
{
/* fdivrp st(i),st */
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();
}
......@@ -173,7 +173,7 @@ void fdivp_()
{
/* fdivp st(i),st */
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();
}
......@@ -26,8 +26,7 @@ void fclex(void)
partial_status &= ~(SW_Backward|SW_Summary|SW_Stack_Fault|SW_Precision|
SW_Underflow|SW_Overflow|SW_Zero_Div|SW_Denorm_Op|
SW_Invalid);
NO_NET_DATA_EFFECT;
FPU_entry_eip = ip_offset; /* We want no net effect */
no_ip_update = 1;
}
/* Needs to be externally visible */
......@@ -43,11 +42,12 @@ void finit()
}
/* The behaviour is different to that detailed in
Section 15.1.6 of the Intel manual */
data_operand_offset = 0;
operand_selector = 0;
NO_NET_DATA_EFFECT;
FPU_entry_op_cs = 0;
FPU_entry_eip = ip_offset = 0;
operand_address.offset = 0;
operand_address.selector = 0;
instruction_address.offset = 0;
instruction_address.selector = 0;
instruction_address.opcode = 0;
no_ip_update = 1;
}
/*
......@@ -71,7 +71,7 @@ void finit_()
static void fstsw_ax(void)
{
*(short *) &FPU_EAX = status_word();
NO_NET_INSTR_EFFECT;
no_ip_update = 1;
}
static FUNC const fstsw_table[] = {
......@@ -108,10 +108,9 @@ void fld_i_()
{ reg_move(&st(FPU_rm), st_new_ptr); push(); }
else
{
if ( control_word & EX_Invalid )
if ( control_word & CW_Invalid )
{
/* The masked response */
push();
stack_underflow();
}
else
......@@ -125,9 +124,9 @@ void fxch_i()
{
/* fxch st(i) */
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 )
{
......@@ -136,20 +135,20 @@ void fxch_i()
return;
}
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);
return;
}
if ( sti_ptr->tag == TW_Empty )
{
if ( control_word & CW_Invalid )
reg_move(FPU_st0_ptr, sti_ptr); /* Masked response */
reg_move(st0_ptr, sti_ptr); /* Masked response */
stack_underflow();
return;
}
clear_C1();
reg_move(FPU_st0_ptr, &t);
reg_move(sti_ptr, FPU_st0_ptr);
reg_move(st0_ptr, &t);
reg_move(sti_ptr, st0_ptr);
reg_move(&t, sti_ptr);
}
......@@ -172,14 +171,14 @@ void ffreep()
void fst_i_()
{
/* fst st(i) */
reg_move(FPU_st0_ptr, &st(FPU_rm));
reg_move(&st(0), &st(FPU_rm));
}
void fstp_i()
{
/* fstp st(i) */
reg_move(FPU_st0_ptr, &st(FPU_rm));
reg_move(&st(0), &st(FPU_rm));
pop();
}
......@@ -60,14 +60,18 @@
#include <linux/math_emu.h>
#include <linux/linkage.h>
#ifdef PARANOID
/*
#define RE_ENTRANT_CHECKING
*/
#ifdef RE_ENTRANT_CHECKING
extern char emulating;
# define RE_ENTRANT_CHECK_OFF emulating = 0
# define RE_ENTRANT_CHECK_ON emulating = 1
#else
# define RE_ENTRANT_CHECK_OFF
# define RE_ENTRANT_CHECK_ON
#endif PARANOID
#endif RE_ENTRANT_CHECKING
#define FWAIT_OPCODE 0x9b
#define OP_SIZE_PREFIX 0x66
......@@ -89,46 +93,43 @@ extern char emulating;
#define PREFIX_SS_ 6
#define PREFIX_DEFAULT 7
/* These are to defeat the default action, giving the instruction
no net effect: */
#define NO_NET_DATA_EFFECT \
{ FPU_data_address = (void *)data_operand_offset; \
FPU_data_selector = operand_selector; }
#define NO_NET_INSTR_EFFECT \
{ FPU_entry_eip = ip_offset; \
FPU_entry_op_cs = cs_selector; }
struct address {
unsigned int offset;
unsigned int selector:16;
unsigned int opcode:11;
unsigned int empty:5;
};
typedef void (*FUNC)(void);
typedef struct fpu_reg FPU_REG;
typedef void (*FUNC_ST0)(FPU_REG *st0_ptr);
typedef struct { unsigned char address_size, operand_size, segment; }
overrides;
/* This structure is 48 bits: */
/* This structure is 32 bits: */
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 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_0 (FPU_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 NOT_EMPTY_ST0 (st0_tag ^ TW_Empty)
#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 */
#define push() { top--; FPU_st0_ptr = st_new_ptr; }
#define push() { top--; }
#define reg_move(x, y) { \
......
This diff is collapsed.
......@@ -17,22 +17,22 @@
#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();
}
else
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();
}
else
......@@ -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:
setcc(SW_C3);
break;
case TW_Valid:
if (FPU_st0_ptr->sign == SIGN_POS)
if (st0_ptr->sign == SIGN_POS)
setcc(0);
else
setcc(SW_C0);
#ifdef DENORM_OPERAND
if ( (FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()) )
if ( (st0_ptr->exp <= EXP_UNDER) && (denormal_operand()) )
{
#ifdef PECULIAR_486
/* This is wierd! */
if (FPU_st0_ptr->sign == SIGN_POS)
if (st0_ptr->sign == SIGN_POS)
setcc(SW_C3);
#endif PECULIAR_486
return;
......@@ -71,7 +71,7 @@ static void ftst_(void)
EXCEPTION(EX_Invalid);
break;
case TW_Infinity:
if (FPU_st0_ptr->sign == SIGN_POS)
if (st0_ptr->sign == SIGN_POS)
setcc(0);
else
setcc(SW_C0);
......@@ -87,10 +87,10 @@ static void ftst_(void)
}
}
static void fxam(void)
static void fxam(FPU_REG *st0_ptr)
{
int c=0;
switch (FPU_st0_tag)
switch (st0_ptr->tag)
{
case TW_Empty:
c = SW_C3|SW_C0;
......@@ -100,7 +100,7 @@ static void fxam(void)
break;
case TW_Valid:
/* 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 */
else
c = SW_C2;
......@@ -112,16 +112,18 @@ static void fxam(void)
c = SW_C2|SW_C0;
break;
}
if (FPU_st0_ptr->sign == SIGN_NEG)
if (st0_ptr->sign == SIGN_NEG)
c |= SW_C1;
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()
{
(fp_etc_table[FPU_rm])();
(fp_etc_table[FPU_rm])(&st(0));
}
......@@ -63,13 +63,16 @@ extern void trig_a(void);
extern void trig_b(void);
/* get_address.c */
extern void get_address(unsigned char FPU_modrm, unsigned long *fpu_eip,
fpu_addr_modes);
extern void get_address_16(unsigned char FPU_modrm, unsigned long *fpu_eip,
fpu_addr_modes);
extern void *get_address(unsigned char FPU_modrm, unsigned long *fpu_eip,
struct address *addr,
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 */
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 */
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,
/* reg_compare.c */
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 fcompst(void);
extern void fcompp(void);
......@@ -108,26 +111,26 @@ extern void fucompp(void);
extern void fconst(void);
/* reg_ld_str.c */
extern int reg_load_extended(void);
extern int reg_load_double(void);
extern int reg_load_single(void);
extern void reg_load_int64(void);
extern void reg_load_int32(void);
extern void reg_load_int16(void);
extern void reg_load_bcd(void);
extern int reg_store_extended(void);
extern int reg_store_double(void);
extern int reg_store_single(void);
extern int reg_store_int64(void);
extern int reg_store_int32(void);
extern int reg_store_int16(void);
extern int reg_store_bcd(void);
extern int reg_load_extended(long double *addr, FPU_REG *loaded_data);
extern int reg_load_double(double *dfloat, FPU_REG *loaded_data);
extern int reg_load_single(float *single, FPU_REG *loaded_data);
extern void reg_load_int64(long long *_s, FPU_REG *loaded_data);
extern void reg_load_int32(long *_s, FPU_REG *loaded_data);
extern void reg_load_int16(short *_s, FPU_REG *loaded_data);
extern void reg_load_bcd(char *s, FPU_REG *loaded_data);
extern int reg_store_extended(long double *d, FPU_REG *st0_ptr);
extern int reg_store_double(double *dfloat, FPU_REG *st0_ptr);
extern int reg_store_single(float *single, FPU_REG *st0_ptr);
extern int reg_store_int64(long long *d, FPU_REG *st0_ptr);
extern int reg_store_int32(long *d, FPU_REG *st0_ptr);
extern int reg_store_int16(short *d, FPU_REG *st0_ptr);
extern int reg_store_bcd(char *d, FPU_REG *st0_ptr);
extern int round_to_int(FPU_REG *r);
extern char *fldenv(fpu_addr_modes addr_modes);
extern void frstor(fpu_addr_modes addr_modes);
extern char *fldenv(fpu_addr_modes addr_modes, char *address);
extern void frstor(fpu_addr_modes addr_modes, char *address);
extern unsigned short tag_word(void);
extern char *fstenv(fpu_addr_modes addr_modes);
extern void fsave(fpu_addr_modes addr_modes);
extern char *fstenv(fpu_addr_modes addr_modes, char *address);
extern void fsave(fpu_addr_modes addr_modes, char *address);
/* reg_mul.c */
extern int reg_mul(FPU_REG const *a, FPU_REG const *b,
......
......@@ -19,6 +19,19 @@
of the stack frame of math_emulate() */
#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 FPU_info (I387.soft.info)
......@@ -30,22 +43,24 @@
#define FPU_EIP (FPU_info->___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_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 control_word (I387.soft.cwd)
#define regs (I387.soft.regs)
#define top (I387.soft.top)
#define ip_offset (I387.soft.fip)
#define cs_selector (I387.soft.fcs)
#define data_operand_offset (I387.soft.foo)
#define operand_selector (I387.soft.fos)
#define instruction_address (*(struct address *)&I387.soft.fip)
#define operand_address (*(struct address *)&I387.soft.foo)
#define FPU_verify_area(x,y,z) if ( verify_area(x,y,z) ) \
math_abort(FPU_info,SIGSEGV)
......@@ -64,7 +79,4 @@
#define FPU_code_verify_area(z) FPU_verify_area(VERIFY_READ,(void *)FPU_EIP,z)
#endif
/* ######## temporary and ugly ;-) */
#define FPU_data_address ((void *)(I387.soft.twd))
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -187,16 +187,8 @@ void poly_add_1(FPU_REG *src)
for the use of this function in poly_atan. Simple truncation
is used here instead of round-to-nearest. */
#ifdef OBSOLETE
char round = (src->sigl & 3) == 3;
#endif OBSOLETE
shrx(&src->sigl, 1);
#ifdef OBSOLETE
if ( round ) significand(src)++; /* Round to even */
#endif OBSOLETE
src->sigh |= 0x80000000;
src->exp = EXP_BIAS;
......
......@@ -24,10 +24,15 @@
int compare(FPU_REG const *b)
{
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_Valid )
......@@ -42,23 +47,23 @@ int compare(FPU_REG const *b)
}
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)
#ifdef DENORM_OPERAND
| ((FPU_st0_ptr->exp <= EXP_UNDER )
| ((st0_ptr->exp <= EXP_UNDER )
? COMP_Denormal : 0 )
#endif DENORM_OPERAND
;
}
}
if ( FPU_st0_ptr->tag == TW_Infinity )
if ( st0_tag == TW_Infinity )
{
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)
#ifdef DENORM_OPERAND
| (((b->tag == TW_Valid) && (b->exp <= EXP_UNDER)) ?
......@@ -69,19 +74,19 @@ int compare(FPU_REG const *b)
else if ( b->tag == TW_Infinity )
{
/* The 80486 book says that infinities can be equal! */
return (FPU_st0_ptr->sign == b->sign) ? COMP_A_eq_B :
((FPU_st0_ptr->sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B);
return (st0_ptr->sign == b->sign) ? COMP_A_eq_B :
((st0_ptr->sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B);
}
/* Fall through to the NaN code */
}
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)
#ifdef DENORM_OPERAND
| (((FPU_st0_ptr->tag == TW_Valid)
&& (FPU_st0_ptr->exp <= EXP_UNDER)) ?
| (((st0_tag == TW_Valid)
&& (st0_ptr->exp <= EXP_UNDER)) ?
COMP_Denormal : 0)
#endif DENORM_OPERAND
;
......@@ -91,9 +96,9 @@ int compare(FPU_REG const *b)
/* The only possibility now should be that one of the arguments
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)) )
/* At least one arg is a signaling NaN */
return COMP_No_Comp | COMP_SNaN | COMP_NaN;
......@@ -106,51 +111,51 @@ int compare(FPU_REG const *b)
}
#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);
#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
|
( ((FPU_st0_ptr->exp <= EXP_UNDER) || (b->exp <= EXP_UNDER)) ?
( ((st0_ptr->exp <= EXP_UNDER) || (b->exp <= EXP_UNDER)) ?
COMP_Denormal : 0)
#endif DENORM_OPERAND
;
}
diff = FPU_st0_ptr->exp - b->exp;
diff = st0_ptr->exp - b->exp;
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 */
if ( diff == 0 )
{
diff = FPU_st0_ptr->sigl > b->sigl;
diff = st0_ptr->sigl > b->sigl;
if ( diff == 0 )
diff = -(FPU_st0_ptr->sigl < b->sigl);
diff = -(st0_ptr->sigl < b->sigl);
}
}
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
|
( ((FPU_st0_ptr->exp <= EXP_UNDER) || (b->exp <= EXP_UNDER)) ?
( ((st0_ptr->exp <= EXP_UNDER) || (b->exp <= EXP_UNDER)) ?
COMP_Denormal : 0)
#endif DENORM_OPERAND
;
}
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
|
( ((FPU_st0_ptr->exp <= EXP_UNDER) || (b->exp <= EXP_UNDER)) ?
( ((st0_ptr->exp <= EXP_UNDER) || (b->exp <= EXP_UNDER)) ?
COMP_Denormal : 0)
#endif DENORM_OPERAND
;
......@@ -159,7 +164,7 @@ int compare(FPU_REG const *b)
return COMP_A_eq_B
#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)
#endif DENORM_OPERAND
;
......@@ -168,11 +173,11 @@ int compare(FPU_REG const *b)
/* 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;
c = compare(&FPU_loaded_data);
c = compare(loaded_data);
if (c & COMP_NaN)
{
......@@ -214,7 +219,7 @@ static int compare_st_st(int nr)
{
int f, c;
if ( !NOT_EMPTY_0 || !NOT_EMPTY(nr) )
if ( !NOT_EMPTY(0) || !NOT_EMPTY(nr) )
{
setcc(SW_C3 | SW_C2 | SW_C0);
/* Stack fault */
......@@ -264,7 +269,7 @@ static int compare_u_st_st(int nr)
{
int f, c;
if ( !NOT_EMPTY_0 || !NOT_EMPTY(nr) )
if ( !NOT_EMPTY(0) || !NOT_EMPTY(nr) )
{
setcc(SW_C3 | SW_C2 | SW_C0);
/* Stack fault */
......@@ -340,10 +345,7 @@ void fcompp()
return;
}
if ( !compare_st_st(1) )
{
pop(); FPU_st0_ptr = &st(0);
pop();
}
poppop();
}
......@@ -369,10 +371,7 @@ void fucompp()
if (FPU_rm == 1)
{
if ( !compare_u_st_st(1) )
{
pop(); FPU_st0_ptr = &st(0);
pop();
}
poppop();
}
else
FPU_illegal();
......
......@@ -66,7 +66,7 @@ static void fld_const(FPU_REG const *c)
return;
}
push();
reg_move(c, FPU_st0_ptr);
reg_move(c, st_new_ptr);
clear_C1();
}
......
......@@ -25,9 +25,9 @@
_reg_div:
pushl %ebp
movl %esp,%ebp
#ifdef REENTRANT_FPU
#ifndef NON_REENTRANT_FPU
subl $28,%esp /* Needed by divide_kernel */
#endif REENTRANT_FPU
#endif NON_REENTRANT_FPU
pushl %esi
pushl %edi
......@@ -214,11 +214,11 @@ LDiv_negative_result:
xorl %eax,%eax /* Valid result */
LDiv_exit:
#ifdef REENTRANT_FPU
#ifndef NON_REENTRANT_FPU
leal -40(%ebp),%esp
#else
leal -12(%ebp),%esp
#endif REENTRANT_FPU
#endif NON_REENTRANT_FPU
popl %ebx
popl %edi
......
This diff is collapsed.
......@@ -82,7 +82,7 @@
#define UNMASKED_UNDERFLOW $2
#ifdef REENTRANT_FPU
#ifndef NON_REENTRANT_FPU
/* Make the code re-entrant by putting
local storage on the stack: */
#define FPU_bits_lost (%esp)
......@@ -97,7 +97,7 @@ FPU_bits_lost:
.byte 0
FPU_denormal:
.byte 0
#endif REENTRANT_FPU
#endif NON_REENTRANT_FPU
.text
......@@ -127,9 +127,9 @@ fpu_reg_round: /* Normal entry point */
fpu_reg_round_sqrt: /* Entry point from wm_sqrt.S */
#ifdef REENTRANT_FPU
#ifndef NON_REENTRANT_FPU
pushl %ebx /* adjust the stack pointer */
#endif REENTRANT_FPU
#endif NON_REENTRANT_FPU
#ifdef PARANOID
/* Cannot use this here yet */
......@@ -417,9 +417,9 @@ xL_Store_significand:
jge L_overflow
fpu_reg_round_exit:
#ifdef REENTRANT_FPU
#ifndef NON_REENTRANT_FPU
popl %ebx /* adjust the stack pointer */
#endif REENTRANT_FPU
#endif NON_REENTRANT_FPU
fpu_Arith_exit:
popl %ebx
......
......@@ -29,7 +29,7 @@
/* #define dSIGH(x) 4(x) */
#ifdef REENTRANT_FPU
#ifndef NON_REENTRANT_FPU
/*
Local storage on the stack:
Result: FPU_accum_3:FPU_accum_2:FPU_accum_1:FPU_accum_0
......@@ -65,7 +65,7 @@ FPU_result_2:
.long 0
FPU_ovfl_flag:
.byte 0
#endif REENTRANT_FPU
#endif NON_REENTRANT_FPU
.text
......@@ -78,9 +78,9 @@ FPU_ovfl_flag:
_reg_u_div:
pushl %ebp
movl %esp,%ebp
#ifdef REENTRANT_FPU
#ifndef NON_REENTRANT_FPU
subl $28,%esp
#endif REENTRANT_FPU
#endif NON_REENTRANT_FPU
pushl %esi
pushl %edi
......
......@@ -27,7 +27,7 @@
#ifdef REENTRANT_FPU
#ifndef NON_REENTRANT_FPU
/* Local storage on the stack: */
#define FPU_accum_0 -4(%ebp) /* ms word */
#define FPU_accum_1 -8(%ebp)
......@@ -40,7 +40,7 @@ FPU_accum_0:
.long 0
FPU_accum_1:
.long 0
#endif REENTRANT_FPU
#endif NON_REENTRANT_FPU
.text
......@@ -50,9 +50,9 @@ FPU_accum_1:
_reg_u_mul:
pushl %ebp
movl %esp,%ebp
#ifdef REENTRANT_FPU
#ifndef NON_REENTRANT_FPU
subl $8,%esp
#endif REENTRANT_FPU
#endif NON_REENTRANT_FPU
pushl %esi
pushl %edi
......
......@@ -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 @@
#include "fpu_asm.h"
#ifdef REENTRANT_FPU
#ifndef NON_REENTRANT_FPU
/* Local storage on the stack: */
#define FPU_accum_3 -4(%ebp) /* ms word */
#define FPU_accum_2 -8(%ebp)
......@@ -70,7 +70,7 @@ FPU_fsqrt_arg_1:
.long 0
FPU_fsqrt_arg_0:
.long 0 /* ls word, at most the ms bit is set */
#endif REENTRANT_FPU
#endif NON_REENTRANT_FPU
.text
......@@ -80,9 +80,9 @@ FPU_fsqrt_arg_0:
_wm_sqrt:
pushl %ebp
movl %esp,%ebp
#ifdef REENTRANT_FPU
#ifndef NON_REENTRANT_FPU
subl $28,%esp
#endif REENTRANT_FPU
#endif NON_REENTRANT_FPU
pushl %esi
pushl %edi
pushl %ebx
......
This diff is collapsed.
......@@ -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 cdu31a_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 void set_device_ro(int dev,int flag);
......
......@@ -19,10 +19,6 @@
#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
* to load a nr of sectors into memory
......
This diff is collapsed.
......@@ -281,6 +281,14 @@ static struct device ppp0_dev = {
#define NEXT_DEV (&ppp0_dev)
#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
extern int loopback_init(struct device *dev);
static struct device loopback_dev = {
......
......@@ -94,6 +94,7 @@ static char ppp_warning[] = KERN_WARNING "PPP: ALERT! not INUSE! %d\n";
int ppp_init(struct device *);
static void ppp_init_ctrl_blk(struct ppp *);
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 void ppp_kick_tty(struct ppp *);
......@@ -264,6 +265,7 @@ ppp_init(struct device *dev)
dev->mtu = PPP_MTU;
dev->hard_start_xmit = ppp_xmit;
dev->open = ppp_dev_open;
dev->do_ioctl = ppp_dev_ioctl;
dev->stop = ppp_dev_close;
dev->get_stats = ppp_get_stats;
dev->hard_header = ppp_header;
......@@ -601,6 +603,32 @@ ppp_dev_close(struct device *dev)
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
* The following function delivers a fully-formed PPP
......@@ -882,6 +910,8 @@ static void ppp_receive_buf(struct tty_struct *tty, unsigned char *cp,
if (ppp_debug >= 5) {
ppp_print_buffer ("receive buffer", cp, count, KERNEL_DS);
}
ppp->stats.rbytes += count;
while (count-- > 0) {
c = *cp++;
......@@ -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));
temp_i = (int) get_fs_long (l);
if (ppp->mru != temp_i)
ppp_changedmtu (ppp, ppp->mtu, temp_i);
ppp_changedmtu (ppp, ppp->dev->mtu, temp_i);
}
break;
......
......@@ -562,7 +562,6 @@ int buslogic_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
if (bufflen != sizeof SCpnt->sense_buffer) {
buslogic_printk("Wrong buffer length supplied for request sense (%d)\n",
bufflen);
panic("buslogic.c: wrong buffer length for request sense");
}
#endif
SCpnt->result = 0;
......@@ -781,6 +780,7 @@ static int setup_mailboxes(unsigned int base, struct Scsi_Host *SHpnt)
buslogic_printk("buslogic_detect: failed setting up mailboxes\n");
}
ok = TRUE;
return ok;
must_be_adaptec:
INTR_RESET(base);
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,
/* Query the board to find out the model. */
static int buslogic_query(unsigned int base, int *trans)
{
#if 0
unsigned const char inquiry_cmd[] = { CMD_INQUIRY };
unsigned char inquiry_result[4];
int i;
......@@ -899,14 +898,18 @@ static int buslogic_query(unsigned int base, int *trans)
buslogic_out(base, inquiry_cmd, sizeof inquiry_cmd);
buslogic_in(base, inquiry_result, 4);
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) {
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;
}
......@@ -1018,8 +1021,13 @@ int buslogic_detect(int hostnum)
host[irq - 9] = SHpnt;
SHpnt->this_id = id;
#ifdef CONFIG_NO_BUGGY_BUSLOGIC
/* Only type 'A' (AT/ISA) bus adapters use unchecked DMA. */
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;
if (SHpnt->sg_tablesize > BUSLOGIC_MAX_SG)
SHpnt->sg_tablesize = BUSLOGIC_MAX_SG;
......
......@@ -44,6 +44,9 @@ extern int check_cdu31a_media_change(int, int);
#ifdef CONFIG_MCD
extern int check_mcd_media_change(int, int);
#endif
#ifdef CONFIG_SBPCD
extern int check_sbpcd_media_change(int, int);
#endif
#define NR_SIZES 4
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)
break;
#endif
#if defined(CONFIG_SBPCD)
case MATSUSHITA_CDROM_MAJOR:
i = check_sbpcd_media_change(dev, 0);
break;
#endif
default:
return;
};
......
This diff is collapsed.
......@@ -18,7 +18,7 @@
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 \
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
all: kernel.o
......
......@@ -517,6 +517,8 @@ static void second_overflow(void)
if (xtime.tv_sec > last_rtc_update + 660)
if (set_rtc_mmss(xtime.tv_sec) == 0)
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 @@
#include <linux/ptrace.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;
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)
} else
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);
else
} else {
do_no_page(error_code, address, current, user_esp);
}
return;
}
address -= TASK_SIZE;
......@@ -1124,6 +1136,9 @@ void mem_init(unsigned long start_low_mem,
invalidate();
if (wp_works_ok < 0)
wp_works_ok = 0;
#ifdef CONFIG_TEST_VERIFY_AREA
wp_works_ok = 0;
#endif
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