mirror of
https://github.com/reactos/reactos.git
synced 2025-02-25 18:02:05 +00:00
Bug fixes
svn path=/trunk/; revision=1732
This commit is contained in:
parent
9b95a9991c
commit
e065bf41ff
3 changed files with 303 additions and 188 deletions
|
@ -298,8 +298,8 @@ entry:
|
|||
;; int 15h opt e801 don't work , try int 15h, option 88h
|
||||
mov ah, 088h
|
||||
int 015h
|
||||
cmp ax,ax
|
||||
jz .cmosmem
|
||||
cmp ax, 0
|
||||
je .cmosmem
|
||||
mov [_multiboot_mem_upper],ax
|
||||
jmp .done_mem
|
||||
.cmosmem:
|
||||
|
|
|
@ -1,5 +1,22 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* ReactOS kernel
|
||||
* Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/*
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ke/i386/thread.c
|
||||
* PURPOSE: Architecture multitasking functions
|
||||
|
|
|
@ -37,9 +37,12 @@
|
|||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
#define IOPL_FLAG ((1 << 12) | (1 << 13))
|
||||
#define INTERRUPT_FLAG (1 << 9)
|
||||
#define TRAP_FLAG (1 << 8)
|
||||
|
||||
#define VALID_FLAGS (0xDFF)
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
ULONG
|
||||
|
@ -47,217 +50,310 @@ KeV86GPF(PKV86M_TRAP_FRAME VTf, PKTRAP_FRAME Tf)
|
|||
{
|
||||
PUCHAR ip;
|
||||
PUSHORT sp;
|
||||
PULONG dsp;
|
||||
BOOL BigDataPrefix = FALSE;
|
||||
BOOL BigAddressPrefix = FALSE;
|
||||
// BOOL RepPrefix = FALSE;
|
||||
ULONG i = 0;
|
||||
BOOL Exit = FALSE;
|
||||
|
||||
ip = (PUCHAR)((Tf->Cs & 0xFFFF) * 16 + (Tf->Eip & 0xFFFF));
|
||||
sp = (PUSHORT)((Tf->Ss & 0xFFFF) * 16 + (Tf->Esp & 0xFFFF));
|
||||
dsp = (PULONG)sp;
|
||||
|
||||
DPRINT("KeV86GPF handling %x at %x:%x ss:sp %x:%x Flags %x\n",
|
||||
ip[0], Tf->Cs, Tf->Eip, Tf->Ss, Tf->Esp, VTf->regs->Flags);
|
||||
|
||||
switch (ip[0])
|
||||
while (!Exit)
|
||||
{
|
||||
/* sti */
|
||||
case 0xFB:
|
||||
if (VTf->regs->Flags & KV86M_EMULATE_CLI_STI)
|
||||
switch (ip[i])
|
||||
{
|
||||
/* 32-bit data prefix */
|
||||
case 0x66:
|
||||
BigDataPrefix = TRUE;
|
||||
i++;
|
||||
Tf->Eip++;
|
||||
VTf->regs->Vif = 1;
|
||||
return(0);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
/* cli */
|
||||
case 0xFA:
|
||||
if (VTf->regs->Flags & KV86M_EMULATE_CLI_STI)
|
||||
{
|
||||
/* 32-bit address prefix */
|
||||
case 0x67:
|
||||
BigAddressPrefix = TRUE;
|
||||
i++;
|
||||
Tf->Eip++;
|
||||
VTf->regs->Vif = 0;
|
||||
return(0);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
/* pushf */
|
||||
case 0x9C:
|
||||
if (VTf->regs->Flags & KV86M_EMULATE_CLI_STI)
|
||||
{
|
||||
Tf->Eip++;
|
||||
Tf->Esp = Tf->Esp - 2;
|
||||
sp = sp - 1;
|
||||
sp[0] = Tf->Eflags & 0xFFFF;
|
||||
if (VTf->regs->Vif)
|
||||
/* sti */
|
||||
case 0xFB:
|
||||
if (BigDataPrefix || BigAddressPrefix)
|
||||
{
|
||||
sp[0] = sp[0] | INTERRUPT_FLAG;
|
||||
return(1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
break;
|
||||
if (VTf->regs->Flags & KV86M_EMULATE_CLI_STI)
|
||||
{
|
||||
Tf->Eip++;
|
||||
VTf->regs->Vif = 1;
|
||||
return(0);
|
||||
}
|
||||
Exit = TRUE;
|
||||
break;
|
||||
|
||||
/* popf */
|
||||
case 0x9D:
|
||||
if (VTf->regs->Flags & KV86M_EMULATE_CLI_STI)
|
||||
{
|
||||
Tf->Eip++;
|
||||
Tf->Eflags = Tf->Eflags & (~0xFFFF);
|
||||
Tf->Eflags = Tf->Eflags | sp[0];
|
||||
if (Tf->Eflags & INTERRUPT_FLAG)
|
||||
{
|
||||
VTf->regs->Vif = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
VTf->regs->Vif = 0;
|
||||
/* cli */
|
||||
case 0xFA:
|
||||
if (BigDataPrefix || BigAddressPrefix)
|
||||
{
|
||||
return(1);
|
||||
}
|
||||
Tf->Eflags = Tf->Eflags & (~INTERRUPT_FLAG);
|
||||
Tf->Esp = Tf->Esp + 2;
|
||||
return(0);
|
||||
}
|
||||
break;
|
||||
if (VTf->regs->Flags & KV86M_EMULATE_CLI_STI)
|
||||
{
|
||||
Tf->Eip++;
|
||||
VTf->regs->Vif = 0;
|
||||
return(0);
|
||||
}
|
||||
Exit = TRUE;
|
||||
break;
|
||||
|
||||
/* pushf */
|
||||
case 0x9C:
|
||||
if (VTf->regs->Flags & KV86M_EMULATE_CLI_STI)
|
||||
{
|
||||
Tf->Eip++;
|
||||
if (!BigAddressPrefix)
|
||||
{
|
||||
Tf->Esp = Tf->Esp - 2;
|
||||
sp = sp - 1;
|
||||
sp[0] = Tf->Eflags & 0xFFFF;
|
||||
if (VTf->regs->Vif == 1)
|
||||
{
|
||||
sp[0] = sp[0] | INTERRUPT_FLAG;
|
||||
}
|
||||
else
|
||||
{
|
||||
sp[0] = sp[0] & (~INTERRUPT_FLAG);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Tf->Esp = Tf->Esp - 4;
|
||||
dsp = dsp - 1;
|
||||
dsp[0] = Tf->Eflags;
|
||||
dsp[0] = dsp[0] & VALID_FLAGS;
|
||||
if (VTf->regs->Vif == 1)
|
||||
{
|
||||
dsp[0] = dsp[0] | INTERRUPT_FLAG;
|
||||
}
|
||||
else
|
||||
{
|
||||
dsp[0] = dsp[0] & (~INTERRUPT_FLAG);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
Exit = TRUE;
|
||||
break;
|
||||
|
||||
/* popf */
|
||||
case 0x9D:
|
||||
if (VTf->regs->Flags & KV86M_EMULATE_CLI_STI)
|
||||
{
|
||||
Tf->Eip++;
|
||||
if (!BigAddressPrefix)
|
||||
{
|
||||
Tf->Eflags = Tf->Eflags & (~0xFFFF);
|
||||
Tf->Eflags = Tf->Eflags | (sp[0] & VALID_FLAGS);
|
||||
if (Tf->Eflags & INTERRUPT_FLAG)
|
||||
{
|
||||
VTf->regs->Vif = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
VTf->regs->Vif = 0;
|
||||
}
|
||||
Tf->Eflags = Tf->Eflags | INTERRUPT_FLAG;
|
||||
Tf->Esp = Tf->Esp + 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
Tf->Eflags = Tf->Eflags | (dsp[0] & VALID_FLAGS);
|
||||
if (dsp[0] & INTERRUPT_FLAG)
|
||||
{
|
||||
VTf->regs->Vif = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
VTf->regs->Vif = 0;
|
||||
}
|
||||
Tf->Eflags = Tf->Eflags | INTERRUPT_FLAG;
|
||||
Tf->Esp = Tf->Esp + 2;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
Exit = TRUE;
|
||||
break;
|
||||
|
||||
/* iret */
|
||||
case 0xCF:
|
||||
if (VTf->regs->Flags & KV86M_EMULATE_CLI_STI)
|
||||
{
|
||||
Tf->Eip = sp[0];
|
||||
Tf->Cs = sp[1];
|
||||
Tf->Eflags = Tf->Eflags & (~0xFFFF);
|
||||
Tf->Eflags = Tf->Eflags | sp[2];
|
||||
if (Tf->Eflags & INTERRUPT_FLAG)
|
||||
case 0xCF:
|
||||
if (VTf->regs->Flags & KV86M_EMULATE_CLI_STI)
|
||||
{
|
||||
VTf->regs->Vif = 1;
|
||||
Tf->Eip = sp[0];
|
||||
Tf->Cs = sp[1];
|
||||
Tf->Eflags = Tf->Eflags & (~0xFFFF);
|
||||
Tf->Eflags = Tf->Eflags | sp[2];
|
||||
if (Tf->Eflags & INTERRUPT_FLAG)
|
||||
{
|
||||
VTf->regs->Vif = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
VTf->regs->Vif = 0;
|
||||
}
|
||||
Tf->Eflags = Tf->Eflags & (~INTERRUPT_FLAG);
|
||||
Tf->Esp = Tf->Esp + 6;
|
||||
return(0);
|
||||
}
|
||||
else
|
||||
Exit = TRUE;
|
||||
break;
|
||||
|
||||
/* out imm8, al */
|
||||
case 0xE6:
|
||||
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
|
||||
{
|
||||
VTf->regs->Vif = 0;
|
||||
WRITE_PORT_UCHAR((PUCHAR)(ULONG)ip[1],
|
||||
Tf->Eax & 0xFF);
|
||||
Tf->Eip = Tf->Eip + 2;
|
||||
return(0);
|
||||
}
|
||||
Tf->Eflags = Tf->Eflags & (~INTERRUPT_FLAG);
|
||||
Tf->Esp = Tf->Esp + 6;
|
||||
return(0);
|
||||
}
|
||||
break;
|
||||
Exit = TRUE;
|
||||
break;
|
||||
|
||||
/* out imm8, al */
|
||||
case 0xE6:
|
||||
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
|
||||
{
|
||||
WRITE_PORT_UCHAR((PUCHAR)(ULONG)ip[1],
|
||||
Tf->Eax & 0xFF);
|
||||
Tf->Eip = Tf->Eip + 2;
|
||||
return(0);
|
||||
}
|
||||
break;
|
||||
/* out imm8, ax */
|
||||
case 0xE7:
|
||||
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
|
||||
{
|
||||
WRITE_PORT_USHORT((PUSHORT)(ULONG)ip[1], Tf->Eax & 0xFFFF);
|
||||
Tf->Eip = Tf->Eip + 2;
|
||||
return(0);
|
||||
}
|
||||
Exit = TRUE;
|
||||
break;
|
||||
|
||||
/* out imm8, ax */
|
||||
case 0xE7:
|
||||
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
|
||||
{
|
||||
WRITE_PORT_USHORT((PUSHORT)(ULONG)ip[1], Tf->Eax & 0xFFFF);
|
||||
Tf->Eip = Tf->Eip + 2;
|
||||
return(0);
|
||||
}
|
||||
break;
|
||||
/* out dx, al */
|
||||
case 0xEE:
|
||||
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
|
||||
{
|
||||
WRITE_PORT_UCHAR((PUCHAR)(Tf->Edx & 0xFFFF), Tf->Eax & 0xFF);
|
||||
Tf->Eip = Tf->Eip + 1;
|
||||
return(0);
|
||||
}
|
||||
Exit = TRUE;
|
||||
break;
|
||||
|
||||
/* out dx, al */
|
||||
case 0xEE:
|
||||
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
|
||||
{
|
||||
WRITE_PORT_UCHAR((PUCHAR)(Tf->Edx & 0xFFFF), Tf->Eax & 0xFF);
|
||||
Tf->Eip = Tf->Eip + 1;
|
||||
return(0);
|
||||
}
|
||||
break;
|
||||
/* out dx, ax */
|
||||
case 0xEF:
|
||||
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
|
||||
{
|
||||
WRITE_PORT_USHORT((PUSHORT)(Tf->Edx & 0xFFFF), Tf->Eax & 0xFFFF);
|
||||
Tf->Eip = Tf->Eip + 1;
|
||||
return(0);
|
||||
}
|
||||
Exit = TRUE;
|
||||
break;
|
||||
|
||||
/* out dx, ax */
|
||||
case 0xEF:
|
||||
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
|
||||
{
|
||||
WRITE_PORT_USHORT((PUSHORT)(Tf->Edx & 0xFFFF), Tf->Eax & 0xFFFF);
|
||||
Tf->Eip = Tf->Eip + 1;
|
||||
return(0);
|
||||
}
|
||||
break;
|
||||
/* in al, imm8 */
|
||||
case 0xE4:
|
||||
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
|
||||
{
|
||||
UCHAR v;
|
||||
|
||||
/* in al, imm8 */
|
||||
case 0xE4:
|
||||
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
|
||||
{
|
||||
UCHAR v;
|
||||
v = READ_PORT_UCHAR((PUCHAR)(ULONG)ip[1]);
|
||||
Tf->Eax = Tf->Eax & (~0xFF);
|
||||
Tf->Eax = Tf->Eax | v;
|
||||
Tf->Eip = Tf->Eip + 2;
|
||||
return(0);
|
||||
}
|
||||
Exit = TRUE;
|
||||
break;
|
||||
|
||||
v = READ_PORT_UCHAR((PUCHAR)(ULONG)ip[1]);
|
||||
Tf->Eax = Tf->Eax & (~0xFF);
|
||||
Tf->Eax = Tf->Eax | v;
|
||||
Tf->Eip = Tf->Eip + 2;
|
||||
return(0);
|
||||
}
|
||||
break;
|
||||
/* in ax, imm8 */
|
||||
case 0xE5:
|
||||
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
|
||||
{
|
||||
USHORT v;
|
||||
|
||||
/* in ax, imm8 */
|
||||
case 0xE5:
|
||||
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
|
||||
{
|
||||
USHORT v;
|
||||
v = READ_PORT_USHORT((PUSHORT)(ULONG)ip[1]);
|
||||
Tf->Eax = Tf->Eax & (~0xFFFF);
|
||||
Tf->Eax = Tf->Eax | v;
|
||||
Tf->Eip = Tf->Eip + 2;
|
||||
return(0);
|
||||
}
|
||||
Exit = TRUE;
|
||||
break;
|
||||
|
||||
v = READ_PORT_USHORT((PUSHORT)(ULONG)ip[1]);
|
||||
Tf->Eax = Tf->Eax & (~0xFFFF);
|
||||
Tf->Eax = Tf->Eax | v;
|
||||
Tf->Eip = Tf->Eip + 2;
|
||||
return(0);
|
||||
}
|
||||
break;
|
||||
/* in al, dx */
|
||||
case 0xEC:
|
||||
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
|
||||
{
|
||||
UCHAR v;
|
||||
|
||||
/* in al, dx */
|
||||
case 0xEC:
|
||||
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
|
||||
{
|
||||
UCHAR v;
|
||||
v = READ_PORT_UCHAR((PUCHAR)(Tf->Edx & 0xFFFF));
|
||||
Tf->Eax = Tf->Eax & (~0xFF);
|
||||
Tf->Eax = Tf->Eax | v;
|
||||
Tf->Eip = Tf->Eip + 1;
|
||||
return(0);
|
||||
}
|
||||
Exit = TRUE;
|
||||
break;
|
||||
|
||||
v = READ_PORT_UCHAR((PUCHAR)(Tf->Edx & 0xFFFF));
|
||||
Tf->Eax = Tf->Eax & (~0xFF);
|
||||
Tf->Eax = Tf->Eax | v;
|
||||
Tf->Eip = Tf->Eip + 1;
|
||||
return(0);
|
||||
}
|
||||
break;
|
||||
/* in ax, dx */
|
||||
case 0xED:
|
||||
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
|
||||
{
|
||||
USHORT v;
|
||||
|
||||
/* in ax, dx */
|
||||
case 0xED:
|
||||
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
|
||||
{
|
||||
USHORT v;
|
||||
v = READ_PORT_USHORT((PUSHORT)(Tf->Edx & 0xFFFF));
|
||||
Tf->Eax = Tf->Eax & (~0xFFFF);
|
||||
Tf->Eax = Tf->Eax | v;
|
||||
Tf->Eip = Tf->Eip + 1;
|
||||
return(0);
|
||||
}
|
||||
Exit = TRUE;
|
||||
break;
|
||||
|
||||
v = READ_PORT_USHORT((PUSHORT)(Tf->Edx & 0xFFFF));
|
||||
Tf->Eax = Tf->Eax & (~0xFFFF);
|
||||
Tf->Eax = Tf->Eax | v;
|
||||
Tf->Eip = Tf->Eip + 1;
|
||||
return(0);
|
||||
}
|
||||
break;
|
||||
/* insb */
|
||||
case 0x6C:
|
||||
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
|
||||
{
|
||||
|
||||
/* Int nn */
|
||||
case 0xCD:
|
||||
{
|
||||
unsigned int inum;
|
||||
unsigned int entry;
|
||||
}
|
||||
Exit = TRUE;
|
||||
break;
|
||||
|
||||
inum = ip[1];
|
||||
entry = ((unsigned int *)0)[inum];
|
||||
|
||||
Tf->Esp = Tf->Esp - 6;
|
||||
sp = sp - 3;
|
||||
|
||||
sp[0] = (Tf->Eip & 0xFFFF) + 2;
|
||||
sp[1] = Tf->Cs & 0xFFFF;
|
||||
sp[2] = Tf->Eflags & 0xFFFF;
|
||||
if (VTf->regs->Vif == 1)
|
||||
/* Int nn */
|
||||
case 0xCD:
|
||||
{
|
||||
sp[2] = sp[2] | INTERRUPT_FLAG;
|
||||
}
|
||||
DPRINT("sp[0] %x sp[1] %x sp[2] %x\n", sp[0], sp[1], sp[2]);
|
||||
Tf->Eip = entry & 0xFFFF;
|
||||
Tf->Cs = entry >> 16;
|
||||
Tf->Eflags = Tf->Eflags & (~TRAP_FLAG);
|
||||
unsigned int inum;
|
||||
unsigned int entry;
|
||||
|
||||
return(0);
|
||||
}
|
||||
inum = ip[1];
|
||||
entry = ((unsigned int *)0)[inum];
|
||||
|
||||
Tf->Esp = Tf->Esp - 6;
|
||||
sp = sp - 3;
|
||||
|
||||
sp[0] = (Tf->Eip & 0xFFFF) + 2;
|
||||
sp[1] = Tf->Cs & 0xFFFF;
|
||||
sp[2] = Tf->Eflags & 0xFFFF;
|
||||
if (VTf->regs->Vif == 1)
|
||||
{
|
||||
sp[2] = sp[2] | INTERRUPT_FLAG;
|
||||
}
|
||||
DPRINT("sp[0] %x sp[1] %x sp[2] %x\n", sp[0], sp[1], sp[2]);
|
||||
Tf->Eip = entry & 0xFFFF;
|
||||
Tf->Cs = entry >> 16;
|
||||
Tf->Eflags = Tf->Eflags & (~TRAP_FLAG);
|
||||
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: Also emulate ins and outs */
|
||||
/* FIXME: Handle opcode prefixes */
|
||||
|
@ -406,3 +502,5 @@ KeV86Exception(ULONG ExceptionNr, PKTRAP_FRAME Tf, ULONG address)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue