ReactOS  0.4.14-dev-98-gb0d4763
common.h File Reference
#include <pshpack1.h>
#include <poppack.h>
#include "common.inl"
Include dependency graph for common.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _FAST486_MOD_REG_RM
 
union  _FAST486_PAGE_DIR
 
union  _FAST486_PAGE_TABLE
 

Macros

#define SIGN_FLAG_BYTE   0x80
 
#define SIGN_FLAG_WORD   0x8000
 
#define SIGN_FLAG_LONG   0x80000000
 
#define REAL_MODE_FLAGS_MASK   0x57FD5
 
#define PROT_MODE_FLAGS_MASK   0x50DD5
 
#define STRING_BLOCK_SIZE   4096
 
#define GET_SEGMENT_RPL(s)   ((s) & 3u)
 
#define GET_SEGMENT_INDEX(s)   ((s) & 0xFFF8u)
 
#define SEGMENT_TABLE_INDICATOR   (1 << 2)
 
#define EXCEPTION_HAS_ERROR_CODE(x)   (((x) == 8) || ((x) >= 10 && (x) <= 14))
 
#define NO_LOCK_PREFIX()
 
#define TOGGLE_OPSIZE(x)   if (State->PrefixFlags & FAST486_PREFIX_OPSIZE) x = !x;
 
#define TOGGLE_ADSIZE(x)   if (State->PrefixFlags & FAST486_PREFIX_ADSIZE) x = !x;
 
#define SWAP(x, y)   { (x) ^= (y); (y) ^= (x); (x) ^= (y); }
 
#define ALIGNMENT_CHECK(x, a)
 
#define PAGE_ALIGN(x)   ((x) & 0xFFFFF000)
 
#define PAGE_OFFSET(x)   ((x) & 0x00000FFF)
 
#define GET_ADDR_PDE(x)   ((x) >> 22)
 
#define GET_ADDR_PTE(x)   (((x) >> 12) & 0x3FF)
 
#define INVALID_TLB_FIELD   0xFFFFFFFF
 
#define NUM_TLB_ENTRIES   0x100000
 

Typedefs

typedef struct _FAST486_MOD_REG_RM FAST486_MOD_REG_RM
 
typedef struct _FAST486_MOD_REG_RMPFAST486_MOD_REG_RM
 
typedef enum _FAST486_TASK_SWITCH_TYPE FAST486_TASK_SWITCH_TYPE
 
typedef enum _FAST486_TASK_SWITCH_TYPEPFAST486_TASK_SWITCH_TYPE
 
typedef union _FAST486_PAGE_DIR FAST486_PAGE_DIR
 
typedef union _FAST486_PAGE_DIRPFAST486_PAGE_DIR
 
typedef union _FAST486_PAGE_TABLE FAST486_PAGE_TABLE
 
typedef union _FAST486_PAGE_TABLEPFAST486_PAGE_TABLE
 

Enumerations

enum  _FAST486_TASK_SWITCH_TYPE { FAST486_TASK_JUMP, FAST486_TASK_CALL, FAST486_TASK_RETURN }
 

Functions

 C_ASSERT (sizeof(FAST486_PAGE_DIR)==sizeof(ULONG))
 
BOOLEAN FASTCALL Fast486ReadMemory (PFAST486_STATE State, FAST486_SEG_REGS SegmentReg, ULONG Offset, BOOLEAN InstFetch, PVOID Buffer, ULONG Size)
 
BOOLEAN FASTCALL Fast486WriteMemory (PFAST486_STATE State, FAST486_SEG_REGS SegmentReg, ULONG Offset, PVOID Buffer, ULONG Size)
 
BOOLEAN FASTCALL Fast486PerformInterrupt (PFAST486_STATE State, UCHAR Number)
 
VOID FASTCALL Fast486ExceptionWithErrorCode (PFAST486_STATE State, FAST486_EXCEPTIONS ExceptionCode, ULONG ErrorCode)
 
BOOLEAN FASTCALL Fast486TaskSwitch (PFAST486_STATE State, FAST486_TASK_SWITCH_TYPE Type, USHORT Selector)
 
BOOLEAN FASTCALL Fast486CallGate (PFAST486_STATE State, PFAST486_CALL_GATE Gate, BOOLEAN Call)
 

Macro Definition Documentation

◆ ALIGNMENT_CHECK

#define ALIGNMENT_CHECK (   x,
  a 
)
Value:
if (State->Flags.Ac \
&& (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_AM)\
&& (State->Cpl == 3)\
&& (((x) % (a)) != 0))\
{\
Fast486Exception(State, FAST486_EXCEPTION_AC);\
return FALSE;\
}
#define FAST486_CR0_AM
Definition: fast486.h:53
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204

Definition at line 58 of file common.h.

◆ EXCEPTION_HAS_ERROR_CODE

#define EXCEPTION_HAS_ERROR_CODE (   x)    (((x) == 8) || ((x) >= 10 && (x) <= 14))

Definition at line 41 of file common.h.

◆ GET_ADDR_PDE

#define GET_ADDR_PDE (   x)    ((x) >> 22)

Definition at line 69 of file common.h.

◆ GET_ADDR_PTE

#define GET_ADDR_PTE (   x)    (((x) >> 12) & 0x3FF)

Definition at line 70 of file common.h.

◆ GET_SEGMENT_INDEX

#define GET_SEGMENT_INDEX (   s)    ((s) & 0xFFF8u)

Definition at line 39 of file common.h.

◆ GET_SEGMENT_RPL

#define GET_SEGMENT_RPL (   s)    ((s) & 3u)

Definition at line 38 of file common.h.

◆ INVALID_TLB_FIELD

#define INVALID_TLB_FIELD   0xFFFFFFFF

Definition at line 71 of file common.h.

◆ NO_LOCK_PREFIX

#define NO_LOCK_PREFIX ( )
Value:
if (State->PrefixFlags & FAST486_PREFIX_LOCK)\
{\
Fast486Exception(State, FAST486_EXCEPTION_UD);\
return;\
}
#define FAST486_PREFIX_LOCK
Definition: fast486.h:101

Definition at line 43 of file common.h.

◆ NUM_TLB_ENTRIES

#define NUM_TLB_ENTRIES   0x100000

Definition at line 72 of file common.h.

◆ PAGE_ALIGN

#define PAGE_ALIGN (   x)    ((x) & 0xFFFFF000)

Definition at line 67 of file common.h.

◆ PAGE_OFFSET

