mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
- Renamed device.c to config.c and removed all irrelevant code from it, leaving only the two KeFindConfigurationEntry*** functions in it.
- Also fixed the above for incorrect formatting/excessive whitespace. - The other routines in device.c were moved to cpu.c, since they deal with CPU-specific things. - Cleaned up KeFlushEntireTb. - Added inlined routines for setting/getting CR, and also getting GDTR, IDTR, LDTR, TR. Used to implement KiSaveProcessorControlState. - Implemented KeSaveStateForHibernate. svn path=/trunk/; revision=24092
This commit is contained in:
parent
b4aab80937
commit
31e4c651c4
7 changed files with 304 additions and 271 deletions
|
@ -152,6 +152,22 @@ KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine,
|
||||||
__asm__("lgdt %0\n\t" \
|
__asm__("lgdt %0\n\t" \
|
||||||
: /* no outputs */ \
|
: /* no outputs */ \
|
||||||
: "m" (X));
|
: "m" (X));
|
||||||
|
|
||||||
|
#define Ke386GetInterruptDescriptorTable(X) \
|
||||||
|
__asm__("sidt %0\n\t" \
|
||||||
|
: /* no outputs */ \
|
||||||
|
: "m" (X));
|
||||||
|
|
||||||
|
#define Ke386GetGlobalDescriptorTable(X) \
|
||||||
|
__asm__("sgdt %0\n\t" \
|
||||||
|
: /* no outputs */ \
|
||||||
|
: "m" (X));
|
||||||
|
|
||||||
|
#define Ke386GetLocalDescriptorTable(X) \
|
||||||
|
__asm__("lldt %0\n\t" \
|
||||||
|
: /* no outputs */ \
|
||||||
|
: "m" (X));
|
||||||
|
|
||||||
#define Ke386SaveFlags(x) __asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */)
|
#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")
|
#define Ke386RestoreFlags(x) __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory")
|
||||||
|
|
||||||
|
@ -166,9 +182,18 @@ KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine,
|
||||||
__asm__("movl %%cr" #N ",%0\n\t" :"=r" (__d)); \
|
__asm__("movl %%cr" #N ",%0\n\t" :"=r" (__d)); \
|
||||||
__d; \
|
__d; \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
#define _Ke386GetDr(N) ({ \
|
||||||
|
unsigned int __d; \
|
||||||
|
__asm__("movl %%dr" #N ",%0\n\t" :"=r" (__d)); \
|
||||||
|
__d; \
|
||||||
|
})
|
||||||
#define _Ke386SetCr(N,X) __asm__ __volatile__("movl %0,%%cr" #N : :"r" (X));
|
#define _Ke386SetCr(N,X) __asm__ __volatile__("movl %0,%%cr" #N : :"r" (X));
|
||||||
|
#define _Ke386SetDr(N,X) __asm__ __volatile__("movl %0,%%dr" #N : :"r" (X));
|
||||||
#define Ke386SetTr(X) __asm__ __volatile__("ltr %%ax" : :"a" (X));
|
#define Ke386SetTr(X) __asm__ __volatile__("ltr %%ax" : :"a" (X));
|
||||||
|
|
||||||
|
#define Ke386GetTr(X) __asm__ __volatile__("str %%ax" : :"a" (X));
|
||||||
|
|
||||||
#define _Ke386SetSeg(N,X) __asm__ __volatile__("movl %0,%%" #N : :"r" (X));
|
#define _Ke386SetSeg(N,X) __asm__ __volatile__("movl %0,%%" #N : :"r" (X));
|
||||||
|
|
||||||
#define Ke386GetCr0() _Ke386GetCr(0)
|
#define Ke386GetCr0() _Ke386GetCr(0)
|
||||||
|
|
126
reactos/ntoskrnl/ke/config.c
Normal file
126
reactos/ntoskrnl/ke/config.c
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS Kernel
|
||||||
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
|
* FILE: ntoskrnl/ke/config.c
|
||||||
|
* PURPOSE: Configuration Tree Routines
|
||||||
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
|
#include <ntoskrnl.h>
|
||||||
|
#define NDEBUG
|
||||||
|
#include <internal/debug.h>
|
||||||
|
|
||||||
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
PCONFIGURATION_COMPONENT_DATA
|
||||||
|
NTAPI
|
||||||
|
INIT_FUNCTION
|
||||||
|
KeFindConfigurationEntry(IN PCONFIGURATION_COMPONENT_DATA Child,
|
||||||
|
IN CONFIGURATION_CLASS Class,
|
||||||
|
IN CONFIGURATION_TYPE Type,
|
||||||
|
IN PULONG ComponentKey OPTIONAL)
|
||||||
|
{
|
||||||
|
/* Start Search at Root */
|
||||||
|
return KeFindConfigurationNextEntry(Child,
|
||||||
|
Class,
|
||||||
|
Type,
|
||||||
|
ComponentKey,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
PCONFIGURATION_COMPONENT_DATA
|
||||||
|
NTAPI
|
||||||
|
INIT_FUNCTION
|
||||||
|
KeFindConfigurationNextEntry(IN PCONFIGURATION_COMPONENT_DATA Child,
|
||||||
|
IN CONFIGURATION_CLASS Class,
|
||||||
|
IN CONFIGURATION_TYPE Type,
|
||||||
|
IN PULONG ComponentKey OPTIONAL,
|
||||||
|
IN PCONFIGURATION_COMPONENT_DATA *NextLink)
|
||||||
|
{
|
||||||
|
ULONG Key = 0;
|
||||||
|
ULONG Mask = 0;
|
||||||
|
PCONFIGURATION_COMPONENT_DATA Sibling;
|
||||||
|
PCONFIGURATION_COMPONENT_DATA ReturnEntry;
|
||||||
|
|
||||||
|
/* If we did get a key, then use it instead */
|
||||||
|
if (ComponentKey)
|
||||||
|
{
|
||||||
|
Key = *ComponentKey;
|
||||||
|
Mask = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loop the Components until we find a a match */
|
||||||
|
while (Child)
|
||||||
|
{
|
||||||
|
/* Check if we are starting somewhere already */
|
||||||
|
if (*NextLink)
|
||||||
|
{
|
||||||
|
/* If we've found the place where we started, clear and continue */
|
||||||
|
if (Child == *NextLink) *NextLink = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Try to get a match */
|
||||||
|
if ((Child->ComponentEntry.Class) == Class &&
|
||||||
|
(Child->ComponentEntry.Type) == Type &&
|
||||||
|
(Child->ComponentEntry.Key & Mask) == Key)
|
||||||
|
{
|
||||||
|
/* Match found */
|
||||||
|
return Child;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now we've also got to lookup the siblings */
|
||||||
|
Sibling = Child->Sibling;
|
||||||
|
while (Sibling)
|
||||||
|
{
|
||||||
|
/* Check if we are starting somewhere already */
|
||||||
|
if (*NextLink)
|
||||||
|
{
|
||||||
|
/* If we've found the place where we started, clear and continue */
|
||||||
|
if (Sibling == *NextLink) *NextLink = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Try to get a match */
|
||||||
|
if ((Sibling->ComponentEntry.Class == Class) &&
|
||||||
|
(Sibling->ComponentEntry.Type == Type) &&
|
||||||
|
(Sibling->ComponentEntry.Key & Mask) == Key)
|
||||||
|
{
|
||||||
|
/* Match found */
|
||||||
|
return Sibling;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We've got to check if the Sibling has a Child as well */
|
||||||
|
if (Sibling->Child)
|
||||||
|
{
|
||||||
|
/* We're just going to call ourselves again */
|
||||||
|
ReturnEntry = KeFindConfigurationNextEntry(Sibling->Child,
|
||||||
|
Class,
|
||||||
|
Type,
|
||||||
|
ComponentKey,
|
||||||
|
NextLink);
|
||||||
|
if (ReturnEntry) return ReturnEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Next Sibling */
|
||||||
|
Sibling = Sibling->Sibling;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Next Child */
|
||||||
|
Child = Child->Child;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we got here, nothign was found */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
|
@ -1,215 +0,0 @@
|
||||||
/*
|
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
|
||||||
* PROJECT: ReactOS kernel
|
|
||||||
* FILE: ntoskrnl/ke/device.c
|
|
||||||
* PURPOSE: Kernel Device/Settings Functions
|
|
||||||
*
|
|
||||||
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <ntoskrnl.h>
|
|
||||||
#define NDEBUG
|
|
||||||
#include <internal/debug.h>
|
|
||||||
|
|
||||||
#if defined (ALLOC_PRAGMA)
|
|
||||||
#pragma alloc_text(INIT, KeFindConfigurationEntry)
|
|
||||||
#pragma alloc_text(INIT, KeFindConfigurationNextEntry)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @implemented
|
|
||||||
*/
|
|
||||||
PCONFIGURATION_COMPONENT_DATA
|
|
||||||
STDCALL
|
|
||||||
INIT_FUNCTION
|
|
||||||
KeFindConfigurationEntry(IN PCONFIGURATION_COMPONENT_DATA Child,
|
|
||||||
IN CONFIGURATION_CLASS Class,
|
|
||||||
IN CONFIGURATION_TYPE Type,
|
|
||||||
IN PULONG ComponentKey OPTIONAL)
|
|
||||||
{
|
|
||||||
/* Start Search at Root */
|
|
||||||
return KeFindConfigurationNextEntry(Child,
|
|
||||||
Class,
|
|
||||||
Type,
|
|
||||||
ComponentKey,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @implemented
|
|
||||||
*/
|
|
||||||
PCONFIGURATION_COMPONENT_DATA
|
|
||||||
STDCALL
|
|
||||||
INIT_FUNCTION
|
|
||||||
KeFindConfigurationNextEntry(IN PCONFIGURATION_COMPONENT_DATA Child,
|
|
||||||
IN CONFIGURATION_CLASS Class,
|
|
||||||
IN CONFIGURATION_TYPE Type,
|
|
||||||
IN PULONG ComponentKey OPTIONAL,
|
|
||||||
IN PCONFIGURATION_COMPONENT_DATA *NextLink)
|
|
||||||
{
|
|
||||||
ULONG Key = 0;
|
|
||||||
ULONG Mask = 0;
|
|
||||||
PCONFIGURATION_COMPONENT_DATA Sibling;
|
|
||||||
PCONFIGURATION_COMPONENT_DATA ReturnEntry;
|
|
||||||
|
|
||||||
/* If we did get a key, then use it instead */
|
|
||||||
if (ComponentKey)
|
|
||||||
{
|
|
||||||
Key = *ComponentKey;
|
|
||||||
Mask = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Loop the Components until we find a a match */
|
|
||||||
while (Child)
|
|
||||||
{
|
|
||||||
/* Check if we are starting somewhere already */
|
|
||||||
if (*NextLink)
|
|
||||||
{
|
|
||||||
/* If we've found the place where we started, clear and continue */
|
|
||||||
if (Child == *NextLink) *NextLink = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Try to get a match */
|
|
||||||
if (Child->ComponentEntry.Class == Class &&
|
|
||||||
Child->ComponentEntry.Type == Type &&
|
|
||||||
(Child->ComponentEntry.Key & Mask) == Key)
|
|
||||||
{
|
|
||||||
/* Match found */
|
|
||||||
return Child;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now we've also got to lookup the siblings */
|
|
||||||
Sibling = Child->Sibling;
|
|
||||||
while (Sibling)
|
|
||||||
{
|
|
||||||
/* Check if we are starting somewhere already */
|
|
||||||
if (*NextLink)
|
|
||||||
{
|
|
||||||
/* If we've found the place where we started, clear and continue */
|
|
||||||
if (Sibling == *NextLink) *NextLink = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Try to get a match */
|
|
||||||
if (Sibling->ComponentEntry.Class == Class &&
|
|
||||||
Sibling->ComponentEntry.Type == Type &&
|
|
||||||
(Sibling->ComponentEntry.Key & Mask) == Key)
|
|
||||||
{
|
|
||||||
/* Match found */
|
|
||||||
return Sibling;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We've got to check if the Sibling has a Child as well */
|
|
||||||
if (Sibling->Child)
|
|
||||||
{
|
|
||||||
/* We're just going to call ourselves again */
|
|
||||||
if ((ReturnEntry = KeFindConfigurationNextEntry(Sibling->Child,
|
|
||||||
Class,
|
|
||||||
Type,
|
|
||||||
ComponentKey,
|
|
||||||
NextLink)))
|
|
||||||
{
|
|
||||||
return ReturnEntry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Next Sibling */
|
|
||||||
Sibling = Sibling->Sibling;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Next Child */
|
|
||||||
Child = Child->Child;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we got here, nothign was found */
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @implemented
|
|
||||||
*/
|
|
||||||
VOID
|
|
||||||
STDCALL
|
|
||||||
KeFlushEntireTb(
|
|
||||||
IN BOOLEAN Unknown,
|
|
||||||
IN BOOLEAN CurrentCpuOnly
|
|
||||||
)
|
|
||||||
{
|
|
||||||
KIRQL OldIrql;
|
|
||||||
PKPROCESS Process = NULL;
|
|
||||||
PKPRCB Prcb = NULL;
|
|
||||||
|
|
||||||
/* Raise the IRQL for the TB Flush */
|
|
||||||
OldIrql = KeRaiseIrqlToSynchLevel();
|
|
||||||
|
|
||||||
/* All CPUs need to have the TB flushed. */
|
|
||||||
if (CurrentCpuOnly == FALSE) {
|
|
||||||
Prcb = KeGetCurrentPrcb();
|
|
||||||
|
|
||||||
/* How many CPUs is our caller using? */
|
|
||||||
Process = Prcb->CurrentThread->ApcState.Process;
|
|
||||||
|
|
||||||
/* More then one, so send an IPI */
|
|
||||||
if (Process->ActiveProcessors > 1) {
|
|
||||||
/* Send IPI Packet */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Flush the TB for the Current CPU */
|
|
||||||
KeFlushCurrentTb();
|
|
||||||
|
|
||||||
/* Clean up */
|
|
||||||
if (CurrentCpuOnly == FALSE) {
|
|
||||||
/* Did we send an IPI? If so, wait for completion */
|
|
||||||
if (Process->ActiveProcessors > 1) {
|
|
||||||
do {
|
|
||||||
} while (Prcb->TargetSet != 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME: According to MSKB, we should increment a counter? */
|
|
||||||
|
|
||||||
/* Return to Original IRQL */
|
|
||||||
KeLowerIrql(OldIrql);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @implemented
|
|
||||||
*/
|
|
||||||
VOID
|
|
||||||
STDCALL
|
|
||||||
KeSetDmaIoCoherency(
|
|
||||||
IN ULONG Coherency
|
|
||||||
)
|
|
||||||
{
|
|
||||||
KiDmaIoCoherency = Coherency;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @implemented
|
|
||||||
*/
|
|
||||||
KAFFINITY
|
|
||||||
STDCALL
|
|
||||||
KeQueryActiveProcessors (
|
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return KeActiveProcessors;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @unimplemented
|
|
||||||
*/
|
|
||||||
VOID
|
|
||||||
__cdecl
|
|
||||||
KeSaveStateForHibernate(
|
|
||||||
IN PVOID State
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED;
|
|
||||||
}
|
|
|
@ -12,7 +12,7 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
/* INCLUDES ******************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
|
|
|
@ -638,58 +638,6 @@ Ki386InitializeTss(VOID)
|
||||||
TssEntry->LimitLow = KTSS_IO_MAPS;
|
TssEntry->LimitLow = KTSS_IO_MAPS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is a rather naive implementation of Ke(Save/Restore)FloatingPointState
|
|
||||||
which will not work for WDM drivers. Please feel free to improve */
|
|
||||||
NTSTATUS
|
|
||||||
NTAPI
|
|
||||||
KeSaveFloatingPointState(OUT PKFLOATING_SAVE Save)
|
|
||||||
{
|
|
||||||
PFNSAVE_FORMAT FpState;
|
|
||||||
ASSERT_IRQL(DISPATCH_LEVEL);
|
|
||||||
|
|
||||||
/* check if we are doing software emulation */
|
|
||||||
if (!KeI386NpxPresent) return STATUS_ILLEGAL_FLOAT_CONTEXT;
|
|
||||||
|
|
||||||
FpState = ExAllocatePool(NonPagedPool, sizeof (FNSAVE_FORMAT));
|
|
||||||
if (!FpState) return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
|
|
||||||
*((PVOID *) Save) = FpState;
|
|
||||||
#ifdef __GNUC__
|
|
||||||
asm volatile("fnsave %0\n\t" : "=m" (*FpState));
|
|
||||||
#else
|
|
||||||
__asm
|
|
||||||
{
|
|
||||||
fnsave [FpState]
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
KeGetCurrentThread()->DispatcherHeader.NpxIrql = KeGetCurrentIrql();
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
NTAPI
|
|
||||||
KeRestoreFloatingPointState(IN PKFLOATING_SAVE Save)
|
|
||||||
{
|
|
||||||
PFNSAVE_FORMAT FpState = *((PVOID *) Save);
|
|
||||||
|
|
||||||
ASSERT(KeGetCurrentThread()->DispatcherHeader.NpxIrql == KeGetCurrentIrql());
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
asm volatile("fnclex\n\t");
|
|
||||||
asm volatile("frstor %0\n\t" : "=m" (*FpState));
|
|
||||||
#else
|
|
||||||
__asm
|
|
||||||
{
|
|
||||||
fnclex
|
|
||||||
frstor [FpState]
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ExFreePool(FpState);
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
INIT_FUNCTION
|
INIT_FUNCTION
|
||||||
Ki386SetProcessorFeatures(VOID)
|
Ki386SetProcessorFeatures(VOID)
|
||||||
|
@ -789,12 +737,161 @@ KeFlushCurrentTb(VOID)
|
||||||
_Ke386SetCr(3, _Ke386GetCr(3));
|
_Ke386SetCr(3, _Ke386GetCr(3));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
KiSaveProcessorControlState(IN PKPROCESSOR_STATE ProcessorState)
|
||||||
|
{
|
||||||
|
/* Save the CR registers */
|
||||||
|
ProcessorState->SpecialRegisters.Cr0 = _Ke386GetCr(0);
|
||||||
|
ProcessorState->SpecialRegisters.Cr2 = _Ke386GetCr(2);
|
||||||
|
ProcessorState->SpecialRegisters.Cr3 = _Ke386GetCr(3);
|
||||||
|
ProcessorState->SpecialRegisters.Cr4 = _Ke386GetCr(4);
|
||||||
|
|
||||||
|
/* Save the DR registers */
|
||||||
|
ProcessorState->SpecialRegisters.KernelDr0 = _Ke386GetDr(0);
|
||||||
|
ProcessorState->SpecialRegisters.KernelDr1 = _Ke386GetDr(1);
|
||||||
|
ProcessorState->SpecialRegisters.KernelDr2 = _Ke386GetDr(2);
|
||||||
|
ProcessorState->SpecialRegisters.KernelDr3 = _Ke386GetDr(3);
|
||||||
|
ProcessorState->SpecialRegisters.KernelDr6 = _Ke386GetDr(6);
|
||||||
|
ProcessorState->SpecialRegisters.KernelDr7 = _Ke386GetDr(7);
|
||||||
|
_Ke386SetDr(7, 0);
|
||||||
|
|
||||||
|
/* Save GDT, IDT, LDT and TSS */
|
||||||
|
Ke386GetGlobalDescriptorTable(ProcessorState->SpecialRegisters.Gdtr);
|
||||||
|
Ke386GetInterruptDescriptorTable(ProcessorState->SpecialRegisters.Idtr);
|
||||||
|
Ke386GetTr(ProcessorState->SpecialRegisters.Tr);
|
||||||
|
Ke386GetLocalDescriptorTable(ProcessorState->SpecialRegisters.Ldtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* PUBLIC FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
KeSaveFloatingPointState(OUT PKFLOATING_SAVE Save)
|
||||||
|
{
|
||||||
|
PFNSAVE_FORMAT FpState;
|
||||||
|
ASSERT_IRQL(DISPATCH_LEVEL);
|
||||||
|
DPRINT1("%s is not really implemented\n", __FUNCTION__);
|
||||||
|
|
||||||
|
/* check if we are doing software emulation */
|
||||||
|
if (!KeI386NpxPresent) return STATUS_ILLEGAL_FLOAT_CONTEXT;
|
||||||
|
|
||||||
|
FpState = ExAllocatePool(NonPagedPool, sizeof (FNSAVE_FORMAT));
|
||||||
|
if (!FpState) return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
*((PVOID *) Save) = FpState;
|
||||||
|
#ifdef __GNUC__
|
||||||
|
asm volatile("fnsave %0\n\t" : "=m" (*FpState));
|
||||||
|
#else
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
fnsave [FpState]
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
KeGetCurrentThread()->DispatcherHeader.NpxIrql = KeGetCurrentIrql();
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
KeRestoreFloatingPointState(IN PKFLOATING_SAVE Save)
|
||||||
|
{
|
||||||
|
PFNSAVE_FORMAT FpState = *((PVOID *) Save);
|
||||||
|
ASSERT(KeGetCurrentThread()->DispatcherHeader.NpxIrql == KeGetCurrentIrql());
|
||||||
|
DPRINT1("%s is not really implemented\n", __FUNCTION__);
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
asm volatile("fnclex\n\t");
|
||||||
|
asm volatile("frstor %0\n\t" : "=m" (*FpState));
|
||||||
|
#else
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
fnclex
|
||||||
|
frstor [FpState]
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ExFreePool(FpState);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
ULONG
|
ULONG
|
||||||
STDCALL
|
NTAPI
|
||||||
KeGetRecommendedSharedDataAlignment(VOID)
|
KeGetRecommendedSharedDataAlignment(VOID)
|
||||||
{
|
{
|
||||||
|
/* Return the global variable */
|
||||||
return KeLargestCacheLine;
|
return KeLargestCacheLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
KeFlushEntireTb(IN BOOLEAN Invalid,
|
||||||
|
IN BOOLEAN AllProcessors)
|
||||||
|
{
|
||||||
|
KIRQL OldIrql;
|
||||||
|
|
||||||
|
/* Raise the IRQL for the TB Flush */
|
||||||
|
OldIrql = KeRaiseIrqlToSynchLevel();
|
||||||
|
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
/* FIXME: Support IPI Flush */
|
||||||
|
#error Not yet implemented!
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Flush the TB for the Current CPU */
|
||||||
|
KeFlushCurrentTb();
|
||||||
|
|
||||||
|
/* Return to Original IRQL */
|
||||||
|
KeLowerIrql(OldIrql);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
KeSetDmaIoCoherency(IN ULONG Coherency)
|
||||||
|
{
|
||||||
|
/* Save the coherency globally */
|
||||||
|
KiDmaIoCoherency = Coherency;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
KAFFINITY
|
||||||
|
NTAPI
|
||||||
|
KeQueryActiveProcessors(VOID)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Simply return the number of active processors */
|
||||||
|
return KeActiveProcessors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
VOID
|
||||||
|
__cdecl
|
||||||
|
KeSaveStateForHibernate(IN PKPROCESSOR_STATE State)
|
||||||
|
{
|
||||||
|
/* Capture the context */
|
||||||
|
RtlCaptureContext(&State->ContextFrame);
|
||||||
|
|
||||||
|
/* Capture the control state */
|
||||||
|
KiSaveProcessorControlState(State);
|
||||||
|
}
|
||||||
|
|
|
@ -242,7 +242,7 @@ KeSynchronizeExecution(IN PKINTERRUPT Interrupt,
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
VOID
|
VOID
|
||||||
STDCALL
|
NTAPI
|
||||||
KeReleaseInterruptSpinLock(IN PKINTERRUPT Interrupt,
|
KeReleaseInterruptSpinLock(IN PKINTERRUPT Interrupt,
|
||||||
IN KIRQL OldIrql)
|
IN KIRQL OldIrql)
|
||||||
{
|
{
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
<file>apc.c</file>
|
<file>apc.c</file>
|
||||||
<file>bug.c</file>
|
<file>bug.c</file>
|
||||||
<file>clock.c</file>
|
<file>clock.c</file>
|
||||||
<file>device.c</file>
|
<file>config.c</file>
|
||||||
<file>dpc.c</file>
|
<file>dpc.c</file>
|
||||||
<file>event.c</file>
|
<file>event.c</file>
|
||||||
<file>exception.c</file>
|
<file>exception.c</file>
|
||||||
|
|
Loading…
Reference in a new issue