From d80b788ff41ddd8b4c3d143d0eed00b70fa394cf Mon Sep 17 00:00:00 2001 From: Aleksandar Andrejevic Date: Sat, 2 Nov 2013 00:47:43 +0000 Subject: [PATCH] [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. svn path=/branches/ntvdm/; revision=60825 --- include/reactos/libs/fast486/fast486.h | 16 +++++++++++++++- lib/fast486/common.inl | 2 +- lib/fast486/fast486.c | 9 ++++++++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/include/reactos/libs/fast486/fast486.h b/include/reactos/libs/fast486/fast486.h index f619773aa7f..4087a94cc29 100644 --- a/include/reactos/libs/fast486/fast486.h +++ b/include/reactos/libs/fast486/fast486.h @@ -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; diff --git a/lib/fast486/common.inl b/lib/fast486/common.inl index 63246059739..5ab2f9fe36b 100644 --- a/lib/fast486/common.inl +++ b/lib/fast486/common.inl @@ -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; diff --git a/lib/fast486/fast486.c b/lib/fast486/fast486.c index 2b00cbdf559..00cf7d8f495 100644 --- a/lib/fast486/fast486.c +++ b/lib/fast486/fast486.c @@ -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;