#define PAGE_OFFSET (   x)    ((x) & 0x00000FFF)

Definition at line 68 of file common.h.

◆ PROT_MODE_FLAGS_MASK

#define PROT_MODE_FLAGS_MASK   0x50DD5

Definition at line 33 of file common.h.

◆ REAL_MODE_FLAGS_MASK

#define REAL_MODE_FLAGS_MASK   0x57FD5

Definition at line 32 of file common.h.

◆ SEGMENT_TABLE_INDICATOR

#define SEGMENT_TABLE_INDICATOR   (1 << 2)

Definition at line 40 of file common.h.

◆ SIGN_FLAG_BYTE

#define SIGN_FLAG_BYTE   0x80

Definition at line 29 of file common.h.

◆ SIGN_FLAG_LONG

#define SIGN_FLAG_LONG   0x80000000

Definition at line 31 of file common.h.

◆ SIGN_FLAG_WORD

#define SIGN_FLAG_WORD   0x8000

Definition at line 30 of file common.h.

◆ STRING_BLOCK_SIZE

#define STRING_BLOCK_SIZE   4096

Definition at line 36 of file common.h.

◆ SWAP

#define SWAP (   x,
  y 
)    { (x) ^= (y); (y) ^= (x); (x) ^= (y); }

Definition at line 56 of file common.h.

◆ TOGGLE_ADSIZE

#define TOGGLE_ADSIZE (   x)    if (State->PrefixFlags & FAST486_PREFIX_ADSIZE) x = !x;

Definition at line 53 of file common.h.

◆ TOGGLE_OPSIZE

#define TOGGLE_OPSIZE (   x)    if (State->PrefixFlags & FAST486_PREFIX_OPSIZE) x = !x;

Definition at line 50 of file common.h.

Typedef Documentation

◆ FAST486_MOD_REG_RM

◆ FAST486_PAGE_DIR

◆ FAST486_PAGE_TABLE

◆ FAST486_TASK_SWITCH_TYPE

◆ PFAST486_MOD_REG_RM

◆ PFAST486_PAGE_DIR

◆ PFAST486_PAGE_TABLE

◆ PFAST486_TASK_SWITCH_TYPE

Enumeration Type Documentation

◆ _FAST486_TASK_SWITCH_TYPE

Enumerator
FAST486_TASK_JUMP 
FAST486_TASK_CALL 
FAST486_TASK_RETURN 

Definition at line 85 of file common.h.

86 {
enum _FAST486_TASK_SWITCH_TYPE FAST486_TASK_SWITCH_TYPE
enum _FAST486_TASK_SWITCH_TYPE * PFAST486_TASK_SWITCH_TYPE

Function Documentation

◆ C_ASSERT()

C_ASSERT ( sizeof(FAST486_PAGE_DIR = =sizeof(ULONG))

◆ Fast486CallGate()

BOOLEAN FASTCALL Fast486CallGate ( PFAST486_STATE  State,
PFAST486_CALL_GATE  Gate,
BOOLEAN  Call 
)

Definition at line 1116 of file common.c.

1119 {
1120  BOOLEAN Valid;
1121  FAST486_GDT_ENTRY NewCodeSegment;
1122  BOOLEAN GateSize = (Gate->Type == FAST486_CALL_GATE_SIGNATURE);
1123  FAST486_TSS Tss;
1124  PFAST486_LEGACY_TSS LegacyTss = (PFAST486_LEGACY_TSS)&Tss;
1125  USHORT OldCs = State->SegmentRegs[FAST486_REG_CS].Selector;
1126  ULONG OldEip = State->InstPtr.Long;
1127  USHORT OldCpl = State->Cpl;
1128  USHORT OldSs = State->SegmentRegs[FAST486_REG_SS].Selector;
1129  ULONG OldEsp = State->GeneralRegs[FAST486_REG_ESP].Long;
1130  ULONG ParamBuffer[32]; /* Maximum possible size - 32 DWORDs */
1131  PULONG LongParams = (PULONG)ParamBuffer;
1132  PUSHORT ShortParams = (PUSHORT)ParamBuffer;
1133 
1134  if (!Gate->Selector)
1135  {
1136  /* The code segment is NULL */
1137  Fast486Exception(State, FAST486_EXCEPTION_GP);
1138  return FALSE;
1139  }
1140 
1141  if (!Fast486ReadDescriptorEntry(State, Gate->Selector, &Valid, &NewCodeSegment))
1142  {
1143  /* Exception occurred */
1144  return FALSE;
1145  }
1146 
1147  if (!Valid || (NewCodeSegment.Dpl > Fast486GetCurrentPrivLevel(State)))
1148  {
1149  /* Code segment invalid */
1150  Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Gate->Selector);
1151  return FALSE;
1152  }
1153 
1154  if (Call && Gate->ParamCount)
1155  {
1156  /* Read the parameters */
1157  if (!Fast486ReadMemory(State,
1158  FAST486_REG_SS,
1159  OldEsp,
1160  FALSE,
1161  ParamBuffer,
1162  Gate->ParamCount * (GateSize ? sizeof(ULONG) : sizeof(USHORT))))
1163  {
1164  /* Exception occurred */
1165  return FALSE;
1166  }
1167  }
1168 
1169  /* Check if the new code segment is more privileged */
1170  if (NewCodeSegment.Dpl < OldCpl)
1171  {
1172  if (Call)
1173  {
1174  USHORT NewSs;
1175  ULONG NewEsp;
1176 
1177  /* Read the TSS */
1178  if (!Fast486ReadLinearMemory(State,
1179  State->TaskReg.Base,
1180  &Tss,
1181  State->TaskReg.Modern
1182  ? sizeof(FAST486_TSS) : sizeof(FAST486_LEGACY_TSS),
1183  FALSE))
1184  {
1185  /* Exception occurred */
1186  return FALSE;
1187  }
1188 
1189  /* Switch to the new privilege level */
1190  State->Cpl = NewCodeSegment.Dpl;
1191 
1192  /* Check the new (higher) privilege level */
1193  switch (State->Cpl)
1194  {
1195  case 0:
1196  {
1197  if (State->TaskReg.Modern)
1198  {
1199  NewSs = Tss.Ss0;
1200  NewEsp = Tss.Esp0;
1201  }
1202  else
1203  {
1204  NewSs = LegacyTss->Ss0;
1205  NewEsp = LegacyTss->Sp0;
1206  }
1207 
1208  break;
1209  }
1210 
1211  case 1:
1212  {
1213  if (State->TaskReg.Modern)
1214  {
1215  NewSs = Tss.Ss1;
1216  NewEsp = Tss.Esp1;
1217  }
1218  else
1219  {
1220  NewSs = LegacyTss->Ss1;
1221  NewEsp = LegacyTss->Sp1;
1222  }
1223 
1224  break;
1225  }
1226 
1227  case 2:
1228  {
1229  if (State->TaskReg.Modern)
1230  {
1231  NewSs = Tss.Ss2;
1232  NewEsp = Tss.Esp2;
1233  }
1234  else
1235  {
1236  NewSs = LegacyTss->Ss2;
1237  NewEsp = LegacyTss->Sp2;
1238  }
1239 
1240  break;
1241  }
1242 
1243  default:
1244  {
1245  /* Should never reach here! */
1246  ASSERT(FALSE);
1247  }
1248  }
1249 
1250  if (!Fast486LoadSegment(State, FAST486_REG_SS, NewSs))
1251  {
1252  /* Exception occurred */
1253  return FALSE;
1254  }
1255 
1256  State->GeneralRegs[FAST486_REG_ESP].Long = NewEsp;
1257  }
1258  else if (!NewCodeSegment.DirConf)
1259  {
1260  /* This is not allowed for jumps */
1261  Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Gate->Selector);
1262  return FALSE;
1263  }
1264  }
1265 
1266  /* Load new CS */
1267  if (!Fast486LoadSegment(State, FAST486_REG_CS, Gate->Selector))
1268  {
1269  /* An exception occurred during the jump */
1270  return FALSE;
1271  }
1272 
1273  /* Set the instruction pointer */
1274  if (GateSize) State->InstPtr.Long = MAKELONG(Gate->Offset, Gate->OffsetHigh);
1275  else State->InstPtr.Long = Gate->Offset;
1276 
1277  if (Call)
1278  {
1279  INT i;
1280 
1281  /* Check if the new code segment is more privileged (again) */
1282  if (NewCodeSegment.Dpl < OldCpl)
1283  {
1284  /* Push SS selector */
1285  if (!Fast486StackPushInternal(State, GateSize, OldSs)) return FALSE;
1286 
1287  /* Push stack pointer */
1288  if (!Fast486StackPushInternal(State, GateSize, OldEsp)) return FALSE;
1289  }
1290 
1291  /* Push the parameters in reverse order */
1292  for (i = Gate->ParamCount - 1; i >= 0; i--)
1293  {
1294  if (!Fast486StackPushInternal(State,
1295  GateSize,
1296  GateSize ? LongParams[i] : ShortParams[i]))
1297  {
1298  /* Exception occurred */
1299  return FALSE;
1300  }
1301  }
1302 
1303  /* Push CS selector */
1304  if (!Fast486StackPushInternal(State, GateSize, OldCs)) return FALSE;
1305 
1306  /* Push the instruction pointer */
1307  if (!Fast486StackPushInternal(State, GateSize, OldEip)) return FALSE;
1308  }
1309 
1310  return TRUE;
1311 }
#define TRUE
Definition: types.h:120
int32_t INT
Definition: typedefs.h:56
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define MAKELONG(a, b)
Definition: typedefs.h:248
unsigned char BOOLEAN
#define FAST486_CALL_GATE_SIGNATURE
Definition: fast486.h:94
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
BOOLEAN FASTCALL Fast486ReadMemory(PFAST486_STATE State, FAST486_SEG_REGS SegmentReg, ULONG Offset, BOOLEAN InstFetch, PVOID Buffer, ULONG Size)
Definition: common.c:36
unsigned short USHORT
Definition: pedump.c:61
unsigned int * PULONG
Definition: retypes.h:1
VOID FASTCALL Fast486ExceptionWithErrorCode(PFAST486_STATE State, FAST486_EXCEPTIONS ExceptionCode, ULONG ErrorCode)
Definition: common.c:557
unsigned int ULONG
Definition: retypes.h:1
unsigned short * PUSHORT
Definition: retypes.h:2

