- 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
This commit is contained in:
Timo Kreuzer
2010-01-11 19:29:16 +00:00
parent f6bd1f70d8
commit 4f3a2dfc7e
2 changed files with 284 additions and 93 deletions
+63 -93
View File
@@ -12,6 +12,8 @@
//#define NDEBUG
#include <debug.h>
#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;
}
+221
View File
@@ -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);