[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:
Aleksandar Andrejevic 2013-11-15 02:32:08 +00:00
parent 5e54387a9c
commit bbc9efd2d9
5 changed files with 32 additions and 21 deletions

View file

@ -394,6 +394,7 @@ struct _FAST486_STATE
FAST486_REG InstPtr, SavedInstPtr; FAST486_REG InstPtr, SavedInstPtr;
FAST486_FLAGS_REG Flags; FAST486_FLAGS_REG Flags;
FAST486_TABLE_REG Gdtr, Idtr, Ldtr, Tss; FAST486_TABLE_REG Gdtr, Idtr, Ldtr, Tss;
UCHAR Cpl;
ULONG ControlRegisters[FAST486_NUM_CTRL_REGS]; ULONG ControlRegisters[FAST486_NUM_CTRL_REGS];
ULONG DebugRegisters[FAST486_NUM_DBG_REGS]; ULONG DebugRegisters[FAST486_NUM_DBG_REGS];
ULONG ExceptionCount; ULONG ExceptionCount;

View file

@ -65,7 +65,8 @@ Fast486ReadMemory(PFAST486_STATE State,
return FALSE; 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); Fast486Exception(State, FAST486_EXCEPTION_GP);
return FALSE; return FALSE;
@ -132,7 +133,8 @@ Fast486WriteMemory(PFAST486_STATE State,
return FALSE; 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); Fast486Exception(State, FAST486_EXCEPTION_GP);
return FALSE; return FALSE;
@ -330,8 +332,18 @@ Fast486ExceptionWithErrorCode(PFAST486_STATE State,
&& (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE)) && (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE))
{ {
/* Push the error code */ /* 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 */ /* EOF */

View file

@ -27,16 +27,8 @@ FORCEINLINE
INT INT
Fast486GetCurrentPrivLevel(PFAST486_STATE State) Fast486GetCurrentPrivLevel(PFAST486_STATE State)
{ {
if (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE) /* Return the CPL, or 3 if we're in virtual 8086 mode */
{ return (!State->Flags.Vm) ? State->Cpl : 3;
/* 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;
}
} }
FORCEINLINE FORCEINLINE
@ -464,7 +456,10 @@ Fast486LoadSegment(PFAST486_STATE State,
else if (Segment == FAST486_REG_CS) else if (Segment == FAST486_REG_CS)
{ {
/* Loading the code segment */ /* Loading the code segment */
// TODO: NOT IMPLEMENTED // TODO: Implement security checks, call gates, etc...
/* Update CPL */
State->Cpl = GET_SEGMENT_RPL(Selector);
} }
else else
{ {
@ -478,7 +473,7 @@ Fast486LoadSegment(PFAST486_STATE State,
} }
if ((GET_SEGMENT_RPL(Selector) > GdtEntry.Dpl) if ((GET_SEGMENT_RPL(Selector) > GdtEntry.Dpl)
&& (Fast486GetCurrentPrivLevel(State) > GdtEntry.Dpl)) || (Fast486GetCurrentPrivLevel(State) > GdtEntry.Dpl))
{ {
Fast486Exception(State, FAST486_EXCEPTION_GP); Fast486Exception(State, FAST486_EXCEPTION_GP);
return FALSE; return FALSE;

View file

@ -239,6 +239,9 @@ Fast486Reset(PFAST486_STATE State)
State->Flags.AlwaysSet = 1; State->Flags.AlwaysSet = 1;
State->InstPtr.LowWord = 0xFFF0; State->InstPtr.LowWord = 0xFFF0;
/* Set the CPL to 0 */
State->Cpl = 0;
/* Initialize segments */ /* Initialize segments */
for (i = 0; i < FAST486_NUM_SEG_REGS; i++) for (i = 0; i < FAST486_NUM_SEG_REGS; i++)
{ {

View file

@ -1668,6 +1668,12 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeGroup0F01)
NO_LOCK_PREFIX(); NO_LOCK_PREFIX();
TOGGLE_ADSIZE(AddressSize); TOGGLE_ADSIZE(AddressSize);
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
return FALSE;
}
/* Check for the segment override */ /* Check for the segment override */
if (State->PrefixFlags & FAST486_PREFIX_SEG) if (State->PrefixFlags & FAST486_PREFIX_SEG)
{ {
@ -1675,12 +1681,6 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeGroup0F01)
Segment = State->SegmentOverride; Segment = State->SegmentOverride;
} }
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
{
/* Exception occurred */
return FALSE;
}
/* Check which operation this is */ /* Check which operation this is */
switch (ModRegRm.Register) switch (ModRegRm.Register)
{ {