◆ Fast486ExceptionWithErrorCode()

VOID FASTCALL Fast486ExceptionWithErrorCode ( PFAST486_STATE  State,
FAST486_EXCEPTIONS  ExceptionCode,
ULONG  ErrorCode 
)

Definition at line 557 of file common.c.

560 {
561  FAST486_IDT_ENTRY IdtEntry;
562 
563  /* Increment the exception count */
564  State->ExceptionCount++;
565 
566  /* Check if the exception occurred more than once */
567  if (State->ExceptionCount > 1)
568  {
569  /* Then this is a double fault */
570  ExceptionCode = FAST486_EXCEPTION_DF;
571  }
572 
573  /* Check if this is a triple fault */
574  if (State->ExceptionCount == 3)
575  {
576  DPRINT("Fast486ExceptionWithErrorCode(%04X:%08X) -- Triple fault\n",
577  State->SegmentRegs[FAST486_REG_CS].Selector,
578  State->InstPtr.Long);
579 
580  /* Reset the CPU */
582  return;
583  }
584 
585  /* Clear the prefix flags */
586  State->PrefixFlags = 0;
587 
588  /* Restore the IP to the saved IP */
589  State->InstPtr = State->SavedInstPtr;
590 
591  /* Restore the SP to the saved SP */
592  State->GeneralRegs[FAST486_REG_ESP] = State->SavedStackPtr;
593 
594  /* Get the interrupt vector */
596  {
597  /*
598  * If this function failed, that means Fast486Exception
599  * was called again, so just return in this case.
600  */
601  return;
602  }
603 
604  /* Perform the interrupt */
606  &IdtEntry,
608  && (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE),
609  ErrorCode))
610  {
611  /*
612  * If this function failed, that means Fast486Exception
613  * was called again, so just return in this case.
614  */
615  return;
616  }
617 
618  /* Reset the exception count */
619  State->ExceptionCount = 0;
620 }
_Inout_ PIRP _In_ NTSTATUS ExceptionCode
Definition: cdprocs.h:1782
_In_ NDIS_ERROR_CODE ErrorCode
Definition: ndis.h:4436
#define FAST486_CR0_PE
Definition: fast486.h:46
static BOOLEAN FASTCALL Fast486GetIntVector(PFAST486_STATE State, UCHAR Number, PFAST486_IDT_ENTRY IdtEntry)
Definition: common.c:251
void DPRINT(...)
Definition: polytest.cpp:61
Definition: hooks.h:42
VOID NTAPI Fast486Reset(PFAST486_STATE State)
Definition: fast486.c:131
static BOOLEAN FASTCALL Fast486InterruptInternal(PFAST486_STATE State, PFAST486_IDT_ENTRY IdtEntry, BOOLEAN PushErrorCode, ULONG ErrorCode)
Definition: common.c:298
#define EXCEPTION_HAS_ERROR_CODE(x)
Definition: common.h:41

