mirror of
https://github.com/reactos/reactos.git
synced 2025-04-18 03:34:11 +00:00
[FAST486]
- Fix the privilege checks. - Store the CPL in a special field, so that it doesn't get mixed up with the lowest 2 bits of real mode selectors while switching into protected mode. - Reset the exception count after a successful ISR call. - In Fast486OpcodeGroup0F01, check for prefix overrides after parsing the Mod-Reg-R/M, which might add a SS: prefix override in some cases. svn path=/branches/ntvdm/; revision=60995
This commit is contained in:
parent
5e54387a9c
commit
bbc9efd2d9
5 changed files with 32 additions and 21 deletions
|
@ -394,6 +394,7 @@ struct _FAST486_STATE
|
|||
FAST486_REG InstPtr, SavedInstPtr;
|
||||
FAST486_FLAGS_REG Flags;
|
||||
FAST486_TABLE_REG Gdtr, Idtr, Ldtr, Tss;
|
||||
UCHAR Cpl;
|
||||
ULONG ControlRegisters[FAST486_NUM_CTRL_REGS];
|
||||
ULONG DebugRegisters[FAST486_NUM_DBG_REGS];
|
||||
ULONG ExceptionCount;
|
||||
|
|
|
@ -65,7 +65,8 @@ Fast486ReadMemory(PFAST486_STATE State,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (GET_SEGMENT_RPL(CachedDescriptor->Selector) > CachedDescriptor->Dpl)
|
||||
if ((!InstFetch && (GET_SEGMENT_RPL(CachedDescriptor->Selector) > CachedDescriptor->Dpl))
|
||||
|| (Fast486GetCurrentPrivLevel(State) > CachedDescriptor->Dpl))
|
||||
{
|
||||
Fast486Exception(State, FAST486_EXCEPTION_GP);
|
||||
return FALSE;
|
||||
|
@ -132,7 +133,8 @@ Fast486WriteMemory(PFAST486_STATE State,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (GET_SEGMENT_RPL(CachedDescriptor->Selector) > CachedDescriptor->Dpl)
|
||||
if ((GET_SEGMENT_RPL(CachedDescriptor->Selector) > CachedDescriptor->Dpl)
|
||||
|| (Fast486GetCurrentPrivLevel(State) > CachedDescriptor->Dpl))
|
||||
{
|
||||
Fast486Exception(State, FAST486_EXCEPTION_GP);
|
||||
return FALSE;
|
||||
|
@ -330,8 +332,18 @@ Fast486ExceptionWithErrorCode(PFAST486_STATE State,
|
|||
&& (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE))
|
||||
{
|
||||
/* Push the error code */
|
||||
Fast486StackPush(State, ErrorCode);
|
||||
if (!Fast486StackPush(State, ErrorCode))
|
||||
{
|
||||
/*
|
||||
* If this function failed, that means Fast486Exception
|
||||
* was called again, so just return in this case.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset the exception count */
|
||||
State->ExceptionCount = 0;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -27,16 +27,8 @@ FORCEINLINE
|
|||
INT
|
||||
Fast486GetCurrentPrivLevel(PFAST486_STATE State)
|
||||
{
|
||||
if (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE)
|
||||
{
|
||||
/* In protected mode, return the RPL of the CS */
|
||||
return GET_SEGMENT_RPL(State->SegmentRegs[FAST486_REG_CS].Selector);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Real mode is always in supervisor mode */
|
||||
return 0;
|
||||
}
|
||||
/* Return the CPL, or 3 if we're in virtual 8086 mode */
|
||||
return (!State->Flags.Vm) ? State->Cpl : 3;
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
|
@ -464,7 +456,10 @@ Fast486LoadSegment(PFAST486_STATE State,
|
|||
else if (Segment == FAST486_REG_CS)
|
||||
{
|
||||
/* Loading the code segment */
|
||||
// TODO: NOT IMPLEMENTED
|
||||
// TODO: Implement security checks, call gates, etc...
|
||||
|
||||
/* Update CPL */
|
||||
State->Cpl = GET_SEGMENT_RPL(Selector);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -478,7 +473,7 @@ Fast486LoadSegment(PFAST486_STATE State,
|
|||
}
|
||||
|
||||
if ((GET_SEGMENT_RPL(Selector) > GdtEntry.Dpl)
|
||||
&& (Fast486GetCurrentPrivLevel(State) > GdtEntry.Dpl))
|
||||
|| (Fast486GetCurrentPrivLevel(State) > GdtEntry.Dpl))
|
||||
{
|
||||
Fast486Exception(State, FAST486_EXCEPTION_GP);
|
||||
return FALSE;
|
||||
|
|
|
@ -239,6 +239,9 @@ Fast486Reset(PFAST486_STATE State)
|
|||
State->Flags.AlwaysSet = 1;
|
||||
State->InstPtr.LowWord = 0xFFF0;
|
||||
|
||||
/* Set the CPL to 0 */
|
||||
State->Cpl = 0;
|
||||
|
||||
/* Initialize segments */
|
||||
for (i = 0; i < FAST486_NUM_SEG_REGS; i++)
|
||||
{
|
||||
|
|
|
@ -1668,6 +1668,12 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeGroup0F01)
|
|||
NO_LOCK_PREFIX();
|
||||
TOGGLE_ADSIZE(AddressSize);
|
||||
|
||||
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Check for the segment override */
|
||||
if (State->PrefixFlags & FAST486_PREFIX_SEG)
|
||||
{
|
||||
|
@ -1675,12 +1681,6 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeGroup0F01)
|
|||
Segment = State->SegmentOverride;
|
||||
}
|
||||
|
||||
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Check which operation this is */
|
||||
switch (ModRegRm.Register)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue