Mega compiler intrinsics patch:

FreeLdr
- Goodbye Ke386EraseFlags & KeAmd64EraseFlags. Welcome __writeeflags.
- Respect MSVC when generating clc (clear carry flag) instruction in PcGetTime.
- Use portable __wbinvd instead of __asm__ in XboxMemInit.
- Replace broken gcc assembly by portable intrinsics in WinLdrpMapApic.
- Use portable Ke386SetSs and Ke386SetGs (new) in WinLdrSetProcessorContext.
- The far jump in WinLdrSetProcessorContext can not be expressed in masm, so we use a (untested) far return instead.

Kernel
- Replace Ke386Set/GetInterruptDescriptorTable, Ke386Save/RestoreFlags, Ke386Set/GetDr, Ki386Cpuid, Ke386Rdmsr and Ke386Wrmsr by MSVC alternatives present in intrin.h.
- Fixed Ke386Get/SetGlobalDescriptorTable, Ke386GetLocalDescriptorTable and Ke386GetTr -- the intrinsics were completely broken for MSVC and generated bogus code. Moreover, Ke386Set/GetInterruptDescriptorTable and Ke386Rdmsr were also affected. This lets us (in addition to having a bootable, working msvc compiled kernel) get rid of several hacky variable zero-initializations that hid this bug -- the way MSVC interpreted the inlined assembly resulted in uninitialized variable usage.
- Implement Ke386SetGs and add missing Ke386SetGs for gcc.
- KdPollBreakIn: Use portable KeDisableInterrupts instead of x86 intrinsics and flags.

svn path=/trunk/; revision=43103
This commit is contained in:
Stefan Ginsberg 2009-09-21 15:20:18 +00:00
parent 302ad7c74f
commit 53231784a0
17 changed files with 158 additions and 377 deletions

View file

@ -90,7 +90,7 @@ FrLdrStartup(ULONG Magic)
_disable();
/* Re-initalize EFLAGS */
KeAmd64EraseFlags();
__writeeflags(0);
/* Initialize the page directory */
FrLdrSetupPageDirectory();

View file

@ -58,7 +58,7 @@ FrLdrStartup(ULONG Magic)
_disable();
/* Re-initalize EFLAGS */
Ke386EraseFlags();
__writeeflags(0);
/* Initialize the page directory */
FrLdrSetupPageDirectory();

View file

@ -19,6 +19,19 @@
#include <freeldr.h>
FORCEINLINE
VOID
ClearCarryFlag(VOID)
{
#if defined(__GNUC__)
__asm__ ("clc");
#elif defined(_MSC_VER)
__asm clc;
#else
#error
#endif
}
#define BCD_INT(bcd) (((bcd & 0xf0) >> 4) * 10 + (bcd &0x0f))
TIMEINFO*
@ -31,7 +44,7 @@ PcGetTime(VOID)
* in the Compaq Deskpro EP/SB, leave CF unchanged
* if successful, so CF should be cleared before
* calling this function. */
__asm__ ("clc");
ClearCarryFlag();
/* Int 1Ah AH=04h
* TIME - GET REAL-TIME CLOCK DATE (AT,XT286,PS)
@ -55,7 +68,7 @@ PcGetTime(VOID)
/* Some BIOSes leave CF unchanged if successful,
* so CF should be cleared before calling this function. */
__asm__ ("clc");
ClearCarryFlag();
/* Int 1Ah AH=02h
* TIME - GET REAL-TIME CLOCK TIME (AT,XT286,PS)

View file

@ -45,14 +45,14 @@ XboxMemInit(VOID)
InstalledMemoryMb = 64;
memset(ControlRegion, TEST_PATTERN1, TEST_SIZE);
memset(MembaseTop, TEST_PATTERN1, TEST_SIZE);
__asm__ ("wbinvd\n");
__wbinvd();
if (0 == memcmp(MembaseTop, ControlRegion, TEST_SIZE))
{
/* Looks like there is memory .. maybe a 128MB box */
memset(ControlRegion, TEST_PATTERN2, TEST_SIZE);
memset(MembaseTop, TEST_PATTERN2, TEST_SIZE);
__asm__ ("wbinvd\n");
__wbinvd();
if (0 == memcmp(MembaseTop, ControlRegion, TEST_SIZE))
{
/* Definitely looks like there is memory */

View file

@ -109,25 +109,6 @@
/* Swap */
#include <bytesex.h>
/* arch defines */
#ifdef __GNUC__
#ifdef _X86_
#define Ke386EraseFlags() __asm__ __volatile__("pushl $0 ; popfl\n")
#endif
#ifdef _M_AMD64
#define KeAmd64EraseFlags() __asm__ __volatile__("pushq $0 ; popfq\n")
#endif
#else
#ifdef _X86_
#define Ke386EraseFlags() __asm push 0; __asm popf;
#endif
#ifdef _M_AMD64
#error FIXME
#endif
#endif
VOID BootMain(LPSTR CmdLine);
VOID RunLoader(VOID);

View file

@ -401,33 +401,24 @@ MempAddMemoryBlock(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
}
#ifdef _M_IX86
BOOLEAN LocalAPIC = FALSE;
ULONG_PTR APICAddress = 0;
VOID
WinLdrpMapApic()
{
BOOLEAN LocalAPIC;
LARGE_INTEGER MsrValue;
ULONG APICAddress, CpuInfo[4];
/* Check if we have a local APIC */
asm(".intel_syntax noprefix\n");
asm("mov eax, 1\n");
asm("cpuid\n");
asm("shr edx, 9\n");
asm("and edx, 0x1\n");
asm("mov _LocalAPIC, edx\n");
asm(".att_syntax\n");
__cpuid((int*)CpuInfo, 1);
LocalAPIC = (((CpuInfo[3] >> 9) & 1) != 0);
/* If there is no APIC, just return */
if (!LocalAPIC)
return;
asm(".intel_syntax noprefix\n");
asm("mov ecx, 0x1B\n");
asm("rdmsr\n");
asm("mov edx, eax\n");
asm("and edx, 0xFFFFF000\n");
asm("mov _APICAddress, edx");
asm(".att_syntax\n");
/* Read the APIC Address */
MsrValue.QuadPart = __readmsr(0x1B);
APICAddress = (MsrValue.LowPart & 0xFFFFF000);
DPRINTM(DPRINT_WINDOWS, "Local APIC detected at address 0x%x\n",
APICAddress);
@ -643,7 +634,7 @@ WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
_disable();
// Re-initalize EFLAGS
Ke386EraseFlags();
__writeeflags(0);
// Set the PDBR
__writecr3((ULONG_PTR)PDE);
@ -743,8 +734,8 @@ WinLdrSetProcessorContext(PVOID GdtIdt, IN ULONG Pcr, IN ULONG Tss)
RtlZeroMemory((PVOID)Pcr, MM_PAGE_SIZE); //FIXME: Why zero only 1 page when we allocate 2?
// Get old values of GDT and IDT
Ke386GetGlobalDescriptorTable(GdtDesc);
Ke386GetInterruptDescriptorTable(IdtDesc);
Ke386GetGlobalDescriptorTable(&GdtDesc);
__sidt(&IdtDesc);
// Save old IDT
OldIdt.Base = IdtDesc.Base;
@ -918,18 +909,28 @@ WinLdrSetProcessorContext(PVOID GdtIdt, IN ULONG Pcr, IN ULONG Tss)
//asm("cli\n"); // they are already masked before enabling paged mode
// Load GDT+IDT
Ke386SetGlobalDescriptorTable(GdtDesc);
Ke386SetInterruptDescriptorTable(IdtDesc);
Ke386SetGlobalDescriptorTable(&GdtDesc);
__lidt(&IdtDesc);
// Jump to proper CS and clear prefetch queue
#if defined(__GNUC__)
asm("ljmp $0x08, $1f\n"
"1:\n");
#elif defined(_MSC_VER)
/* We can't express the above in MASM so we use this far return instead */
DbgPrint("WinLdrSetProcessorContext: Performing untested far-return\n");
__asm {
push 8
push offset resume
retf
resume:
};
#else
#error
#endif
// Set SS selector
asm(".intel_syntax noprefix\n");
asm("mov ax, 0x10\n"); // DataSelector=0x10
asm("mov ss, ax\n");
asm(".att_syntax\n");
Ke386SetSs(0x10); // DataSelector=0x10
// Set DS and ES selectors
Ke386SetDs(0x10);
@ -942,10 +943,7 @@ WinLdrSetProcessorContext(PVOID GdtIdt, IN ULONG Pcr, IN ULONG Tss)
Ke386SetTr(0x28);
// Clear GS
asm(".intel_syntax noprefix\n");
asm("push 0\n");
asm("pop gs\n");
asm(".att_syntax\n");
Ke386SetGs(0);
// Set FS to PCR
Ke386SetFs(0x30);

View file

@ -238,7 +238,7 @@ CmpInitializeMachineDependentConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBloc
HANDLE KeyHandle, BiosHandle, SystemHandle, FpuHandle, SectionHandle;
CONFIGURATION_COMPONENT_DATA ConfigData;
CHAR Buffer[128];
ULONG ExtendedId, Dummy;
ULONG ExtendedId, CpuInfo[4];
PKPRCB Prcb;
USHORT IndexTable[MaximumType + 1] = {0};
ANSI_STRING TempString;
@ -428,19 +428,17 @@ CmpInitializeMachineDependentConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBloc
else
{
/* Check if we have extended CPUID that supports name ID */
Ki386Cpuid(0x80000000, &ExtendedId, &Dummy, &Dummy, &Dummy);
CPUID(CpuInfo, 0x80000000);
ExtendedId = CpuInfo[0];
if (ExtendedId >= 0x80000004)
{
/* Do all the CPUIDs requred to get the full name */
/* Do all the CPUIDs required to get the full name */
PartialString = CpuString;
for (ExtendedId = 2; ExtendedId <= 4; ExtendedId++)
{
/* Do the CPUID and save the name string */
Ki386Cpuid(0x80000000 | ExtendedId,
(PULONG)PartialString,
(PULONG)PartialString + 1,
(PULONG)PartialString + 2,
(PULONG)PartialString + 3);
CPUID((PULONG)PartialString,
0x80000000 | ExtendedId);
/* Go to the next name string */
PartialString += 16;

View file

@ -9,31 +9,20 @@
#if defined(__GNUC__)
#define Ke386SetInterruptDescriptorTable(X) \
__asm__("lidt %0\n\t" \
: /* no outputs */ \
: "m" (X));
#define Ke386GetInterruptDescriptorTable(X) \
__asm__("sidt %0\n\t" \
: "=m" (X) \
: /* no input */ \
: "memory");
#define Ke386SetGlobalDescriptorTable(X) \
__asm__("lgdt %0\n\t" \
: /* no outputs */ \
: "m" (X));
: "m" (*X));
#define Ke386GetGlobalDescriptorTable(X) \
__asm__("sgdt %0\n\t" \
: "=m" (X) \
: "=m" (*X) \
: /* no input */ \
: "memory");
#define Ke386GetLocalDescriptorTable(X) \
__asm__("sldt %0\n\t" \
: "=m" (X) \
: "=m" (*X) \
: /* no input */ \
: "memory");
@ -46,10 +35,7 @@
#define Ke386GetTr(X) \
__asm__("str %0\n\t" \
: "=m" (X));
#define Ke386SaveFlags(x) __asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */)
#define Ke386RestoreFlags(x) __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory")
: "=m" (*X));
#define _Ke386GetSeg(N) ({ \
unsigned int __d; \
@ -59,25 +45,6 @@
#define _Ke386SetSeg(N,X) __asm__ __volatile__("movl %0,%%" #N : :"r" (X));
#define _Ke386GetDr(N) ({ \
unsigned int __d; \
__asm__("movl %%dr" #N ",%0\n\t" :"=r" (__d)); \
__d; \
})
#define _Ke386SetDr(N,X) __asm__ __volatile__("movl %0,%%dr" #N : :"r" (X));
static inline void Ki386Cpuid(ULONG Op, PULONG Eax, PULONG Ebx, PULONG Ecx, PULONG Edx)
{
__asm__("cpuid"
: "=a" (*Eax), "=b" (*Ebx), "=c" (*Ecx), "=d" (*Edx)
: "0" (Op));
}
#define Ke386Rdmsr(msr,val1,val2) __asm__ __volatile__("rdmsr" : "=a" (val1), "=d" (val2) : "c" (msr))
#define Ke386Wrmsr(msr,val1,val2) __asm__ __volatile__("wrmsr" : /* no outputs */ : "c" (msr), "a" (val1), "d" (val2))
#define Ke386HaltProcessor() __asm__("hlt\n\t");
#define Ke386FnInit() __asm__("fninit\n\t");
@ -88,24 +55,6 @@ static inline void Ki386Cpuid(ULONG Op, PULONG Eax, PULONG Ebx, PULONG Ecx, PULO
//
#define Ke386SetCr2(X) __asm__ __volatile__("movl %0,%%cr2" : :"r" (X));
//
// DR Macros
//
#define Ke386GetDr0() _Ke386GetDr(0)
#define Ke386GetDr1() _Ke386GetDr(1)
#define Ke386SetDr0(X) _Ke386SetDr(0,X)
#define Ke386SetDr1(X) _Ke386SetDr(1,X)
#define Ke386GetDr2() _Ke386GetDr(2)
#define Ke386SetDr2(X) _Ke386SetDr(2,X)
#define Ke386GetDr3() _Ke386GetDr(3)
#define Ke386SetDr3(X) _Ke386SetDr(3,X)
#define Ke386GetDr4() _Ke386GetDr(4)
#define Ke386SetDr4(X) _Ke386SetDr(4,X)
#define Ke386GetDr6() _Ke386GetDr(6)
#define Ke386SetDr6(X) _Ke386SetDr(6,X)
#define Ke386GetDr7() _Ke386GetDr(7)
#define Ke386SetDr7(X) _Ke386SetDr(7,X)
//
// Segment Macros
//
@ -114,49 +63,11 @@ static inline void Ki386Cpuid(ULONG Op, PULONG Eax, PULONG Ebx, PULONG Ecx, PULO
#define Ke386SetFs(X) _Ke386SetSeg(fs, X)
#define Ke386SetDs(X) _Ke386SetSeg(ds, X)
#define Ke386SetEs(X) _Ke386SetSeg(es, X)
#define Ke386SetSs(X) _Ke386SetSeg(ss, X)
#define Ke386SetGs(X) _Ke386SetSeg(gs, X)
#elif defined(_MSC_VER)
FORCEINLINE
VOID
Ke386Wrmsr(IN ULONG Register,
IN ULONG Var1,
IN ULONG Var2)
{
__asm mov ecx, Register;
__asm mov eax, Var1;
__asm mov edx, Var2;
__asm wrmsr;
}
FORCEINLINE
ULONGLONG
Ke386Rdmsr(IN ULONG Register,
IN ULONG Var1,
IN ULONG Var2)
{
__asm mov ecx, Register;
__asm mov eax, Var1;
__asm mov edx, Var2;
__asm rdmsr;
}
FORCEINLINE
VOID
Ki386Cpuid(IN ULONG Operation,
OUT PULONG Var1,
OUT PULONG Var2,
OUT PULONG Var3,
OUT PULONG Var4)
{
__asm mov eax, Operation;
__asm cpuid;
__asm mov [Var1], eax;
__asm mov [Var2], ebx;
__asm mov [Var3], ecx;
__asm mov [Var4], edx;
}
FORCEINLINE
VOID
Ke386FnInit(VOID)
@ -173,37 +84,25 @@ Ke386HaltProcessor(VOID)
FORCEINLINE
VOID
Ke386GetInterruptDescriptorTable(OUT KDESCRIPTOR Descriptor)
Ke386GetGlobalDescriptorTable(OUT PVOID Descriptor)
{
__asm sidt Descriptor;
__asm sgdt [Descriptor];
}
FORCEINLINE
VOID
Ke386SetInterruptDescriptorTable(IN KDESCRIPTOR Descriptor)
Ke386SetGlobalDescriptorTable(IN PVOID Descriptor)
{
__asm lidt Descriptor;
__asm lgdt [Descriptor];
}
FORCEINLINE
VOID
Ke386GetGlobalDescriptorTable(OUT KDESCRIPTOR Descriptor)
Ke386GetLocalDescriptorTable(OUT PUSHORT Descriptor)
{
__asm sgdt Descriptor;
}
FORCEINLINE
VOID
Ke386SetGlobalDescriptorTable(IN KDESCRIPTOR Descriptor)
{
__asm lgdt Descriptor;
}
FORCEINLINE
VOID
Ke386GetLocalDescriptorTable(OUT USHORT Descriptor)
{
__asm sldt Descriptor;
USHORT _Descriptor;
__asm sldt _Descriptor;
*Descriptor = _Descriptor;
}
FORCEINLINE
@ -213,22 +112,6 @@ Ke386SetLocalDescriptorTable(IN USHORT Descriptor)
__asm lldt Descriptor;
}
FORCEINLINE
VOID
Ke386SaveFlags(IN ULONG Flags)
{
__asm pushf;
__asm pop Flags;
}
FORCEINLINE
VOID
Ke386RestoreFlags(IN ULONG Flags)
{
__asm push Flags;
__asm popf;
}
FORCEINLINE
VOID
Ke386SetTr(IN USHORT Tr)
@ -238,9 +121,11 @@ Ke386SetTr(IN USHORT Tr)
FORCEINLINE
USHORT
Ke386GetTr(IN USHORT Tr)
Ke386GetTr(OUT PUSHORT Tr)
{
__asm str Tr;
USHORT _Tr;
__asm str _Tr;
*Tr = _Tr;
}
//
@ -254,99 +139,6 @@ Ke386SetCr2(IN ULONG Value)
__asm mov cr2, eax;
}
//
// DR Macros
//
FORCEINLINE
ULONG
Ke386GetDr0(VOID)
{
__asm mov eax, dr0;
}
FORCEINLINE
ULONG
Ke386GetDr1(VOID)
{
__asm mov eax, dr1;
}
FORCEINLINE
ULONG
Ke386GetDr2(VOID)
{
__asm mov eax, dr2;
}
FORCEINLINE
ULONG
Ke386GetDr3(VOID)
{
__asm mov eax, dr3;
}
FORCEINLINE
ULONG
Ke386GetDr6(VOID)
{
__asm mov eax, dr6;
}
FORCEINLINE
ULONG
Ke386GetDr7(VOID)
{
__asm mov eax, dr7;
}
FORCEINLINE
VOID
Ke386SetDr0(IN ULONG Value)
{
__asm mov eax, Value;
__asm mov dr0, eax;
}
FORCEINLINE
VOID
Ke386SetDr1(IN ULONG Value)
{
__asm mov eax, Value;
__asm mov dr1, eax;
}
FORCEINLINE
VOID
Ke386SetDr2(IN ULONG Value)
{
__asm mov eax, Value;
__asm mov dr2, eax;
}
FORCEINLINE
VOID
Ke386SetDr3(IN ULONG Value)
{
__asm mov eax, Value;
__asm mov dr3, eax;
}
FORCEINLINE
VOID
Ke386SetDr6(IN ULONG Value)
{
__asm mov eax, Value;
__asm mov dr6, eax;
}
FORCEINLINE
VOID
Ke386SetDr7(IN ULONG Value)
{
__asm mov eax, Value;
__asm mov dr7, eax;
}
//
// Segment Macros
//
@ -410,6 +202,14 @@ Ke386SetEs(IN USHORT Value)
__asm mov es, ax;
}
FORCEINLINE
VOID
Ke386SetGs(IN USHORT Value)
{
__asm mov ax, Value;
__asm mov gs, ax;
}
#else
#error Unknown compiler for inline assembler
#endif

View file

@ -994,6 +994,7 @@ NTAPI
KiI386PentiumLockErrataFixup(VOID);
VOID
NTAPI
WRMSR(
IN ULONG Register,
IN LONGLONG Value

View file

@ -1115,7 +1115,7 @@ GspUnloadBreakpoints(void)
DPRINT("GspUnloadBreakpoints\n");
/* Disable hardware debugging while we are inside the stub */
Ke386SetDr7(0);
__writedr(7, 0);
for (Index = 0; Index < GspSwBreakpointCount; Index++)
{
@ -1402,7 +1402,7 @@ KdpGdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
if (Stepping)
Context->EFlags |= EFLAGS_TF;
Dr6 = Ke386GetDr6();
Dr6 = __readdr(6);
if (!(Dr6 & DR6_BS))
{
for (BreakpointNumber = 0;
@ -1422,7 +1422,7 @@ KdpGdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
}
GspLoadBreakpoints(TrapFrame);
Ke386SetDr6(0);
__writedr(6, 0);
if (NULL != GspDbgThread)
{

View file

@ -74,16 +74,13 @@ BOOLEAN
NTAPI
KdPollBreakIn(VOID)
{
BOOLEAN DoBreak = FALSE;
ULONG Flags = 0;
BOOLEAN DoBreak = FALSE, Enable;
/* First make sure that KD is enabled */
if (KdDebuggerEnabled)
{
/* Disable interrupts */
Ke386SaveFlags(Flags);
//Flags = __getcallerseflags();
_disable();
Enable = KeDisableInterrupts();
/* Check if a CTRL-C is in the queue */
if (KdpContext.KdpControlCPending)
@ -115,11 +112,10 @@ KdPollBreakIn(VOID)
}
}
/* Re-enable interrupts if they were disabled */
if (Flags & EFLAGS_INTERRUPT_MASK) _enable();
/* Re-enable interrupts if they were enabled previously */
if (Enable) _enable();
}
/* Tell the caller to do a break */
return DoBreak;
}

View file

@ -413,7 +413,7 @@ KdbpStepIntoInstruction(
}
/* Read the interrupt descriptor table register */
Ke386GetInterruptDescriptorTable(*(PKDESCRIPTOR)&Idtr.Limit);
__sidt(&Idtr.Limit);
if (IntVect >= (Idtr.Limit + 1) / 8)
{
/*KdbpPrint("IDT does not contain interrupt vector %d\n.", IntVect);*/
@ -1573,14 +1573,7 @@ KdbEnterDebuggerException(
ULONG_PTR TrapCr2;
ULONG Err;
#ifdef __GNUC__
asm volatile("movl %%cr2, %0" : "=r"(TrapCr2));
#elif _MSC_VER
__asm mov eax, cr2;
__asm mov TrapCr2, eax;
#else
#error Unknown compiler for inline assembler
#endif
TrapCr2 = __readcr2();
Err = TrapFrame->ErrCode;
KdbpPrint("Memory at 0x%p could not be %s: ", TrapCr2, (Err & (1 << 1)) ? "written" : "read");
@ -1611,13 +1604,13 @@ KdbEnterDebuggerException(
KdbpTrapFrameToKdbTrapFrame(TrapFrame, &KdbTrapFrame);
/* Enter critical section */
Ke386SaveFlags(OldEflags);
OldEflags = __readeflags();
_disable();
/* Exception inside the debugger? Game over. */
if (InterlockedIncrement(&KdbEntryCount) > 1)
{
Ke386RestoreFlags(OldEflags);
__writeeflags(OldEflags);
return kdHandleException;
}
@ -1654,7 +1647,7 @@ KdbEnterDebuggerException(
InterlockedDecrement(&KdbEntryCount);
/* Leave critical section */
Ke386RestoreFlags(OldEflags);
__writeeflags(OldEflags);
/* Check if user requested a bugcheck */
if (KdbpBugCheckRequested)

View file

@ -648,8 +648,8 @@ KdbpCmdRegs(
else if (Argv[0][0] == 'c') /* cregs */
{
ULONG Cr0, Cr2, Cr3, Cr4;
KDESCRIPTOR Gdtr = {0}, Ldtr = {0}, Idtr = {0};
ULONG Tr = 0;
KDESCRIPTOR Gdtr, Ldtr, Idtr;
ULONG Tr;
static const PCHAR Cr0Bits[32] = { " PE", " MP", " EM", " TS", " ET", " NE", NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
" WP", NULL, " AM", NULL, NULL, NULL, NULL, NULL,
@ -665,12 +665,12 @@ KdbpCmdRegs(
Cr4 = KdbCurrentTrapFrame->Cr4;
/* Get descriptor table regs */
Ke386GetGlobalDescriptorTable(*(PKDESCRIPTOR)&Gdtr.Limit);
Ke386GetLocalDescriptorTable(Ldtr.Limit);
Ke386GetInterruptDescriptorTable(*(PKDESCRIPTOR)&Idtr.Limit);
Ke386GetGlobalDescriptorTable(&Gdtr.Limit);
Ke386GetLocalDescriptorTable(&Ldtr.Limit);
__sidt(&Idtr.Limit);
/* Get the task register */
Ke386GetTr(Tr);
Ke386GetTr((PUSHORT)&Tr);
/* Display the control registers */
KdbpPrint("CR0 0x%08x ", Cr0);
@ -1541,7 +1541,7 @@ KdbpCmdGdtLdtIdt(
ULONG Argc,
PCHAR Argv[])
{
KDESCRIPTOR Reg = {0};
KDESCRIPTOR Reg;
ULONG SegDesc[2];
ULONG SegBase;
ULONG SegLimit;
@ -1554,7 +1554,7 @@ KdbpCmdGdtLdtIdt(
if (Argv[0][0] == 'i')
{
/* Read IDTR */
Ke386GetInterruptDescriptorTable(*(PKDESCRIPTOR)&Reg.Limit);
__sidt(&Reg.Limit);
if (Reg.Limit < 7)
{
@ -1614,7 +1614,7 @@ KdbpCmdGdtLdtIdt(
if (Argv[0][0] == 'g')
{
/* Read GDTR */
Ke386GetGlobalDescriptorTable(*(PKDESCRIPTOR)&Reg.Limit);
Ke386GetGlobalDescriptorTable(&Reg.Limit);
i = 8;
}
else
@ -1622,7 +1622,7 @@ KdbpCmdGdtLdtIdt(
ASSERT(Argv[0][0] == 'l');
/* Read LDTR */
Ke386GetLocalDescriptorTable(Reg.Limit);
Ke386GetLocalDescriptorTable(&Reg.Limit);
i = 0;
ul = 1 << 2;
}
@ -2742,7 +2742,7 @@ KdbpCliInit()
HANDLE hFile = NULL;
INT FileSize;
PCHAR FileBuffer;
ULONG OldEflags = 0;
ULONG OldEflags;
/* Initialize the object attributes */
RtlInitUnicodeString(&FileName, L"\\SystemRoot\\system32\\drivers\\etc\\KDBinit");
@ -2793,7 +2793,7 @@ KdbpCliInit()
FileBuffer[FileSize] = '\0';
/* Enter critical section */
Ke386SaveFlags(OldEflags);
OldEflags = __readeflags();
_disable();
/* Interpret the init file... */
@ -2802,7 +2802,7 @@ KdbpCliInit()
KdbInitFileBuffer = NULL;
/* Leave critical section */
Ke386RestoreFlags(OldEflags);
__writeeflags(OldEflags);
ExFreePool(FileBuffer);
}

View file

@ -1269,16 +1269,16 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy,
#if defined(_M_IX86)
PKTSS Tss;
PKGDTENTRY TssEntry;
KDESCRIPTOR IdtDescriptor = { 0, 0, 0 };
KDESCRIPTOR IdtDescriptor;
Ke386GetInterruptDescriptorTable(*(PKDESCRIPTOR)&IdtDescriptor.Limit);
__sidt(&IdtDescriptor.Limit);
RtlCopyMemory(KiHackIdt, (PVOID)IdtDescriptor.Base, IdtDescriptor.Limit + 1);
IdtDescriptor.Base = (ULONG)&KiHackIdt;
IdtDescriptor.Limit = sizeof(KiHackIdt) - 1;
/* Load the GDT and IDT */
Ke386SetGlobalDescriptorTable(*(PKDESCRIPTOR)&KiGdtDescriptor.Limit);
Ke386SetInterruptDescriptorTable(*(PKDESCRIPTOR)&IdtDescriptor.Limit);
Ke386SetGlobalDescriptorTable(&KiGdtDescriptor.Limit);
__lidt(&IdtDescriptor.Limit);
/* Initialize the boot TSS */
Tss = &KiBootTss;

View file

@ -90,24 +90,25 @@ NTAPI
CPUID(OUT ULONG CpuInfo[4],
IN ULONG InfoType)
{
Ki386Cpuid(InfoType, &CpuInfo[0], &CpuInfo[1], &CpuInfo[2], &CpuInfo[3]);
/* Perform the CPUID Operation */
__cpuid((int*)CpuInfo, InfoType);
}
VOID
NTAPI
WRMSR(IN ULONG Register,
IN LONGLONG Value)
{
LARGE_INTEGER LargeVal;
LargeVal.QuadPart = Value;
Ke386Wrmsr(Register, LargeVal.HighPart, LargeVal.LowPart);
/* Write to the MSR */
__writemsr(Register, Value);
}
LONGLONG
NTAPI
RDMSR(IN ULONG Register)
{
LARGE_INTEGER LargeVal = {{0, 0}};
Ke386Rdmsr(Register, LargeVal.HighPart, LargeVal.LowPart);
return LargeVal.QuadPart;
/* Read from the MSR */
return __readmsr(Register);
}
/* FUNCTIONS *****************************************************************/
@ -116,7 +117,7 @@ VOID
NTAPI
KiSetProcessorType(VOID)
{
ULONG EFlags = 0, NewEFlags;
ULONG EFlags, NewEFlags;
ULONG Reg[4];
ULONG Stepping, Type;
@ -124,19 +125,19 @@ KiSetProcessorType(VOID)
KeGetCurrentPrcb()->CpuID = 0;
/* Save EFlags */
Ke386SaveFlags(EFlags);
EFlags = __readeflags();
/* XOR out the ID bit and update EFlags */
NewEFlags = EFlags ^ EFLAGS_ID;
Ke386RestoreFlags(NewEFlags);
__writeeflags(NewEFlags);
/* Get them back and see if they were modified */
Ke386SaveFlags(NewEFlags);
NewEFlags = __readeflags();
if (NewEFlags != EFlags)
{
/* The modification worked, so CPUID exists. Set the ID Bit again. */
EFlags |= EFLAGS_ID;
Ke386RestoreFlags(EFlags);
__writeeflags(EFlags);
/* Peform CPUID 0 to see if CPUID 1 is supported */
CPUID(Reg, 0);
@ -175,7 +176,7 @@ KiSetProcessorType(VOID)
}
/* Restore EFLAGS */
Ke386RestoreFlags(EFlags);
__writeeflags(EFlags);
}
ULONG
@ -720,18 +721,18 @@ KiRestoreProcessorControlState(PKPROCESSOR_STATE ProcessorState)
//
// Restore the DR registers
//
Ke386SetDr0(ProcessorState->SpecialRegisters.KernelDr0);
Ke386SetDr1(ProcessorState->SpecialRegisters.KernelDr1);
Ke386SetDr2(ProcessorState->SpecialRegisters.KernelDr2);
Ke386SetDr3(ProcessorState->SpecialRegisters.KernelDr3);
Ke386SetDr6(ProcessorState->SpecialRegisters.KernelDr6);
Ke386SetDr7(ProcessorState->SpecialRegisters.KernelDr7);
__writedr(0, ProcessorState->SpecialRegisters.KernelDr0);
__writedr(1, ProcessorState->SpecialRegisters.KernelDr1);
__writedr(2, ProcessorState->SpecialRegisters.KernelDr2);
__writedr(3, ProcessorState->SpecialRegisters.KernelDr3);
__writedr(6, ProcessorState->SpecialRegisters.KernelDr6);
__writedr(7, ProcessorState->SpecialRegisters.KernelDr7);
//
// Restore GDT, IDT, LDT and TSS
//
Ke386SetGlobalDescriptorTable(*(PKDESCRIPTOR)&ProcessorState->SpecialRegisters.Gdtr.Limit);
Ke386SetInterruptDescriptorTable(*(PKDESCRIPTOR)&ProcessorState->SpecialRegisters.Idtr.Limit);
Ke386SetGlobalDescriptorTable(&ProcessorState->SpecialRegisters.Gdtr.Limit);
__lidt(&ProcessorState->SpecialRegisters.Idtr.Limit);
Ke386SetTr(ProcessorState->SpecialRegisters.Tr);
Ke386SetLocalDescriptorTable(ProcessorState->SpecialRegisters.Ldtr);
}
@ -748,19 +749,19 @@ KiSaveProcessorControlState(OUT PKPROCESSOR_STATE ProcessorState)
__readcr4() : 0;
/* Save the DR registers */
ProcessorState->SpecialRegisters.KernelDr0 = Ke386GetDr0();
ProcessorState->SpecialRegisters.KernelDr1 = Ke386GetDr1();
ProcessorState->SpecialRegisters.KernelDr2 = Ke386GetDr2();
ProcessorState->SpecialRegisters.KernelDr3 = Ke386GetDr3();
ProcessorState->SpecialRegisters.KernelDr6 = Ke386GetDr6();
ProcessorState->SpecialRegisters.KernelDr7 = Ke386GetDr7();
Ke386SetDr7(0);
ProcessorState->SpecialRegisters.KernelDr0 = __readdr(0);
ProcessorState->SpecialRegisters.KernelDr1 = __readdr(1);
ProcessorState->SpecialRegisters.KernelDr2 = __readdr(2);
ProcessorState->SpecialRegisters.KernelDr3 = __readdr(3);
ProcessorState->SpecialRegisters.KernelDr6 = __readdr(6);
ProcessorState->SpecialRegisters.KernelDr7 = __readdr(7);
__writedr(7, 0);
/* Save GDT, IDT, LDT and TSS */
Ke386GetGlobalDescriptorTable(*(PKDESCRIPTOR)&ProcessorState->SpecialRegisters.Gdtr.Limit);
Ke386GetInterruptDescriptorTable(*(PKDESCRIPTOR)&ProcessorState->SpecialRegisters.Idtr.Limit);
Ke386GetTr(ProcessorState->SpecialRegisters.Tr);
Ke386GetLocalDescriptorTable(ProcessorState->SpecialRegisters.Ldtr);
Ke386GetGlobalDescriptorTable(&ProcessorState->SpecialRegisters.Gdtr.Limit);
__sidt(&ProcessorState->SpecialRegisters.Idtr.Limit);
Ke386GetTr(&ProcessorState->SpecialRegisters.Tr);
Ke386GetLocalDescriptorTable(&ProcessorState->SpecialRegisters.Ldtr);
}
VOID
@ -776,11 +777,11 @@ NTAPI
KiLoadFastSyscallMachineSpecificRegisters(IN ULONG_PTR Context)
{
/* Set CS and ESP */
Ke386Wrmsr(0x174, KGDT_R0_CODE, 0);
Ke386Wrmsr(0x175, (ULONG)KeGetCurrentPrcb()->DpcStack, 0);
WRMSR(0x174, KGDT_R0_CODE);
WRMSR(0x175, (ULONG_PTR)KeGetCurrentPrcb()->DpcStack);
/* Set LSTAR */
Ke386Wrmsr(0x176, (ULONG)KiFastCallEntry, 0);
WRMSR(0x176, (ULONG_PTR)KiFastCallEntry);
return 0;
}
@ -842,7 +843,7 @@ VOID
NTAPI
KiI386PentiumLockErrataFixup(VOID)
{
KDESCRIPTOR IdtDescriptor = { 0, 0, 0 };
KDESCRIPTOR IdtDescriptor;
PKIDTENTRY NewIdt, NewIdt2;
/* Allocate memory for a new IDT */
@ -855,14 +856,14 @@ KiI386PentiumLockErrataFixup(VOID)
_disable();
/* Get the current IDT and copy it */
Ke386GetInterruptDescriptorTable(*(PKDESCRIPTOR)&IdtDescriptor.Limit);
__sidt(&IdtDescriptor.Limit);
RtlCopyMemory(NewIdt2,
(PVOID)IdtDescriptor.Base,
IdtDescriptor.Limit + 1);
IdtDescriptor.Base = (ULONG)NewIdt2;
/* Set the new IDT */
Ke386SetInterruptDescriptorTable(*(PKDESCRIPTOR)&IdtDescriptor.Limit);
__lidt(&IdtDescriptor.Limit);
((PKIPCR)KeGetPcr())->IDT = NewIdt2;
/* Restore interrupts */
@ -877,10 +878,10 @@ NTAPI
KeFreezeExecution(IN PKTRAP_FRAME TrapFrame,
IN PKEXCEPTION_FRAME ExceptionFrame)
{
ULONG Flags = 0;
ULONG Flags;
/* Disable interrupts and get previous state */
Ke386SaveFlags(Flags);
Flags = __readeflags();
//Flags = __getcallerseflags();
_disable();

View file

@ -27,11 +27,11 @@ BOOLEAN
NTAPI
KeDisableInterrupts(VOID)
{
ULONG Flags = 0;
ULONG Flags;
BOOLEAN Return;
/* Get EFLAGS and check if the interrupt bit is set */
Ke386SaveFlags(Flags);
Flags = __readeflags();
Return = (Flags & EFLAGS_INTERRUPT_MASK) ? TRUE: FALSE;
/* Disable interrupts */

View file

@ -607,20 +607,20 @@ KiGetMachineBootPointers(IN PKGDTENTRY *Gdt,
IN PKIPCR *Pcr,
IN PKTSS *Tss)
{
KDESCRIPTOR GdtDescriptor = { 0, 0, 0 }, IdtDescriptor = { 0, 0, 0 };
KDESCRIPTOR GdtDescriptor, IdtDescriptor;
KGDTENTRY TssSelector, PcrSelector;
USHORT Tr = 0, Fs;
USHORT Tr, Fs;
/* Get GDT and IDT descriptors */
Ke386GetGlobalDescriptorTable(*(PKDESCRIPTOR)&GdtDescriptor.Limit);
Ke386GetInterruptDescriptorTable(*(PKDESCRIPTOR)&IdtDescriptor.Limit);
Ke386GetGlobalDescriptorTable(&GdtDescriptor.Limit);
__sidt(&IdtDescriptor.Limit);
/* Save IDT and GDT */
*Gdt = (PKGDTENTRY)GdtDescriptor.Base;
*Idt = (PKIDTENTRY)IdtDescriptor.Base;
/* Get TSS and FS Selectors */
Ke386GetTr(Tr);
Ke386GetTr(&Tr);
if (Tr != KGDT_TSS) Tr = KGDT_TSS; // FIXME: HACKHACK
Fs = Ke386GetFs();