Referenced by FAST486_OPCODE_HANDLER(), Fast486CallGate(), and Fast486TaskSwitch().

◆ Fast486PerformInterrupt()

BOOLEAN FASTCALL Fast486PerformInterrupt ( PFAST486_STATE  State,
UCHAR  Number 
)

Definition at line 533 of file common.c.

535 {
536  FAST486_IDT_ENTRY IdtEntry;
537 
538  /* Get the interrupt vector */
540  {
541  /* Exception occurred */
542  return FALSE;
543  }
544 
545  /* Perform the interrupt */
547  {
548  /* Exception occurred */
549  return FALSE;
550  }
551 
552  return TRUE;
553 }
#define TRUE
Definition: types.h:120
static BOOLEAN FASTCALL Fast486GetIntVector(PFAST486_STATE State, UCHAR Number, PFAST486_IDT_ENTRY IdtEntry)
Definition: common.c:251
Definition: hooks.h:42
_In_opt_ PENTER_STATE_SYSTEM_HANDLER _In_opt_ PVOID _In_ LONG _In_opt_ LONG volatile * Number
Definition: ntpoapi.h:204
static BOOLEAN FASTCALL Fast486InterruptInternal(PFAST486_STATE State, PFAST486_IDT_ENTRY IdtEntry, BOOLEAN PushErrorCode, ULONG ErrorCode)
Definition: common.c:298

Referenced by FAST486_OPCODE_HANDLER(), and Fast486ExecutionControl().

◆ Fast486ReadMemory()

BOOLEAN FASTCALL Fast486ReadMemory ( PFAST486_STATE  State,
FAST486_SEG_REGS  SegmentReg,
ULONG  Offset,
BOOLEAN  InstFetch,
PVOID  Buffer,
ULONG  Size 
)

Definition at line 36 of file common.c.

42 {
43  ULONG LinearAddress;
44  PFAST486_SEG_REG CachedDescriptor;
45  FAST486_EXCEPTIONS Exception = SegmentReg != FAST486_REG_SS
46  ? FAST486_EXCEPTION_GP : FAST486_EXCEPTION_SS;
47 
48  ASSERT(SegmentReg < FAST486_NUM_SEG_REGS);
49 
50  /* Get the cached descriptor */
51  CachedDescriptor = &State->SegmentRegs[SegmentReg];
52 
53  if (InstFetch || CachedDescriptor->Executable || !CachedDescriptor->DirConf)
54  {
55  if ((Offset + Size - 1) > CachedDescriptor->Limit)
56  {
57  /* Read beyond limit */
58  Fast486Exception(State, Exception);
59  return FALSE;
60  }
61  }
62  else
63  {
65  {
66  /* Read beyond limit */
67  Fast486Exception(State, Exception);
68  return FALSE;
69  }
70  }
71 
72  /* Check for protected mode */
73  if ((State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE) && !State->Flags.Vm)
74  {
75  /* Privilege checks */
76 
77  if (!CachedDescriptor->Present)
78  {
79  Fast486Exception(State, Exception);
80  return FALSE;
81  }
82 
83  if ((!InstFetch && (CachedDescriptor->Rpl > CachedDescriptor->Dpl))
84  || (Fast486GetCurrentPrivLevel(State) > CachedDescriptor->Dpl))
85  {
86  Fast486Exception(State, Exception);
87  return FALSE;
88  }
89 
90  if (InstFetch)
91  {
92  if (!CachedDescriptor->Executable)
93  {
94  /* Data segment not executable */
95  Fast486Exception(State, Exception);
96  return FALSE;
97  }
98  }
99  else
100  {
101  if (CachedDescriptor->Executable && (!CachedDescriptor->ReadWrite))
102  {
103  /* Code segment not readable */
104  Fast486Exception(State, Exception);
105  return FALSE;
106  }
107  }
108  }
109 
110  /* Find the linear address */
111  LinearAddress = CachedDescriptor->Base + Offset;
112 
113 #ifndef FAST486_NO_PREFETCH
114  if (InstFetch && ((Offset + FAST486_CACHE_SIZE - 1) <= CachedDescriptor->Limit))
115  {
116  State->PrefetchAddress = LinearAddress;
117 
118  if ((State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PG)
119  && (PAGE_OFFSET(State->PrefetchAddress) > (FAST486_PAGE_SIZE - FAST486_CACHE_SIZE)))
120  {
121  /* We mustn't prefetch across a page boundary */
122  State->PrefetchAddress = PAGE_ALIGN(State->PrefetchAddress)
124 
125  if ((LinearAddress - State->PrefetchAddress + Size) >= FAST486_CACHE_SIZE)
126  {
127  /* We can't prefetch without possibly violating page permissions */
128  State->PrefetchValid = FALSE;
129  return Fast486ReadLinearMemory(State, LinearAddress, Buffer, Size, TRUE);
130  }
131  }
132 
133  /* Prefetch */
134  if (Fast486ReadLinearMemory(State,
135  State->PrefetchAddress,
136  State->PrefetchCache,
138  TRUE))
139  {
140  State->PrefetchValid = TRUE;
141 
143  &State->PrefetchCache[LinearAddress - State->PrefetchAddress],
144  Size);
145  return TRUE;
146  }
147  else
148  {
149  State->PrefetchValid = FALSE;
150  return FALSE;
151  }
152  }
153  else
154 #endif
155  {
156  /* Read from the linear address */
157  return Fast486ReadLinearMemory(State, LinearAddress, Buffer, Size, TRUE);
158  }
159 }
#define FAST486_CR0_PG
Definition: fast486.h:56
#define TRUE
Definition: types.h:120
#define PAGE_OFFSET(x)
Definition: common.h:68
#define FAST486_CR0_PE
Definition: fast486.h:46
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
Definition: bufpool.h:45
#define PAGE_ALIGN(Va)
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define FAST486_CACHE_SIZE
Definition: fast486.h:108
#define FAST486_NUM_SEG_REGS
Definition: fast486.h:41
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
unsigned int ULONG
Definition: retypes.h:1
_In_ LONG _In_ LONG Limit
Definition: kefuncs.h:328
#define FAST486_PAGE_SIZE
Definition: fast486.h:107

