Author: aandrejevic Date: Sat Nov 2 00:47:43 2013 New Revision: 60825
URL: http://svn.reactos.org/svn/reactos?rev=60825&view=rev Log: [FAST486] 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.
Modified: branches/ntvdm/include/reactos/libs/fast486/fast486.h branches/ntvdm/lib/fast486/common.inl branches/ntvdm/lib/fast486/fast486.c
Modified: branches/ntvdm/include/reactos/libs/fast486/fast486.h URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/include/reactos/libs/fast4... ============================================================================== --- branches/ntvdm/include/reactos/libs/fast486/fast486.h [iso-8859-1] (original) +++ branches/ntvdm/include/reactos/libs/fast486/fast486.h [iso-8859-1] Sat Nov 2 00:47:43 2013 @@ -251,10 +251,13 @@ 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 @@ 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 @@ 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; @@ -294,6 +303,11 @@ ULONG Present : 1; 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 {
Modified: branches/ntvdm/lib/fast486/common.inl URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/fast486/common.inl?rev... ============================================================================== --- branches/ntvdm/lib/fast486/common.inl [iso-8859-1] (original) +++ branches/ntvdm/lib/fast486/common.inl [iso-8859-1] Sat Nov 2 00:47:43 2013 @@ -260,7 +260,7 @@
/* 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;
Modified: branches/ntvdm/lib/fast486/fast486.c URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/fast486/fast486.c?rev=... ============================================================================== --- branches/ntvdm/lib/fast486/fast486.c [iso-8859-1] (original) +++ branches/ntvdm/lib/fast486/fast486.c [iso-8859-1] Sat Nov 2 00:47:43 2013 @@ -239,13 +239,20 @@ /* 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;