1) Corrected bugs in ERESOURCE code

and added test
2) Moved some files which are only
architecture-dependant out of the hal
3) Corrected timer implementation (it
should now be possible to use them as dispatcher
objects)
4) Corrected stupid bug in dpc code
5) Made thread list locking more sensible
6) Altered system call handler to build a
proper context in preparation for implementing APCs
7) Rationalised the waiting code

svn path=/trunk/; revision=767
This commit is contained in:
David Welch 1999-11-12 12:01:17 +00:00
parent 1a8f8005ae
commit b0ff680e0e
45 changed files with 2118 additions and 574 deletions

View file

@ -1,7 +1,7 @@
#include <stdio.h>
#include <windows.h>
#define NR_THREADS (0x5)
#define NR_THREADS (0x1)
DWORD WINAPI
@ -28,7 +28,7 @@ int main (void)
DWORD i=0;
DWORD id;
#if 0
#if 1
printf("Creating %d threads...\n",NR_THREADS*2);
for (i=0;i<NR_THREADS;i++)
{
@ -39,16 +39,16 @@ int main (void)
0,
&id);
CreateThread(NULL,
/* CreateThread(NULL,
0,
thread_main2,
(LPVOID)i,
0,
&id);
&id);*/
}
printf("All threads created...\n");
/*
* Waiting for threads is not implemented yet.
* If you want to see all threads running, uncomment the

View file

@ -1,4 +1,4 @@
# $Id: Makefile,v 1.2 1999/11/11 21:22:08 rex Exp $
# $Id: Makefile,v 1.3 1999/11/12 12:01:09 dwelch Exp $
#
BASE_CFLAGS = -I../../include
@ -6,11 +6,14 @@ TARGETNAME=buildno
CLEAN_FILES= $(TARGETNAME).o $(TARGETNAME)$(EXE_POSTFIX) $(TARGETNAME).sym
all: $(TARGETNAME)$(EXE_POSTFIX)
$(TARGETNAME)$(EXE_POSTFIX) -q
$(EXE_PREFIX)$(TARGETNAME)$(EXE_POSTFIX) -q
$(TARGETNAME)$(EXE_POSTFIX): $(TARGETNAME).c ../../include/reactos/version.h
$(NATIVE_CC) -I../../include -o $(TARGETNAME)$(EXE_POSTFIX) $(TARGETNAME).c
clean:
$(RM) $(TARGETNAME).o
$(RM) $(TARGETNAME).sym

View file

@ -1130,7 +1130,7 @@ NTSTATUS FsdMountDevice(PDEVICE_EXTENSION DeviceExt,
DeviceExt->rootDirectorySectors=DeviceExt->Boot->SectorsPerCluster;
DeviceExt->rootStart=
DeviceExt->FATStart+DeviceExt->Boot->FATCount
* ((struct _BootSector32 *)( DeviceExt->Boot))->FATSectors32;
*((struct _BootSector32 *)( DeviceExt->Boot))->FATSectors32;
DeviceExt->dataStart=DeviceExt->rootStart;
}
else
@ -1217,6 +1217,11 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
FirstCluster=CurrentCluster;
DPRINT("DeviceExt->BytesPerCluster %x\n",DeviceExt->BytesPerCluster);
if (Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY)
{
return(STATUS_FILE_IS_A_DIRECTORY);
}
if (ReadOffset >= Fcb->entry.FileSize
&& !(Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY))
{

View file

@ -8,7 +8,6 @@ typedef enum _EVENT_TYPE
{
NotificationEvent,
SynchronizationEvent,
SemaphoreType,
} EVENT_TYPE;
typedef enum _KWAIT_REASON

View file

@ -58,7 +58,6 @@ typedef struct _KQUEUE
struct _KDPC;
/*
typedef struct _KTIMER
{
DISPATCHER_HEADER Header;
@ -67,8 +66,8 @@ typedef struct _KTIMER
struct _KDPC* Dpc;
LONG Period;
} KTIMER, *PKTIMER;
*/
/*
typedef struct _KTIMER
{
LIST_ENTRY entry;
@ -79,7 +78,8 @@ typedef struct _KTIMER
TIMER_TYPE type;
ULONG period;
} KTIMER, *PKTIMER;
*/
struct _KSPIN_LOCK;
typedef struct _KSPIN_LOCK

View file

@ -2,13 +2,17 @@
* Structure ids
*/
#define InternalBaseType (0xcc)
#define InternalNotificationEvent (InternalBaseType + 1)
#define InternalSynchronizationEvent (InternalBaseType + 2)
#define InternalSemaphoreType (InternalBaseType + 3)
#define InternalProcessType (InternalBaseType + 4)
#define InternalThreadType (InternalBaseType + 5)
#define InternalFileType (InternalBaseType + 6)
#define InternalDriverType (InternalBaseType + 7)
#define InternalDeviceType (InternalBaseType + 8)
#define InternalMutexType (InternalBaseType + 9)
#define InternalNotificationTimer (InternalBaseType + 10)
#define InternalSynchronizationTimer (InternalBaseType + 11)
#define ID_BASE_OBJECT (0x34)
#define ID_FILE_OBJECT (ID_BASE_OBJECT + 1)
#define ID_DEVICE_OBJECT (ID_BASE_OBJECT + 2)
#define ID_DRIVER_OBJECT (ID_BASE_OBJECT + 3)
#define ID_DIRECTORY_OBJECT (ID_BASE_OBJECT + 4)
#define ID_EVENT_OBJECT (ID_BASE_OBJECT + 5)
#define ID_TIMER_OBJECT (ID_BASE_OBJECT + 6)
#define ID_PROCESS_OBJECT (ID_BASE_OBJECT + 7)
#define ID_THREAD_OBJECT (ID_BASE_OBJECT + 8)

View file

