ReactOS  0.4.14-dev-41-g31d7680
common.c
Go to the documentation of this file.
1 /*
2  * Fast486 386/486 CPU Emulation Library
3  * common.c
4  *
5  * Copyright (C) 2015 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  */
21 
22 /* INCLUDES *******************************************************************/
23 
24 #include <windef.h>
25 
26 // #define NDEBUG
27 #include <debug.h>
28 
29 #include <fast486.h>
30 #include "common.h"
31 
32 /* PUBLIC FUNCTIONS ***********************************************************/
33 
34 BOOLEAN
36 Fast486ReadMemory(PFAST486_STATE State,
37  FAST486_SEG_REGS SegmentReg,
38  ULONG Offset,
39  BOOLEAN InstFetch,
40  PVOID Buffer,
41  ULONG Size)
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 }
160 
161 BOOLEAN
162 FASTCALL
163 Fast486WriteMemory(PFAST486_STATE State,
164  FAST486_SEG_REGS SegmentReg,
165  ULONG Offset,
166  PVOID Buffer,
167  ULONG Size)
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 }
248 
249 static inline BOOLEAN
250 FASTCALL
251 Fast486GetIntVector(PFAST486_STATE State,
252  UCHAR Number,
253  PFAST486_IDT_ENTRY IdtEntry)
254 {
255  /* Check for protected mode */
256  if (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE)
257  {
258  /* Read from the IDT */
259  if (!Fast486ReadLinearMemory(State,
260  State->Idtr.Address
261  + Number * sizeof(*IdtEntry),
262  IdtEntry,
263  sizeof(*IdtEntry),
264  FALSE))
265  {
266  /* Exception occurred */
267  return FALSE;
268  }
269  }
270  else
271  {
272  /* Read from the real-mode IVT */
273  ULONG FarPointer;
274 
275  /* Paging is always disabled in real mode */
276  State->MemReadCallback(State,
277  State->Idtr.Address
278  + Number * sizeof(FarPointer),
279  &FarPointer,
280  sizeof(FarPointer));
281 
282  /* Fill a fake IDT entry */
283  IdtEntry->Offset = LOWORD(FarPointer);
284  IdtEntry->Selector = HIWORD(FarPointer);
285  IdtEntry->Zero = 0;
287  IdtEntry->Storage = FALSE;
288  IdtEntry->Dpl = 0;
289  IdtEntry->Present = TRUE;
290  IdtEntry->OffsetHigh = 0;
291  }
292 
293  return TRUE;
294 }
295 
296 static inline BOOLEAN
297 FASTCALL
299  PFAST486_IDT_ENTRY IdtEntry,
300  BOOLEAN PushErrorCode,
302 {
303  BOOLEAN GateSize = (IdtEntry->Type == FAST486_IDT_INT_GATE_32) ||
305  USHORT OldCs = State->SegmentRegs[FAST486_REG_CS].Selector;
306  ULONG OldEip = State->InstPtr.Long;
307  ULONG OldFlags = State->Flags.Long;
308  UCHAR OldCpl = State->Cpl;
309 
310  /* Check for protected mode */
311  if (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE)
312  {
313  USHORT OldSs = State->SegmentRegs[FAST486_REG_SS].Selector;
314  ULONG OldEsp = State->GeneralRegs[FAST486_REG_ESP].Long;
315  BOOLEAN OldVm = State->Flags.Vm;
316 
318  {
319  /* Task call */
321  {
322  /* Exception occurred */
323  return FALSE;
324  }
325 
326  goto Finish;
327  }
328 
329  /* Check if the interrupt handler is more privileged or if we're in V86 mode */
330  if ((OldCpl > GET_SEGMENT_RPL(IdtEntry->Selector)) || State->Flags.Vm)
331  {
332  FAST486_TSS Tss;
333  PFAST486_LEGACY_TSS LegacyTss = (PFAST486_LEGACY_TSS)&Tss;
334  USHORT NewSs;
335  ULONG NewEsp;
336 
337  /* Read the TSS */
338  if (!Fast486ReadLinearMemory(State,
339  State->TaskReg.Base,
340  &Tss,
341  State->TaskReg.Modern
342  ? sizeof(FAST486_TSS) : sizeof(FAST486_LEGACY_TSS),
343  FALSE))
344  {
345  /* Exception occurred */
346  return FALSE;
347  }
348 
349  /* Switch to the new privilege level */
350  State->Cpl = GET_SEGMENT_RPL(IdtEntry->Selector);
351 
352  /* Clear the VM flag */
353  State->Flags.Vm = FALSE;
354 
355  /* Check the new (higher) privilege level */
356  switch (State->Cpl)
357  {
358  case 0:
359  {
360  if (State->TaskReg.Modern)
361  {
362  NewSs = Tss.Ss0;
363  NewEsp = Tss.Esp0;
364  }
365  else
366  {
367  NewSs = LegacyTss->Ss0;
368  NewEsp = LegacyTss->Sp0;
369  }
370 
371  break;
372  }
373 
374  case 1:
375  {
376  if (State->TaskReg.Modern)
377  {
378  NewSs = Tss.Ss1;
379  NewEsp = Tss.Esp1;
380  }
381  else
382  {
383  NewSs = LegacyTss->Ss1;
384  NewEsp = LegacyTss->Sp1;
385  }
386 
387  break;
388  }
389 
390  case 2:
391  {
392  if (State->TaskReg.Modern)
393  {
394  NewSs = Tss.Ss2;
395  NewEsp = Tss.Esp2;
396  }
397  else
398  {
399  NewSs = LegacyTss->Ss2;
400  NewEsp = LegacyTss->Sp2;
401  }
402 
403  break;
404  }
405 
406  default:
407  {
408  /* Should never reach here! */
409  ASSERT(FALSE);
410  }
411  }
412 
413  if (!Fast486LoadSegment(State, FAST486_REG_SS, NewSs))
414  {
415  /* Exception occurred */
416  return FALSE;
417  }
418 
419  State->GeneralRegs[FAST486_REG_ESP].Long = NewEsp;
420  }
421 
422  /* Load new CS */
423  if (!Fast486LoadSegment(State, FAST486_REG_CS, IdtEntry->Selector))
424  {
425  /* An exception occurred during the jump */
426  return FALSE;
427  }
428 
429  if (GateSize)
430  {
431  /* 32-bit code segment, use EIP */
432  State->InstPtr.Long = MAKELONG(IdtEntry->Offset, IdtEntry->OffsetHigh);
433  }
434  else
435  {
436  /* 16-bit code segment, use IP */
437  State->InstPtr.LowWord = IdtEntry->Offset;
438  }
439 
440  /* Clear NT */
441  State->Flags.Nt = FALSE;
442 
443  if (OldVm)
444  {
445  /* Push GS, FS, DS and ES */
446  if (!Fast486StackPushInternal(State,
447  GateSize,
448  State->SegmentRegs[FAST486_REG_GS].Selector))
449  {
450  return FALSE;
451  }
452  if (!Fast486StackPushInternal(State,
453  GateSize,
454  State->SegmentRegs[FAST486_REG_FS].Selector))
455  {
456  return FALSE;
457  }
458  if (!Fast486StackPushInternal(State,
459  GateSize,
460  State->SegmentRegs[FAST486_REG_DS].Selector))
461  {
462  return FALSE;
463  }
464  if (!Fast486StackPushInternal(State,
465  GateSize,
466  State->SegmentRegs[FAST486_REG_ES].Selector))
467  {
468  return FALSE;
469  }
470 
471  /* Now load them with NULL selectors, since they are useless in protected mode */
472  if (!Fast486LoadSegment(State, FAST486_REG_GS, 0)) return FALSE;
473  if (!Fast486LoadSegment(State, FAST486_REG_FS, 0)) return FALSE;
474  if (!Fast486LoadSegment(State, FAST486_REG_DS, 0)) return FALSE;
475  if (!Fast486LoadSegment(State, FAST486_REG_ES, 0)) return FALSE;
476  }
477 
478  /* Check if the interrupt handler is more privileged or we're in VM86 mode (again) */
479  if ((OldCpl > GET_SEGMENT_RPL(IdtEntry->Selector)) || OldVm)
480  {
481  /* Push SS selector */
482  if (!Fast486StackPushInternal(State, GateSize, OldSs)) return FALSE;
483 
484  /* Push the stack pointer */
485  if (!Fast486StackPushInternal(State, GateSize, OldEsp)) return FALSE;
486  }
487  }
488  else
489  {
490  /* Load new CS */
491  if (!Fast486LoadSegment(State, FAST486_REG_CS, IdtEntry->Selector))
492  {
493  /* An exception occurred during the jump */
494  return FALSE;
495  }
496 
497  /* Set the new IP */
498  State->InstPtr.LowWord = IdtEntry->Offset;
499  }
500 
501  /* Push EFLAGS */
502  if (!Fast486StackPushInternal(State, GateSize, OldFlags)) return FALSE;
503 
504  /* Push CS selector */
505  if (!Fast486StackPushInternal(State, GateSize, OldCs)) return FALSE;
506 
507  /* Push the instruction pointer */
508  if (!Fast486StackPushInternal(State, GateSize, OldEip)) return FALSE;
509 
510 Finish:
511 
512  if (PushErrorCode)
513  {
514  /* Push the error code */
515  if (!Fast486StackPushInternal(State, GateSize, ErrorCode)) return FALSE;
516  }
517 
518  if ((IdtEntry->Type == FAST486_IDT_INT_GATE)
519  || (IdtEntry->Type == FAST486_IDT_INT_GATE_32))
520  {
521  /* Disable interrupts after a jump to an interrupt gate handler */
522  State->Flags.If = FALSE;
523  }
524 
525  /* Clear TF */
526  State->Flags.Tf = FALSE;
527 
528  return TRUE;
529 }
530 
531 BOOLEAN
532 FASTCALL
534  UCHAR Number)
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 }
554 
555 VOID
556 FASTCALL
558  FAST486_EXCEPTIONS ExceptionCode,
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 }
621 
622 BOOLEAN
623 FASTCALL
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 }
1113 
1114 BOOLEAN
1115 FASTCALL
1116 Fast486CallGate(PFAST486_STATE State,
1117  PFAST486_CALL_GATE Gate,
1118  BOOLEAN Call)
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 }
1312 
1313 /* EOF */
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
_Inout_ PIRP _In_ NTSTATUS ExceptionCode
Definition: cdprocs.h:1782
#define FAST486_CR0_PG
Definition: fast486.h:56
#define TRUE
Definition: types.h:120
_In_ NDIS_ERROR_CODE ErrorCode
Definition: ndis.h:4436
#define PAGE_OFFSET(x)
Definition: common.h:68
Type
Definition: Type.h:6
enum _FAST486_TASK_SWITCH_TYPE FAST486_TASK_SWITCH_TYPE
#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
#define FAST486_TASK_GATE_SIGNATURE
Definition: fast486.h:89
#define FASTCALL
Definition: nt_native.h:50
int32_t INT
Definition: typedefs.h:56
#define FAST486_IDT_INT_GATE_32
Definition: fast486.h:95
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
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
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define GET_SEGMENT_INDEX(s)
Definition: common.h:39
#define MAKELONG(a, b)
Definition: typedefs.h:248
unsigned char BOOLEAN
void DPRINT(...)
Definition: polytest.cpp:61
Definition: hooks.h:42
Definition: bufpool.h:45
#define FAST486_BUSY_TSS_SIGNATURE
Definition: fast486.h:93
int min(int a, int b)
Definition: common.c:179
BOOLEAN FASTCALL Fast486WriteMemory(PFAST486_STATE State, FAST486_SEG_REGS SegmentReg, ULONG Offset, PVOID Buffer, ULONG Size)
Definition: common.c:163
#define FAST486_CALL_GATE_SIGNATURE
Definition: fast486.h:94
#define PAGE_ALIGN(Va)
BOOLEAN FASTCALL Fast486PerformInterrupt(PFAST486_STATE State, UCHAR Number)
Definition: common.c:533
#define FAST486_BUSY_TSS_16_SIGNATURE
Definition: fast486.h:87
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned char UCHAR
Definition: xmlstorage.h:181
#define FAST486_CACHE_SIZE
Definition: fast486.h:108
VOID NTAPI Fast486Reset(PFAST486_STATE State)
Definition: fast486.c:131
#define FAST486_TSS_16_SIGNATURE
Definition: fast486.h:85
#define FAST486_NUM_SEG_REGS
Definition: fast486.h:41
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
_In_opt_ PENTER_STATE_SYSTEM_HANDLER _In_opt_ PVOID _In_ LONG _In_opt_ LONG volatile * Number
Definition: ntpoapi.h:204
BOOLEAN FASTCALL Fast486ReadMemory(PFAST486_STATE State, FAST486_SEG_REGS SegmentReg, ULONG Offset, BOOLEAN InstFetch, PVOID Buffer, ULONG Size)
Definition: common.c:36
#define SEGMENT_TABLE_INDICATOR
Definition: common.h:40
BOOLEAN FASTCALL Fast486CallGate(PFAST486_STATE State, PFAST486_CALL_GATE Gate, BOOLEAN Call)
Definition: common.c:1116
BOOLEAN FASTCALL Fast486TaskSwitch(PFAST486_STATE State, FAST486_TASK_SWITCH_TYPE Type, USHORT Selector)
Definition: common.c:624
unsigned short USHORT
Definition: pedump.c:61
#define GET_SEGMENT_RPL(s)
Definition: common.h:38
#define FAST486_CR0_TS
Definition: fast486.h:49
unsigned int * PULONG
Definition: retypes.h:1
VOID FASTCALL Fast486ExceptionWithErrorCode(PFAST486_STATE State, FAST486_EXCEPTIONS ExceptionCode, ULONG ErrorCode)
Definition: common.c:557
static BOOLEAN FASTCALL Fast486InterruptInternal(PFAST486_STATE State, PFAST486_IDT_ENTRY IdtEntry, BOOLEAN PushErrorCode, ULONG ErrorCode)
Definition: common.c:298
#define FAST486_TSS_SIGNATURE
Definition: fast486.h:92
#define HIWORD(l)
Definition: typedefs.h:246
unsigned int ULONG
Definition: retypes.h:1
#define EXCEPTION_HAS_ERROR_CODE(x)
Definition: common.h:41
#define FAST486_IDT_INT_GATE
Definition: fast486.h:90
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define LOWORD(l)
Definition: pedump.c:82
_In_ LONG _In_ LONG Limit
Definition: kefuncs.h:328
#define FAST486_LDT_SIGNATURE
Definition: fast486.h:86
unsigned short * PUSHORT
Definition: retypes.h:2
#define FAST486_IDT_TRAP_GATE_32
Definition: fast486.h:96
#define FAST486_PAGE_SIZE
Definition: fast486.h:107