Referenced by FAST486_OPCODE_HANDLER(), Fast486CallGate(), and Fast486FpuLoadEnvironment().

◆ Fast486TaskSwitch()

BOOLEAN FASTCALL Fast486TaskSwitch ( PFAST486_STATE  State,
FAST486_TASK_SWITCH_TYPE  Type,
USHORT  Selector 
)

Definition at line 624 of file common.c.

625 {
626  ULONG NewTssAddress;
627  ULONG NewTssLimit;
628  FAST486_SYSTEM_DESCRIPTOR NewTssDescriptor;
629  FAST486_TSS OldTss;
630  PFAST486_LEGACY_TSS OldLegacyTss = (PFAST486_LEGACY_TSS)&OldTss;
631  FAST486_TSS NewTss;
632  PFAST486_LEGACY_TSS NewLegacyTss = (PFAST486_LEGACY_TSS)&NewTss;
633  USHORT NewLdtr, NewEs, NewCs, NewSs, NewDs;
634 
635  if ((State->TaskReg.Modern && State->TaskReg.Limit < (sizeof(FAST486_TSS) - 1))
636  || (!State->TaskReg.Modern && State->TaskReg.Limit < (sizeof(FAST486_LEGACY_TSS) - 1)))
637  {
638  /* Invalid task register limit */
639  Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_TS, State->TaskReg.Selector);
640  return FALSE;
641  }
642 
643  /* Read the old TSS */
644  if (!Fast486ReadLinearMemory(State,
645  State->TaskReg.Base,
646  &OldTss,
647  State->TaskReg.Modern
648  ? sizeof(FAST486_TSS) : sizeof(FAST486_LEGACY_TSS),
649  FALSE))
650  {
651  /* Exception occurred */
652  return FALSE;
653  }
654 
655 
656  /* If this is a task return, use the linked previous selector */
657  if (Type == FAST486_TASK_RETURN)
658  {
659  if (State->TaskReg.Modern) Selector = LOWORD(OldTss.Link);
660  else Selector = OldLegacyTss->Link;
661  }
662 
663  /* Make sure the entry exists in the GDT (not LDT!) */
664  if ((GET_SEGMENT_INDEX(Selector) == 0)
665  || (Selector & SEGMENT_TABLE_INDICATOR)
666  || GET_SEGMENT_INDEX(Selector) >= (State->Gdtr.Size + 1u))
667  {
668  Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_TS, Selector);
669  return FALSE;
670  }
671 
672  /* Get the TSS descriptor from the GDT */
673  if (!Fast486ReadLinearMemory(State,
674  State->Gdtr.Address + GET_SEGMENT_INDEX(Selector),
675  &NewTssDescriptor,
676  sizeof(NewTssDescriptor),
677  FALSE))
678  {
679  /* Exception occurred */
680  return FALSE;
681  }
682 
683  if (!NewTssDescriptor.Present)
684  {
685  /* Incoming task TSS not present */
686  Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_NP, Selector);
687  return FALSE;
688  }
689 
690  /* Calculate the linear address of the new TSS */
691  NewTssAddress = NewTssDescriptor.Base;
692  NewTssAddress |= NewTssDescriptor.BaseMid << 16;
693  NewTssAddress |= NewTssDescriptor.BaseHigh << 24;
694 
695  /* Calculate the limit of the new TSS */
696  NewTssLimit = NewTssDescriptor.Limit | (NewTssDescriptor.LimitHigh << 16);
697 
698  if (NewTssDescriptor.Granularity)
699  {
700  NewTssLimit <<= 12;
701  NewTssLimit |= 0x00000FFF;
702  }
703 
704  if (NewTssLimit < (sizeof(FAST486_TSS) - 1)
705  && NewTssLimit != (sizeof(FAST486_LEGACY_TSS) - 1))
706  {
707  /* TSS limit invalid */
708  Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_TS, Selector);
709  return FALSE;
710  }
711 
712  /*
713  * The incoming task shouldn't be busy if we're executing it as a
714  * new task, and it should be busy if we're returning to it.
715  */
716  if ((((NewTssDescriptor.Signature != FAST486_TSS_SIGNATURE)
717  && (NewTssDescriptor.Signature != FAST486_TSS_16_SIGNATURE))
718  || (Type == FAST486_TASK_RETURN))
719  && (((NewTssDescriptor.Signature != FAST486_BUSY_TSS_SIGNATURE)
720  && (NewTssDescriptor.Signature != FAST486_BUSY_TSS_16_SIGNATURE))
721  || (Type != FAST486_TASK_RETURN)))
722  {
723  Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector);
724  return FALSE;
725  }
726 
727  /* Read the new TSS */
728  if (!Fast486ReadLinearMemory(State,
729  NewTssAddress,
730  &NewTss,
731  (NewTssDescriptor.Signature == FAST486_TSS_SIGNATURE)
732  || (NewTssDescriptor.Signature == FAST486_BUSY_TSS_SIGNATURE)
733  ? sizeof(FAST486_TSS) : sizeof(FAST486_LEGACY_TSS),
734  FALSE))
735  {
736  /* Exception occurred */
737  return FALSE;
738  }
739 
740  if (Type != FAST486_TASK_CALL)
741  {
742  /* Clear the busy bit of the outgoing task */
743  FAST486_SYSTEM_DESCRIPTOR OldTssDescriptor;
744 
745  if (!Fast486ReadLinearMemory(State,
746  State->Gdtr.Address
747  + GET_SEGMENT_INDEX(State->TaskReg.Selector),
748  &OldTssDescriptor,
749  sizeof(OldTssDescriptor),
750  FALSE))
751  {
752  /* Exception occurred */
753  return FALSE;
754  }
755 
756  OldTssDescriptor.Signature = FAST486_TSS_SIGNATURE;
757 
758  if (!Fast486WriteLinearMemory(State,
759  State->Gdtr.Address
760  + GET_SEGMENT_INDEX(State->TaskReg.Selector),
761  &OldTssDescriptor,
762  sizeof(OldTssDescriptor),
763  FALSE))
764  {
765  /* Exception occurred */
766  return FALSE;
767  }
768  }
769  else
770  {
771  /* Store the link */
772  if ((NewTssDescriptor.Signature == FAST486_TSS_SIGNATURE)
773  || (NewTssDescriptor.Signature == FAST486_BUSY_TSS_SIGNATURE))
774  {
775  NewTss.Link = State->TaskReg.Selector;
776 
777  /* Write back the new TSS link */
778  if (!Fast486WriteLinearMemory(State,
779  NewTssAddress,
780  &NewTss.Link,
781  sizeof(NewTss.Link),
782  FALSE))
783  {
784  /* Exception occurred */
785  return FALSE;
786  }
787  }
788  else
789  {
790  NewLegacyTss->Link = State->TaskReg.Selector;
791 
792  /* Write back the new legacy TSS link */
793  if (!Fast486WriteLinearMemory(State,
794  NewTssAddress,
795  &NewLegacyTss->Link,
796  sizeof(NewLegacyTss->Link),
797  FALSE))
798  {
799  /* Exception occurred */
800  return FALSE;
801  }
802  }
803  }
804 
805  /* Save the current task into the TSS */
806  if (State->TaskReg.Modern)
807  {
808  OldTss.Cr3 = State->ControlRegisters[FAST486_REG_CR3];
809  OldTss.Eip = State->InstPtr.Long;
810  OldTss.Eflags = State->Flags.Long;
811  OldTss.Eax = State->GeneralRegs[FAST486_REG_EAX].Long;
812  OldTss.Ecx = State->GeneralRegs[FAST486_REG_ECX].Long;
813  OldTss.Edx = State->GeneralRegs[FAST486_REG_EDX].Long;
814  OldTss.Ebx = State->GeneralRegs[FAST486_REG_EBX].Long;
815  OldTss.Esp = State->GeneralRegs[FAST486_REG_ESP].Long;
816  OldTss.Ebp = State->GeneralRegs[FAST486_REG_EBP].Long;
817  OldTss.Esi = State->GeneralRegs[FAST486_REG_ESI].Long;
818  OldTss.Edi = State->GeneralRegs[FAST486_REG_EDI].Long;
819  OldTss.Es = State->SegmentRegs[FAST486_REG_ES].Selector;
820  OldTss.Cs = State->SegmentRegs[FAST486_REG_CS].Selector;
821  OldTss.Ss = State->SegmentRegs[FAST486_REG_SS].Selector;
822  OldTss.Ds = State->SegmentRegs[FAST486_REG_DS].Selector;
823  OldTss.Fs = State->SegmentRegs[FAST486_REG_FS].Selector;
824  OldTss.Gs = State->SegmentRegs[FAST486_REG_GS].Selector;
825  OldTss.Ldtr = State->Ldtr.Selector;
826  }
827  else
828  {
829  OldLegacyTss->Ip = State->InstPtr.LowWord;
830  OldLegacyTss->Flags = State->Flags.LowWord;
831  OldLegacyTss->Ax = State->GeneralRegs[FAST486_REG_EAX].LowWord;
832  OldLegacyTss->Cx = State->GeneralRegs[FAST486_REG_ECX].LowWord;
833  OldLegacyTss->Dx = State->GeneralRegs[FAST486_REG_EDX].LowWord;
834  OldLegacyTss->Bx = State->GeneralRegs[FAST486_REG_EBX].LowWord;
835  OldLegacyTss->Sp = State->GeneralRegs[FAST486_REG_ESP].LowWord;
836  OldLegacyTss->Bp = State->GeneralRegs[FAST486_REG_EBP].LowWord;
837  OldLegacyTss->Si = State->GeneralRegs[FAST486_REG_ESI].LowWord;
838  OldLegacyTss->Di = State->GeneralRegs[FAST486_REG_EDI].LowWord;
839  OldLegacyTss->Es = State->SegmentRegs[FAST486_REG_ES].Selector;
840  OldLegacyTss->Cs = State->SegmentRegs[FAST486_REG_CS].Selector;
841  OldLegacyTss->Ss = State->SegmentRegs[FAST486_REG_SS].Selector;
842  OldLegacyTss->Ds = State->SegmentRegs[FAST486_REG_DS].Selector;
843  OldLegacyTss->Ldtr = State->Ldtr.Selector;
844  }
845 
846  /* Write back the old TSS */
847  if (!Fast486WriteLinearMemory(State,
848  State->TaskReg.Base,
849  &OldTss,
850  State->TaskReg.Modern
851  ? sizeof(FAST486_TSS) : sizeof(FAST486_LEGACY_TSS),
852  FALSE))
853  {
854  /* Exception occurred */
855  return FALSE;
856  }
857 
858  /* Mark the new task as busy */
859  if (NewTssDescriptor.Signature == FAST486_TSS_SIGNATURE
860  || NewTssDescriptor.Signature == FAST486_BUSY_TSS_SIGNATURE)
861  {
862  /* 32-bit TSS */
863  NewTssDescriptor.Signature = FAST486_BUSY_TSS_SIGNATURE;
864  }
865  else
866  {
867  /* 16-bit TSS */
868  NewTssDescriptor.Signature = FAST486_BUSY_TSS_16_SIGNATURE;
869  }
870 
871  /* Write back the new TSS descriptor */
872  if (!Fast486WriteLinearMemory(State,
873  State->Gdtr.Address + GET_SEGMENT_INDEX(Selector),
874  &NewTssDescriptor,
875  sizeof(NewTssDescriptor),
876  FALSE))
877  {
878  /* Exception occurred */
879  return FALSE;
880  }
881 
882  /* Set the task switch bit */
883  State->ControlRegisters[FAST486_REG_CR0] |= FAST486_CR0_TS;
884 
885  /* Load the task register with the new values */
886  State->TaskReg.Selector = Selector;
887  State->TaskReg.Base = NewTssAddress;
888  State->TaskReg.Limit = NewTssLimit;
889  State->TaskReg.Modern = (NewTssDescriptor.Signature == FAST486_BUSY_TSS_SIGNATURE);
890 
891  if (NewTssDescriptor.Signature == FAST486_BUSY_TSS_SIGNATURE)
892  {
893  /* Change the page directory */
894  State->ControlRegisters[FAST486_REG_CR3] = NewTss.Cr3;
895  }
896 
897  /* Flush the TLB */
898  Fast486FlushTlb(State);
899 
900  /* Update the CPL */
901  if (NewTssDescriptor.Signature == FAST486_BUSY_TSS_SIGNATURE)
902  {
903  State->Cpl = GET_SEGMENT_RPL(NewTss.Cs);
904  }
905  else
906  {
907  State->Cpl = GET_SEGMENT_RPL(NewLegacyTss->Cs);
908  }
909 
910 #ifndef FAST486_NO_PREFETCH
911  /* Context switching invalidates the prefetch */
912  State->PrefetchValid = FALSE;
913 #endif
914 
915  /* Load the registers */
916  if (NewTssDescriptor.Signature == FAST486_BUSY_TSS_SIGNATURE)
917  {
918  State->InstPtr.Long = State->SavedInstPtr.Long = NewTss.Eip;
919  State->Flags.Long = NewTss.Eflags;
920  State->GeneralRegs[FAST486_REG_EAX].Long = NewTss.Eax;
921  State->GeneralRegs[FAST486_REG_ECX].Long = NewTss.Ecx;
922  State->GeneralRegs[FAST486_REG_EDX].Long = NewTss.Edx;
923  State->GeneralRegs[FAST486_REG_EBX].Long = NewTss.Ebx;
924  State->GeneralRegs[FAST486_REG_EBP].Long = NewTss.Ebp;
925  State->GeneralRegs[FAST486_REG_ESI].Long = NewTss.Esi;
926  State->GeneralRegs[FAST486_REG_EDI].Long = NewTss.Edi;
927  NewEs = NewTss.Es;
928  NewCs = NewTss.Cs;
929  NewDs = NewTss.Ds;
930  NewLdtr = NewTss.Ldtr;
931 
932  if (Type == FAST486_TASK_CALL && State->Cpl < 3)
933  {
934  switch (State->Cpl)
935  {
936  case 0:
937  {
938  State->GeneralRegs[FAST486_REG_ESP].Long = NewTss.Esp0;
939  NewSs = NewTss.Ss0;
940  break;
941  }
942 
943  case 1:
944  {
945  State->GeneralRegs[FAST486_REG_ESP].Long = NewTss.Esp1;
946  NewSs = NewTss.Ss1;
947  break;
948  }
949 
950  case 2:
951  {
952  State->GeneralRegs[FAST486_REG_ESP].Long = NewTss.Esp2;
953  NewSs = NewTss.Ss2;
954  break;
955  }
956  }
957  }
958  else
959  {
960  State->GeneralRegs[FAST486_REG_ESP].Long = NewTss.Esp;
961  NewSs = NewTss.Ss;
962  }
963  }
964  else
965  {
966  State->InstPtr.LowWord = State->SavedInstPtr.LowWord = NewLegacyTss->Ip;
967  State->Flags.LowWord = NewLegacyTss->Flags;
968  State->GeneralRegs[FAST486_REG_EAX].LowWord = NewLegacyTss->Ax;
969  State->GeneralRegs[FAST486_REG_ECX].LowWord = NewLegacyTss->Cx;
970  State->GeneralRegs[FAST486_REG_EDX].LowWord = NewLegacyTss->Dx;
971  State->GeneralRegs[FAST486_REG_EBX].LowWord = NewLegacyTss->Bx;
972  State->GeneralRegs[FAST486_REG_EBP].LowWord = NewLegacyTss->Bp;
973  State->GeneralRegs[FAST486_REG_ESI].LowWord = NewLegacyTss->Si;
974  State->GeneralRegs[FAST486_REG_EDI].LowWord = NewLegacyTss->Di;
975  NewEs = NewLegacyTss->Es;
976  NewCs = NewLegacyTss->Cs;
977  NewDs = NewLegacyTss->Ds;
978  NewLdtr = NewLegacyTss->Ldtr;
979 
980  if (Type == FAST486_TASK_CALL && State->Cpl < 3)
981  {
982  switch (State->Cpl)
983  {
984  case 0:
985  {
986  State->GeneralRegs[FAST486_REG_ESP].Long = NewLegacyTss->Sp0;
987  NewSs = NewLegacyTss->Ss0;
988  break;
989  }
990 
991  case 1:
992  {
993  State->GeneralRegs[FAST486_REG_ESP].Long = NewLegacyTss->Sp1;
994  NewSs = NewLegacyTss->Ss1;
995  break;
996  }
997 
998  case 2:
999  {
1000  State->GeneralRegs[FAST486_REG_ESP].Long = NewLegacyTss->Sp2;
1001  NewSs = NewLegacyTss->Ss2;
1002  break;
1003  }
1004  }
1005  }
1006  else
1007  {
1008  State->GeneralRegs[FAST486_REG_ESP].Long = NewLegacyTss->Sp;
1009  NewSs = NewLegacyTss->Ss;
1010  }
1011  }
1012 
1013  /* Set the NT flag if nesting */
1014  if (Type == FAST486_TASK_CALL) State->Flags.Nt = TRUE;
1015 
1016  if (GET_SEGMENT_INDEX(NewLdtr) != 0)
1017  {
1018  BOOLEAN Valid;
1019  FAST486_SYSTEM_DESCRIPTOR GdtEntry;
1020 
1021  if (NewLdtr & SEGMENT_TABLE_INDICATOR)
1022  {
1023  /* This selector doesn't point to the GDT */
1024  Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_TS, NewLdtr);
1025  return FALSE;
1026  }
1027 
1028  if (!Fast486ReadDescriptorEntry(State, NewLdtr, &Valid, (PFAST486_GDT_ENTRY)&GdtEntry))
1029  {
1030  /* Exception occurred */
1031  return FALSE;
1032  }
1033 
1034  if (!Valid)
1035  {
1036  /* Invalid selector */
1037  Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_TS, NewLdtr);
1038  return FALSE;
1039  }
1040 
1041  if (GdtEntry.Signature != FAST486_LDT_SIGNATURE)
1042  {
1043  /* This is not an LDT descriptor */
1044  Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_TS, NewLdtr);
1045  return FALSE;
1046  }
1047 
1048  if (!GdtEntry.Present)
1049  {
1050  Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_TS, NewLdtr);
1051  return FALSE;
1052  }
1053 
1054  /* Update the LDTR */
1055  State->Ldtr.Selector = NewLdtr;
1056  State->Ldtr.Base = GdtEntry.Base | (GdtEntry.BaseMid << 16) | (GdtEntry.BaseHigh << 24);
1057  State->Ldtr.Limit = GdtEntry.Limit | (GdtEntry.LimitHigh << 16);
1058 
1059  if (GdtEntry.Granularity)
1060  {
1061  State->Ldtr.Limit <<= 12;
1062  State->Ldtr.Limit |= 0x00000FFF;
1063  }
1064  }
1065  else
1066  {
1067  /* The LDT of this task is empty */
1068  RtlZeroMemory(&State->Ldtr, sizeof(State->Ldtr));
1069  }
1070 
1071  /* Load the new segments */
1072  if (!Fast486LoadSegmentInternal(State, FAST486_REG_CS, NewCs, FAST486_EXCEPTION_TS))
1073  {
1074  return FALSE;
1075  }
1076 
1077  if (!Fast486LoadSegmentInternal(State, FAST486_REG_SS, NewSs, FAST486_EXCEPTION_TS))
1078  {
1079  return FALSE;
1080  }
1081 
1082  if (!Fast486LoadSegmentInternal(State, FAST486_REG_ES, NewEs, FAST486_EXCEPTION_TS))
1083  {
1084  return FALSE;
1085  }
1086 
1087  if (!Fast486LoadSegmentInternal(State, FAST486_REG_DS, NewDs, FAST486_EXCEPTION_TS))
1088  {
1089  return FALSE;
1090  }
1091 
1092  if (NewTssDescriptor.Signature == FAST486_BUSY_TSS_SIGNATURE)
1093  {
1094  if (!Fast486LoadSegmentInternal(State,
1095  FAST486_REG_FS,
1096  NewTss.Fs,
1097  FAST486_EXCEPTION_TS))
1098  {
1099  return FALSE;
1100  }
1101 
1102  if (!Fast486LoadSegmentInternal(State,
1103  FAST486_REG_GS,
1104  NewTss.Gs,
1105  FAST486_EXCEPTION_TS))
1106  {
1107  return FALSE;
1108  }
1109  }
1110 
1111  return TRUE;
1112 }
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
#define TRUE
Definition: types.h:120
Type
Definition: Type.h:6
#define GET_SEGMENT_INDEX(s)
Definition: common.h:39
unsigned char BOOLEAN
#define FAST486_BUSY_TSS_SIGNATURE
Definition: fast486.h:93
#define FAST486_BUSY_TSS_16_SIGNATURE
Definition: fast486.h:87
#define FAST486_TSS_16_SIGNATURE
Definition: fast486.h:85
#define SEGMENT_TABLE_INDICATOR
Definition: common.h:40
unsigned short USHORT
Definition: pedump.c:61
#define GET_SEGMENT_RPL(s)
Definition: common.h:38
#define FAST486_CR0_TS
Definition: fast486.h:49
VOID FASTCALL Fast486ExceptionWithErrorCode(PFAST486_STATE State, FAST486_EXCEPTIONS ExceptionCode, ULONG ErrorCode)
Definition: common.c:557
#define FAST486_TSS_SIGNATURE
Definition: fast486.h:92
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define LOWORD(l)
Definition: pedump.c:82
#define FAST486_LDT_SIGNATURE
Definition: fast486.h:86

