From 4f3a2dfc7e17db860ea451b1d9a73d12821ece05 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Mon, 11 Jan 2010 19:29:16 +0000 Subject: [PATCH] [HAL] - Move x86 emulator definitions into their own header - Fix handling of the real mode IDT in x86BiosCall - Implement HalpBiosDisplayReset - Fix a copy paste error svn path=/branches/ros-amd64-bringup/; revision=45047 --- reactos/hal/halx86/generic/amd64/x86bios.c | 156 ++++++--------- reactos/hal/halx86/generic/amd64/x86emu.h | 221 +++++++++++++++++++++ 2 files changed, 284 insertions(+), 93 deletions(-) create mode 100644 reactos/hal/halx86/generic/amd64/x86emu.h diff --git a/reactos/hal/halx86/generic/amd64/x86bios.c b/reactos/hal/halx86/generic/amd64/x86bios.c index 250c5ccc759..16e120ff8e0 100644 --- a/reactos/hal/halx86/generic/amd64/x86bios.c +++ b/reactos/hal/halx86/generic/amd64/x86bios.c @@ -12,6 +12,8 @@ //#define NDEBUG #include +#include "x86emu.h" + /* This page serves as fallback for pages used by Mm */ #define DEFAULT_PAGE 0x21 @@ -21,6 +23,24 @@ BOOLEAN x86BiosIsInitialized; LONG x86BiosBufferIsAllocated = 0; PUCHAR x86BiosMemoryMapping; + +VOID +NTAPI +DbgDumpPage(PUCHAR MemBuffer, USHORT Segment) +{ + ULONG x, y, Offset; + + for (y = 0; y < 0x100; y++) + { + for (x = 0; x < 0x10; x++) + { + Offset = Segment * 16 + y * 16 + x; + DbgPrint("%02x ", MemBuffer[Offset]); + } + DbgPrint("\n"); + } +} + VOID NTAPI HalInitializeBios(ULONG Unknown, PLOADER_PARAMETER_BLOCK LoaderBlock) @@ -62,7 +82,7 @@ HalInitializeBios(ULONG Unknown, PLOADER_PARAMETER_BLOCK LoaderBlock) { /* Check if the memory type is firmware */ if (Descriptor->MemoryType != LoaderFirmwarePermanent && - Descriptor->MemoryType != LoaderFirmwarePermanent) + Descriptor->MemoryType != LoaderSpecialMemory) { /* It's something else, so don't use it! */ Last = min(Descriptor->BasePage + Descriptor->PageCount, 0x100); @@ -82,13 +102,16 @@ HalInitializeBios(ULONG Unknown, PLOADER_PARAMETER_BLOCK LoaderBlock) ASSERT(x86BiosMemoryMapping); DPRINT1("memory: %p, %p\n", *(PVOID*)x86BiosMemoryMapping, *(PVOID*)(x86BiosMemoryMapping + 8)); + //DbgDumpPage(x86BiosMemoryMapping, 0xc351); x86BiosIsInitialized = TRUE; + + HalpBiosDisplayReset(); } NTSTATUS NTAPI -x86BiosAllocateBuffer ( +x86BiosAllocateBuffer( ULONG *Size, USHORT *Segment, USHORT *Offset) @@ -117,7 +140,7 @@ x86BiosAllocateBuffer ( NTSTATUS NTAPI -x86BiosFreeBuffer ( +x86BiosFreeBuffer( USHORT Segment, USHORT Offset) { @@ -141,7 +164,7 @@ x86BiosFreeBuffer ( NTSTATUS NTAPI -x86BiosReadMemory ( +x86BiosReadMemory( USHORT Segment, USHORT Offset, PVOID Buffer, @@ -168,7 +191,7 @@ x86BiosReadMemory ( NTSTATUS NTAPI -x86BiosWriteMemory ( +x86BiosWriteMemory( USHORT Segment, USHORT Offset, PVOID Buffer, @@ -193,97 +216,18 @@ x86BiosWriteMemory ( return STATUS_SUCCESS; } -typedef struct -{ - union - { - ULONG Eax; - USHORT Ax; - struct - { - UCHAR Al; - UCHAR Ah; - }; - }; - union - { - ULONG Ecx; - USHORT Cx; - struct - { - UCHAR Cl; - UCHAR Ch; - }; - }; - union - { - ULONG Edx; - USHORT Dx; - struct - { - UCHAR Dl; - UCHAR Dh; - }; - }; - union - { - ULONG Ebx; - USHORT Bx; - struct - { - UCHAR Bl; - UCHAR Bh; - }; - }; - ULONG Ebp; - ULONG Esi; - ULONG Edi; - USHORT SegDs; - USHORT SegEs; - - /* Extended */ - union - { - ULONG Eip; - USHORT Ip; - }; - - union - { - ULONG Esp; - USHORT Sp; - }; - -} X86_REGISTERS, *PX86_REGISTERS; - -enum -{ - X86_VMFLAGS_RETURN_ON_IRET = 1, -}; - -typedef struct -{ - union - { - X86_BIOS_REGISTERS BiosRegisters; - X86_REGISTERS Registers; - }; - - struct - { - ULONG ReturnOnIret:1; - } Flags; - - PVOID MemBuffer; -} X86_VM_STATE, *PX86_VM_STATE; - BOOLEAN NTAPI -x86BiosCall ( +x86BiosCall( ULONG InterruptNumber, X86_BIOS_REGISTERS *Registers) { X86_VM_STATE VmState; + struct + { + USHORT Ip; + USHORT SegCs; + } *InterrupTable; /* Zero the VmState */ RtlZeroMemory(&VmState, sizeof(VmState)); @@ -294,9 +238,18 @@ x86BiosCall ( /* Set the physical memory buffer */ VmState.MemBuffer = x86BiosMemoryMapping; - /* Initialize IP from the interrupt vector table */ - VmState.Registers.Ip = ((PUSHORT)x86BiosMemoryMapping)[InterruptNumber]; + /* Set Eflags */ + VmState.Registers.Eflags.Long = 0; // FIXME + /* Setup stack */ + VmState.Registers.SegSs = 0; // FIXME + VmState.Registers.Sp = 0x2000 - 2; // FIXME + + /* Initialize IP from the interrupt vector table */ + InterrupTable = (PVOID)x86BiosMemoryMapping; + VmState.Registers.SegCs = InterrupTable[InterruptNumber].SegCs; + VmState.Registers.Eip = InterrupTable[InterruptNumber].Ip; + /* Make the function return on IRET */ VmState.Flags.ReturnOnIret = 1; @@ -313,7 +266,24 @@ BOOLEAN NTAPI HalpBiosDisplayReset(VOID) { - UNIMPLEMENTED; + X86_BIOS_REGISTERS Registers; + ULONG OldEflags; + + /* Save flags and disable interrupts */ + OldEflags = __readeflags(); + _disable(); + + /* Set AH = 0 (Set video mode), AL = 0x12 (640x480x16 vga) */ + Registers.Eax = 0x12; + + /* Call INT 0x10 */ + x86BiosCall(0x10, &Registers); + + // FIXME: check result + + /* Restore previous flags */ + __writeeflags(OldEflags); + return TRUE; } diff --git a/reactos/hal/halx86/generic/amd64/x86emu.h b/reactos/hal/halx86/generic/amd64/x86emu.h new file mode 100644 index 00000000000..7e475c1b04f --- /dev/null +++ b/reactos/hal/halx86/generic/amd64/x86emu.h @@ -0,0 +1,221 @@ + +typedef union +{ + USHORT Short; + ULONG Long; + struct + { + ULONG Cf:1; + ULONG Pf:1; + ULONG Af:1; + ULONG Zf:1; + ULONG Sf:1; + ULONG Tf:1; + ULONG If:1; + ULONG Df:1; + ULONG Of:1; + ULONG Iopl:3; + ULONG Nt:1; + ULONG Rf:1; + ULONG Vm:1; + ULONG Ac:1; + ULONG Vif:1; + ULONG Vip:1; + ULONG Id:1; + }; +} EFLAGS; + +typedef union +{ + ULONG Dword; + USHORT Word; + UCHAR Byte; + struct + { + UCHAR Low; + UCHAR High; + }; +} REGU; + +typedef union +{ + struct + { + UCHAR mod:2; + UCHAR reg:3; + UCHAR rm:3; + }; + UCHAR Byte; +} MODRM; + +typedef struct +{ + union + { + ULONG Eax; + USHORT Ax; + struct + { + UCHAR Al; + UCHAR Ah; + }; + }; + union + { + ULONG Ecx; + USHORT Cx; + struct + { + UCHAR Cl; + UCHAR Ch; + }; + }; + union + { + ULONG Edx; + USHORT Dx; + struct + { + UCHAR Dl; + UCHAR Dh; + }; + }; + union + { + ULONG Ebx; + USHORT Bx; + struct + { + UCHAR Bl; + UCHAR Bh; + }; + }; + union + { + ULONG Ebp; + USHORT Bp; + }; + union + { + ULONG Esi; + USHORT Si; + }; + union + { + ULONG Edi; + USHORT Di; + }; + union + { + struct + { + ULONG ReservedDsMBZ:4; + ULONG SegDs:16; + }; + ULONG ShiftedDs; + }; + union + { + struct + { + ULONG ReservedEsMBZ:4; + ULONG SegEs:16; + }; + ULONG ShiftedEs; + }; + + /* Extended */ + union + { + struct + { + ULONG ReservedCsMBZ:4; + ULONG SegCs:16; + }; + ULONG ShiftedCs; + }; + union + { + struct + { + ULONG ReservedSsMBZ:4; + ULONG SegSs:16; + }; + ULONG ShiftedSs; + }; + + union + { + struct + { + ULONG ReservedMsMBZ:4; + ULONG SegMs:16; + }; + ULONG ShiftedMs; + }; + + union + { + ULONG Eip; + USHORT Ip; + }; + + union + { + ULONG Esp; + USHORT Sp; + }; + + EFLAGS Eflags; + +} X86_REGISTERS, *PX86_REGISTERS; + +enum +{ + X86_VMFLAGS_RETURN_ON_IRET = 1, +}; + +typedef struct +{ + union + { + X86_BIOS_REGISTERS BiosRegisters; + X86_REGISTERS Registers; + REGU IndexedRegisters[8]; + }; + + struct + { + ULONG ReturnOnIret:1; + } Flags; + + PVOID MemBuffer; + +#if 1 + PCHAR Mnemonic; + PCHAR DstReg; + PCHAR SrcReg; + ULONG SrcEncodung; + ULONG DstEncoding; + ULONG Length; +#endif +} X86_VM_STATE, *PX86_VM_STATE; + +enum +{ + PREFIX_SIZE_OVERRIDE = 0x010001, + PREFIX_ADDRESS_OVERRIDE = 0x020002, + PREFIX_SEGMENT_CS = 0x040004, + PREFIX_SEGMENT_DS = 0x040008, + PREFIX_SEGMENT_ES = 0x040010, + PREFIX_SEGMNET_FS = 0x040020, + PREFIX_SEGMENT_GS = 0x040040, + PREFIX_SEGMENT_SS = 0x040080, + PREFIX_LOCK = 0x080100, + PREFIX_REP = 0x100200, +} PREFIX_STATE; + + +VOID +NTAPI +x86Emulator(PX86_VM_STATE VmState);