@ -41,10 +41,6 @@ PIRP IoBuildFilesystemControlRequest(ULONG MinorFunction,
PKEVENT UserEvent,
PIO_STATUS_BLOCK IoStatusBlock,
PDEVICE_OBJECT DeviceToMount);
NTSTATUS IoPageRead(PFILE_OBJECT FileObject,
PVOID Address,
PLARGE_INTEGER Offset,
PIO_STATUS_BLOCK StatusBlock);
VOID IoSecondStageCompletion(PIRP Irp, CCHAR PriorityBoost);
NTSTATUS IopCreateFile(PVOID ObjectBody,
@ -57,4 +53,11 @@ NTSTATUS IopCreateDevice(PVOID ObjectBody,
POBJECT_ATTRIBUTES ObjectAttributes);
NTSTATUS IoAttachVpb(PDEVICE_OBJECT DeviceObject);
PIRP IoBuildSynchronousFsdRequestWithMdl(ULONG MajorFunction,
PDEVICE_OBJECT DeviceObject,
PMDL Mdl,
PLARGE_INTEGER StartingOffset,
PKEVENT Event,
PIO_STATUS_BLOCK IoStatusBlock);
#endif

View file

@ -97,9 +97,10 @@ NTSTATUS MmReleaseMmInfo(PEPROCESS Process);
NTSTATUS Mmi386ReleaseMmInfo(PEPROCESS Process);
VOID MmDeletePageEntry(PEPROCESS Process, PVOID Address, BOOL FreePage);
NTSTATUS IoPageRead(PFILE_OBJECT FileObject,
PVOID Address,
PMDL Mdl,
PLARGE_INTEGER Offset,
PIO_STATUS_BLOCK StatusBlock);
VOID MmBuildMdlFromPages(PMDL Mdl);
PVOID MmGetMdlPageAddress(PMDL Mdl, PVOID Offset);
#endif

View file

@ -1,4 +1,4 @@
/* $Id: version.h,v 1.1 1999/11/07 08:03:24 ea Exp $
/* $Id: version.h,v 1.2 1999/11/12 12:01:09 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -20,6 +20,8 @@
/* Edit each time a new release is out: format is YYYYMMDD (UTC) */
#define KERNEL_RELEASE_DATE 19990606L
#define KERNEL_VERSION "0.0.14"
#endif
/* EOF */

View file

@ -1,4 +1,4 @@
; $Id: advapi32.edf,v 1.4 1999/11/07 08:03:24 ea Exp $
; $Id: advapi32.edf,v 1.5 1999/11/12 12:01:10 dwelch Exp $
;
; advapi32.def
;
@ -408,3 +408,4 @@ UnlockServiceDatabase=UnlockServiceDatabase@4
;WinLoadTrustProvider=WinLoadTrustProvider@4
;WinSubmitCertificate=WinSubmitCertificate@4
;WinVerifyTrust=WinVerifyTrust@12

View file

@ -36,3 +36,4 @@ BEGIN
END
END

View file

@ -1,4 +1,4 @@
; $Id: ntdll.def,v 1.19 1999/11/09 18:09:57 ekohl Exp $
; $Id: ntdll.def,v 1.20 1999/11/12 12:01:10 dwelch Exp $
;
; ReactOS Operating System
;
@ -556,3 +556,4 @@ LdrGetExportByOrdinal
LdrLoadDll
LdrMapNTDllForProcess
LdrUnloadDll

View file

@ -1,4 +1,4 @@
; $Id: ntdll.edf,v 1.9 1999/11/09 18:09:57 ekohl Exp $
; $Id: ntdll.edf,v 1.10 1999/11/12 12:01:10 dwelch Exp $
;
; ReactOS Operating System
;
@ -556,3 +556,4 @@ LdrGetExportByOrdinal
LdrLoadDll
LdrMapNTDllForProcess
LdrUnloadDll

View file

@ -40,7 +40,7 @@
#include <stddef.h>
#include <internal/string.h>
//#define NDEBUG
#define NDEBUG
#include <internal/debug.h>
/* FUNCTIONS *****************************************************************/
@ -186,15 +186,34 @@ static BOOLEAN EiAddSharedOwner(PERESOURCE Resource)
{
ERESOURCE_THREAD CurrentThread = ExGetCurrentResourceThread();
POWNER_ENTRY freeEntry;
ULONG i;
ULONG i = 0;
DPRINT("EiAddSharedOwner(Resource %x)\n", Resource);
if (Resource->ActiveCount == 0)
{
/* no owner, it's easy */
Resource->OwnerThreads[1].OwnerThread = ExGetCurrentResourceThread();
Resource->OwnerThreads[1].a.OwnerCount = 1;
if (Resource->OwnerTable != NULL)
{
ExFreePool(Resource->OwnerTable);
}
Resource->OwnerTable = NULL;
Resource->ActiveCount = 1;
DPRINT("EiAddSharedOwner() = TRUE\n");
return(TRUE);
}
/*
* now, we must search if this thread has already acquired this resource
* then increase ownercount if found, else create new entry or reuse free
* entry
*/
if (!Resource->OwnerThreads[1].a.TableSize)
if (Resource->OwnerTable == NULL)
{
DPRINT("Creating owner table\n");
/* allocate ownertable,memset to 0, initialize first entry */
Resource->OwnerTable = ExAllocatePool(NonPagedPool,
sizeof(OWNER_ENTRY)*3);
@ -216,11 +235,17 @@ static BOOLEAN EiAddSharedOwner(PERESOURCE Resource)
return(TRUE);
}
DPRINT("Search free entries\n");
DPRINT("Number of entries %d\n",
Resource->OwnerThreads[1].a.TableSize);
freeEntry = NULL;
for (i=0; i<Resource->OwnerThreads[1].a.TableSize; i++)
{
if (Resource->OwnerTable[i].OwnerThread == CurrentThread)
{
DPRINT("Thread already owns resource\n");
Resource->OwnerTable[i].a.OwnerCount++;
return(TRUE);
}
@ -230,8 +255,12 @@ static BOOLEAN EiAddSharedOwner(PERESOURCE Resource)
}
}
DPRINT("Found free entry %x\n", freeEntry);
if (!freeEntry)
{
DPRINT("Allocating new entry\n");
/* reallocate ownertable with one more entry */
freeEntry = ExAllocatePool(NonPagedPool,
sizeof(OWNER_ENTRY)*
@ -246,8 +275,9 @@ static BOOLEAN EiAddSharedOwner(PERESOURCE Resource)
ExFreePool(Resource->OwnerTable);
Resource->OwnerTable=freeEntry;
freeEntry=&Resource->OwnerTable[Resource->OwnerThreads[1].a.TableSize];
Resource->OwnerThreads[1].a.TableSize ++;
Resource->OwnerThreads[1].a.TableSize++;
}
DPRINT("Creating entry\n");
freeEntry->OwnerThread=ExGetCurrentResourceThread();
freeEntry->a.OwnerCount=1;
Resource->ActiveCount++;
@ -277,12 +307,9 @@ BOOLEAN ExAcquireResourceSharedLite(PERESOURCE Resource, BOOLEAN Wait)
/* first, resolve trivial cases */
if (Resource->ActiveCount == 0)
{
/* no owner, it's easy */
Resource->OwnerThreads[1].OwnerThread = ExGetCurrentResourceThread();
Resource->OwnerThreads[1].a.OwnerCount = 1;
Resource->ActiveCount = 1;
EiAddSharedOwner(Resource);
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
DPRINT("ExAcquireResourceExclusiveLite() = TRUE\n");
DPRINT("ExAcquireResourceSharedLite() = TRUE\n");
return(TRUE);
}
@ -295,7 +322,7 @@ BOOLEAN ExAcquireResourceSharedLite(PERESOURCE Resource, BOOLEAN Wait)
*/
Resource->OwnerThreads[0].a.OwnerCount++;
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
DPRINT("ExAcquireResourceExclusiveLite() = TRUE\n");
DPRINT("ExAcquireResourceSharedLite() = TRUE\n");
return(TRUE);
}
@ -306,7 +333,7 @@ BOOLEAN ExAcquireResourceSharedLite(PERESOURCE Resource, BOOLEAN Wait)
if (!Wait)
{
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
DPRINT("ExAcquireResourceExclusiveLite() = FALSE\n");
DPRINT("ExAcquireResourceSharedLite() = FALSE\n");
return(FALSE);
}
else
@ -322,7 +349,7 @@ BOOLEAN ExAcquireResourceSharedLite(PERESOURCE Resource, BOOLEAN Wait)
EiAddSharedOwner(Resource);
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
DPRINT("ExAcquireResourceExclusiveLite() = TRUE\n");
DPRINT("ExAcquireResourceSharedLite() = TRUE\n");
return(TRUE);
}
@ -601,6 +628,8 @@ VOID ExReleaseResourceForThreadLite(PERESOURCE Resource,
if (Resource->Flag & ResourceOwnedExclusive)
{
DPRINT("Releasing from exclusive access\n");
Resource->OwnerThreads[0].a.OwnerCount--;
if (Resource->OwnerThreads[0].a.OwnerCount > 0)
{
@ -613,6 +642,8 @@ VOID ExReleaseResourceForThreadLite(PERESOURCE Resource,
Resource->ActiveCount--;
Resource->Flag &=(~ResourceOwnedExclusive);
assert(Resource->ActiveCount == 0);
DPRINT("Resource->NumberOfExclusiveWaiters %d\n",
Resource->NumberOfExclusiveWaiters);
if (Resource->NumberOfExclusiveWaiters)
{
/* get resource to first exclusive waiter */
@ -623,11 +654,14 @@ VOID ExReleaseResourceForThreadLite(PERESOURCE Resource,
DPRINT("ExReleaseResourceForThreadLite() finished\n");
return;
}
DPRINT("Resource->NumberOfSharedWaiters %d\n",
Resource->NumberOfSharedWaiters);
if (Resource->NumberOfSharedWaiters)
{
DPRINT("Releasing semaphore\n");
KeReleaseSemaphore(Resource->SharedWaiters,
IO_NO_INCREMENT,
Resource->ActiveCount,
Resource->NumberOfSharedWaiters,
FALSE);
}
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);

View file

@ -32,6 +32,9 @@ static exception_hook* exception_hooks[256]={NULL,};
extern void interrupt_handler2e(void);
extern ULONG init_stack;
extern ULONG init_stack_top;
/* FUNCTIONS ****************************************************************/
#define EXCEPTION_HANDLER_WITH_ERROR(x,y) \
@ -246,6 +249,7 @@ asmlinkage void exception_handler(unsigned int edi,
{
DbgPrint("kernel ESP %.8x\n",esp);
}
for(;;);
if ((cs & 0xffff) == KERNEL_CS)
{
DbgPrint("ESP %x\n",esp);
@ -263,9 +267,11 @@ asmlinkage void exception_handler(unsigned int edi,
DbgPrint("Frames:\n");
for (i = 0; i < 32; i++)
{
if (stack[i] > ((unsigned int) &stext))
if (stack[i] > ((unsigned int) &stext) &&
!(stack[i] >= ((ULONG)&init_stack) &&
stack[i] <= ((ULONG)&init_stack_top)))
{
DbgPrint(" %.8x\n",
DbgPrint(" %.8x",
stack[i]);
}
}
@ -290,6 +296,7 @@ asmlinkage void exception_handler(unsigned int edi,
}
DPRINT1("Killing current task\n");
for(;;);
KeLowerIrql(PASSIVE_LEVEL);
if ((cs&0xffff) == USER_CS)
{

View file

@ -1,14 +1,14 @@
#define NR_TASKS 128
.globl _stext
.globl _idt
.globl _gdt
.globl _start
.globl _mainCRTStartup
.globl start
/*.globl _DllMainCRTStartup@12*/
.globl _DllMainCRTStartup@12
.globl _init_stack
.globl _init_stack_top
/*_DllMainCRTStartup@12:*/
_DllMainCRTStartup@12:
_stext:
_mainCRTStartup:
_start:

View file

@ -1,7 +1,7 @@
HAL_OBJECTS = hal/x86/head.o hal/x86/irq.o hal/x86/exp.o hal/x86/isa.o \
hal/x86/pci.o hal/x86/irqhand.o hal/x86/page.o hal/x86/halinit.o \
hal/x86/irql.o hal/x86/bios32.o hal/x86/thread.o hal/x86/spinlock.o \
HAL_OBJECTS = hal/x86/head.o hal/x86/irq.o hal/x86/isa.o \
hal/x86/pci.o hal/x86/irqhand.o hal/x86/halinit.o \
hal/x86/irql.o hal/x86/bios32.o hal/x86/spinlock.o \
hal/x86/mp.o hal/x86/dma.o hal/x86/bus.o hal/x86/mbr.o \
hal/x86/sysinfo.o hal/x86/time.o hal/x86/usercall.o hal/x86/beep.o \
hal/x86/sysinfo.o hal/x86/time.o hal/x86/beep.o \
hal/x86/display.o hal/x86/reboot.o hal/x86/kdbg.o hal/x86/portio.o

View file

@ -451,3 +451,85 @@ PIRP IoBuildSynchronousFsdRequest(ULONG MajorFunction,
return(Irp);
}
PIRP IoBuildSynchronousFsdRequestWithMdl(ULONG MajorFunction,
PDEVICE_OBJECT DeviceObject,
PMDL Mdl,
PLARGE_INTEGER StartingOffset,
PKEVENT Event,
PIO_STATUS_BLOCK IoStatusBlock)
/*
* FUNCTION: Allocates and builds an IRP to be sent synchronously to lower
* level driver(s)
* ARGUMENTS:
* MajorFunction = Major function code, one of IRP_MJ_READ,
* IRP_MJ_WRITE, IRP_MJ_FLUSH_BUFFERS, IRP_MJ_SHUTDOWN
* DeviceObject = Target device object
* Buffer = Buffer containing data for a read or write
* Length = Length in bytes of the information to be transferred
* StartingOffset = Offset to begin the read/write from
* Event (OUT) = Will be set when the operation is complete
* IoStatusBlock (OUT) = Set to the status of the operation
* RETURNS: The IRP allocated on success, or
* NULL on failure
*/
{
PIRP Irp;
PIO_STACK_LOCATION StackPtr;
DPRINT("IoBuildSynchronousFsdRequestWithMdl(MajorFunction %x, "
"DeviceObject %x, "
"Mdl %x, StartingOffset %x, Event %x, "
"IoStatusBlock %x\n",MajorFunction,DeviceObject,Mdl,
StartingOffset,Event,IoStatusBlock);
Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE);
if (Irp==NULL)
{
return(NULL);
}
Irp->UserEvent = Event;
Irp->UserIosb = IoStatusBlock;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = MajorFunction;
StackPtr->MinorFunction = 0;
StackPtr->Flags = 0;
StackPtr->Control = 0;
StackPtr->DeviceObject = DeviceObject;
StackPtr->FileObject = NULL;
StackPtr->CompletionRoutine = NULL;
Irp->MdlAddress = Mdl;
Irp->UserBuffer = NULL;
Irp->AssociatedIrp.SystemBuffer = NULL;
if (MajorFunction == IRP_MJ_READ)
{
if (StartingOffset != NULL)
{
StackPtr->Parameters.Read.ByteOffset = *StartingOffset;
}
else
{
StackPtr->Parameters.Read.ByteOffset.QuadPart = 0;
}
StackPtr->Parameters.Read.Length = MmGetMdlByteCount(Mdl);
}
else
{
if (StartingOffset!=NULL)
{
StackPtr->Parameters.Write.ByteOffset = *StartingOffset;
}
else
{
StackPtr->Parameters.Write.ByteOffset.QuadPart = 0;
}
StackPtr->Parameters.Write.Length = MmGetMdlByteCount(Mdl);
}
return(Irp);
}

View file

@ -21,13 +21,9 @@
/* FUNCTIONS *************************************************************/
NTSTATUS
STDCALL
NtDeleteFile (
IN POBJECT_ATTRIBUTES ObjectAttributes
)
NTSTATUS STDCALL NtDeleteFile(IN POBJECT_ATTRIBUTES ObjectAttributes)
{
UNIMPLEMENTED;
UNIMPLEMENTED;
}
@ -94,7 +90,7 @@ NTSTATUS IopCreateFile(PVOID ObjectBody,
DPRINT("FileObject->FileName.Buffer %w\n",FileObject->FileName.Buffer);
FileObject->DeviceObject = DeviceObject;
FileObject->Vpb = DeviceObject->Vpb;
FileObject->Type = ID_FILE_OBJECT;
FileObject->Type = InternalFileType;
return(STATUS_SUCCESS);
}
@ -126,7 +122,7 @@ PFILE_OBJECT IoCreateStreamFileObject(PFILE_OBJECT FileObject,
DeviceObject = IoGetAttachedDevice(DeviceObject);
CreatedFileObject->DeviceObject = DeviceObject;
CreatedFileObject->Vpb = DeviceObject->Vpb;
CreatedFileObject->Type = ID_FILE_OBJECT;
CreatedFileObject->Type = InternalFileType;
CreatedFileObject->Flags = CreatedFileObject->Flags | FO_DIRECT_DEVICE_OPEN;
ZwClose(FileHandle);

View file

@ -1,4 +1,4 @@
/* $Id: device.c,v 1.11 1999/10/24 17:07:57 rex Exp $
/* $Id: device.c,v 1.12 1999/11/12 12:01:13 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -24,13 +24,9 @@
/* FUNCTIONS ***************************************************************/
NTSTATUS
STDCALL
NtUnloadDriver (
IN PUNICODE_STRING DriverServiceName
)
NTSTATUS STDCALL NtUnloadDriver(IN PUNICODE_STRING DriverServiceName)
{
UNIMPLEMENTED;
UNIMPLEMENTED;
}
@ -50,36 +46,27 @@ NtUnloadDriver (
*
* REVISIONS
*/
NTSTATUS
STDCALL
NtLoadDriver (
PUNICODE_STRING DriverServiceName
)
NTSTATUS STDCALL NtLoadDriver (PUNICODE_STRING DriverServiceName)
{
/* FIXME: this should lookup the filename from the registry and then call LdrLoadDriver */
return LdrLoadDriver (DriverServiceName);
}
NTSTATUS
IoAttachDeviceByPointer (
PDEVICE_OBJECT SourceDevice,
PDEVICE_OBJECT TargetDevice
)
NTSTATUS IoAttachDeviceByPointer(PDEVICE_OBJECT SourceDevice,
PDEVICE_OBJECT TargetDevice)
{
UNIMPLEMENTED;
}
VOID
IoDeleteDevice(PDEVICE_OBJECT DeviceObject)
VOID IoDeleteDevice(PDEVICE_OBJECT DeviceObject)
{
UNIMPLEMENTED;
}
PDEVICE_OBJECT
IoGetRelatedDeviceObject(PFILE_OBJECT FileObject)
PDEVICE_OBJECT IoGetRelatedDeviceObject(PFILE_OBJECT FileObject)
{
return(FileObject->DeviceObject);
}
@ -163,7 +150,7 @@ NTSTATUS IoInitializeDriver(PDRIVER_INITIALIZE DriverEntry)
}
memset(DriverObject, 0, sizeof(DRIVER_OBJECT));
DriverObject->Type = ID_DRIVER_OBJECT;
DriverObject->Type = InternalDriverType;
for (i=0; i<=IRP_MJ_MAXIMUM_FUNCTION; i++)
{
@ -293,7 +280,7 @@ NTSTATUS IoCreateDevice(PDRIVER_OBJECT DriverObject,
DriverObject->DeviceObject = CreatedDeviceObject;
}
CreatedDeviceObject->Type = ID_DEVICE_OBJECT;
CreatedDeviceObject->Type = DeviceType;
CreatedDeviceObject->DriverObject = DriverObject;
CreatedDeviceObject->CurrentIrp = NULL;
CreatedDeviceObject->Flags = 0;

View file

@ -19,7 +19,7 @@
/* FUNCTIONS *****************************************************************/
NTSTATUS IoPageRead(PFILE_OBJECT FileObject,
PVOID Address,
PMDL Mdl,
PLARGE_INTEGER Offset,
PIO_STATUS_BLOCK StatusBlock)
{
@ -37,13 +37,12 @@ NTSTATUS IoPageRead(PFILE_OBJECT FileObject,
UserMode);
KeInitializeEvent(&Event,NotificationEvent,FALSE);
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
FileObject->DeviceObject,
Address,
4096,
Offset,
&Event,
StatusBlock);
Irp = IoBuildSynchronousFsdRequestWithMdl(IRP_MJ_READ,
FileObject->DeviceObject,
Mdl,
Offset,
&Event,
StatusBlock);
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->FileObject = FileObject;
DPRINT("Before IoCallDriver\n");

View file

@ -62,8 +62,6 @@ VOID KeApcProlog2(PKAPC Apc)
* a kernel APC
*/
{
KIRQL oldIrql;
DPRINT("KeApcProlog2(Apc %x)\n",Apc);
KeEnterCriticalRegion();
Apc->Thread->ApcState.KernelApcInProgress++;
@ -77,7 +75,6 @@ VOID KeApcProlog2(PKAPC Apc)
Apc->Thread->ApcState.KernelApcInProgress--;
KeLeaveCriticalRegion();
PsSuspendThread(CONTAINING_RECORD(Apc->Thread,ETHREAD,Tcb));
KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
}
VOID KeDeliverKernelApc(PKAPC Apc)

View file

@ -71,15 +71,21 @@ void KeDrainDpcQueue(void)
while (current_entry!=(&DpcQueueHead))
{
CHECKPOINT;
DPRINT("DpcQueueSize %d current %x current->DeferredContext %x\n",
DpcQueueSize, current, current->DeferredContext);
DPRINT("current->Flink %x\n", current->DpcListEntry.Flink);
current->DeferredRoutine(current,current->DeferredContext,
current->SystemArgument1,
current->SystemArgument2);
CHECKPOINT;
current->Lock=FALSE;
KeRaiseIrql(HIGH_LEVEL,&oldlvl);
current_entry = RemoveHeadList(&DpcQueueHead);
DPRINT("current_entry %x\n", current_entry);
DpcQueueSize--;
KeLowerIrql(oldlvl);
current = CONTAINING_RECORD(&current_entry,KDPC,DpcListEntry);
current = CONTAINING_RECORD(current_entry,KDPC,DpcListEntry);
DPRINT("current %x\n", current);
}
KeReleaseSpinLockFromDpcLevel(&DpcQueueLock);
}
@ -93,13 +99,18 @@ BOOLEAN KeRemoveQueueDpc(PKDPC Dpc)
* FALSE otherwise
*/
{
KIRQL oldIrql;
KeAcquireSpinLock(&DpcQueueLock, &oldIrql);
if (!Dpc->Lock)
{
KeReleaseSpinLock(&DpcQueueLock, oldIrql);
return(FALSE);
}
RemoveEntryList(&Dpc->DpcListEntry);
DpcQueueSize--;
Dpc->Lock=0;
KeReleaseSpinLock(&DpcQueueLock, oldIrql);
return(TRUE);
}
@ -130,6 +141,7 @@ BOOLEAN KeInsertQueueDpc(PKDPC dpc, PVOID SystemArgument1,
}
KeAcquireSpinLockAtDpcLevel(&DpcQueueLock);
InsertHeadList(&DpcQueueHead,&dpc->DpcListEntry);
DPRINT("dpc->DpcListEntry.Flink %x\n", dpc->DpcListEntry.Flink);
DpcQueueSize++;
KeReleaseSpinLockFromDpcLevel(&DpcQueueLock);
dpc->Lock=(PULONG)1;

View file

@ -26,7 +26,24 @@ VOID KeClearEvent(PKEVENT Event)
VOID KeInitializeEvent(PKEVENT Event, EVENT_TYPE Type, BOOLEAN State)
{
KeInitializeDispatcherHeader(&(Event->Header),Type,
ULONG IType;
if (Type == NotificationEvent)
{
IType = InternalNotificationEvent;
}
else if (Type == SynchronizationEvent)
{
IType = InternalSynchronizationEvent;
}
else
{
assert(FALSE);
return;
}
KeInitializeDispatcherHeader(&(Event->Header),
IType,
sizeof(Event)/sizeof(ULONG),State);
InitializeListHead(&(Event->Header.WaitListHead));
}

View file

@ -0,0 +1,396 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/hal/x86/exp.c
* PURPOSE: Handling exceptions
* PROGRAMMER: David Welch (welch@cwcom.net)
* REVISION HISTORY:
* ??/??/??: Created
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <internal/ntoskrnl.h>
#include <internal/ke.h>
#include <internal/symbol.h>
#include <internal/i386/segment.h>
#include <internal/mmhal.h>
#define NDEBUG
#include <internal/debug.h>
/* GLOBALS *****************************************************************/
asmlinkage int page_fault_handler(unsigned int cs,
unsigned int eip);
static exception_hook* exception_hooks[256]={NULL,};
#define _STR(x) #x
#define STR(x) _STR(x)
extern void interrupt_handler2e(void);
extern ULONG init_stack;
extern ULONG init_stack_top;
/* FUNCTIONS ****************************************************************/
#define EXCEPTION_HANDLER_WITH_ERROR(x,y) \
void exception_handler##y (void); \
void tmp_exception_handler##y (void) { \
__asm__("\n\t_exception_handler"##x":\n\t" \
"pushl %gs\n\t" \
"pushl %fs\n\t" \
"pushl %es\n\t" \
"pushl %ds\n\t" \
"pushl $"##x"\n\t" \
"pusha\n\t" \
"movw $"STR(KERNEL_DS)",%ax\n\t" \
"movw %ax,%ds\n\t" \
"movw %ax,%es\n\t" \
"movw %ax,%fs\n\t" \
"movw %ax,%gs\n\t" \
"call _exception_handler\n\t" \
"popa\n\t" \
"addl $4,%esp\n\t" \
"popl %ds\n\t" \
"popl %es\n\t" \
"popl %fs\n\t" \
"popl %gs\n\t" \
"addl $4,%esp\n\t" \
"iret\n\t"); }
#define EXCEPTION_HANDLER_WITHOUT_ERROR(x,y) \
asmlinkage void exception_handler##y (void); \
void tmp_exception_handler##y (void) { \
__asm__("\n\t_exception_handler"##x":\n\t" \
"pushl $0\n\t" \
"pushl %gs\n\t" \
"pushl %fs\n\t" \
"pushl %es\n\t" \
"pushl %ds\n\t" \
"pushl $"##x"\n\t" \
"pusha\n\t" \
"movw $"STR(KERNEL_DS)",%ax\n\t" \
"movw %ax,%ds\n\t" \
"movw %ax,%es\n\t" \
"movw %ax,%fs\n\t" \
"movw %ax,%gs\n\t" \
"call _exception_handler\n\t" \
"popa\n\t" \
"addl $4,%esp\n\t" \
"popl %ds\n\t" \
"popl %es\n\t" \
"popl %fs\n\t" \
"popl %gs\n\t" \
"addl $4,%esp\n\t" \
"iret\n\t"); }
asmlinkage void exception_handler_unknown(void);
asmlinkage void tmp_exception_handler_unknown(void)
{
__asm__("\n\t_exception_handler_unknown:\n\t"
"pushl $0\n\t"
"pushl %gs\n\t"
"pushl %fs\n\t"
"pushl %es\n\t"
"pushl %ds\n\t"
"pushl %ds\n\t"
"pushl $0xff\n\t"
"pusha\n\t"
"movw $"STR(KERNEL_DS)",%ax\n\t"
"movw %ax,%ds\n\t"
"movw %ax,%es\n\t"
"movw %ax,%fs\n\t"
"movw %ax,%gs\n\t"
"call _exception_handler\n\t"
"popa\n\t"
"addl $8,%esp\n\t"
"iret\n\t");
}
EXCEPTION_HANDLER_WITHOUT_ERROR("0",0);
EXCEPTION_HANDLER_WITHOUT_ERROR("1",1);
EXCEPTION_HANDLER_WITHOUT_ERROR("2",2);
EXCEPTION_HANDLER_WITHOUT_ERROR("3",3);
EXCEPTION_HANDLER_WITHOUT_ERROR("4",4);
EXCEPTION_HANDLER_WITHOUT_ERROR("5",5);
EXCEPTION_HANDLER_WITHOUT_ERROR("6",6);
EXCEPTION_HANDLER_WITHOUT_ERROR("7",7);
EXCEPTION_HANDLER_WITH_ERROR("8",8);
EXCEPTION_HANDLER_WITHOUT_ERROR("9",9);
EXCEPTION_HANDLER_WITH_ERROR("10",10);
EXCEPTION_HANDLER_WITH_ERROR("11",11);
EXCEPTION_HANDLER_WITH_ERROR("12",12);
EXCEPTION_HANDLER_WITH_ERROR("13",13);
EXCEPTION_HANDLER_WITH_ERROR("14",14);
EXCEPTION_HANDLER_WITH_ERROR("15",15);
EXCEPTION_HANDLER_WITHOUT_ERROR("16",16);
extern unsigned int stext, etext;
asmlinkage void exception_handler(unsigned int edi,
unsigned int esi, unsigned int ebp,
unsigned int esp, unsigned int ebx,
unsigned int edx, unsigned int ecx,
unsigned int eax,
unsigned int type,
unsigned int ds,
unsigned int es,
unsigned int fs,
unsigned int gs,
unsigned int error_code,
unsigned int eip,
unsigned int cs, unsigned int eflags,
unsigned int esp0, unsigned int ss0)
/*
* FUNCTION: Called by the lowlevel execption handlers to print an amusing
* message and halt the computer
* ARGUMENTS:
* Complete CPU context
*/
{
unsigned int cr2, cr3;
unsigned int i, j, sym;
unsigned int* stack;
static char *TypeStrings[] =
{
"Divide Error",
"Debug Trap",
"Unknown(2)",
"Breakpoint",
"Overflow",
"BOUND range exceeded",
"Invalid Opcode",
"No Math Coprocessor",
"Double Fault",
"Unknown(9)",
"Invalid TSS",
"Segment Not Present",
"Stack Segment Fault",
"General Protection",
"Page Fault",
"Math Fault",
"Alignment Check",
"Machine Check"
};
__asm__("cli\n\t");
if (type==14)
{
if (page_fault_handler(cs&0xffff,eip))
{
return;
}
}
if (type==1)
{
DbgPrint("Trap at CS:EIP %x:%x\n",cs&0xffff,eip);
return;
}
/*
* Activate any hook for the exception
*/
if (exception_hooks[type]!=NULL)
{
exception_hooks[type](NULL,type);
}
/*
* Print out the CPU registers
*/
if (type < 19)
{
DbgPrint("%s Exception: %d(%x)\n",TypeStrings[type],type,
error_code&0xffff);
}
else
{
DbgPrint("Exception: %d(%x)\n",type,error_code&0xffff);
}
DbgPrint("CS:EIP %x:%x\n",cs&0xffff,eip);
__asm__("movl %%cr2,%0\n\t"
: "=d" (cr2));
__asm__("movl %%cr3,%0\n\t"
: "=d" (cr3));
DbgPrint("cr2 %x cr3 %x\n",cr2,cr3);
// for(;;);
DbgPrint("Process: %x\n",PsGetCurrentProcess());
if (PsGetCurrentProcess() != NULL)
{
DbgPrint("Process id: %x\n", PsGetCurrentProcess()->UniqueProcessId);
}
if (PsGetCurrentThread() != NULL)
{
DbgPrint("Thread: %x Thread id: %x\n",
PsGetCurrentThread(),
PsGetCurrentThread()->Cid.UniqueThread);
}
DbgPrint("DS %x ES %x FS %x GS %x\n",ds&0xffff,es&0xffff,fs&0xffff,
gs&0xfff);
DbgPrint("EAX: %.8x EBX: %.8x ECX: %.8x\n",eax,ebx,ecx);
DbgPrint("EDX: %.8x EBP: %.8x ESI: %.8x\n",edx,ebp,esi);
DbgPrint("EDI: %.8x EFLAGS: %.8x ",edi,eflags);
if ((cs&0xffff) == KERNEL_CS)
{
DbgPrint("kESP %.8x\n",esp);
if (PsGetCurrentThread() != NULL)
{
DbgPrint("kernel stack base %x\n",
PsGetCurrentThread()->Tcb.Context.KernelStackBase);
}
}
else
{
DbgPrint("kernel ESP %.8x\n",esp);
}
for(;;);
if ((cs & 0xffff) == KERNEL_CS)
{
DbgPrint("ESP %x\n",esp);
stack = (unsigned int *) (esp + 24);
DbgPrint("Stack:\n");
for (i = 0; i < 16; i = i + 4)
{
DbgPrint("%.8x %.8x %.8x %.8x\n",
stack[i],
stack[i+1],
stack[i+2],
stack[i+3]);
}
DbgPrint("Frames:\n");
for (i = 0; i < 32; i++)
{
if (stack[i] > ((unsigned int) &stext) &&
!(stack[i] >= ((ULONG)&init_stack) &&
stack[i] <= ((ULONG)&init_stack_top)))
{
DbgPrint(" %.8x",
stack[i]);
}
}
}
else
{
DbgPrint("SS:ESP %x:%x\n",ss0,esp0);
stack=(unsigned int *)(esp0);
DbgPrint("Stack:\n");
for (i=0; i<16; i++)
{
if (MmIsPagePresent(NULL,&stack[i]))
{
DbgPrint("%.8x ",stack[i]);
if (((i+1)%4) == 0)
{
DbgPrint("\n");
}
}
}
}
DPRINT1("Killing current task\n");
for(;;);
KeLowerIrql(PASSIVE_LEVEL);
if ((cs&0xffff) == USER_CS)
{
ZwTerminateProcess(NtCurrentProcess(),
STATUS_NONCONTINUABLE_EXCEPTION);
}
for(;;);
}
VOID KeDumpStackFrames(ULONG DummyArg, ULONG NrFrames)
{
PULONG Stack = &((&DummyArg)[-1]);
ULONG i;
Stack = (PVOID)(((ULONG)Stack) & (~0x3));
DbgPrint("Frames:\n");
for (i=0; i<NrFrames; i++)
{
// if (Stack[i] > KERNEL_BASE && Stack[i] < ((ULONG)&etext))
if (Stack[i] > KERNEL_BASE)
{
DbgPrint("%.8x ",Stack[i]);
}
if (Stack[i] == 0xceafbeef)
{
DbgPrint("IRQ ");
}
}
DbgPrint("\n");
}
static void set_system_call_gate(unsigned int sel, unsigned int func)
{
DPRINT("sel %x %d\n",sel,sel);
KiIdt[sel].a = (((int)func)&0xffff) +
(KERNEL_CS << 16);
KiIdt[sel].b = 0xef00 + (((int)func)&0xffff0000);
DPRINT("idt[sel].b %x\n",KiIdt[sel].b);
}
static void set_interrupt_gate(unsigned int sel, unsigned int func)
{
DPRINT("set_interrupt_gate(sel %d, func %x)\n",sel,func);
KiIdt[sel].a = (((int)func)&0xffff) +
(KERNEL_CS << 16);
KiIdt[sel].b = 0x8f00 + (((int)func)&0xffff0000);
}
asmlinkage unsigned int ExHookException(exception_hook fn, unsigned int exp)
/*
* FUNCTION: Hook an exception
*/
{
if (exp>=256)
{
return(1);
}
exception_hooks[exp]=fn;
return(0);
}
asmlinkage void KeInitExceptions(void)
/*
* FUNCTION: Initalize CPU exception handling
*/
{
int i;
DPRINT("KeInitExceptions()\n",0);
set_interrupt_gate(0,(int)exception_handler0);
set_interrupt_gate(1,(int)exception_handler1);
set_interrupt_gate(2,(int)exception_handler2);
set_interrupt_gate(3,(int)exception_handler3);
set_interrupt_gate(4,(int)exception_handler4);
set_interrupt_gate(5,(int)exception_handler5);
set_interrupt_gate(6,(int)exception_handler6);
set_interrupt_gate(7,(int)exception_handler7);
set_interrupt_gate(8,(int)exception_handler8);
set_interrupt_gate(9,(int)exception_handler9);
set_interrupt_gate(10,(int)exception_handler10);
set_interrupt_gate(11,(int)exception_handler11);
set_interrupt_gate(12,(int)exception_handler12);
set_interrupt_gate(13,(int)exception_handler13);
set_interrupt_gate(14,(int)exception_handler14);
set_interrupt_gate(15,(int)exception_handler15);
set_interrupt_gate(16,(int)exception_handler16);
for (i=17;i<256;i++)
{
set_interrupt_gate(i,(int)exception_handler_unknown);
}
set_system_call_gate(0x2e,(int)interrupt_handler2e);
}

View file

@ -0,0 +1,341 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/x86/thread.c
* PURPOSE: HAL multitasking functions
* PROGRAMMER: David Welch (welch@cwcom.net)
* REVISION HISTORY:
* 27/06/98: Created
*/
/* INCLUDES ****************************************************************/
#include <ddk/ntddk.h>
#include <internal/ntoskrnl.h>
#include <internal/ps.h>
#include <string.h>
#include <internal/string.h>
#include <internal/hal.h>
#include <internal/i386/segment.h>
#include <internal/mmhal.h>
#include <internal/ke.h>
#define NDEBUG
#include <internal/debug.h>
/* GLOBALS ***************************************************************/
#define NR_TASKS 128
#define FIRST_TSS_SELECTOR (KERNEL_DS + 0x8)
#define FIRST_TSS_OFFSET (FIRST_TSS_SELECTOR / 8)
static char KiNullLdt[8] = {0,};
static unsigned int KiNullLdtSel = 0;
static PETHREAD FirstThread = NULL;
/* FUNCTIONS **************************************************************/
VOID HalTaskSwitch(PKTHREAD thread)
/*
* FUNCTION: Switch tasks
* ARGUMENTS:
* thread = Thread to switch to
* NOTE: This function will not return until the current thread is scheduled
* again (possibly never);
*/
{
DPRINT("Scheduling thread %x\n",thread);
DPRINT("Scheduling thread %x\n",thread->Context.nr);
DPRINT("previous task %x reserved1 %x esp0 %x ss0 %x\n",
thread->Context.previous_task,thread->Context.reserved1,
thread->Context.esp0,thread->Context.ss0);
DPRINT("reserved2 %x esp1 %x ss1 %x reserved3 %x esp2 %x ss2 %x\n",
thread->Context.reserved2,thread->Context.esp1,thread->Context.ss1,
thread->Context.reserved3,thread->Context.esp2,thread->Context.ss2);
DPRINT("reserved4 %x cr3 %x eip %x eflags %x eax %x\n",
thread->Context.reserved4,thread->Context.cr3,thread->Context.eip,
thread->Context.eflags,thread->Context.eax);
DPRINT("ecx %x edx %x ebx %x esp %x ebp %x esi %x\n",
thread->Context.ecx,thread->Context.edx,thread->Context.ebx,
thread->Context.esp,thread->Context.ebp,thread->Context.esi);
DPRINT("edi %x es %x reserved5 %x cs %x reserved6 %x\n",
thread->Context.edi,thread->Context.es,thread->Context.reserved5,
thread->Context.cs,thread->Context.reserved6);
DPRINT("ss %x reserved7 %x ds %x reserved8 %x fs %x\n",
thread->Context.ss,thread->Context.reserved7,thread->Context.ds,
thread->Context.reserved8,thread->Context.fs);
DPRINT("reserved9 %x gs %x reserved10 %x ldt %x reserved11 %x\n",
thread->Context.reserved9,thread->Context.gs,
thread->Context.reserved10,thread->Context.ldt,
thread->Context.reserved11);
DPRINT("trap %x iomap_base %x nr %x io_bitmap[0] %x\n",
thread->Context.trap,thread->Context.iomap_base,
thread->Context.nr,thread->Context.io_bitmap[0]);
DPRINT("thread->Context.cr3 %x\n",thread->Context.cr3);
__asm__("pushfl\n\t"
"cli\n\t"
"ljmp %0\n\t"
"popfl\n\t"
: /* No outputs */
: "m" (*(((unsigned char *)(&(thread->Context.nr)))-4) )
: "ax","dx");
}
#define FLAG_NT (1<<14)
#define FLAG_VM (1<<17)
#define FLAG_IF (1<<9)
#define FLAG_IOPL ((1<<12)+(1<<13))
NTSTATUS KeValidateUserContext(PCONTEXT Context)
/*
* FUNCTION: Validates a processor context
* ARGUMENTS:
* Context = Context to validate
* RETURNS: Status
* NOTE: This only validates the context as not violating system security, it
* doesn't guararantee the thread won't crash at some point
* NOTE2: This relies on there only being two selectors which can access
* system space
*/
{
if (Context->Eip >= KERNEL_BASE)
{
return(STATUS_UNSUCCESSFUL);
}
if (Context->SegCs == KERNEL_CS)
{
return(STATUS_UNSUCCESSFUL);
}
if (Context->SegDs == KERNEL_DS)
{
return(STATUS_UNSUCCESSFUL);
}
if (Context->SegEs == KERNEL_DS)
{
return(STATUS_UNSUCCESSFUL);
}
if (Context->SegFs == KERNEL_DS)
{
return(STATUS_UNSUCCESSFUL);
}
if (Context->SegGs == KERNEL_DS)
{
return(STATUS_UNSUCCESSFUL);
}
if ((Context->EFlags & FLAG_IOPL) != 0 ||
(Context->EFlags & FLAG_NT) ||
(Context->EFlags & FLAG_VM) ||
(!(Context->EFlags & FLAG_IF)))
{
return(STATUS_UNSUCCESSFUL);
}
return(STATUS_SUCCESS);
}
NTSTATUS HalReleaseTask(PETHREAD Thread)
/*
* FUNCTION: Releases the resource allocated for a thread by
* HalInitTaskWithContext or HalInitTask
* NOTE: The thread had better not be running when this is called
*/
{
KeFreeGdtSelector(Thread->Tcb.Context.nr);
ExFreePool(Thread->Tcb.Context.KernelStackBase);
if (Thread->Tcb.Context.SavedKernelStackBase != NULL)
{
ExFreePool(Thread->Tcb.Context.SavedKernelStackBase);
}
return(STATUS_SUCCESS);
}
NTSTATUS HalInitTaskWithContext(PETHREAD Thread, PCONTEXT Context)
/*
* FUNCTION: Initialize a task with a user mode context
* ARGUMENTS:
* Thread = Thread to initialize
* Context = Processor context to initialize it with
* RETURNS: Status
*/
{
unsigned int desc;
unsigned int length;
unsigned int base;
PVOID kernel_stack;
NTSTATUS Status;
PVOID stack_start;
ULONG GdtDesc[2];
DPRINT("HalInitTaskWithContext(Thread %x, Context %x)\n",
Thread,Context);
assert(sizeof(hal_thread_state)>=0x68);
if ((Status=KeValidateUserContext(Context))!=STATUS_SUCCESS)
{
return(Status);
}
length = sizeof(hal_thread_state) - 1;
base = (unsigned int)(&(Thread->Tcb.Context));
// kernel_stack = ExAllocatePool(NonPagedPool,PAGESIZE);
kernel_stack = ExAllocatePool(NonPagedPool, 3*PAGESIZE);
/*
* Setup a TSS descriptor
*/
GdtDesc[0] = (length & 0xffff) | ((base & 0xffff) << 16);
GdtDesc[1] = ((base & 0xff0000)>>16) | 0x8900 | (length & 0xf0000)
| (base & 0xff000000);
desc = KeAllocateGdtSelector(GdtDesc);
if (desc == 0)
{
return(STATUS_UNSUCCESSFUL);
}
stack_start = kernel_stack + 4096 - sizeof(CONTEXT);
memcpy(stack_start, Context, sizeof(CONTEXT));
/*
* Initialize the thread context
*/
memset(&Thread->Tcb.Context,0,sizeof(hal_thread_state));
Thread->Tcb.Context.ldt = KiNullLdtSel;
Thread->Tcb.Context.eflags = (1<<1) + (1<<9);
Thread->Tcb.Context.iomap_base = FIELD_OFFSET(hal_thread_state,io_bitmap);
Thread->Tcb.Context.esp0 = (ULONG)stack_start;
Thread->Tcb.Context.ss0 = KERNEL_DS;
Thread->Tcb.Context.esp = (ULONG)stack_start;
Thread->Tcb.Context.ss = KERNEL_DS;
Thread->Tcb.Context.cs = KERNEL_CS;
Thread->Tcb.Context.eip = (ULONG)PsBeginThreadWithContextInternal;
Thread->Tcb.Context.io_bitmap[0] = 0xff;
Thread->Tcb.Context.cr3 = (ULONG)
Thread->ThreadsProcess->Pcb.PageTableDirectory;
Thread->Tcb.Context.ds = KERNEL_DS;
Thread->Tcb.Context.es = KERNEL_DS;
Thread->Tcb.Context.fs = KERNEL_DS;
Thread->Tcb.Context.gs = KERNEL_DS;
Thread->Tcb.Context.nr = desc * 8;
Thread->Tcb.Context.KernelStackBase = kernel_stack;
Thread->Tcb.Context.SavedKernelEsp = 0;
Thread->Tcb.Context.SavedKernelStackBase = NULL;
return(STATUS_SUCCESS);
}
NTSTATUS HalInitTask(PETHREAD thread, PKSTART_ROUTINE fn, PVOID StartContext)
/*
* FUNCTION: Initializes the HAL portion of a thread object
* ARGUMENTS:
* thread = Object describes the thread
* fn = Entrypoint for the thread
* StartContext = parameter to pass to the thread entrypoint
* RETURNS: True if the function succeeded
*/
{
unsigned int desc;
unsigned int length = sizeof(hal_thread_state) - 1;
unsigned int base = (unsigned int)(&(thread->Tcb.Context));
// PULONG KernelStack = ExAllocatePool(NonPagedPool,4096);
PULONG KernelStack;
ULONG GdtDesc[2];
DPRINT("HalInitTask(Thread %x, fn %x, StartContext %x)\n",
thread,fn,StartContext);
DPRINT("thread->ThreadsProcess %x\n",thread->ThreadsProcess);
KernelStack = ExAllocatePool(NonPagedPool, 3*PAGESIZE);
/*
* Make sure
*/
assert(sizeof(hal_thread_state)>=0x68);
/*
* Setup a TSS descriptor
*/
GdtDesc[0] = (length & 0xffff) | ((base & 0xffff) << 16);
GdtDesc[1] = ((base & 0xff0000)>>16) | 0x8900 | (length & 0xf0000)
| (base & 0xff000000);
desc = KeAllocateGdtSelector(GdtDesc);
if (desc == 0)
{
return(STATUS_UNSUCCESSFUL);
}
// DPRINT("sizeof(descriptor) %d\n",sizeof(descriptor));
// DPRINT("desc %d\n",desc);
/*
* Initialize the stack for the thread (including the two arguments to
* the general start routine).
*/
KernelStack[1023] = (unsigned int)StartContext;
KernelStack[1022] = (unsigned int)fn;
KernelStack[1021] = 0;
/*
* Initialize the thread context
*/
memset(&thread->Tcb.Context,0,sizeof(hal_thread_state));
thread->Tcb.Context.ldt = KiNullLdtSel;
thread->Tcb.Context.eflags = (1<<1)+(1<<9);
thread->Tcb.Context.iomap_base = FIELD_OFFSET(hal_thread_state,io_bitmap);
thread->Tcb.Context.esp0 = (ULONG)&KernelStack[1021];
thread->Tcb.Context.ss0 = KERNEL_DS;
thread->Tcb.Context.esp = (ULONG)&KernelStack[1021];
thread->Tcb.Context.ss = KERNEL_DS;
thread->Tcb.Context.cs = KERNEL_CS;
thread->Tcb.Context.eip = (ULONG)PsBeginThread;
thread->Tcb.Context.io_bitmap[0] = 0xff;
thread->Tcb.Context.cr3 = (ULONG)
thread->ThreadsProcess->Pcb.PageTableDirectory;
thread->Tcb.Context.ds = KERNEL_DS;
thread->Tcb.Context.es = KERNEL_DS;
thread->Tcb.Context.fs = KERNEL_DS;
thread->Tcb.Context.gs = KERNEL_DS;
thread->Tcb.Context.nr = desc * 8;
thread->Tcb.Context.KernelStackBase = KernelStack;
thread->Tcb.Context.SavedKernelEsp = 0;
thread->Tcb.Context.SavedKernelStackBase = NULL;
DPRINT("Allocated %x\n",desc*8);
return(STATUS_SUCCESS);
}
void HalInitFirstTask(PETHREAD thread)
/*
* FUNCTION: Called to setup the HAL portion of a thread object for the
* initial thread
*/
{
ULONG base;
ULONG length;
ULONG desc;
ULONG GdtDesc[2];
memset(KiNullLdt, 0, sizeof(KiNullLdt));
base = (unsigned int)&KiNullLdt;
length = sizeof(KiNullLdt) - 1;
GdtDesc[0] = (length & 0xffff) | ((base & 0xffff) << 16);
GdtDesc[1] = ((base & 0xff0000)>>16) | 0x8200 | (length & 0xf0000)
| (base & 0xff000000);
desc = KeAllocateGdtSelector(GdtDesc);
KiNullLdtSel = desc*8;
/*
* Initialize the thread context
*/
HalInitTask(thread,NULL,NULL);
/*
* Load the task register
*/
__asm__("ltr %%ax"
: /* no output */
: "a" (thread->Tcb.Context.nr));
FirstThread = thread;
}

View file

@ -0,0 +1,259 @@
/* $Id: usercall.c,v 1.1 1999/11/12 12:01:16 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/hal/x86/usercall.c
* PURPOSE: 2E interrupt handler
* PROGRAMMER: David Welch (david.welch@seh.ox.ac.uk)
* UPDATE HISTORY:
* ???
*/
#include <ddk/ntddk.h>
#include <internal/ntoskrnl.h>
#include <internal/ke.h>
#include <internal/symbol.h>
#include <internal/i386/segment.h>
#include <internal/mmhal.h>
#define NDEBUG
#include <internal/debug.h>
#include <internal/service.h>
#include <ddk/defines.h>
extern SERVICE_TABLE _SystemServiceTable[];
/* The service dispatcher will take the service number passed in
* by the user mode process, logical and it with ServiceNumberMask
* and compare the resulting value with ServiceNumberValue. If the
* value matches, The passed service number will be and'ed with the
* inverse of ServiceNumberMask to obtain the index into the ServiceTable
* for the service to call
*/
typedef struct _HAL_DISPATCH_TABLE_ENTRY
{
DWORD ServiceNumberMask;
DWORD ServiceNumberValue;
PSERVICE_TABLE ServiceTable;
DWORD TableCount;
} HAL_DISPATCH_TABLE_ENTRY, *PHAL_DISPATCH_TABLE_ENTRY;
static KSPIN_LOCK DispatchTableLock = {0,};
static DWORD DispatchTableCount = 0;
static HAL_DISPATCH_TABLE_ENTRY DispatchTables[16];
NTSTATUS HalRegisterServiceTable(DWORD Mask,
DWORD Value,
PSERVICE_TABLE Table,
DWORD Count)
{
NTSTATUS Status;
KIRQL OldLvl;
KeAcquireSpinLock(&DispatchTableLock, &OldLvl);
Status = STATUS_SUCCESS;
/* FIXME: should check for invalid/overlapping service tables */
DispatchTables[DispatchTableCount].ServiceNumberMask = Mask;
DispatchTables[DispatchTableCount].ServiceNumberValue = Value;
DispatchTables[DispatchTableCount].ServiceTable = Table;
DispatchTables[DispatchTableCount].TableCount = Count;
DispatchTableCount++;
KeReleaseSpinLock(&DispatchTableLock, OldLvl);
return Status;
}
#define _STR(x) #x
#define STR(x) _STR(x)
void PsBeginThreadWithContextInternal(void);
__asm__(
"\n\t.global _PsBeginThreadWithContextInternal\n\t"
"_PsBeginThreadWithContextInternal:\n\t"
// "pushl $1\n\t"
// "call _KeLowerIrql\n\t"
"call _PiBeforeBeginThread\n\t"
// "popl %eax\n\t"
"popl %eax\n\t"
"popl %eax\n\t"
"popl %eax\n\t"
"popl %eax\n\t"
"popl %eax\n\t"
"popl %eax\n\t"
"popl %eax\n\t"
"addl $112,%esp\n\t"
"popl %gs\n\t"
"popl %fs\n\t"
"popl %es\n\t"
"popl %ds\n\t"
"popl %edi\n\t"
"popl %esi\n\t"
"popl %ebx\n\t"
"popl %edx\n\t"
"popl %ecx\n\t"
"popl %eax\n\t"
"popl %ebp\n\t"
"iret\n\t");
VOID KiSystemCallHook(ULONG Nr)
{
// DbgPrint("KiSystemCallHook(Nr %d) %d\n", Nr, KeGetCurrentIrql());
// DbgPrint("SystemCall %x\n", _SystemServiceTable[Nr].Function);
assert_irql(PASSIVE_LEVEL);
}
void interrupt_handler2e(void);
__asm__("\n\t.global _interrupt_handler2e\n\t"
"_interrupt_handler2e:\n\t"
/* Save the user context */
"pushl %ebp\n\t" /* Ebp */
"pushl %eax\n\t" /* Eax */
"pushl %ecx\n\t" /* Ecx */
"pushl %edx\n\t" /* Edx */
"pushl %ebx\n\t" /* Ebx */
"pushl %esi\n\t" /* Esi */
"pushl %edi\n\t" /* Edi */
"pushl %ds\n\t" /* SegDs */
"pushl %es\n\t" /* SegEs */
"pushl %fs\n\t" /* SegFs */
"pushl %gs\n\t" /* SegGs */
"subl $112,%esp\n\t" /* FloatSave */
"pushl $0\n\t" /* Dr7 */
"pushl $0\n\t" /* Dr6 */
"pushl $0\n\t" /* Dr3 */
"pushl $0\n\t" /* Dr2 */
"pushl $0\n\t" /* Dr1 */
"pushl $0\n\t" /* Dr0 */
"pushl $0\n\t" /* ContextFlags */
/* Set ES to kernel segment */
"movw $"STR(KERNEL_DS)",%bx\n\t"
"movw %bx,%es\n\t"
/* Save pointer to user context as argument to system call */
"pushl %esp\n\t"
/* Allocate new Kernel stack frame */
"movl %esp,%ebp\n\t"
/* Users's current stack frame pointer is source */
"movl %edx,%esi\n\t"
/* FIXME: determine system service table to use */
/* FIXME: chech to see if SS is valid/inrange */
/* Allocate room for argument list from kernel stack */
"movl %es:__SystemServiceTable(,%eax,8),%ecx\n\t"
"subl %ecx,%esp\n\t"
/* Copy the arguments from the user stack to the kernel stack */
"movl %esp,%edi\n\t"
"rep\n\tmovsb\n\t"
/* DS is now also kernel segment */
"movw %bx,%ds\n\t"
/* Call system call hook */
"pushl %eax\n\t"
"call _KiSystemCallHook\n\t"
"popl %eax\n\t"
/* Make the system service call */
"movl %ds:__SystemServiceTable+4(,%eax,8),%eax\n\t"
"call *%eax\n\t"
/* Deallocate the kernel stack frame */
"movl %ebp,%esp\n\t"
/* Remove pointer to user context from stack */
"addl $4,%esp\n\t"
/* Restore the user context */
"addl $4,%esp\n\t" /* UserContext */
"addl $24,%esp\n\t" /* Dr[0-3,6-7] */
"addl $112,%esp\n\t" /* FloatingSave */
"popl %gs\n\t" /* SegGs */
"popl %fs\n\t" /* SegFs */
"popl %es\n\t" /* SegEs */
"popl %ds\n\t" /* SegDs */
"popl %edi\n\t" /* Edi */
"popl %esi\n\t" /* Esi */
"popl %ebx\n\t" /* Ebx */
"popl %edx\n\t" /* Edx */
"popl %ecx\n\t" /* Ecx */
"addl $4,%esp\n\t" /* Eax (Not restored) */
"popl %ebp\n\t" /* Ebp */
"iret\n\t");
void old_interrupt_handler2e(void);
__asm__("\n\t.global _old_interrupt_handler2e\n\t"
"_old_interrupt_handler2e:\n\t"
/* Save the users context */
"pushl %ds\n\t"
"pushl %es\n\t"
"pushl %esi\n\t"
"pushl %edi\n\t"
"pushl %ebp\n\t"
"pushl %ebx\n\t"
/* Set ES to kernel segment */
"movw $"STR(KERNEL_DS)",%bx\n\t"
"movw %bx,%es\n\t"
/* Allocate new Kernel stack frame */
"movl %esp,%ebp\n\t"
/* Users's current stack frame pointer is source */
"movl %edx,%esi\n\t"
/* FIXME: determine system service table to use */
/* FIXME: chech to see if SS is valid/inrange */
/* Allocate room for argument list from kernel stack */
"movl %es:__SystemServiceTable(,%eax,8),%ecx\n\t"
"subl %ecx,%esp\n\t"
/* Copy the arguments from the user stack to the kernel stack */
"movl %esp,%edi\n\t"
"rep\n\tmovsb\n\t"
/* DS is now also kernel segment */
"movw %bx,%ds\n\t"
/* Call system call hook */
"pushl %eax\n\t"
"call _KiSystemCallHook\n\t"
"popl %eax\n\t"
/* Make the system service call */
"movl %ds:__SystemServiceTable+4(,%eax,8),%eax\n\t"
"call *%eax\n\t"
/* Deallocate the kernel stack frame */
"movl %ebp,%esp\n\t"
/* Restore the user context */
"popl %ebx\n\t"
"popl %ebp\n\t"
"popl %edi\n\t"
"popl %esi\n\t"
"popl %es\n\t"
"popl %ds\n\t"
"iret\n\t");

View file

@ -13,6 +13,7 @@
#include <ddk/ntddk.h>
#include <internal/ke.h>
//#define NDEBUG
#include <internal/debug.h>
/* FUNCTIONS *****************************************************************/
@ -27,7 +28,9 @@ VOID KeInit(VOID)
/*
* Allow interrupts
*/
CHECKPOINT;
KeLowerIrql(PASSIVE_LEVEL);
CHECKPOINT;
KeCalibrateTimerLoop();
}

View file

@ -1,4 +1,4 @@
/* $Id: main.c,v 1.29 1999/11/07 08:03:28 ea Exp $
/* $Id: main.c,v 1.30 1999/11/12 12:01:15 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -126,6 +126,68 @@ unsigned int old_idt[256][2];
//extern unsigned int idt[];
unsigned int old_idt_valid = 1;
ERESOURCE TestResource;
VOID thread_main(PVOID param)
{
ULONG Id;
Id = (ULONG)param;
DbgPrint("THREAD(%d) Resource %x\n",Id,&TestResource);
DbgPrint("THREAD(%d) Acquiring resource for shared access\n", Id);
ExAcquireResourceExclusiveLite(&TestResource, TRUE);
DbgPrint("THREAD(%d) Acquired resource for shared access\n", Id);
}
VOID resource_test(VOID)
{
HANDLE thread1_handle;
CLIENT_ID thread1_cid;
HANDLE thread2_handle;
CLIENT_ID thread2_cid;
ULONG i;
ExInitializeResourceLite(&TestResource);
DbgPrint("Resource %x\n", &TestResource);
ExAcquireResourceExclusiveLite(&TestResource, TRUE);
DbgPrint("Acquired resource for exclusive access\n");
PsCreateSystemThread(&thread1_handle,
THREAD_ALL_ACCESS,
NULL,
NULL,
&thread1_cid,
thread_main,
(PVOID)1);
PsCreateSystemThread(&thread2_handle,
THREAD_ALL_ACCESS,
NULL,
NULL,
&thread2_cid,
thread_main,
(PVOID)2);
DbgPrint("KeGetCurrentIrql() %d\n", KeGetCurrentIrql());
for (i=0; i<10000000; i++)
{
__asm__("nop\n\t");
}
ExReleaseResourceLite(&TestResource);
DbgPrint("Released resource\n");
for(;;);
}
asmlinkage void _main(boot_param* _bp)
/*
* FUNCTION: Called by the boot loader to start the kernel
@ -180,13 +242,21 @@ asmlinkage void _main(boot_param* _bp)
/*
* Initalize various critical subsystems
*/
DPRINT("HalInitSystem()\n");
HalInitSystem (1, &bp);
DPRINT("MmInitialize()\n");
MmInitialize(&bp, last_kernel_address);
DPRINT("KeInit()\n");
KeInit();
DPRINT("ExInit()\n");
ExInit();
DPRINT("ObInit()\n");
ObInit();
DPRINT("PsInit()\n");
PsInit();
DPRINT("IoInit()\n");
IoInit();
DPRINT("LdrInitModuleManagement()\n");
LdrInitModuleManagement();
CmInitializeRegistry();

View file

@ -11,6 +11,7 @@
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <internal/ke.h>
#include <internal/debug.h>
@ -18,12 +19,10 @@
VOID KeInitializeMutex(PKMUTEX Mutex, ULONG Level)
{
Mutex->Header.Type=2;
Mutex->Header.SignalState=TRUE;
Mutex->Header.Size = 8;
Mutex->OwnerThread = NULL;
Mutex->ApcDisable = 0;
InitializeListHead(&Mutex->Header.WaitListHead);
KeInitializeDispatcherHeader(&Mutex->Header,
InternalMutexType,
sizeof(KMUTEX) / sizeof(ULONG),
TRUE);
}
LONG KeReadStateMutex(PKMUTEX Mutex)
@ -33,7 +32,9 @@ LONG KeReadStateMutex(PKMUTEX Mutex)
LONG KeReleaseMutex(PKMUTEX Mutex, BOOLEAN Wait)
{
UNIMPLEMENTED;
KeAcquireDispatcherDatabaseLock(Wait);
KeDispatcherObjectWake(&Mutex->Header);
KeReleaseDispatcherDatabaseLock(Wait);
}
NTSTATUS KeWaitForMutexObject(PKMUTEX Mutex,

View file

@ -13,6 +13,7 @@
#include <ddk/ntddk.h>
#include <internal/ke.h>
#define NDEBUG
#include <internal/debug.h>
/* FUNCTIONS *****************************************************************/
@ -21,7 +22,8 @@ VOID KeInitializeSemaphore(PKSEMAPHORE Semaphore,
LONG Count,
LONG Limit)
{
KeInitializeDispatcherHeader(&Semaphore->Header,SemaphoreType,
KeInitializeDispatcherHeader(&Semaphore->Header,
InternalSemaphoreType,
sizeof(KSEMAPHORE)/sizeof(ULONG),
Count);
Semaphore->Limit=Limit;
@ -36,18 +38,49 @@ LONG KeReleaseSemaphore(PKSEMAPHORE Semaphore,
KPRIORITY Increment,
LONG Adjustment,
BOOLEAN Wait)
/*
* FUNCTION: KeReleaseSemaphore releases a given semaphore object. This
* routine supplies a runtime priority boost for waiting threads. If this
* call sets the semaphore to the Signaled state, the semaphore count is
* augmented by the given value. The caller can also specify whether it
* will call one of the KeWaitXXX routines as soon as KeReleaseSemaphore
* returns control.
* ARGUMENTS:
* Semaphore = Points to an initialized semaphore object for which the
* caller provides the storage.
* Increment = Specifies the priority increment to be applied if
* releasing the semaphore causes a wait to be
* satisfied.
* Adjustment = Specifies a value to be added to the current semaphore
* count. This value must be positive
* Wait = Specifies whether the call to KeReleaseSemaphore is to be
* followed immediately by a call to one of the KeWaitXXX.
* RETURNS: If the return value is zero, the previous state of the semaphore
* object is Not-Signaled.
*/
{
ULONG initState = Semaphore->Header.SignalState;
KeAcquireDispatcherDatabaseLock(Wait);
if(Semaphore->Limit < initState+Adjustment
|| initState > initState+Adjustment)
ExRaiseStatus(STATUS_SEMAPHORE_LIMIT_EXCEEDED);
Semaphore->Header.SignalState+=Adjustment;
if(initState == 0)
{
// wake up SignalState waiters
KeDispatcherObjectWake(&Semaphore->Header) ;
}
ULONG initState = Semaphore->Header.SignalState;
DPRINT("KeReleaseSemaphore(Semaphore %x, Increment %d, Adjustment %d, "
"Wait %d)\n", Semaphore, Increment, Adjustment, Wait);
KeAcquireDispatcherDatabaseLock(Wait);
if (Semaphore->Limit < initState+Adjustment
|| initState > initState+Adjustment)
{
ExRaiseStatus(STATUS_SEMAPHORE_LIMIT_EXCEEDED);
}
Semaphore->Header.SignalState+=Adjustment;
DPRINT("initState %d\n", initState);
if(initState == 0)
{
// wake up SignalState waiters
DPRINT("Waking waiters\n");
KeDispatcherObjectWake(&Semaphore->Header);
}
KeReleaseDispatcherDatabaseLock(Wait);
return initState;
}

View file

@ -1,4 +1,4 @@
/* $Id: timer.c,v 1.19 1999/11/02 08:55:40 dwelch Exp $
/* $Id: timer.c,v 1.20 1999/11/12 12:01:15 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -21,6 +21,7 @@
#include <string.h>
#include <internal/string.h>
#include <stdio.h>
#include <internal/ke.h>
#define NDEBUG
#include <internal/debug.h>
@ -29,7 +30,6 @@
#define TIMER_IRQ 0
/* GLOBALS ****************************************************************/
#define IDMAP_BASE (0xd0000000)
@ -71,8 +71,8 @@ volatile ULONGLONG KiTimerTicks;
/*
* PURPOSE: List of timers
*/
static LIST_ENTRY timer_list_head = {NULL,NULL};
static KSPIN_LOCK timer_list_lock = {0,};
static LIST_ENTRY TimerListHead;
static KSPIN_LOCK TimerListLock;
extern ULONG PiNrRunnableThreads;
@ -83,74 +83,29 @@ extern ULONG PiNrRunnableThreads;
static unsigned int loops_per_microsecond = 100;
static BOOLEAN TimerInitDone = FALSE;
/* FUNCTIONS **************************************************************/
VOID KeCalibrateTimerLoop(VOID)
{
unsigned int start_tick;
// unsigned int end_tick;
// unsigned int nr_ticks;
unsigned int i;
unsigned int microseconds;
for (i=0;i<20;i++)
{
start_tick = KiTimerTicks;
microseconds = 0;
while (start_tick == KiTimerTicks);
while (KiTimerTicks == (start_tick+TICKS_TO_CALIBRATE))
{
KeStallExecutionProcessor(1);
microseconds++;
};
// DbgPrint("microseconds %d\n",microseconds);
if (microseconds > (CALIBRATE_PERIOD+1000))
{
loops_per_microsecond = loops_per_microsecond + 1;
}
if (microseconds < (CALIBRATE_PERIOD-1000))
{
loops_per_microsecond = loops_per_microsecond - 1;
}
// DbgPrint("loops_per_microsecond %d\n",loops_per_microsecond);
}
// for(;;);
}
NTSTATUS
STDCALL
NtQueryTimerResolution (
OUT PULONG MinimumResolution,
OUT PULONG MaximumResolution,
OUT PULONG ActualResolution
)
NTSTATUS STDCALL NtQueryTimerResolution(OUT PULONG MinimumResolution,
OUT PULONG MaximumResolution,
OUT PULONG ActualResolution)
{
UNIMPLEMENTED;
}
NTSTATUS
STDCALL
NtSetTimerResolution (
IN ULONG RequestedResolution,
IN BOOL SetOrUnset,
OUT PULONG ActualResolution
)
NTSTATUS STDCALL NtSetTimerResolution(IN ULONG RequestedResolution,
IN BOOL SetOrUnset,
OUT PULONG ActualResolution)
{
UNIMPLEMENTED;
}
NTSTATUS
STDCALL
NtQueryPerformanceCounter (
IN PLARGE_INTEGER Counter,
IN PLARGE_INTEGER Frequency
)
NTSTATUS STDCALL NtQueryPerformanceCounter (IN PLARGE_INTEGER Counter,
IN PLARGE_INTEGER Frequency)
{
UNIMPLEMENTED;
}
@ -167,31 +122,23 @@ NTSTATUS KeAddThreadTimeout(PKTHREAD Thread, PLARGE_INTEGER Interval)
KeSetTimer(&(Thread->Timer),*Interval,NULL);
DPRINT("Thread->Timer.entry.Flink %x\n",
Thread->Timer.entry.Flink);
Thread->Timer.TimerListEntry.Flink);
return STATUS_SUCCESS;
}
NTSTATUS
STDCALL
NtDelayExecution (
IN BOOLEAN Alertable,
IN TIME * Interval
)
NTSTATUS STDCALL NtDelayExecution(IN BOOLEAN Alertable,
IN TIME* Interval)
{
KeBugCheck(0);
return(STATUS_UNSUCCESSFUL);
UNIMPLEMENTED;
return(STATUS_UNSUCCESSFUL);
}
NTSTATUS
STDCALL
KeDelayExecutionThread (
KPROCESSOR_MODE WaitMode,
BOOLEAN Alertable,
PLARGE_INTEGER Interval
)
NTSTATUS STDCALL KeDelayExecutionThread(KPROCESSOR_MODE WaitMode,
BOOLEAN Alertable,
PLARGE_INTEGER Interval)
/*
* FUNCTION: Puts the current thread into an alertable or nonalertable
* wait state for a given internal
@ -202,74 +149,15 @@ KeDelayExecutionThread (
* RETURNS: Status
*/
{
PKTHREAD CurrentThread = KeGetCurrentThread();
KeAddThreadTimeout (
CurrentThread,
Interval
);
return (KeWaitForSingleObject (
& (CurrentThread->Timer),
Executive,
KernelMode,
Alertable,
NULL
)
);
PKTHREAD CurrentThread = KeGetCurrentThread();
KeAddThreadTimeout(CurrentThread, Interval);
return (KeWaitForSingleObject(&(CurrentThread->Timer),
Executive,
KernelMode,
Alertable,
NULL));
}
VOID KeStallExecutionProcessor(ULONG MicroSeconds)
{
unsigned int i;
for (i=0; i<(loops_per_microsecond*MicroSeconds) ;i++)
{
__asm__("nop\n\t");
}
}
#if 0
static inline void ULLToLargeInteger(unsigned long long src,
PLARGE_INTEGER dest)
{
dest->LowPart = src & 0xffffffff;
dest->HighPart = (src>>32);
}
static inline void SLLToLargeInteger(signed long long src,
PLARGE_INTEGER dest)
{
if (src > 0)
{
dest->LowPart = src & 0xffffffff;
dest->HighPart = (src>>32);
}
else
{
src = -src;
dest->LowPart = src & 0xffffffff;
dest->HighPart = -(src>>32);
}
}
static inline signed long long LargeIntegerToSLL(PLARGE_INTEGER src)
{
signed long long r;
r = src->LowPart;
if (src->HighPart >= 0)
{
r = r | (((unsigned long long)src->HighPart)<<32);
}
else
{
r = r | (((unsigned long long)(-(src->HighPart)))<<32);
r = -r;
}
return(r);
}
#endif
LARGE_INTEGER KeQueryPerformanceCounter(PLARGE_INTEGER PerformanceFreq)
/*
* FUNCTION: Queries the finest grained running count avaiable in the system
@ -311,9 +199,7 @@ VOID KeQuerySystemTime(PLARGE_INTEGER CurrentTime)
}
NTSTATUS
STDCALL
NtGetTickCount (PULONG UpTime)
NTSTATUS STDCALL NtGetTickCount (PULONG UpTime)
{
UNIMPLEMENTED;
}
@ -333,7 +219,7 @@ BOOLEAN KeSetTimer(PKTIMER Timer, LARGE_INTEGER DueTime, PKDPC Dpc)
* False otherwise
*/
{
return(KeSetTimerEx(Timer,DueTime,0,Dpc));
return(KeSetTimerEx(Timer, DueTime, 0, Dpc));
}
BOOLEAN KeSetTimerEx(PKTIMER Timer, LARGE_INTEGER DueTime, LONG Period,
@ -355,32 +241,26 @@ BOOLEAN KeSetTimerEx(PKTIMER Timer, LARGE_INTEGER DueTime, LONG Period,
DPRINT("KeSetTimerEx(Timer %x)\n",Timer);
KeAcquireSpinLock(&timer_list_lock,&oldlvl);
KeAcquireSpinLock(&TimerListLock,&oldlvl);
Timer->dpc=Dpc;
Timer->period=Period;
Timer->expire_time = (*(long long int *)&DueTime);
if (Timer->expire_time < 0)
Timer->Dpc = Dpc;
if (DueTime.QuadPart < 0)
{
Timer->expire_time = system_time + (-Timer->expire_time);
Timer->DueTime.QuadPart = system_time + (-(DueTime.QuadPart));
}
DPRINT("System:%ld:%ld Expire:%d:%d Period:%d\n",
(unsigned long) (system_time & 0xffffffff),
(unsigned long) ((system_time >> 32) & 0xffffffff),
(unsigned long) (Timer->expire_time & 0xffffffff),
(unsigned long) ((Timer->expire_time >> 32) & 0xffffffff),
Timer->period);
Timer->signaled = FALSE;
if (Timer->running)
else
{
KeReleaseSpinLock(&timer_list_lock,oldlvl);
return TRUE;
Timer->DueTime.QuadPart = DueTime.QuadPart;
}
DPRINT("Inserting %x in list\n",&Timer->entry);
DPRINT("Timer->entry.Flink %x\n",Timer->entry.Flink);
Timer->running=TRUE;
InsertTailList(&timer_list_head,&Timer->entry);
KeReleaseSpinLock(&timer_list_lock,oldlvl);
Timer->Period = Period;
Timer->Header.SignalState = FALSE;
if (Timer->TimerListEntry.Flink != NULL)
{
KeReleaseSpinLock(&TimerListLock, oldlvl);
return(TRUE);
}
InsertTailList(&TimerListHead,&Timer->TimerListEntry);
KeReleaseSpinLock(&TimerListLock, oldlvl);
return FALSE;
}
@ -398,23 +278,23 @@ BOOLEAN KeCancelTimer(PKTIMER Timer)
DPRINT("KeCancelTimer(Timer %x)\n",Timer);
KeAcquireSpinLock(&timer_list_lock, &oldlvl);
KeAcquireSpinLock(&TimerListLock, &oldlvl);
if (!Timer->running)
if (Timer->TimerListEntry.Flink == NULL)
{
KeReleaseSpinLock(&timer_list_lock, oldlvl);
return FALSE;
KeReleaseSpinLock(&TimerListLock, oldlvl);
return(FALSE);
}
RemoveEntryList(&Timer->entry);
Timer->running = FALSE;
KeReleaseSpinLock(&timer_list_lock, oldlvl);
RemoveEntryList(&Timer->TimerListEntry);
Timer->TimerListEntry.Flink = Timer->TimerListEntry.Blink = NULL;
KeReleaseSpinLock(&TimerListLock, oldlvl);
return TRUE;
return(TRUE);
}
BOOLEAN KeReadStateTimer(PKTIMER Timer)
{
return Timer->signaled;
return(Timer->Header.SignalState);
}
VOID KeInitializeTimer(PKTIMER Timer)
@ -440,9 +320,27 @@ VOID KeInitializeTimerEx(PKTIMER Timer, TIMER_TYPE Type)
* single waiting thread is released and then the timer is reset.
*/
{
Timer->running=FALSE;
Timer->type=Type;
Timer->signaled=FALSE;
ULONG IType;
if (Type == NotificationTimer)
{
IType = InternalNotificationTimer;
}
else if (Type == SynchronizationTimer)
{
IType = InternalSynchronizationTimer;
}
else
{
assert(FALSE);
return;
}
KeInitializeDispatcherHeader(&Timer->Header,
IType,
sizeof(KTIMER) / sizeof(ULONG),
FALSE);
Timer->TimerListEntry.Flink = Timer->TimerListEntry.Blink = NULL;
}
VOID KeQueryTickCount(PLARGE_INTEGER TickCount)
@ -458,64 +356,68 @@ VOID KeQueryTickCount(PLARGE_INTEGER TickCount)
static void HandleExpiredTimer(PKTIMER current)
{
DPRINT("HandleExpiredTime(current %x)\n",current);
if (current->dpc!=NULL)
if (current->Dpc != NULL)
{
DPRINT("current->dpc->DeferredRoutine %x\n",
current->dpc->DeferredRoutine);
current->dpc->DeferredRoutine(current->dpc,
current->dpc->DeferredContext,
current->dpc->SystemArgument1,
current->dpc->SystemArgument2);
DPRINT("current->Dpc %x current->Dpc->DeferredRoutine %x\n",
current->Dpc, current->Dpc->DeferredRoutine);
KeInsertQueueDpc(current->Dpc,
NULL,
NULL);
DPRINT("Finished dpc routine\n");
}
current->signaled=TRUE;
if (current->period != 0)
current->Header.SignalState = TRUE;
if (current->Period != 0)
{
DPRINT("System:%ld:%ld Expire:%d:%d Period:%d\n",
(unsigned long) (system_time & 0xffffffff),
(unsigned long) ((system_time >> 32) & 0xffffffff),
(unsigned long) (current->expire_time & 0xffffffff),
(unsigned long) ((current->expire_time >> 32) & 0xffffffff),
current->period);
current->expire_time += current->period * SYSTEM_TIME_UNITS_PER_MSEC;
current->DueTime.QuadPart +=
current->Period * SYSTEM_TIME_UNITS_PER_MSEC;
}
else
{
RemoveEntryList(&current->entry);
current->running=FALSE;
RemoveEntryList(&current->TimerListEntry);
current->TimerListEntry.Flink = current->TimerListEntry.Blink = NULL;
}
}
void KeExpireTimers(void)
VOID KeExpireTimers(VOID)
{
PLIST_ENTRY current_entry = timer_list_head.Flink;
PKTIMER current = CONTAINING_RECORD(current_entry,KTIMER,entry);
PLIST_ENTRY current_entry = NULL;
PKTIMER current = NULL;
KIRQL oldlvl;
DPRINT("KeExpireTimers()\n");
DPRINT("&timer_list_head %x\n",&timer_list_head);
DPRINT("current_entry %x\n",current_entry);
DPRINT("current_entry->Flink %x\n",current_entry->Flink);
DPRINT("current_entry->Flink->Flink %x\n",current_entry->Flink->Flink);
// DPRINT("KeExpireTimers()\n");
KeAcquireSpinLock(&timer_list_lock,&oldlvl);
while (current_entry!=(&timer_list_head))
if (TimerInitDone == FALSE)
{
if (system_time >= current->expire_time)
return;
}
current_entry = TimerListHead.Flink;
// DPRINT("&TimerListHead %x\n",&TimerListHead);
// DPRINT("current_entry %x\n",current_entry);
// DPRINT("current_entry->Flink %x\n",current_entry->Flink);
// DPRINT("current_entry->Flink->Flink %x\n",current_entry->Flink->Flink);
KeAcquireSpinLock(&TimerListLock, &oldlvl);
while (current_entry!=(&TimerListHead))
{
current = CONTAINING_RECORD(current_entry, KTIMER, TimerListEntry);
current_entry = current_entry->Flink;
if (system_time >= current->DueTime.QuadPart)
{
HandleExpiredTimer(current);
}
current_entry = current_entry->Flink;
current = CONTAINING_RECORD(current_entry,KTIMER,entry);
}
}
KeReleaseSpinLock(&timer_list_lock,oldlvl);
DPRINT("Finished KeExpireTimers()\n");
KeReleaseSpinLock(&TimerListLock,oldlvl);
// DPRINT("Finished KeExpireTimers()\n");
}
BOOLEAN KiTimerInterrupt(VOID)
VOID KiTimerInterrupt(VOID)
/*
* FUNCTION: Handles a timer interrupt
*/
@ -527,6 +429,7 @@ BOOLEAN KiTimerInterrupt(VOID)
extern ULONG EiNrUsedBlocks;
extern unsigned int EiFreeNonPagedPool;
extern unsigned int EiUsedNonPagedPool;
extern ULONG MiNrFreePages;
/*
* Increment the number of timers ticks
@ -555,7 +458,8 @@ BOOLEAN KiTimerInterrupt(VOID)
// sprintf(str,"%.8u %.8u",(unsigned int)EiNrUsedBlocks,
// (unsigned int)EiFreeNonPagedPool);
// sprintf(str,"%.8u %.8u",EiFreeNonPagedPool,EiUsedNonPagedPool);
sprintf(str,"%.8u %.8u",PiNrRunnableThreads,KiTimerTicks);
// sprintf(str,"%.8u %.8u",PiNrRunnableThreads,KiTimerTicks);
sprintf(str,"%.8u %.8u",PiNrRunnableThreads,MiNrFreePages);
for (i=0;i<17;i++)
{
*vidmem=str[i];
@ -576,9 +480,13 @@ VOID KeInitializeTimerImpl(VOID)
{
TIME_FIELDS TimeFields;
LARGE_INTEGER SystemBootTime;
InitializeListHead(&timer_list_head);
KeInitializeSpinLock(&timer_list_lock);
DPRINT("KeInitializeTimerImpl()\n");
InitializeListHead(&TimerListHead);
KeInitializeSpinLock(&TimerListLock);
TimerInitDone = TRUE;
/*
* Calculate the starting time for the system clock
@ -587,4 +495,6 @@ VOID KeInitializeTimerImpl(VOID)
RtlTimeFieldsToTime(&TimeFields, &SystemBootTime);
boot_time=SystemBootTime.QuadPart;
system_time=boot_time;
DPRINT("Finished KeInitializeTimerImpl()\n");
}

View file

@ -0,0 +1,82 @@
/* $Id: udelay.c,v 1.1 1999/11/12 12:01:15 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/udelay.c
* PURPOSE: Busy waiting
* PROGRAMMER: David Welch (david.welch@seh.ox.ac.uk)
* UPDATE HISTORY:
* 06/11/99 Created
*/
/* INCLUDES ***************************************************************/
#include <limits.h>
#include <ddk/ntddk.h>
#include <string.h>
#include <internal/string.h>
#include <stdio.h>
#define NDEBUG
#include <internal/debug.h>
/* GLOBALS ******************************************************************/
#define MICROSECONDS_PER_TICK (54945)
#define TICKS_TO_CALIBRATE (1)
#define CALIBRATE_PERIOD (MICROSECONDS_PER_TICK * TICKS_TO_CALIBRATE)
#define SYSTEM_TIME_UNITS_PER_MSEC (10000)
static unsigned int loops_per_microsecond = 100;
extern ULONGLONG KiTimerTicks;
/* FUNCTIONS **************************************************************/
VOID KeCalibrateTimerLoop(VOID)
{
unsigned int start_tick;
// unsigned int end_tick;
// unsigned int nr_ticks;
unsigned int i;
unsigned int microseconds;
#if 0
for (i=0;i<20;i++)
{
start_tick = KiTimerTicks;
microseconds = 0;
while (start_tick == KiTimerTicks);
while (KiTimerTicks == (start_tick+TICKS_TO_CALIBRATE))
{
KeStallExecutionProcessor(1);
microseconds++;
};
// DbgPrint("microseconds %d\n",microseconds);
if (microseconds > (CALIBRATE_PERIOD+1000))
{
loops_per_microsecond = loops_per_microsecond + 1;
}
if (microseconds < (CALIBRATE_PERIOD-1000))
{
loops_per_microsecond = loops_per_microsecond - 1;
}
// DbgPrint("loops_per_microsecond %d\n",loops_per_microsecond);
}
// for(;;);
#endif
}
VOID KeStallExecutionProcessor(ULONG MicroSeconds)
{
unsigned int i;
for (i=0; i<(loops_per_microsecond*MicroSeconds) ;i++)
{
__asm__("nop\n\t");
}
}

View file

@ -68,6 +68,57 @@ VOID KeReleaseDispatcherDatabaseLock(BOOLEAN Wait)
}
}
VOID KiSideEffectsBeforeWake(DISPATCHER_HEADER* hdr)
/*
* FUNCTION: Perform side effects on object before a wait for a thread is
* satisfied
*/
{
switch (hdr->Type)
{
case InternalSynchronizationEvent:
hdr->SignalState = FALSE;
break;
case InternalSemaphoreType:
hdr->SignalState--;
break;
case InternalProcessType:
break;
case InternalThreadType:
break;
case InternalNotificationEvent:
break;
case InternalSynchronizationTimer:
hdr->SignalState = FALSE;
break;
case InternalNotificationTimer:
break;
default:
DbgPrint("(%s:%d) Dispatcher object %x has unknown type\n",
__FILE__,__LINE__,hdr);
KeBugCheck(0);
}
}
static BOOLEAN KiIsObjectSignalled(DISPATCHER_HEADER* hdr)
{
if (hdr->SignalState <= 0)
{
return(FALSE);
}
KiSideEffectsBeforeWake(hdr);
return(TRUE);
}
static BOOLEAN KeDispatcherObjectWakeAll(DISPATCHER_HEADER* hdr)
{
PKWAIT_BLOCK current;
@ -125,7 +176,9 @@ static BOOLEAN KeDispatcherObjectWakeAll(DISPATCHER_HEADER* hdr)
DPRINT("WaitAll: Wait Block List is empty!\n");
}
}
KiSideEffectsBeforeWake(hdr);
PsResumeThread(CONTAINING_RECORD(current->Thread,ETHREAD,Tcb));
};
return(TRUE);
@ -189,8 +242,7 @@ static BOOLEAN KeDispatcherObjectWakeOne(DISPATCHER_HEADER* hdr)
DPRINT("Waking %x\n",current->Thread);
if (hdr->Type == SemaphoreType)
hdr->SignalState--;
KiSideEffectsBeforeWake(hdr);
PsResumeThread(CONTAINING_RECORD(current->Thread,ETHREAD,Tcb));
return(TRUE);
@ -210,33 +262,40 @@ BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr)
DPRINT("hdr->Type %x\n",hdr->Type);
switch (hdr->Type)
{
case NotificationEvent:
case InternalNotificationEvent:
return(KeDispatcherObjectWakeAll(hdr));
case InternalNotificationTimer:
return(KeDispatcherObjectWakeAll(hdr));
case InternalSynchronizationEvent:
return(KeDispatcherObjectWakeOne(hdr));
case SynchronizationEvent:
Ret = KeDispatcherObjectWakeOne(hdr);
if (Ret)
{
hdr->SignalState = FALSE;
}
return(Ret);
case SemaphoreType:
case InternalSynchronizationTimer:
return(KeDispatcherObjectWakeOne(hdr));
case InternalSemaphoreType:
DPRINT("hdr->SignalState %d\n", hdr->SignalState);
if(hdr->SignalState>0)
{
do
{
Ret = KeDispatcherObjectWakeOne(hdr);
} while(hdr->SignalState > 0 && Ret) ;
return(Ret);
do
{
DPRINT("Waking one semaphore waiter\n");
Ret = KeDispatcherObjectWakeOne(hdr);
} while(hdr->SignalState > 0 && Ret) ;
return(Ret);
}
else return FALSE;
case ID_PROCESS_OBJECT:
case InternalProcessType:
return(KeDispatcherObjectWakeAll(hdr));
case ID_THREAD_OBJECT:
case InternalThreadType:
return(KeDispatcherObjectWakeAll(hdr));
case InternalMutexType:
return(KeDispatcherObjectWakeOne(hdr));
}
DPRINT("Dispatcher object %x has unknown type\n",hdr);
KeBugCheck(0);
@ -276,32 +335,8 @@ NTSTATUS KeWaitForSingleObject(PVOID Object,
DPRINT("hdr->SignalState %d\n", hdr->SignalState);
if (hdr->SignalState > 0)
if (KiIsObjectSignalled(hdr))
{
switch (hdr->Type)
{
case SynchronizationEvent:
hdr->SignalState = FALSE;
break;
case SemaphoreType:
break;
case ID_PROCESS_OBJECT:
break;
case ID_THREAD_OBJECT:
break;
case NotificationEvent:
break;
default:
DbgPrint("(%s:%d) Dispatcher object %x has unknown type\n",
__FILE__,__LINE__,hdr);
KeBugCheck(0);
}
KeReleaseDispatcherDatabaseLock(FALSE);
return(STATUS_WAIT_0);
}
@ -337,6 +372,7 @@ NTSTATUS KeWaitForSingleObject(PVOID Object,
return(STATUS_WAIT_0);
}
NTSTATUS KeWaitForMultipleObjects(ULONG Count,
PVOID Object[],
WAIT_TYPE WaitType,
@ -387,34 +423,10 @@ NTSTATUS KeWaitForMultipleObjects(ULONG Count,
DPRINT("hdr->SignalState %d\n", hdr->SignalState);
if (hdr->SignalState > 0)
if (KiIsObjectSignalled(hdr))
{
CountSignaled++;
switch (hdr->Type)
{
case SynchronizationEvent:
hdr->SignalState = FALSE;
break;
case SemaphoreType:
break;
case ID_PROCESS_OBJECT:
break;
case ID_THREAD_OBJECT:
break;
case NotificationEvent:
break;
default:
DbgPrint("(%s:%d) Dispatcher object %x has unknown type\n",
__FILE__,__LINE__,hdr);
KeBugCheck(0);
}
if (WaitType == WaitAny)
{
KeReleaseDispatcherDatabaseLock(FALSE);
@ -552,13 +564,9 @@ NTSTATUS STDCALL NtWaitForMultipleObjects(IN ULONG Count,
}
NTSTATUS
STDCALL
NtWaitForSingleObject (
IN HANDLE Object,
IN BOOLEAN Alertable,
IN PLARGE_INTEGER Time
)
NTSTATUS STDCALL NtWaitForSingleObject (IN HANDLE Object,
IN BOOLEAN Alertable,
IN PLARGE_INTEGER Time)
{
PVOID ObjectPtr;
NTSTATUS Status;
@ -589,14 +597,11 @@ NtWaitForSingleObject (
}
NTSTATUS
STDCALL
NtSignalAndWaitForSingleObject (
IN HANDLE EventHandle,
IN BOOLEAN Alertable,
IN PLARGE_INTEGER Time,
PULONG NumberOfWaitingThreads OPTIONAL
)
NTSTATUS STDCALL NtSignalAndWaitForSingleObject (IN HANDLE EventHandle,
IN BOOLEAN Alertable,
IN PLARGE_INTEGER Time,
PULONG
NumberOfWaitingThreads OPTIONAL)
{
UNIMPLEMENTED;
UNIMPLEMENTED;
}

View file

@ -1,4 +1,4 @@
# $Id: makefile_rex,v 1.35 1999/11/07 08:03:27 ea Exp $
# $Id: makefile_rex,v 1.36 1999/11/12 12:01:11 dwelch Exp $
#
# ReactOS Operating System
#
@ -27,12 +27,15 @@ KE_OBJECTS = ke/main.o ke/timer.o ke/error.o ke/catch.o \
ke/dpc.o ke/wait.o ke/kqueue.o ke/dispatch.o \
ke/sem.o ke/critical.o ke/event.o ke/apc.o ke/bug.o \
ke/mutex.o ke/kernel.o ke/ldt.o ke/apchelp.o \
ke/process.o ke/gdt.o ke/idt.o
ke/process.o ke/gdt.o ke/idt.o ke/udelay.o
KE_I386_OBJECTS = ke/i386/thread.o ke/i386/usercall.o ke/i386/exp.o
MM_OBJECTS = mm/mm.o mm/freelist.o mm/pool.o mm/virtual.o \
mm/mdl.o mm/zone.o mm/special.o mm/paging.o \
mm/section.o mm/marea.o mm/ppool.o mm/npool.o
MM_I386_OBJECTS = mm/i386/page.o
IO_OBJECTS = io/iomgr.o io/create.o io/irp.o io/device.o io/rw.o \
io/queue.o io/drvlck.o io/timer.o io/share.o io/errlog.o \
@ -74,14 +77,14 @@ objects/hal.o: $(HAL_OBJECTS)
objects/io.o: $(IO_OBJECTS)
$(LD) -r $(IO_OBJECTS) -o objects/io.o
objects/ke.o: $(KE_OBJECTS)
$(LD) -r $(KE_OBJECTS) -o objects/ke.o
objects/ke.o: $(KE_OBJECTS) $(KE_I386_OBJECTS)
$(LD) -r $(KE_OBJECTS) $(KE_I386_OBJECTS) -o objects/ke.o
objects/rtl.o: $(RTL_OBJECTS)
$(LD) -r $(RTL_OBJECTS) -o objects/rtl.o
objects/mm.o: $(MM_OBJECTS)
$(LD) -r $(MM_OBJECTS) -o objects/mm.o
objects/mm.o: $(MM_OBJECTS) $(MM_I386_OBJECTS)
$(LD) -r $(MM_OBJECTS) $(MM_I386_OBJECTS) -o objects/mm.o
objects/ob.o: $(OB_OBJECTS)
$(LD) -r $(OB_OBJECTS) -o objects/ob.o
@ -125,11 +128,13 @@ OBJECTS = objects/hal.o objects/ke.o objects/rtl.o objects/mm.o \
ifeq ($(DOSCLI),yes)
CLEAN_FILES = objects\*.o cc\*.o cm\*.o dbg\*.o ex\*.o hal\x86\*.o io\*.o \
ke\*.o ldr\*.o mm\*.o nt\*.o ob\*.o ps\*.o rtl\*.o se\*.o \
ke\i386\*.o mm\i386\*.o \
kd\*.o utils\export\export.exe $(TARGET).o $(TARGET).a junk.tmp \
base.tmp temp.exp $(TARGET).exe $(TARGET).sym $(TARGET).coff
else
CLEAN_FILES = objects/*.o cc/*.o cm/*.o dbg/*.o ex/*.o hal/x86/*.o io/*.o \
ke/*.o ldr/*.o mm/*.o nt/*.o ob/*.o ps/*.o rtl/*.o se/*.o \
ke/i386/*.o mm/i386/*.o \
kd/*.o utils/export/export $(TARGET).o $(TARGET).a junk.tmp \
base.tmp temp.exp $(TARGET).exe $(TARGET).sym $(TARGET).coff
endif

View file

@ -45,6 +45,9 @@ static KSPIN_LOCK FreePageListLock;
static LIST_ENTRY BiosPageListHead;
static KSPIN_LOCK BiosPageListLock;
ULONG MiNrFreePages;
ULONG MiNrUsedPages;
/* FUNCTIONS *************************************************************/
PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
@ -83,15 +86,22 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
DPRINT("Reserved %d\n", Reserved);
MiNrFreePages = 0;
MiNrUsedPages = 0;
i = 1;
if ((ULONG)FirstPhysKernelAddress < 0xa0000)
{
MiNrFreePages = MiNrFreePages +
((ULONG)FirstPhysKernelAddress/PAGESIZE);
for (; i<((ULONG)FirstPhysKernelAddress/PAGESIZE); i++)
{
MmPageArray[i].Flags = PHYSICAL_PAGE_FREE;
InsertTailList(&FreePageListHead,
&MmPageArray[i].ListEntry);
}
MiNrUsedPages = MiNrUsedPages +
(((0xa0000) / PAGESIZE) - i);
for (; i<(0xa0000 / PAGESIZE); i++)
{
MmPageArray[i].Flags = PHYSICAL_PAGE_INUSE;
@ -107,6 +117,7 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
}
else
{
MiNrFreePages = MiNrFreePages + (0xa0000 / PAGESIZE);
for (; i<(0xa0000 / PAGESIZE); i++)
{
MmPageArray[i].Flags = PHYSICAL_PAGE_FREE;
@ -119,12 +130,16 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
InsertTailList(&BiosPageListHead,
&MmPageArray[i].ListEntry);
}
MiNrFreePages = MiNrFreePages +
(((ULONG)FirstPhysKernelAddress/PAGESIZE) - i);
for (; i<((ULONG)FirstPhysKernelAddress/PAGESIZE); i++)
{
MmPageArray[i].Flags = PHYSICAL_PAGE_FREE;
InsertTailList(&FreePageListHead,
&MmPageArray[i].ListEntry);
}
MiNrUsedPages = MiNrUsedPages +
(((ULONG)LastPhysKernelAddress/PAGESIZE) - i);
for (; i<((ULONG)LastPhysKernelAddress/PAGESIZE); i++)
{
MmPageArray[i].Flags = PHYSICAL_PAGE_INUSE;
@ -133,12 +148,13 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
}
}
MiNrFreePages = MiNrFreePages + (MemorySizeInPages - i);
for (; i<MemorySizeInPages; i++)
{
MmPageArray[i].Flags = PHYSICAL_PAGE_FREE;
InsertTailList(&FreePageListHead,
&MmPageArray[i].ListEntry);
}
}
DPRINT("\nMmInitializePageList() = %x\n",
LastKernelAddress + Reserved * PAGESIZE);
return((PVOID)(LastKernelAddress + Reserved * PAGESIZE));
@ -152,6 +168,11 @@ VOID MmFreePage(PVOID PhysicalAddress, ULONG Nr)
DPRINT("MmFreePage(PhysicalAddress %x, Nr %x)\n", PhysicalAddress, Nr);
assert(((ULONG)PhysicalAddress) <= 0x400000);
MiNrFreePages = MiNrFreePages + Nr;
MiNrUsedPages = MiNrUsedPages - Nr;
for (i=0; i<Nr; i++)
{
KeAcquireSpinLock(&UsedPageListLock, &oldIrql);
@ -194,6 +215,11 @@ PVOID MmAllocPage(VOID)
offset = offset / sizeof(PHYSICAL_PAGE) * PAGESIZE;
DPRINT("offset %x\n",offset);
MiNrUsedPages = MiNrUsedPages + 1;
MiNrFreePages = MiNrFreePages - 1;
assert(offset <= 0x400000);
DPRINT("MmAllocPage() = %x\n",offset);
return((PVOID)offset);
}

View file

@ -0,0 +1,265 @@
/*
* COPYRIGHT: See COPYING in the top directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/i386/page.c
* PURPOSE: low level memory managment manipulation
* PROGRAMER: David Welch (welch@cwcom.net)
* UPDATE HISTORY:
* 9/3/98: Created
*/
/* INCLUDES ***************************************************************/
#include <ddk/ntddk.h>
#include <internal/mm.h>
#include <internal/mmhal.h>
#include <string.h>
#include <internal/string.h>
#include <internal/bitops.h>
#include <internal/ex.h>
#define NDEBUG
#include <internal/debug.h>
/* GLOBALS *****************************************************************/
#define PA_BIT_PRESENT (0)
#define PA_BIT_READWRITE (1)
#define PA_BIT_USER (2)
#define PA_PRESENT (1<<PA_BIT_PRESENT)
#define PAGETABLE_MAP (0xf0000000)
#define PAGEDIRECTORY_MAP (0xf0000000 + (PAGETABLE_MAP / (1024)))
/* FUNCTIONS ***************************************************************/
static ULONG ProtectToPTE(ULONG flProtect)
{
ULONG Attributes = 0;
if (flProtect & PAGE_NOACCESS || flProtect & PAGE_GUARD)
{
Attributes = 0;
}
if (flProtect & PAGE_READWRITE || flProtect & PAGE_EXECUTE_READWRITE)
{
Attributes = PA_WRITE | PA_USER;
}
if (flProtect & PAGE_READONLY || flProtect & PAGE_EXECUTE ||
flProtect & PAGE_EXECUTE_READ)
{
Attributes = PA_READ | PA_USER;
}
return(Attributes);
}
#define ADDR_TO_PDE(v) (PULONG)(PAGEDIRECTORY_MAP + \
(((ULONG)v / (1024 * 1024))&(~0x3)))
#define ADDR_TO_PTE(v) (PULONG)(PAGETABLE_MAP + ((ULONG)v / 1024))
NTSTATUS Mmi386ReleaseMmInfo(PEPROCESS Process)
{
DPRINT("Mmi386ReleaseMmInfo(Process %x)\n",Process);
MmFreePage(Process->Pcb.PageTableDirectory, 1);
Process->Pcb.PageTableDirectory = NULL;
DPRINT("Finished Mmi386ReleaseMmInfo()\n");
return(STATUS_SUCCESS);
}
NTSTATUS MmCopyMmInfo(PEPROCESS Src, PEPROCESS Dest)
{
PULONG PhysPageDirectory;
PULONG PageDirectory;
PULONG CurrentPageDirectory;
PKPROCESS KProcess = &Dest->Pcb;
ULONG i;
DPRINT("MmCopyMmInfo(Src %x, Dest %x)\n", Src, Dest);
PageDirectory = ExAllocatePage();
if (PageDirectory == NULL)
{
return(STATUS_UNSUCCESSFUL);
}
PhysPageDirectory = (PULONG)(MmGetPhysicalAddress(PageDirectory)).u.LowPart;
KProcess->PageTableDirectory = PhysPageDirectory;
CurrentPageDirectory = (PULONG)PAGEDIRECTORY_MAP;
memset(PageDirectory,0,PAGESIZE);
for (i=768; i<896; i++)
{
PageDirectory[i] = CurrentPageDirectory[i];
}
DPRINT("Addr %x\n",0xf0000000 / (4*1024*1024));
PageDirectory[0xf0000000 / (4*1024*1024)] = (ULONG)PhysPageDirectory | 0x7;
ExUnmapPage(PageDirectory);
DPRINT("Finished MmCopyMmInfo()\n");
return(STATUS_SUCCESS);
}
VOID MmDeletePageTable(PEPROCESS Process, PVOID Address)
{
PEPROCESS CurrentProcess = PsGetCurrentProcess();
if (Process != NULL && Process != CurrentProcess)
{
KeAttachProcess(Process);
}
*(ADDR_TO_PDE(Address)) = 0;
FLUSH_TLB;
if (Process != NULL && Process != CurrentProcess)
{
KeDetachProcess();
}
}
ULONG MmGetPageEntryForProcess(PEPROCESS Process, PVOID Address)
{
ULONG Entry;
PEPROCESS CurrentProcess = PsGetCurrentProcess();
if (Process != NULL && Process != CurrentProcess)
{
KeAttachProcess(Process);
}
Entry = *MmGetPageEntry(Address);
if (Process != NULL && Process != CurrentProcess)
{
KeDetachProcess();
}
return(Entry);
}
VOID MmDeletePageEntry(PEPROCESS Process, PVOID Address, BOOL FreePage)
{
PULONG page_tlb;
PULONG page_dir;
PEPROCESS CurrentProcess = PsGetCurrentProcess();
if (Process != NULL && Process != CurrentProcess)
{
KeAttachProcess(Process);
}
page_dir = ADDR_TO_PDE(Address);
if ((*page_dir) == 0)
{
if (Process != NULL && Process != CurrentProcess)
{
KeDetachProcess();
}
return;
}
page_tlb = ADDR_TO_PTE(Address);
if (FreePage && PAGE_MASK(*page_tlb) != 0)
{
MmFreePage((PVOID)PAGE_MASK(*page_tlb),1);
}
*page_tlb = 0;
if (Process != NULL && Process != CurrentProcess)
{
KeDetachProcess();
}
}
PULONG MmGetPageEntry(PVOID PAddress)
/*
* FUNCTION: Get a pointer to the page table entry for a virtual address
*/
{
PULONG page_tlb;
PULONG page_dir;
ULONG Address = (ULONG)PAddress;
DPRINT("MmGetPageEntry(Address %x)\n", Address);
page_dir = ADDR_TO_PDE(Address);
DPRINT("page_dir %x *page_dir %x\n",page_dir,*page_dir);
if ((*page_dir) == 0)
{
(*page_dir) = ((ULONG)MmAllocPage()) | 0x7;
FLUSH_TLB;
}
page_tlb = ADDR_TO_PTE(Address);
DPRINT("page_tlb %x\n",page_tlb);
return(page_tlb);
}
BOOLEAN MmIsPagePresent(PEPROCESS Process, PVOID Address)
{
return((MmGetPageEntryForProcess(Process, Address)) & PA_PRESENT);
}
VOID MmSetPage(PEPROCESS Process,
PVOID Address,
ULONG flProtect,
ULONG PhysicalAddress)
{
PEPROCESS CurrentProcess = PsGetCurrentProcess();
ULONG Attributes = 0;
DPRINT("MmSetPage(Process %x, Address %x, flProtect %x, "
"PhysicalAddress %x)\n",Process,Address,flProtect,
PhysicalAddress);
assert(((ULONG)PhysicalAddress)<0x400000);
Attributes = ProtectToPTE(flProtect);
if (Process != NULL && Process != CurrentProcess)
{
KeAttachProcess(Process);
}
(*MmGetPageEntry(Address)) = PhysicalAddress | Attributes;
FLUSH_TLB;
if (Process != NULL && Process != CurrentProcess)
{
KeDetachProcess();
}
}
VOID MmSetPageProtect(PEPROCESS Process,
PVOID Address,
ULONG flProtect)
{
ULONG Attributes = 0;
PULONG PageEntry;
PEPROCESS CurrentProcess = PsGetCurrentProcess();
Attributes = ProtectToPTE(flProtect);
if (Process != CurrentProcess)
{
KeAttachProcess(Process);
}
PageEntry = MmGetPageEntry(Address);
(*PageEntry) = PAGE_MASK(*PageEntry) | Attributes;
FLUSH_TLB;
if (Process != CurrentProcess)
{
KeDetachProcess();
}
}
PHYSICAL_ADDRESS MmGetPhysicalAddress(PVOID vaddr)
/*
* FUNCTION: Returns the physical address corresponding to a virtual address
*/
{
PHYSICAL_ADDRESS p;
p.QuadPart = 0;
DPRINT("MmGetPhysicalAddress(vaddr %x)\n", vaddr);
p.u.LowPart = PAGE_MASK(*MmGetPageEntry(vaddr));
p.u.HighPart = 0;
return p;
}

View file

@ -21,6 +21,14 @@
/* FUNCTIONS ***************************************************************/
PVOID MmGetMdlPageAddress(PMDL Mdl, PVOID Offset)
{
PULONG mdl_pages;
mdl_pages = (PULONG)(Mdl + 1);
return((PVOID)mdl_pages[((ULONG)Offset) / PAGESIZE]);
}
VOID MmUnlockPages(PMDL MemoryDescriptorList)
/*
@ -106,6 +114,22 @@ VOID KeFlushIoBuffers(PMDL Mdl, BOOLEAN ReadOperation, BOOLEAN DmaOperation)
/* See ntddk.h from Windows 98 DDK */
}
VOID MmBuildMdlFromPages(PMDL Mdl)
{
ULONG i;
PULONG mdl_pages;
mdl_pages = (PULONG)(Mdl + 1);
for (i=0;i<(PAGE_ROUND_UP(Mdl->ByteOffset+Mdl->ByteCount)/PAGESIZE);i++)
{
mdl_pages[i] = MmAllocPage();
DPRINT("mdl_pages[i] %x\n",mdl_pages[i]);
}
}
VOID MmProbeAndLockPages(PMDL Mdl, KPROCESSOR_MODE AccessMode,
LOCK_OPERATION Operation)
/*
@ -160,7 +184,12 @@ VOID MmProbeAndLockPages(PMDL Mdl, KPROCESSOR_MODE AccessMode,
ULONG MmGetMdlByteCount(PMDL Mdl)
/*
*
* FUNCTION: MmGetMdlByteCount returns the length in bytes described
* by a given MDL.
* ARGUMENTS:
* Mdl = Points to an MDL
* RETURN: MmGetMdlByteCount returns the byte count of the buffer described
* by Mdl.
*/
{
return(Mdl->ByteCount);

View file

@ -52,6 +52,11 @@ static MEMORY_AREA* kernel_data_desc = NULL;
static MEMORY_AREA* kernel_param_desc = NULL;
static MEMORY_AREA* kernel_pool_desc = NULL;
/*
* All pagefaults are synchronized on this
*/
static KSPIN_LOCK MiPageFaultLock;
/* FUNCTIONS ****************************************************************/
VOID MmInitVirtualMemory(boot_param* bp)
@ -127,14 +132,16 @@ NTSTATUS MmSectionHandleFault(MEMORY_AREA* MemoryArea, PVOID Address)
{
LARGE_INTEGER Offset;
IO_STATUS_BLOCK IoStatus;
PMDL Mdl;
PVOID Page;
DPRINT("MmSectionHandleFault(MemoryArea %x, Address %x)\n",
MemoryArea,Address);
MmSetPage(NULL,
Address,
MemoryArea->Attributes,
(ULONG)MmAllocPage());
Mdl = MmCreateMdl(NULL, NULL, PAGESIZE);
MmBuildMdlFromPages(Mdl);
Page = MmGetMdlPageAddress(Mdl, 0);
Offset.QuadPart = (Address - MemoryArea->BaseAddress) +
MemoryArea->Data.SectionData.ViewOffset;
@ -148,9 +155,14 @@ NTSTATUS MmSectionHandleFault(MEMORY_AREA* MemoryArea, PVOID Address)
}
IoPageRead(MemoryArea->Data.SectionData.Section->FileObject,
(PVOID)Address,
Mdl,
&Offset,
&IoStatus);
MmSetPage(NULL,
Address,
MemoryArea->Attributes,
(ULONG)Page);
DPRINT("Returning from MmSectionHandleFault()\n");
@ -189,6 +201,8 @@ asmlinkage int page_fault_handler(unsigned int cs,
KeRaiseIrql(DISPATCH_LEVEL, &oldlvl);
KeAcquireSpinLockAtDpcLevel(&MiPageFaultLock);
/*
* Find the memory area for the faulting address
*/
@ -237,6 +251,7 @@ asmlinkage int page_fault_handler(unsigned int cs,
DPRINT("Completed page fault handling\n");
if (NT_SUCCESS(Status))
{
KeReleaseSpinLockFromDpcLevel(&MiPageFaultLock);
KeLowerIrql(oldlvl);
}
// DbgPrint("%%)");

View file

@ -1,4 +1,4 @@
/* $Id: section.c,v 1.14 1999/08/29 06:59:10 ea Exp $
/* $Id: section.c,v 1.15 1999/11/12 12:01:16 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -367,7 +367,7 @@ NtMapViewOfSection (
Process,
MEMORY_AREA_SECTION_VIEW_COMMIT,
BaseAddress,
* ViewSize,
*ViewSize,
Protect,
& Result
);

View file

@ -96,16 +96,12 @@ BOOLEAN MmIsAddressValid(PVOID VirtualAddress)
}
NTSTATUS
STDCALL
NtAllocateVirtualMemory (
IN HANDLE ProcessHandle,
IN OUT PVOID * BaseAddress,
IN ULONG ZeroBits,
IN OUT PULONG RegionSize,
IN ULONG AllocationType,
IN ULONG Protect
)
NTSTATUS STDCALL NtAllocateVirtualMemory(IN HANDLE ProcessHandle,
IN OUT PVOID * BaseAddress,
IN ULONG ZeroBits,
IN OUT PULONG RegionSize,
IN ULONG AllocationType,
IN ULONG Protect)
/*
* FUNCTION: Allocates a block of virtual memory in the process address space
* ARGUMENTS:
@ -194,8 +190,8 @@ NtAllocateVirtualMemory (
}
}
//FIXME RegionSize should be passed as pointer
// FIXME RegionSize should be passed as pointer
// dwelch: Why?
Status = MmCreateMemoryArea(UserMode,
Process,
@ -218,14 +214,10 @@ NtAllocateVirtualMemory (
}
NTSTATUS
STDCALL
NtFlushVirtualMemory (
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
IN ULONG NumberOfBytesToFlush,
OUT PULONG NumberOfBytesFlushed OPTIONAL
)
NTSTATUS STDCALL NtFlushVirtualMemory(IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
IN ULONG NumberOfBytesToFlush,
OUT PULONG NumberOfBytesFlushed OPTIONAL)
/*
* FUNCTION: Flushes virtual memory to file
* ARGUMENTS:
@ -241,14 +233,10 @@ NtFlushVirtualMemory (
}
NTSTATUS
STDCALL
NtFreeVirtualMemory (
IN HANDLE ProcessHandle,
IN PVOID * BaseAddress,
IN PULONG RegionSize,
IN ULONG FreeType
)
NTSTATUS STDCALL NtFreeVirtualMemory(IN HANDLE ProcessHandle,
IN PVOID * BaseAddress,
IN PULONG RegionSize,
IN ULONG FreeType)
/*
* FUNCTION: Frees a range of virtual memory
* ARGUMENTS:
@ -319,14 +307,10 @@ NtFreeVirtualMemory (
}
NTSTATUS
STDCALL
NtLockVirtualMemory (
HANDLE ProcessHandle,
PVOID BaseAddress,
ULONG NumberOfBytesToLock,
PULONG NumberOfBytesLocked
)
NTSTATUS STDCALL NtLockVirtualMemory(HANDLE ProcessHandle,
PVOID BaseAddress,
ULONG NumberOfBytesToLock,
PULONG NumberOfBytesLocked)
{
UNIMPLEMENTED;
}
@ -349,15 +333,11 @@ VOID MmChangeAreaProtection(PEPROCESS Process,
}
NTSTATUS
STDCALL
NtProtectVirtualMemory (
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
IN ULONG NumberOfBytesToProtect,
IN ULONG NewAccessProtection,
OUT PULONG OldAccessProtection
)
NTSTATUS STDCALL NtProtectVirtualMemory(IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
IN ULONG NumberOfBytesToProtect,
IN ULONG NewAccessProtection,
OUT PULONG OldAccessProtection)
{
PMEMORY_AREA MemoryArea;
PEPROCESS Process;
@ -406,16 +386,12 @@ NtProtectVirtualMemory (
}
NTSTATUS
STDCALL
NtQueryVirtualMemory (
IN HANDLE ProcessHandle,
IN PVOID Address,
IN CINT VirtualMemoryInformationClass,
OUT PVOID VirtualMemoryInformation,
IN ULONG Length,
OUT PULONG ResultLength
)
NTSTATUS STDCALL NtQueryVirtualMemory(IN HANDLE ProcessHandle,
IN PVOID Address,
IN CINT VirtualMemoryInformationClass,
OUT PVOID VirtualMemoryInformation,
IN ULONG Length,
OUT PULONG ResultLength)
{
NTSTATUS Status;
PEPROCESS Process;
@ -480,8 +456,8 @@ NtQueryVirtualMemory (
Info->BaseAddress = MemoryArea->BaseAddress;
Info->RegionSize = MemoryArea->Length;
DbgPrint("BaseAddress %p, Length %x\n",
Info->BaseAddress, Info->RegionSize);
DbgPrint("BaseAddress %p, Length %x\n",
Info->BaseAddress, Info->RegionSize);
ObDereferenceObject(Process);
@ -491,20 +467,14 @@ NtQueryVirtualMemory (
}
return(STATUS_INVALID_INFO_CLASS);
// UNIMPLEMENTED;
}
NTSTATUS
STDCALL
NtReadVirtualMemory (
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
OUT PVOID Buffer,
IN ULONG NumberOfBytesToRead,
OUT PULONG NumberOfBytesRead
)
NTSTATUS STDCALL NtReadVirtualMemory(IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
OUT PVOID Buffer,
IN ULONG NumberOfBytesToRead,
OUT PULONG NumberOfBytesRead)
{
NTSTATUS Status;
PMDL Mdl;
@ -547,28 +517,20 @@ NtReadVirtualMemory (
}
NTSTATUS
STDCALL
NtUnlockVirtualMemory (
HANDLE ProcessHandle,
PVOID BaseAddress,
ULONG NumberOfBytesToUnlock,
PULONG NumberOfBytesUnlocked OPTIONAL
)
NTSTATUS STDCALL NtUnlockVirtualMemory(HANDLE ProcessHandle,
PVOID BaseAddress,
ULONG NumberOfBytesToUnlock,
PULONG NumberOfBytesUnlocked OPTIONAL)
{
UNIMPLEMENTED;
}
NTSTATUS
STDCALL
NtWriteVirtualMemory (
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
IN PVOID Buffer,
IN ULONG NumberOfBytesToWrite,
OUT PULONG NumberOfBytesWritten
)
NTSTATUS STDCALL NtWriteVirtualMemory(IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
IN PVOID Buffer,
IN ULONG NumberOfBytesToWrite,
OUT PULONG NumberOfBytesWritten)
{
NTSTATUS Status;
PMDL Mdl;

View file

@ -16,7 +16,7 @@
#include <internal/mm.h>
#include <internal/ob.h>
//#define NDEBUG
#define NDEBUG
#include <internal/debug.h>
/* GLOBALS *******************************************************************/
@ -45,16 +45,16 @@ VOID PsTerminateCurrentThread(NTSTATUS ExitStatus)
ObDereferenceObject(CurrentThread->ThreadsProcess);
CurrentThread->ThreadsProcess = NULL;
KeRaiseIrql(DISPATCH_LEVEL,&oldlvl);
PsDispatchThread(THREAD_STATE_TERMINATED);
KeBugCheck(0);
#if 0
CurrentThread->Tcb.State = THREAD_STATE_TERMINATED;
ObDereferenceObject(CurrentThread);
DPRINT("ObGetReferenceCount(CurrentThread) %d\n",
ObGetReferenceCount(CurrentThread));
CurrentThread->Tcb.DispatcherHeader.SignalState = TRUE;
KeDispatcherObjectWake(&CurrentThread->Tcb.DispatcherHeader);
ZwYieldExecution();
for(;;);
#endif
PsDispatchThread(THREAD_STATE_TERMINATED);
KeBugCheck(0);
}
VOID PsTerminateOtherThread(PETHREAD Thread, NTSTATUS ExitStatus)
@ -75,6 +75,7 @@ VOID PsTerminateOtherThread(PETHREAD Thread, NTSTATUS ExitStatus)
Thread->Tcb.DispatcherHeader.SignalState = TRUE;
KeDispatcherObjectWake(&Thread->Tcb.DispatcherHeader);
ObDereferenceObject(Thread->ThreadsProcess);
ObDereferenceObject(Thread);
Thread->ThreadsProcess = NULL;
KeReleaseSpinLock(&PiThreadListLock, oldIrql);
}
@ -118,12 +119,8 @@ NTSTATUS STDCALL NtTerminateProcess(IN HANDLE ProcessHandle,
}
NTSTATUS
STDCALL
NtTerminateThread (
IN HANDLE ThreadHandle,
IN NTSTATUS ExitStatus
)
NTSTATUS STDCALL NtTerminateThread(IN HANDLE ThreadHandle,
IN NTSTATUS ExitStatus)
{
PETHREAD Thread;
NTSTATUS Status;
@ -150,21 +147,6 @@ NtTerminateThread (
return(STATUS_SUCCESS);
}
VOID PsReleaseThread(PETHREAD Thread)
/*
* FUNCTION: Called internally to release a thread's resources from another
* thread's context
* ARGUMENTS:
* Thread = Thread to release
*/
{
DPRINT("PsReleaseThread(Thread %x)\n",Thread);
// RemoveEntryList(&Thread->Tcb.QueueListEntry);
HalReleaseTask(Thread);
ObDereferenceObject(Thread);
}
NTSTATUS PsTerminateSystemThread(NTSTATUS ExitStatus)
/*
@ -179,11 +161,7 @@ NTSTATUS PsTerminateSystemThread(NTSTATUS ExitStatus)
}
NTSTATUS
STDCALL
NtRegisterThreadTerminatePort (
HANDLE TerminationPort
)
NTSTATUS STDCALL NtRegisterThreadTerminatePort(HANDLE TerminationPort)
{
UNIMPLEMENTED;
UNIMPLEMENTED;
}

View file

@ -77,7 +77,7 @@ VOID PsInitProcessManagment(VOID)
NULL,
PsProcessType);
KeInitializeDispatcherHeader(&SystemProcess->Pcb.DispatcherHeader,
ID_PROCESS_OBJECT,
InternalProcessType,
sizeof(EPROCESS),
FALSE);
KProcess = &SystemProcess->Pcb;
@ -232,7 +232,7 @@ NtCreateProcess (
ObjectAttributes,
PsProcessType);
KeInitializeDispatcherHeader(&Process->Pcb.DispatcherHeader,
ID_PROCESS_OBJECT,
InternalProcessType,
sizeof(EPROCESS),
FALSE);
KProcess = &(Process->Pcb);

View file

@ -1,4 +1,4 @@
/* $Id: thread.c,v 1.29 1999/11/02 08:55:43 dwelch Exp $
/* $Id: thread.c,v 1.30 1999/11/12 12:01:17 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -83,7 +83,6 @@ VOID PiTerminateProcessThreads(PEPROCESS Process, NTSTATUS ExitStatus)
if (current->ThreadsProcess == Process &&
current != PsGetCurrentThread())
{
// RemoveEntryList(current->Tcb.ThreadListEntry);
PsTerminateOtherThread(current, ExitStatus);
}
current_entry = current_entry->Flink;
@ -94,9 +93,9 @@ VOID PiTerminateProcessThreads(PEPROCESS Process, NTSTATUS ExitStatus)
static VOID PsInsertIntoThreadList(KPRIORITY Priority, PETHREAD Thread)
{
DPRINT("PsInsertIntoThreadList(Priority %x, Thread %x)\n",Priority,
Thread);
DPRINT("Offset %x\n", THREAD_PRIORITY_MAX + Priority);
// DPRINT("PsInsertIntoThreadList(Priority %x, Thread %x)\n",Priority,
// Thread);
// DPRINT("Offset %x\n", THREAD_PRIORITY_MAX + Priority);
InsertTailList(&PriorityListHead[THREAD_PRIORITY_MAX+Priority],
&Thread->Tcb.QueueListEntry);
@ -106,7 +105,8 @@ VOID PsBeginThread(PKSTART_ROUTINE StartRoutine, PVOID StartContext)
{
NTSTATUS Ret;
KeReleaseSpinLock(&PiThreadListLock,PASSIVE_LEVEL);
// KeReleaseSpinLock(&PiThreadListLock,PASSIVE_LEVEL);
KeLowerIrql(PASSIVE_LEVEL);
Ret = StartRoutine(StartContext);
PsTerminateSystemThread(Ret);
KeBugCheck(0);
@ -165,7 +165,6 @@ static VOID PsDispatchThreadNoLock (ULONG NewThreadStatus)
{
KPRIORITY CurrentPriority;
PETHREAD Candidate;
LARGE_INTEGER TickCount;
if (!DoneInitYet)
{
@ -186,6 +185,7 @@ static VOID PsDispatchThreadNoLock (ULONG NewThreadStatus)
Candidate = PsScanThreadList(CurrentPriority);
if (Candidate == CurrentThread)
{
KeReleaseSpinLockFromDpcLevel(&PiThreadListLock);
return;
}
if (Candidate != NULL)
@ -196,6 +196,7 @@ static VOID PsDispatchThreadNoLock (ULONG NewThreadStatus)
CurrentThread = Candidate;
KeReleaseSpinLockFromDpcLevel(&PiThreadListLock);
HalTaskSwitch(&CurrentThread->Tcb);
return;
}
@ -207,7 +208,8 @@ static VOID PsDispatchThreadNoLock (ULONG NewThreadStatus)
VOID PiBeforeBeginThread(VOID)
{
DPRINT("PiBeforeBeginThread()\n");
KeReleaseSpinLock(&PiThreadListLock, PASSIVE_LEVEL);
//KeReleaseSpinLock(&PiThreadListLock, PASSIVE_LEVEL);
KeLowerIrql(PASSIVE_LEVEL);
DPRINT("KeGetCurrentIrql() %d\n", KeGetCurrentIrql());
}
@ -217,7 +219,8 @@ VOID PsDispatchThread(ULONG NewThreadStatus)
KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
PsDispatchThreadNoLock(NewThreadStatus);
KeReleaseSpinLock(&PiThreadListLock, oldIrql);
// KeReleaseSpinLock(&PiThreadListLock, oldIrql);
KeLowerIrql(oldIrql);
// DPRINT("oldIrql %d\n",oldIrql);
}
@ -247,7 +250,7 @@ NTSTATUS PsInitializeThread(HANDLE ProcessHandle,
Thread->Tcb.KernelApcDisable = 1;
KeInitializeDispatcherHeader(&Thread->Tcb.DispatcherHeader,
ID_THREAD_OBJECT,
InternalThreadType,
sizeof(ETHREAD),
FALSE);
@ -312,7 +315,7 @@ ULONG PsResumeThread(PETHREAD Thread)
// DPRINT("Marking thread %x as runnable\n",Thread);
Thread->Tcb.State = THREAD_STATE_RUNNABLE;
PsInsertIntoThreadList(Thread->Tcb.BasePriority, Thread);
PiNrRunnableThreads++;
PiNrRunnableThreads++;
}
DPRINT("About release ThreadListLock = %x\n", &PiThreadListLock);
KeReleaseSpinLock(&PiThreadListLock, oldIrql);
@ -343,17 +346,22 @@ ULONG PsSuspendThread(PETHREAD Thread)
}
Thread->Tcb.State = THREAD_STATE_SUSPENDED;
PiNrRunnableThreads--;
KeReleaseSpinLock(&PiThreadListLock, oldIrql);
}
else
{
DPRINT("Suspending current thread\n");
PiNrRunnableThreads--;
PsDispatchThreadNoLock(THREAD_STATE_SUSPENDED);
KeLowerIrql(oldIrql);
}
}
DPRINT("About to release ThreadListLock = %x\n", &PiThreadListLock);
KeReleaseSpinLock(&PiThreadListLock, oldIrql);
DPRINT("PsSuspendThread() finished\n");
else
{
DPRINT("About to release ThreadListLock = %x\n", &PiThreadListLock);
KeReleaseSpinLock(&PiThreadListLock, oldIrql);
DPRINT("PsSuspendThread() finished\n");
}
return(r);
}
@ -361,6 +369,8 @@ ULONG PsSuspendThread(PETHREAD Thread)
VOID PiDeleteThread(PVOID ObjectBody)
{
DbgPrint("PiDeleteThread(ObjectBody %x)\n",ObjectBody);
HalReleaseTask((PETHREAD)ObjectBody);
}

View file

@ -14,6 +14,7 @@ ifeq ($(HOST),mingw32-linux)
NASM_FORMAT = win32
PREFIX = i586-mingw32-
EXE_POSTFIX =
EXE_PREFIX = ./
CP = cp
DLLTOOL = $(PREFIX)dlltool --as=$(PREFIX)as
NASM_CMD = nasm
@ -61,6 +62,7 @@ endif
CC = $(PREFIX)gcc
NATIVE_CC = gcc
NATIVE_NM = nm
CFLAGS = $(BASE_CFLAGS) \
-pipe \
-O2 \