Referenced by FAST486_OPCODE_HANDLER(), and Fast486InterruptInternal().

◆ Fast486WriteMemory()

BOOLEAN FASTCALL Fast486WriteMemory ( PFAST486_STATE  State,
FAST486_SEG_REGS  SegmentReg,
ULONG  Offset,
PVOID  Buffer,
ULONG  Size 
)

Definition at line 163 of file common.c.

168 {
169  ULONG LinearAddress;
170  PFAST486_SEG_REG CachedDescriptor;
171  FAST486_EXCEPTIONS Exception = SegmentReg != FAST486_REG_SS
172  ? FAST486_EXCEPTION_GP : FAST486_EXCEPTION_SS;
173 
174  ASSERT(SegmentReg < FAST486_NUM_SEG_REGS);
175 
176  /* Get the cached descriptor */
177  CachedDescriptor = &State->SegmentRegs[SegmentReg];
178 
179  if (CachedDescriptor->Executable || !CachedDescriptor->DirConf)
180  {
181  if ((Offset + Size - 1) > CachedDescriptor->Limit)
182  {
183  /* Write beyond limit */
184  Fast486Exception(State, Exception);
185  return FALSE;
186  }
187  }
188  else
189  {
191  {
192  /* Write beyond limit */
193  Fast486Exception(State, Exception);
194  return FALSE;
195  }
196  }
197 
198  /* Check for protected mode */
199  if ((State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE) && !State->Flags.Vm)
200  {
201  /* Privilege checks */
202 
203  if (!CachedDescriptor->Present)
204  {
205  Fast486Exception(State, Exception);
206  return FALSE;
207  }
208 
209  if ((CachedDescriptor->Rpl > CachedDescriptor->Dpl)
210  || (Fast486GetCurrentPrivLevel(State) > CachedDescriptor->Dpl))
211  {
212  Fast486Exception(State, Exception);
213  return FALSE;
214  }
215 
216  if (CachedDescriptor->Executable)
217  {
218  /* Code segment not writable */
219  Fast486Exception(State, Exception);
220  return FALSE;
221  }
222  else if (!CachedDescriptor->ReadWrite)
223  {
224  /* Data segment not writeable */
225  Fast486Exception(State, Exception);
226  return FALSE;
227  }
228  }
229 
230  /* Find the linear address */
231  LinearAddress = CachedDescriptor->Base + Offset;
232 
233 #ifndef FAST486_NO_PREFETCH
234  if (State->PrefetchValid
235  && (LinearAddress >= State->PrefetchAddress)
236  && ((LinearAddress + Size) <= (State->PrefetchAddress + FAST486_CACHE_SIZE)))
237  {
238  /* Update the prefetch */
239  RtlMoveMemory(&State->PrefetchCache[LinearAddress - State->PrefetchAddress],
240  Buffer,
241  min(Size, FAST486_CACHE_SIZE + State->PrefetchAddress - LinearAddress));
242  }
243 #endif
244 
245  /* Write to the linear address */
246  return Fast486WriteLinearMemory(State, LinearAddress, Buffer, Size, TRUE);
247 }
#define TRUE
Definition: types.h:120
#define FAST486_CR0_PE
Definition: fast486.h:46
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
Definition: bufpool.h:45
int min(int a, int b)
Definition: common.c:179
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define FAST486_CACHE_SIZE
Definition: fast486.h:108
#define FAST486_NUM_SEG_REGS
Definition: fast486.h:41
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
unsigned int ULONG
Definition: retypes.h:1
_In_ LONG _In_ LONG Limit
Definition: kefuncs.h:328

Referenced by FAST486_OPCODE_HANDLER(), and Fast486FpuSaveEnvironment().