[FAST486]
authorAleksandar Andrejevic <aandrejevic@reactos.org>
Sat, 2 Nov 2013 00:47:43 +0000 (00:47 +0000)
committerAleksandar Andrejevic <aandrejevic@reactos.org>
Sat, 2 Nov 2013 00:47:43 +0000 (00:47 +0000)
Fix segment initialization. The cached descriptors must have valid values
during the switch to protected mode.
For some odd reason, GCC makes the FAST486_GDT_ENTRY structure 12 bytes
instead of 8 if there is a bit field with more than 16 bits, so split
the Base field into Base and BaseMid.
Add size checks below important structure declarations.

svn path=/branches/ntvdm/; revision=60825

include/reactos/libs/fast486/fast486.h
lib/fast486/common.inl
lib/fast486/fast486.c

index f619773..4087a94 100644 (file)
@@ -251,10 +251,13 @@ typedef struct _FAST486_SEG_REG
     ULONG Base;
 } FAST486_SEG_REG, *PFAST486_SEG_REG;
 
+#pragma pack(push, 1)
+
 typedef struct
 {
     ULONG Limit         : 16;
-    ULONG Base          : 24;
+    ULONG Base          : 16;
+    ULONG BaseMid       : 8;
     ULONG Accessed      : 1;
     ULONG ReadWrite     : 1;
     ULONG DirConf       : 1;
@@ -270,6 +273,9 @@ typedef struct
     ULONG BaseHigh      : 8;
 } FAST486_GDT_ENTRY, *PFAST486_GDT_ENTRY;
 
+/* Verify the structure size */
+C_ASSERT(sizeof(FAST486_GDT_ENTRY) == sizeof(ULONGLONG));
+
 typedef struct
 {
     ULONG Offset : 16;
@@ -283,6 +289,9 @@ typedef struct
     ULONG OffsetHigh : 16;
 } FAST486_CALL_GATE, *PFAST486_CALL_GATE;
 
+/* Verify the structure size */
+C_ASSERT(sizeof(FAST486_CALL_GATE) == sizeof(ULONGLONG));
+
 typedef struct
 {
     ULONG Offset        : 16;
@@ -295,6 +304,11 @@ typedef struct
     ULONG OffsetHigh    : 16;
 } FAST486_IDT_ENTRY, *PFAST486_IDT_ENTRY;
 
+/* Verify the structure size */
+C_ASSERT(sizeof(FAST486_IDT_ENTRY) == sizeof(ULONGLONG));
+
+#pragma pack(pop)
+
 typedef struct _FAST486_TABLE_REG
 {
     USHORT Size;
index 6324605..5ab2f9f 100644 (file)
@@ -260,7 +260,7 @@ Fast486LoadSegment(PFAST486_STATE State,
 
         /* Update the cache entry */
         CachedDescriptor->Selector = Selector;
-        CachedDescriptor->Base = GdtEntry.Base | (GdtEntry.BaseHigh << 24);
+        CachedDescriptor->Base = GdtEntry.Base | (GdtEntry.BaseMid << 16) | (GdtEntry.BaseHigh << 24);
         CachedDescriptor->Limit = GdtEntry.Limit | (GdtEntry.LimitHigh << 16);
         CachedDescriptor->Accessed = GdtEntry.Accessed;
         CachedDescriptor->ReadWrite = GdtEntry.ReadWrite;
index 2b00cbd..00cf7d8 100644 (file)
@@ -239,13 +239,20 @@ Fast486Reset(PFAST486_STATE State)
     /* Initialize segments */
     for (i = 0; i < FAST486_NUM_SEG_REGS; i++)
     {
-        /* Set the selector, base and limit, other values don't apply in real mode */
         State->SegmentRegs[i].Selector = 0;
         State->SegmentRegs[i].Base = 0;
         State->SegmentRegs[i].Limit = 0xFFFF;
+        State->SegmentRegs[i].Present = TRUE;
+        State->SegmentRegs[i].ReadWrite = TRUE;
+        State->SegmentRegs[i].Executable = FALSE;
+        State->SegmentRegs[i].DirConf = FALSE;
+        State->SegmentRegs[i].SystemType = 1; // Segment descriptor
+        State->SegmentRegs[i].Dpl = 0;
+        State->SegmentRegs[i].Size = FALSE; // 16-bit
     }
 
     /* Initialize the code segment */
+    State->SegmentRegs[FAST486_REG_CS].Executable = TRUE;
     State->SegmentRegs[FAST486_REG_CS].Selector = 0xF000;
     State->SegmentRegs[FAST486_REG_CS].Base = 0xFFFF0000;