Some work on file caching

Some work on the minix filesystem
Some work on v86 mode support
Implemented NtGetContextThread

svn path=/trunk/; revision=1467
This commit is contained in:
David Welch 2000-12-10 23:42:01 +00:00
parent 4ac4987dd2
commit 488f0ac078
28 changed files with 2053 additions and 1465 deletions

View file

@ -1,3 +1,10 @@
2000-12-04 David Welch <welch@cwcom.net>
* ntoskrnl/ke/i386/irq.c (KiInterruptDispatch): Record the last PC
value for a rescheduled thread.
* ntoskrnl/ke/i386/irqhand.s: Construct a primitive trap frame
in interrupt handlers.
2000-08-30 David Welch <welch@cwcom.net> 2000-08-30 David Welch <welch@cwcom.net>
* Added calibration of KeStallExecutionProcessor timing * Added calibration of KeStallExecutionProcessor timing

View file

@ -37,7 +37,7 @@ DEVICE_DRIVERS = vidport vga blue ide null floppy
INPUT_DRIVERS = keyboard INPUT_DRIVERS = keyboard
FS_DRIVERS = vfat FS_DRIVERS = vfat minix
# FS_DRIVERS = minix ext2 template # FS_DRIVERS = minix ext2 template
# ndis tdi tcpip tditest wshtcpip # ndis tdi tcpip tditest wshtcpip
@ -53,6 +53,7 @@ SYS_APPS = shell winlogon services
APPS = args hello test cat bench apc shm lpc thread event file gditest \ APPS = args hello test cat bench apc shm lpc thread event file gditest \
pteb consume dump_shared_data vmtest regtest pteb consume dump_shared_data vmtest regtest
# objdir # objdir
# ping # ping

View file

@ -0,0 +1,41 @@
# $Id: Makefile,v 1.1 2000/12/10 23:42:01 dwelch Exp $
#
#
PATH_TO_TOP = ../../..
TARGET = minixfs
BASE_CFLAGS = -I../../../include
OBJECTS = block.o rw.o inode.o dir.o mount.o blockdev.o cache.o bitops.o \
$(TARGET).coff ../../../ntoskrnl/ntoskrnl.a
all: $(TARGET).sys $(TARGET).sys.unstripped
.phony: all
clean:
- $(RM) $(TARGET).o
- $(RM) $(TARGET).coff
- $(RM) junk.tmp
- $(RM) base.tmp
- $(RM) temp.exp
- $(RM) $(TARGET).sys
- $(RM) $(TARGET).sys.unstripped
.phony: clean
install: $(FLOPPY_DIR)/drivers/$(TARGET).sys
$(FLOPPY_DIR)/drivers/$(TARGET).sys: $(TARGET).sys
$(CP) $(TARGET).sys $(FLOPPY_DIR)/drivers/$(TARGET).sys
dist: ../../../$(DIST_DIR)/drivers/$(TARGET).sys
../../../$(DIST_DIR)/drivers/$(TARGET).sys: $(TARGET).sys
$(CP) $(TARGET).sys ../../../$(DIST_DIR)/drivers/$(TARGET).sys
$(TARGET).sys $(TARGET).sys.unstripped: $(OBJECTS)
WARNINGS_ARE_ERRORS = yes
include ../../../rules.mak

View file

@ -0,0 +1,203 @@
/*
* ReactOS kernel
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* Copyright 1992, Linus Torvalds.
*/
/*
* These have to be done with inline assembly: that way the bit-setting
* is guaranteed to be atomic. All bit operations return 0 if the bit
* was cleared before the operation and != 0 if it was not.
*
* bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
*/
#ifdef __SMP__
#define LOCK_PREFIX "lock ; "
#else
#define LOCK_PREFIX ""
#endif
/*
* Function prototypes to keep gcc -Wall happy
*/
extern void set_bit(int nr, volatile void * addr);
extern void clear_bit(int nr, volatile void * addr);
extern void change_bit(int nr, volatile void * addr);
extern int test_and_set_bit(int nr, volatile void * addr);
extern int test_and_clear_bit(int nr, volatile void * addr);
extern int test_and_change_bit(int nr, volatile void * addr);
extern int __constant_test_bit(int nr, const volatile void * addr);
extern int __test_bit(int nr, volatile void * addr);
extern int find_first_zero_bit(void * addr, unsigned size);
extern int find_next_zero_bit (void * addr, int size, int offset);
extern unsigned long ffz(unsigned long word);
/*
* Some hacks to defeat gcc over-optimizations..
*/
struct __dummy { unsigned long a[100]; };
#define ADDR (*(volatile struct __dummy *) addr)
#define CONST_ADDR (*(volatile const struct __dummy *) addr)
void set_bit(int nr, volatile void * addr)
{
__asm__ __volatile__( LOCK_PREFIX
"btsl %1,%0"
:"=m" (ADDR)
:"Ir" (nr));
}
void clear_bit(int nr, volatile void * addr)
{
__asm__ __volatile__( LOCK_PREFIX
"btrl %1,%0"
:"=m" (ADDR)
:"Ir" (nr));
}
void change_bit(int nr, volatile void * addr)
{
__asm__ __volatile__( LOCK_PREFIX
"btcl %1,%0"
:"=m" (ADDR)
:"Ir" (nr));
}
int test_and_set_bit(int nr, volatile void * addr)
{
int oldbit;
__asm__ __volatile__( LOCK_PREFIX
"btsl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit),"=m" (ADDR)
:"Ir" (nr));
return oldbit;
}
int test_and_clear_bit(int nr, volatile void * addr)
{
int oldbit;
__asm__ __volatile__( LOCK_PREFIX
"btrl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit),"=m" (ADDR)
:"Ir" (nr));
return oldbit;
}
int test_and_change_bit(int nr, volatile void * addr)
{
int oldbit;
__asm__ __volatile__( LOCK_PREFIX
"btcl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit),"=m" (ADDR)
:"Ir" (nr));
return oldbit;
}
/*
* This routine doesn't need to be atomic.
*/
int __constant_test_bit(int nr, const volatile void * addr)
{
return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
}
int test_bit(int nr, volatile void * addr)
{
int oldbit;
__asm__ __volatile__(
"btl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit)
:"m" (ADDR),"Ir" (nr));
return oldbit;
}
#if 0
#define test_bit(nr,addr) \
(__builtin_constant_p(nr) ? \
__constant_test_bit((nr),(addr)) : \
__test_bit((nr),(addr)))
#endif
/*
* Find-bit routines..
*/
int find_first_zero_bit(void * addr, unsigned size)
{
int d0, d1, d2;
int res;
if (!size)
return 0;
__asm__("cld\n\t"
"movl $-1,%%eax\n\t"
"xorl %%edx,%%edx\n\t"
"repe; scasl\n\t"
"je 1f\n\t"
"xorl -4(%%edi),%%eax\n\t"
"subl $4,%%edi\n\t"
"bsfl %%eax,%%edx\n"
"1:\tsubl %%ebx,%%edi\n\t"
"shll $3,%%edi\n\t"
"addl %%edi,%%edx"
:"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2)
:"1" ((size + 31) >> 5), "2" (addr), "b" (addr));
return res;
}
int find_next_zero_bit (void * addr, int size, int offset)
{
unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
int set = 0, bit = offset & 31, res;
if (bit) {
/*
* Look for zero in first byte
*/
__asm__("bsfl %1,%0\n\t"
"jne 1f\n\t"
"movl $32, %0\n"
"1:"
: "=r" (set)
: "r" (~(*p >> bit)));
if (set < (32 - bit))
return set + offset;
set = 32 - bit;
p++;
}
/*
* No zero yet, search remaining full bytes for a zero
*/
res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr));
return (offset + set + res);
}
/*
* ffz = Find First Zero in word. Undefined if no zero exists,
* so code should check against ~0UL first..
*/
unsigned long ffz(unsigned long word)
{
__asm__("bsfl %1,%0"
:"=r" (word)
:"r" (~word));
return word;
}

View file

@ -0,0 +1,30 @@
#ifndef _I386_BITOPS_H
#define _I386_BITOPS_H
/*
* Copyright 1992, Linus Torvalds.
*/
/*
* These have to be done with inline assembly: that way the bit-setting
* is guaranteed to be atomic. All bit operations return 0 if the bit
* was cleared before the operation and != 0 if it was not.
*
* bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
*/
/*
* Function prototypes to keep gcc -Wall happy
*/
extern void set_bit(int nr, volatile void * addr);
extern void clear_bit(int nr, volatile void * addr);
extern void change_bit(int nr, volatile void * addr);
extern int test_and_set_bit(int nr, volatile void * addr);
extern int test_and_clear_bit(int nr, volatile void * addr);
extern int test_and_change_bit(int nr, volatile void * addr);
extern int test_bit(int nr, volatile void * addr);
extern int find_first_zero_bit(void * addr, unsigned size);
extern int find_next_zero_bit (void * addr, int size, int offset);
extern unsigned long ffz(unsigned long word);
#endif /* _I386_BITOPS_H */

View file

@ -11,7 +11,7 @@
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
#include <string.h> #include <string.h>
#include "../../../ntoskrnl/include/internal/bitops.h" #include "bitops.h"
#include <ddk/ntifs.h> #include <ddk/ntifs.h>
#define NDEBUG #define NDEBUG

View file

@ -1,101 +0,0 @@
# $Id: makefile_rex,v 1.13 2000/11/20 19:59:11 ekohl Exp $
#
# Minix IFS Driver makefile
#
BASE_CFLAGS = -I../../../include
TARGETNAME=minixfs
all: $(TARGETNAME).sys
OBJECTS = block.o rw.o inode.o dir.o mount.o blockdev.o cache.o \
minix.coff ../../../ntoskrnl/ntoskrnl.a
.phony: all
clean:
- $(RM) *.o
- $(RM) junk.tmp
- $(RM) base.tmp
- $(RM) temp.exp
- $(RM) cache.o
- $(RM) minix.coff
- $(RM) $(TARGETNAME).sys
.phony: clean
minix.o: $(OBJECTS)
$(LD) -r $(OBJECTS) -o minix.o
minixfs.nostrip.sys: $(OBJECTS)
$(CC) \
-specs=../../svc_specs \
-mdll \
-o junk.tmp \
-Wl,--defsym,_end=end \
-Wl,--defsym,_edata=__data_end__ \
-Wl,--defsym,_etext=etext \
-Wl,--base-file,base.tmp \
$(OBJECTS)
- $(RM) junk.tmp
$(DLLTOOL) \
--dllname $(TARGETNAME).sys \
--base-file base.tmp \
--output-exp temp.exp
- $(RM) base.tmp
$(CC) \
--verbose \
-Wl,--image-base,0x10000 \
-Wl,-e,_DriverEntry@8 \
-specs=../../svc_specs \
-mdll \
-o $(TARGETNAME).nostrip.sys \
$(OBJECTS) \
-Wl,temp.exp
- $(RM) temp.exp
minixfs.sys: $(OBJECTS)
$(STRIP) --strip-debug $(OBJECTS)
$(CC) \
-specs=../../svc_specs \
-mdll \
-o junk.tmp \
-Wl,--defsym,_end=end \
-Wl,--defsym,_edata=__data_end__ \
-Wl,--defsym,_etext=etext \
-Wl,--base-file,base.tmp \
$(OBJECTS)
- $(RM) junk.tmp
$(DLLTOOL) \
--dllname $(TARGETNAME).sys \
--base-file base.tmp \
--output-exp temp.exp
- $(RM) base.tmp
$(CC) \
--verbose \
-Wl,--image-base,0x10000 \
-Wl,-e,_DriverEntry@8 \
-specs=../../svc_specs \
-mdll \
-o $(TARGETNAME).sys \
$(OBJECTS) \
-Wl,temp.exp
- $(RM) temp.exp
minix.coff: ../../../include/reactos/buildno.h minix.rc
install: $(FLOPPY_DIR)/drivers/$(TARGETNAME).sys
$(FLOPPY_DIR)/drivers/$(TARGETNAME).sys: $(TARGETNAME).sys
$(CP) $(TARGETNAME).sys $(FLOPPY_DIR)/drivers/$(TARGETNAME).sys
dist: ../../../$(DIST_DIR)/drivers/$(TARGETNAME).sys
../../../$(DIST_DIR)/drivers/$(TARGETNAME).sys: $(TARGETNAME).sys
$(CP) $(TARGETNAME).sys ../../../$(DIST_DIR)/drivers/$(TARGETNAME).sys
WIN32_LEAN_AND_MEAN = yes
WARNINGS_ARE_ERRORS = yes
WITH_DEBUGGING = yes
include ../../../rules.mak
# EOF

View file

@ -8,6 +8,7 @@ cp loaders/dos/loadros.com $1
cp ntoskrnl/ntoskrnl.exe $1 cp ntoskrnl/ntoskrnl.exe $1
cp services/fs/vfat/vfatfs.sys $1 cp services/fs/vfat/vfatfs.sys $1
cp services/dd/ide/ide.sys $1 cp services/dd/ide/ide.sys $1
cp services/fs/minix/minixfs.sys $1
#cp services/dd/floppy/floppy.sys $1 #cp services/dd/floppy/floppy.sys $1
#cp ntoskrnl/ntoskrnl.exe $1/reactos/system32/ #cp ntoskrnl/ntoskrnl.exe $1/reactos/system32/
#cp services/fs/vfat/vfatfs.sys $1/reactos/system32/drivers/ #cp services/fs/vfat/vfatfs.sys $1/reactos/system32/drivers/

View file

@ -5,6 +5,9 @@ mount -t vfat /bochs/1.44a /mnt/floppy -o loop,rw
umount /mnt/floppy umount /mnt/floppy
echo "Installing to disk." echo "Installing to disk."
mount -t vfat /bochs/10M.vga.dos /mnt/floppy -o loop,offset=8704,rw mount -t vfat /bochs/10M.vga.dos /mnt/floppy -o loop,offset=8704,rw
#mount -t minix /bochs/10M.vga.dos /mnt/floppy -o loop,offset=8704,rw ./install.sh /mnt/floppy
umount /mnt/floppy
echo "Installing to minix disk."
mount -t minix /bochs/10M.vga.minix /mnt/floppy -o loop,offset=8704,rw
./install.sh /mnt/floppy ./install.sh /mnt/floppy
umount /mnt/floppy umount /mnt/floppy

View file

@ -4,7 +4,7 @@ mkdir -p $1/reactos/system32/drivers
mkdir -p $1/reactos/bin mkdir -p $1/reactos/bin
./install-system.sh $1 ./install-system.sh $1
cp services/dd/floppy/floppy.sys $1/reactos/system32/drivers/ cp services/dd/floppy/floppy.sys $1/reactos/system32/drivers/
cp services/dd/keyboard/keyboard.sys $1/reactos/system32/drivers cp services/input/keyboard/keyboard.sys $1/reactos/system32/drivers
cp services/dd/blue/blue.sys $1/reactos/system32/drivers cp services/dd/blue/blue.sys $1/reactos/system32/drivers
cp services/dd/vga/miniport/vgamp.sys $1/reactos/system32/drivers cp services/dd/vga/miniport/vgamp.sys $1/reactos/system32/drivers
cp services/dd/vga/display/vgaddi.dll $1/reactos/system32/drivers cp services/dd/vga/display/vgaddi.dll $1/reactos/system32/drivers
@ -37,3 +37,5 @@ cp apps/consume/consume.exe $1/reactos/bin
cp apps/float/float.exe $1/reactos/bin cp apps/float/float.exe $1/reactos/bin
cp apps/dump_shared_data/dump_shared_data.exe $1/reactos/bin cp apps/dump_shared_data/dump_shared_data.exe $1/reactos/bin
cp apps/vmtest/vmtest.exe $1/reactos/bin cp apps/vmtest/vmtest.exe $1/reactos/bin
cp apps/uitest/uitest.exe $1/reactos/bin/
cp apps/gditest/gditest.exe $1/reactos/bin/

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
# $Id: Makefile,v 1.3 2000/10/22 16:36:48 ekohl Exp $ # $Id: Makefile,v 1.4 2000/12/10 23:41:59 dwelch Exp $
# #
# ReactOS Operating System # ReactOS Operating System
# #
@ -92,7 +92,9 @@ OBJECTS_KE_I386 = \
ke/i386/irqhand.o \ ke/i386/irqhand.o \
ke/i386/thread.o \ ke/i386/thread.o \
ke/i386/usercall.o \ ke/i386/usercall.o \
ke/i386/trap.o ke/i386/trap.o \
ke/i386/bthread.o \
ke/i386/syscall.o
# Memory Manager (Mm) # Memory Manager (Mm)
OBJECTS_MM = \ OBJECTS_MM = \
@ -178,7 +180,8 @@ OBJECTS_PS = \
ps/process.o \ ps/process.o \
ps/psmgr.o \ ps/psmgr.o \
ps/thread.o \ ps/thread.o \
ps/tinfo.o ps/tinfo.o \
ps/debug.o
# Executive Subsystem (Ex) # Executive Subsystem (Ex)
OBJECTS_EX = \ OBJECTS_EX = \

View file

@ -1,4 +1,22 @@
/* $Id: view.c,v 1.10 2000/08/20 17:02:07 dwelch Exp $ /*
* ReactOS kernel
* Copyright (C) 2000, 1999, 1998 David Welch <welch@cwcom.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: view.c,v 1.11 2000/12/10 23:42:00 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -9,7 +27,29 @@
* Created 22/05/98 * Created 22/05/98
*/ */
/* INCLUDES *****************************************************************/ /* NOTES **********************************************************************
*
* This is not the NT implementation of a file cache nor anything much like
* it.
*
* The general procedure for a filesystem to implement a read or write
* dispatch routine is as follows
*
* (1) If caching for the FCB hasn't been initiated then so do by calling
* CcInitializeFileCache.
*
* (2) For each 4k region which is being read or written obtain a cache page
* by calling CcRequestCachePage.
*
* (3) If either the page is being read or not completely written, and it is
* not up to date then read its data from the underlying medium. If the read
* fails then call CcReleaseCachePage with VALID as FALSE and return a error.
*
* (4) Copy the data into or out of the page as necessary.
*
* (5) Release the cache page
*/
/* INCLUDES ******************************************************************/
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
#include <ddk/ntifs.h> #include <ddk/ntifs.h>
@ -21,7 +61,8 @@
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
NTSTATUS STDCALL CcFlushCachePage(PCACHE_SEGMENT CacheSeg) NTSTATUS STDCALL
CcFlushCachePage(PCACHE_SEGMENT CacheSeg)
/* /*
* FUNCTION: Asks the FSD to flush the contents of the page back to disk * FUNCTION: Asks the FSD to flush the contents of the page back to disk
*/ */
@ -36,7 +77,8 @@ NTSTATUS STDCALL CcFlushCachePage(PCACHE_SEGMENT CacheSeg)
return(STATUS_NOT_IMPLEMENTED); return(STATUS_NOT_IMPLEMENTED);
} }
NTSTATUS STDCALL CcReleaseCachePage(PBCB Bcb, NTSTATUS STDCALL
CcReleaseCachePage(PBCB Bcb,
PCACHE_SEGMENT CacheSeg, PCACHE_SEGMENT CacheSeg,
BOOLEAN Valid) BOOLEAN Valid)
{ {
@ -52,11 +94,15 @@ NTSTATUS STDCALL CcReleaseCachePage(PBCB Bcb,
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
NTSTATUS STDCALL CcRequestCachePage(PBCB Bcb, NTSTATUS STDCALL
CcRequestCachePage(PBCB Bcb,
ULONG FileOffset, ULONG FileOffset,
PVOID* BaseAddress, PVOID* BaseAddress,
PBOOLEAN UptoDate, PBOOLEAN UptoDate,
PCACHE_SEGMENT* CacheSeg) PCACHE_SEGMENT* CacheSeg)
/*
* FUNCTION: Request a page mapping for a BCB
*/
{ {
KIRQL oldirql; KIRQL oldirql;
PLIST_ENTRY current_entry; PLIST_ENTRY current_entry;
@ -105,20 +151,15 @@ NTSTATUS STDCALL CcRequestCachePage(PBCB Bcb,
CACHE_SEGMENT_SIZE, CACHE_SEGMENT_SIZE,
PAGE_READWRITE, PAGE_READWRITE,
(PMEMORY_AREA*)&current->MemoryArea); (PMEMORY_AREA*)&current->MemoryArea);
CHECKPOINT;
current->Valid = FALSE; current->Valid = FALSE;
current->FileOffset = PAGE_ROUND_DOWN(FileOffset); current->FileOffset = PAGE_ROUND_DOWN(FileOffset);
current->Bcb = Bcb; current->Bcb = Bcb;
CHECKPOINT;
KeInitializeEvent(&current->Lock, SynchronizationEvent, FALSE); KeInitializeEvent(&current->Lock, SynchronizationEvent, FALSE);
current->ReferenceCount = 1; current->ReferenceCount = 1;
CHECKPOINT;
InsertTailList(&Bcb->CacheSegmentListHead, &current->ListEntry); InsertTailList(&Bcb->CacheSegmentListHead, &current->ListEntry);
CHECKPOINT;
*UptoDate = current->Valid; *UptoDate = current->Valid;
*BaseAddress = current->BaseAddress; *BaseAddress = current->BaseAddress;
*CacheSeg = current; *CacheSeg = current;
CHECKPOINT;
MmCreateVirtualMapping(NULL, MmCreateVirtualMapping(NULL,
current->BaseAddress, current->BaseAddress,
PAGE_READWRITE, PAGE_READWRITE,
@ -130,9 +171,12 @@ NTSTATUS STDCALL CcRequestCachePage(PBCB Bcb,
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
NTSTATUS STDCALL CcFreeCacheSegment(PFILE_OBJECT FileObject, NTSTATUS STDCALL
PBCB Bcb, CcFreeCacheSegment(PBCB Bcb,
PCACHE_SEGMENT CacheSeg) PCACHE_SEGMENT CacheSeg)
/*
* FUNCTION: Releases a cache segment associated with a BCB
*/
{ {
MmFreeMemoryArea(NULL, MmFreeMemoryArea(NULL,
CacheSeg->BaseAddress, CacheSeg->BaseAddress,
@ -142,8 +186,12 @@ NTSTATUS STDCALL CcFreeCacheSegment(PFILE_OBJECT FileObject,
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
NTSTATUS STDCALL CcReleaseFileCache(PFILE_OBJECT FileObject, NTSTATUS STDCALL
CcReleaseFileCache(PFILE_OBJECT FileObject,
PBCB Bcb) PBCB Bcb)
/*
* FUNCTION: Releases the BCB associated with a file object
*/
{ {
PLIST_ENTRY current_entry; PLIST_ENTRY current_entry;
PCACHE_SEGMENT current; PCACHE_SEGMENT current;
@ -156,8 +204,7 @@ NTSTATUS STDCALL CcReleaseFileCache(PFILE_OBJECT FileObject,
{ {
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, ListEntry); current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, ListEntry);
current_entry = current_entry->Flink; current_entry = current_entry->Flink;
CcFreeCacheSegment(FileObject, CcFreeCacheSegment(Bcb,
Bcb,
current); current);
} }
@ -168,8 +215,12 @@ NTSTATUS STDCALL CcReleaseFileCache(PFILE_OBJECT FileObject,
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
NTSTATUS STDCALL CcInitializeFileCache(PFILE_OBJECT FileObject, NTSTATUS STDCALL
CcInitializeFileCache(PFILE_OBJECT FileObject,
PBCB* Bcb) PBCB* Bcb)
/*
* FUNCTION: Initializes a BCB for a file object
*/
{ {
DPRINT("CcInitializeFileCache(FileObject %x)\n",FileObject); DPRINT("CcInitializeFileCache(FileObject %x)\n",FileObject);

View file

@ -69,7 +69,9 @@ VOID KeAcquireDispatcherDatabaseLock(BOOLEAN Wait);
VOID KeReleaseDispatcherDatabaseLock(BOOLEAN Wait); VOID KeReleaseDispatcherDatabaseLock(BOOLEAN Wait);
BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr); BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr);
#if 0
VOID KiInterruptDispatch(ULONG irq); VOID KiInterruptDispatch(ULONG irq);
#endif
VOID KeExpireTimers(VOID); VOID KeExpireTimers(VOID);
NTSTATUS KeAddThreadTimeout(struct _KTHREAD* Thread, NTSTATUS KeAddThreadTimeout(struct _KTHREAD* Thread,
PLARGE_INTEGER Interval); PLARGE_INTEGER Interval);
@ -82,6 +84,8 @@ VOID KeFreeGdtSelector(ULONG Entry);
BOOLEAN KiTestAlert(VOID); BOOLEAN KiTestAlert(VOID);
VOID KeRemoveAllWaitsThread(struct _ETHREAD* Thread, NTSTATUS WaitStatus); VOID KeRemoveAllWaitsThread(struct _ETHREAD* Thread, NTSTATUS WaitStatus);
PULONG KeGetStackTopThread(struct _ETHREAD* Thread); PULONG KeGetStackTopThread(struct _ETHREAD* Thread);
VOID KeContextToTrapFrame(PCONTEXT Context,
PKTRAP_FRAME TrapFrame);
/* INITIALIZATION FUNCTIONS *************************************************/ /* INITIALIZATION FUNCTIONS *************************************************/

View file

@ -78,14 +78,23 @@ typedef struct _KAPC_STATE
typedef struct _KTHREAD typedef struct _KTHREAD
{ {
/* For waiting on thread exit */
DISPATCHER_HEADER DispatcherHeader; /* 00 */ DISPATCHER_HEADER DispatcherHeader; /* 00 */
/* List of mutants owned by the thread */
LIST_ENTRY MutantListHead; /* 10 */ LIST_ENTRY MutantListHead; /* 10 */
PVOID InitialStack; /* 18 */ PVOID InitialStack; /* 18 */
ULONG StackLimit; /* 1C */ ULONG StackLimit; /* 1C */
/* Pointer to the thread's environment block in user memory */
NT_TEB* Teb; /* 20 */ NT_TEB* Teb; /* 20 */
/* Pointer to the thread's TLS array */
PVOID TlsArray; /* 24 */ PVOID TlsArray; /* 24 */
PVOID KernelStack; /* 28 */ PVOID KernelStack; /* 28 */
UCHAR DebugActive; /* 2C */ UCHAR DebugActive; /* 2C */
/* Thread state (one of THREAD_STATE_xxx constants below) */
UCHAR State; /* 2D */ UCHAR State; /* 2D */
UCHAR Alerted[2]; /* 2E */ UCHAR Alerted[2]; /* 2E */
UCHAR Iopl; /* 30 */ UCHAR Iopl; /* 30 */
@ -152,10 +161,14 @@ typedef struct _KTHREAD
/* Added by Phillip Susi for list of threads in a process */ /* Added by Phillip Susi for list of threads in a process */
LIST_ENTRY ProcessThreadListEntry; LIST_ENTRY ProcessThreadListEntry;
/* Provisionally added by David Welch */ /* Provisionally added by David Welch */
hal_thread_state Context; hal_thread_state Context;
/* Added by Phillip Susi for internal KeAddThreadTimeout() implementation */ /* Added by Phillip Susi for internal KeAddThreadTimeout() implementation */
KDPC TimerDpc; KDPC TimerDpc;
/* Record the last EIP value when the thread is suspended */
ULONG LastEip;
} __attribute__((packed)) KTHREAD, *PKTHREAD; } __attribute__((packed)) KTHREAD, *PKTHREAD;
// According to documentation the stack should have a commited [ 1 page ] and // According to documentation the stack should have a commited [ 1 page ] and
@ -400,12 +413,11 @@ ULONG PsResumeThread(PETHREAD Thread,
* Functions the HAL must provide * Functions the HAL must provide
*/ */
VOID VOID KeInitializeThread(PKPROCESS Process, PKTHREAD Thread);
KeInitializeThread(PKPROCESS Process, PKTHREAD Thread);
void HalInitFirstTask(PETHREAD thread); VOID HalInitFirstTask(PETHREAD thread);
NTSTATUS HalInitTask(PETHREAD thread, PKSTART_ROUTINE fn, PVOID StartContext); NTSTATUS HalInitTask(PETHREAD thread, PKSTART_ROUTINE fn, PVOID StartContext);
void HalTaskSwitch(PKTHREAD thread); VOID HalTaskSwitch(PKTHREAD thread);
NTSTATUS HalInitTaskWithContext(PETHREAD Thread, PCONTEXT Context); NTSTATUS HalInitTaskWithContext(PETHREAD Thread, PCONTEXT Context);
NTSTATUS HalReleaseTask(PETHREAD Thread); NTSTATUS HalReleaseTask(PETHREAD Thread);
VOID PiDeleteProcess(PVOID ObjectBody); VOID PiDeleteProcess(PVOID ObjectBody);

View file

@ -0,0 +1,76 @@
/*
* ReactOS kernel
* Copyright (C) 2000 David Welch <welch@cwcom.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* FILE: ntoskrnl/ke/i386/vm86_sup.S
* PURPOSE: V86 mode support
* PROGRAMMER: David Welch (welch@cwcom.net)
* UPDATE HISTORY:
* Created 10/12/00
*/
#ifndef __NTOSKRNL_INCLUDE_INTERNAL_VM86_H
#define __NTOSKRNL_INCLUDE_INTERNAL_VM86_H
#ifndef ASSEMBLER
typedef struct
{
ULONG Ebp;
ULONG Edi;
ULONG Esi;
ULONG Edx;
ULONG Ecx;
ULONG Ebx;
ULONG Eax;
ULONG Ds;
ULONG Es;
ULONG Fs;
ULONG Gs;
ULONG Eip;
ULONG Cs;
ULONG Eflags;
ULONG Esp;
ULONG Ss;
} KV86M_REGISTERS;
#else
/*
* Definitions for the offsets of members in the KV86M_REGISTERS
*/
#define KV86M_REGISTERS_EBP (0x0)
#define KV86M_REGISTERS_EDI (0x4)
#define KV86M_REGISTERS_ESI (0x8)
#define KV86M_REGISTERS_EDX (0xC)
#define KV86M_REGISTERS_ECX (0x10)
#define KV86M_REGISTERS_EBX (0x14)
#define KV86M_REGISTERS_EAX (0x18)
#define KV86M_REGISTERS_DS (0x1C)
#define KV86M_REGISTERS_ES (0x20)
#define KV86M_REGISTERS_FS (0x24)
#define KV86M_REGISTERS_GS (0x28)
#define KV86M_REGISTERS_EIP (0x2C)
#define KV86M_REGISTERS_CS (0x30)
#define KV86M_REGISTERS_EFLAGS (0x34)
#define KV86M_REGISTERS_ESP (0x38)
#define KV86M_REGISTERS_SS (0x3C)
#endif /* ASSEMBLER */
#endif /* __NTOSKRNL_INCLUDE_INTERNAL_VM86_H */

View file

@ -1,4 +1,24 @@
/* $Id: dpc.c,v 1.18 2000/07/10 21:54:19 ekohl Exp $ /*
* ReactOS kernel
* Copyright (C) 2000, 1999, 1998 David Welch <welch@cwcom.net>,
* Philip Susi <phreak@iag.net>,
* Eric Kohl <ekohl@abo.rhein-zeitung.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: dpc.c,v 1.19 2000/12/10 23:42:00 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -26,13 +46,19 @@
/* GLOBALS ******************************************************************/ /* GLOBALS ******************************************************************/
static LIST_ENTRY DpcQueueHead; static LIST_ENTRY DpcQueueHead; /* Head of the list of pending DPCs */
static KSPIN_LOCK DpcQueueLock; static KSPIN_LOCK DpcQueueLock; /* Lock for the above list */
/*
* Number of pending DPCs. This is inspected by
* the idle thread to determine if the queue needs to
* be run down
*/
ULONG DpcQueueSize = 0; ULONG DpcQueueSize = 0;
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
VOID STDCALL KeInitializeDpc (PKDPC Dpc, VOID STDCALL
KeInitializeDpc (PKDPC Dpc,
PKDEFERRED_ROUTINE DeferredRoutine, PKDEFERRED_ROUTINE DeferredRoutine,
PVOID DeferredContext) PVOID DeferredContext)
/* /*
@ -50,7 +76,8 @@ VOID STDCALL KeInitializeDpc (PKDPC Dpc,
Dpc->Lock = 0; Dpc->Lock = 0;
} }
VOID STDCALL KiDispatchInterrupt(VOID) VOID STDCALL
KiDispatchInterrupt(VOID)
/* /*
* FUNCTION: Called to execute queued dpcs * FUNCTION: Called to execute queued dpcs
*/ */
@ -65,38 +92,32 @@ VOID STDCALL KiDispatchInterrupt(VOID)
{ {
return; return;
} }
DPRINT("KiDispatchInterrupt()\n");
KeRaiseIrql(HIGH_LEVEL, &oldlvl); KeRaiseIrql(HIGH_LEVEL, &oldlvl);
KeAcquireSpinLockAtDpcLevel(&DpcQueueLock); KeAcquireSpinLockAtDpcLevel(&DpcQueueLock);
current_entry = RemoveHeadList(&DpcQueueHead); current_entry = RemoveHeadList(&DpcQueueHead);
DpcQueueSize--;
KeReleaseSpinLockFromDpcLevel(&DpcQueueLock); KeReleaseSpinLockFromDpcLevel(&DpcQueueLock);
KeLowerIrql(oldlvl); KeLowerIrql(oldlvl);
current = CONTAINING_RECORD(current_entry,KDPC,DpcListEntry); current = CONTAINING_RECORD(current_entry,KDPC,DpcListEntry);
while (current_entry!=(&DpcQueueHead)) 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->DeferredRoutine(current,current->DeferredContext,
current->SystemArgument1, current->SystemArgument1,
current->SystemArgument2); current->SystemArgument2);
CHECKPOINT;
current->Lock=FALSE; current->Lock=FALSE;
KeRaiseIrql(HIGH_LEVEL, &oldlvl); KeRaiseIrql(HIGH_LEVEL, &oldlvl);
KeAcquireSpinLockAtDpcLevel(&DpcQueueLock); KeAcquireSpinLockAtDpcLevel(&DpcQueueLock);
current_entry = RemoveHeadList(&DpcQueueHead); current_entry = RemoveHeadList(&DpcQueueHead);
DPRINT("current_entry %x\n", current_entry);
DpcQueueSize--; DpcQueueSize--;
KeReleaseSpinLockFromDpcLevel(&DpcQueueLock); KeReleaseSpinLockFromDpcLevel(&DpcQueueLock);
KeLowerIrql(oldlvl); KeLowerIrql(oldlvl);
current = CONTAINING_RECORD(current_entry,KDPC,DpcListEntry); current = CONTAINING_RECORD(current_entry,KDPC,DpcListEntry);
DPRINT("current %x\n", current);
} }
} }
BOOLEAN STDCALL KeRemoveQueueDpc (PKDPC Dpc) BOOLEAN STDCALL
KeRemoveQueueDpc (PKDPC Dpc)
/* /*
* FUNCTION: Removes DPC object from the system dpc queue * FUNCTION: Removes DPC object from the system dpc queue
* ARGUMENTS: * ARGUMENTS:
@ -121,7 +142,8 @@ BOOLEAN STDCALL KeRemoveQueueDpc (PKDPC Dpc)
return(TRUE); return(TRUE);
} }
BOOLEAN STDCALL KeInsertQueueDpc (PKDPC Dpc, BOOLEAN STDCALL
KeInsertQueueDpc (PKDPC Dpc,
PVOID SystemArgument1, PVOID SystemArgument1,
PVOID SystemArgument2) PVOID SystemArgument2)
/* /*
@ -167,12 +189,9 @@ BOOLEAN STDCALL KeInsertQueueDpc (PKDPC Dpc,
* Importance = DPC importance * Importance = DPC importance
* RETURNS: None * RETURNS: None
*/ */
VOID VOID STDCALL
STDCALL KeSetImportanceDpc (IN PKDPC Dpc,
KeSetImportanceDpc ( IN KDPC_IMPORTANCE Importance)
IN PKDPC Dpc,
IN KDPC_IMPORTANCE Importance
)
{ {
Dpc->Importance = Importance; Dpc->Importance = Importance;
} }
@ -184,17 +203,15 @@ KeSetImportanceDpc (
* Number = Processor number * Number = Processor number
* RETURNS: None * RETURNS: None
*/ */
VOID VOID STDCALL
STDCALL KeSetTargetProcessorDpc (IN PKDPC Dpc,
KeSetTargetProcessorDpc ( IN CCHAR Number)
IN PKDPC Dpc,
IN CCHAR Number
)
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
} }
VOID KeInitDpc(VOID) VOID
KeInitDpc(VOID)
/* /*
* FUNCTION: Initialize DPC handling * FUNCTION: Initialize DPC handling
*/ */

View file

@ -0,0 +1,64 @@
/*
* ReactOS kernel
* Copyright (C) 2000 David Welch <welch@cwcom.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: bthread.S,v 1.1 2000/12/10 23:42:00 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/hal/x86/bthread.s
* PURPOSE: Trap handlers
* PROGRAMMER: David Welch (david.welch@seh.ox.ac.uk)
* UPDATE HISTORY:
* ???
*/
#include <ddk/status.h>
#include <internal/i386/segment.h>
#include <internal/ps.h>
#include <ddk/defines.h>
/*
*
*/
.globl _PsBeginThreadWithContextInternal
_PsBeginThreadWithContextInternal:
call _PiBeforeBeginThread
popl %eax
popl %eax
popl %eax
popl %eax
popl %eax
popl %eax
popl %eax
addl $112,%esp
popl %gs
; popl %fs
movl $TEB_SELECTOR, %ax
movl %ax, %fs
popl %es
popl %ds
popl %edi
popl %esi
popl %ebx
popl %edx
popl %ecx
popl %eax
popl %ebp
iret

View file

@ -1,4 +1,4 @@
/* $Id: irq.c,v 1.2 2000/07/24 23:51:46 ekohl Exp $ /* $Id: irq.c,v 1.3 2000/12/10 23:42:00 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -103,8 +103,27 @@ VOID KeInitInterrupts (VOID)
} }
} }
typedef struct _KIRQ_TRAPFRAME
{
ULONG Magic;
ULONG Fs;
ULONG Es;
ULONG Ds;
ULONG Eax;
ULONG Ecx;
ULONG Edx;
ULONG Ebx;
ULONG Esp;
ULONG Ebp;
ULONG Esi;
ULONG Edi;
ULONG Eip;
ULONG Cs;
ULONG Eflags;
} KIRQ_TRAPFRAME, *PKIRQ_TRAPFRAME;
VOID KiInterruptDispatch (ULONG irq) VOID
KiInterruptDispatch (ULONG irq, PKIRQ_TRAPFRAME Trapframe)
/* /*
* FUNCTION: Calls the irq specific handler for an irq * FUNCTION: Calls the irq specific handler for an irq
* ARGUMENTS: * ARGUMENTS:
@ -175,6 +194,10 @@ VOID KiInterruptDispatch (ULONG irq)
{ {
KeExpireTimers(); KeExpireTimers();
} }
if (KeGetCurrentThread() != NULL)
{
KeGetCurrentThread()->LastEip = Trapframe->Eip;
}
KiDispatchInterrupt(); KiDispatchInterrupt();
PsDispatchThread(THREAD_STATE_RUNNABLE); PsDispatchThread(THREAD_STATE_RUNNABLE);
} }
@ -188,7 +211,8 @@ VOID KiInterruptDispatch (ULONG irq)
} }
static VOID KeDumpIrqList(VOID) static VOID
KeDumpIrqList(VOID)
{ {
PKINTERRUPT current; PKINTERRUPT current;
PLIST_ENTRY current_entry; PLIST_ENTRY current_entry;
@ -210,8 +234,7 @@ static VOID KeDumpIrqList(VOID)
} }
NTSTATUS NTSTATUS STDCALL
STDCALL
KeConnectInterrupt(PKINTERRUPT InterruptObject) KeConnectInterrupt(PKINTERRUPT InterruptObject)
{ {
KIRQL oldlvl; KIRQL oldlvl;
@ -266,8 +289,7 @@ KeConnectInterrupt(PKINTERRUPT InterruptObject)
} }
VOID VOID STDCALL
STDCALL
KeDisconnectInterrupt(PKINTERRUPT InterruptObject) KeDisconnectInterrupt(PKINTERRUPT InterruptObject)
/* /*
* FUNCTION: Releases a drivers isr * FUNCTION: Releases a drivers isr

View file

@ -24,10 +24,12 @@
"inb $0x21,%al\n\t" \ "inb $0x21,%al\n\t" \
"orb $1<<"##x",%al\n\t" \ "orb $1<<"##x",%al\n\t" \
"outb %al,$0x21\n\t" \ "outb %al,$0x21\n\t" \
"pushl %esp\n\t" \
"pushl $"##x"\n\t" \ "pushl $"##x"\n\t" \
"call _KiInterruptDispatch\n\t"\ "call _KiInterruptDispatch\n\t"\
"popl %eax\n\t" \ "popl %eax\n\t" \
"popl %eax\n\t" \ "popl %eax\n\t" \
"popl %eax\n\t" \
"popl %fs\n\t" \ "popl %fs\n\t" \
"popl %es\n\t" \ "popl %es\n\t" \
"popl %ds\n\t" \ "popl %ds\n\t" \
@ -49,10 +51,12 @@
"inb $0xa1,%al\n\t" \ "inb $0xa1,%al\n\t" \
"orb $1<<("##x"-8),%al\n\t" \ "orb $1<<("##x"-8),%al\n\t" \
"outb %al,$0xa1\n\t" \ "outb %al,$0xa1\n\t" \
"pushl %esp\n\t" \
"pushl $"##x"\n\t" \ "pushl $"##x"\n\t" \
"call _KiInterruptDispatch\n\t"\ "call _KiInterruptDispatch\n\t"\
"popl %eax\n\t" \ "popl %eax\n\t" \
"popl %eax\n\t" \ "popl %eax\n\t" \
"popl %eax\n\t" \
"popl %fs\n\t" \ "popl %fs\n\t" \
"popl %es\n\t" \ "popl %es\n\t" \
"popl %ds\n\t" \ "popl %ds\n\t" \

View file

@ -0,0 +1,246 @@
/*
* ReactOS kernel
* Copyright (C) 2000 David Welch <welch@cwcom.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: syscall.S,v 1.1 2000/12/10 23:42:00 dwelch Exp $
*
* FILE: ntoskrnl/hal/x86/syscall.s
* PURPOSE: 2E trap handler
* PROGRAMMER: David Welch (david.welch@seh.ox.ac.uk)
* UPDATE HISTORY:
* ???
*/
#include <ddk/status.h>
#include <internal/i386/segment.h>
#include <internal/ps.h>
#include <ddk/defines.h>
/*
*
*/
.globl _interrupt_handler2e
_interrupt_handler2e:
/* Construct a trap frame on the stack */
/* Error code */
pushl $0
pushl %ebp
pushl %ebx
pushl %esi
pushl %edi
pushl %fs
/* Load PCR selector into fs */
movl $PCR_SELECTOR, %ebx
movl %ebx, %fs
/* Save the old exception list */
movl %fs:KPCR_EXCEPTION_LIST, %ebx
pushl %ebx
/* Put the exception handler chain terminator */
movl $0xffffffff, %fs:KPCR_EXCEPTION_LIST
/* Get a pointer to the current thread */
movl %fs:KPCR_CURRENT_THREAD, %esi
/* Save the old previous mode */
movl $0, %ebx
movb %ss:KTHREAD_PREVIOUS_MODE(%esi), %bl
pushl %ebx
/* Set the new previous mode based on the saved CS selector */
movl 0x24(%esp), %ebx
cmpl $KERNEL_CS, %ebx
jne L1
movb $KernelMode, %ss:KTHREAD_PREVIOUS_MODE(%esi)
jmp L3
L1:
movb $UserMode, %ss:KTHREAD_PREVIOUS_MODE(%esi)
L3:
/* Save other registers */
pushl %eax
pushl %ecx
pushl %edx
pushl %ds
pushl %es
pushl %gs
pushl $0 /* DR7 */
pushl $0 /* DR6 */
pushl $0 /* DR3 */
pushl $0 /* DR2 */
pushl $0 /* DR1 */
pushl $0 /* DR0 */
pushl $0 /* XXX: TempESP */
pushl $0 /* XXX: TempCS */
pushl $0 /* XXX: DebugPointer */
pushl $0 /* XXX: DebugArgMark */
pushl $0 /* XXX: DebugEIP */
pushl $0 /* XXX: DebugEBP */
/* Load the segment registers */
movl $KERNEL_DS, %ebx
movl %ebx, %ds
movl %ebx, %es
movl %ebx, %gs
/* Save the old trap frame pointer (over the EDX register??) */
movl KTHREAD_TRAP_FRAME(%esi), %ebx
movl %ebx, 0x3C(%esp)
/* Save a pointer to the trap frame in the TCB */
movl %esp, KTHREAD_TRAP_FRAME(%esi)
/* Set ES to kernel segment */
movw $KERNEL_DS,%bx
movw %bx,%es
/* Allocate new Kernel stack frame */
movl %esp,%ebp
/* Users's current stack frame pointer is source */
movl %edx,%esi
/* Determine system service table to use */
cmpl $0x0fff, %eax
ja new_useShadowTable
/* Check to see if EAX is valid/inrange */
cmpl %es:_KeServiceDescriptorTable + 8, %eax
jbe new_serviceInRange
movl $STATUS_INVALID_SYSTEM_SERVICE, %eax
jmp new_done
new_serviceInRange:
/* Allocate room for argument list from kernel stack */
movl %es:_KeServiceDescriptorTable + 12, %ecx
movl %es:(%ecx, %eax, 4), %ecx
subl %ecx, %esp
/* Copy the arguments from the user stack to the kernel stack */
movl %esp,%edi
rep movsb
/* DS is now also kernel segment */
movw %bx, %ds
/* Call system call hook */
pushl %eax
call _KiSystemCallHook
popl %eax
/* Make the system service call */
movl %es:_KeServiceDescriptorTable, %ecx
movl %es:(%ecx, %eax, 4), %eax
call *%eax
#if CHECKED
/* Bump Service Counter */
#endif
/* Deallocate the kernel stack frame */
movl %ebp,%esp
/* Call the post system call hook and deliver any pending APCs */
pushl %ebp
pushl %eax
call _KiAfterSystemCallHook
addl $8,%esp
jmp new_done
new_useShadowTable:
subl $0x1000, %eax
/* Check to see if EAX is valid/inrange */
cmpl %es:_KeServiceDescriptorTableShadow + 24, %eax
jbe new_shadowServiceInRange
movl $STATUS_INVALID_SYSTEM_SERVICE, %eax
jmp new_done
new_shadowServiceInRange:
/* Allocate room for argument list from kernel stack */
movl %es:_KeServiceDescriptorTableShadow + 28, %ecx
movl %es:(%ecx, %eax, 4), %ecx
subl %ecx, %esp
/* Copy the arguments from the user stack to the kernel stack */
movl %esp,%edi
rep movsb
/* DS is now also kernel segment */
movw %bx,%ds
/* Call system call hook */
pushl %eax
call _KiSystemCallHook
popl %eax
/* Make the system service call */
movl %es:_KeServiceDescriptorTableShadow + 16, %ecx
movl %es:(%ecx, %eax, 4), %eax
call *%eax
#if CHECKED
/* Bump Service Counter */
#endif
/* Deallocate the kernel stack frame */
movl %ebp,%esp
/* Call the post system call hook and deliver any pending APCs */
pushl %esp
pushl %eax
call _KiAfterSystemCallHook
addl $8,%esp
new_done:
/* Restore the user context */
/* Get a pointer to the current thread */
movl %fs:0x124, %esi
/* Restore the old trap frame pointer */
movl 0x3c(%esp), %ebx
movl %ebx, KTHREAD_TRAP_FRAME(%esi)
/* Skip debug information and unsaved registers */
addl $0x30, %esp
popl %gs
popl %es
popl %ds
popl %edx
popl %ecx
addl $0x4, %esp /* Don't restore eax */
/* Restore the old previous mode */
popl %ebx
movb %bl, %ss:KTHREAD_PREVIOUS_MODE(%esi)
/* Restore the old exception handler list */
popl %ebx
movl %ebx, %fs:KPCR_EXCEPTION_LIST
popl %fs
popl %edi
popl %esi
popl %ebx
popl %ebp
addl $0x4, %esp /* Ignore error code */
iret

View file

@ -1,9 +1,27 @@
/* $Id: trap.s,v 1.4 2000/10/11 20:50:34 dwelch Exp $ /*
* ReactOS kernel
* Copyright (C) 2000 David Welch <welch@cwcom.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: trap.s,v 1.5 2000/12/10 23:42:00 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/hal/x86/trap.s * FILE: ntoskrnl/hal/x86/trap.s
* PURPOSE: 2E trap handler * PURPOSE: Exception handlers
* PROGRAMMER: David Welch (david.welch@seh.ox.ac.uk) * PROGRAMMER: David Welch (david.welch@seh.ox.ac.uk)
* UPDATE HISTORY: * UPDATE HISTORY:
* ??? * ???
@ -15,417 +33,18 @@
#include <ddk/defines.h> #include <ddk/defines.h>
/* /*
* * Epilog for exception handlers
*/ */
_exception_handler_epilog:
.globl _PsBeginThreadWithContextInternal popa
addl $4, %esp
_PsBeginThreadWithContextInternal:
call _PiBeforeBeginThread
popl %eax
popl %eax
popl %eax
popl %eax
popl %eax
popl %eax
popl %eax
addl $112,%esp
popl %gs
; popl %fs
movl $TEB_SELECTOR, %ax
movl %ax, %fs
popl %es
popl %ds popl %ds
popl %edi
popl %esi
popl %ebx
popl %edx
popl %ecx
popl %eax
popl %ebp
iret
/*
*
*/
.globl _interrupt_handler2e
_interrupt_handler2e:
/* Construct a trap frame on the stack */
/* Error code */
pushl $0
pushl %ebp
pushl %ebx
pushl %esi
pushl %edi
pushl %fs
/* Load PCR selector into fs */
movl $PCR_SELECTOR, %ebx
movl %ebx, %fs
/* Save the old exception list */
movl %fs:KPCR_EXCEPTION_LIST, %ebx
pushl %ebx
/* Put the exception handler chain terminator */
movl $0xffffffff, %fs:KPCR_EXCEPTION_LIST
/* Get a pointer to the current thread */
movl %fs:KPCR_CURRENT_THREAD, %esi
/* Save the old previous mode */
movl $0, %ebx
movb %ss:KTHREAD_PREVIOUS_MODE(%esi), %bl
pushl %ebx
/* Set the new previous mode based on the saved CS selector */
movl 0x24(%esp), %ebx
cmpl $KERNEL_CS, %ebx
jne L1
movb $KernelMode, %ss:KTHREAD_PREVIOUS_MODE(%esi)
jmp L3
L1:
movb $UserMode, %ss:KTHREAD_PREVIOUS_MODE(%esi)
L3:
/* Save other registers */
pushl %eax
pushl %ecx
pushl %edx
pushl %ds
pushl %es
pushl %gs
pushl $0 /* DR7 */
pushl $0 /* DR6 */
pushl $0 /* DR3 */
pushl $0 /* DR2 */
pushl $0 /* DR1 */
pushl $0 /* DR0 */
pushl $0 /* XXX: TempESP */
pushl $0 /* XXX: TempCS */
pushl $0 /* XXX: DebugPointer */
pushl $0 /* XXX: DebugArgMark */
pushl $0 /* XXX: DebugEIP */
pushl $0 /* XXX: DebugEBP */
/* Load the segment registers */
movl $KERNEL_DS, %ebx
movl %ebx, %ds
movl %ebx, %es
movl %ebx, %gs
/* Save the old trap frame pointer (over the EDX register??) */
movl KTHREAD_TRAP_FRAME(%esi), %ebx
movl %ebx, 0x3C(%esp)
/* Save a pointer to the trap frame in the TCB */
movl %esp, KTHREAD_TRAP_FRAME(%esi)
/* Set ES to kernel segment */
movw $KERNEL_DS,%bx
movw %bx,%es
/* Allocate new Kernel stack frame */
movl %esp,%ebp
/* Users's current stack frame pointer is source */
movl %edx,%esi
/* Determine system service table to use */
cmpl $0x0fff, %eax
ja new_useShadowTable
/* Check to see if EAX is valid/inrange */
cmpl %es:_KeServiceDescriptorTable + 8, %eax
jbe new_serviceInRange
movl $STATUS_INVALID_SYSTEM_SERVICE, %eax
jmp new_done
new_serviceInRange:
/* Allocate room for argument list from kernel stack */
movl %es:_KeServiceDescriptorTable + 12, %ecx
movl %es:(%ecx, %eax, 4), %ecx
subl %ecx, %esp
/* Copy the arguments from the user stack to the kernel stack */
movl %esp,%edi
rep movsb
/* DS is now also kernel segment */
movw %bx, %ds
/* Call system call hook */
pushl %eax
call _KiSystemCallHook
popl %eax
/* Make the system service call */
movl %es:_KeServiceDescriptorTable, %ecx
movl %es:(%ecx, %eax, 4), %eax
call *%eax
#if CHECKED
/* Bump Service Counter */
#endif
/* Deallocate the kernel stack frame */
movl %ebp,%esp
/* Call the post system call hook and deliver any pending APCs */
pushl %ebp
pushl %eax
call _KiAfterSystemCallHook
addl $8,%esp
jmp new_done
new_useShadowTable:
subl $0x1000, %eax
/* Check to see if EAX is valid/inrange */
cmpl %es:_KeServiceDescriptorTableShadow + 24, %eax
jbe new_shadowServiceInRange
movl $STATUS_INVALID_SYSTEM_SERVICE, %eax
jmp new_done
new_shadowServiceInRange:
/* Allocate room for argument list from kernel stack */
movl %es:_KeServiceDescriptorTableShadow + 28, %ecx
movl %es:(%ecx, %eax, 4), %ecx
subl %ecx, %esp
/* Copy the arguments from the user stack to the kernel stack */
movl %esp,%edi
rep movsb
/* DS is now also kernel segment */
movw %bx,%ds
/* Call system call hook */
pushl %eax
call _KiSystemCallHook
popl %eax
/* Make the system service call */
movl %es:_KeServiceDescriptorTableShadow + 16, %ecx
movl %es:(%ecx, %eax, 4), %eax
call *%eax
#if CHECKED
/* Bump Service Counter */
#endif
/* Deallocate the kernel stack frame */
movl %ebp,%esp
/* Call the post system call hook and deliver any pending APCs */
pushl %esp
pushl %eax
call _KiAfterSystemCallHook
addl $8,%esp
new_done:
/* Restore the user context */
/* Get a pointer to the current thread */
movl %fs:0x124, %esi
/* Restore the old trap frame pointer */
movl 0x3c(%esp), %ebx
movl %ebx, KTHREAD_TRAP_FRAME(%esi)
/* Skip debug information and unsaved registers */
addl $0x30, %esp
popl %gs
popl %es popl %es
popl %ds
popl %edx
popl %ecx
addl $0x4, %esp /* Don't restore eax */
/* Restore the old previous mode */
popl %ebx
movb %bl, %ss:KTHREAD_PREVIOUS_MODE(%esi)
/* Restore the old exception handler list */
popl %ebx
movl %ebx, %fs:KPCR_EXCEPTION_LIST
popl %fs popl %fs
popl %edi popl %gs
popl %esi addl $4, %esp
popl %ebx
popl %ebp
addl $0x4, %esp /* Ignore error code */
iret iret
/*
*
*/
.globl _old_interrupt_handler2e
_old_interrupt_handler2e:
/* Save the user context */
pushl %ebp /* Ebp */
pushl %eax /* Eax */
pushl %ecx /* Ecx */
pushl %edx /* Edx */
pushl %ebx /* Ebx */
pushl %esi /* Esi */
pushl %edi /* Edi */
pushl %ds /* SegDs */
pushl %es /* SegEs */
pushl %fs /* SegFs */
pushl %gs /* SegGs */
subl $112,%esp /* FloatSave */
pushl $0 /* Dr7 */
pushl $0 /* Dr6 */
pushl $0 /* Dr3 */
pushl $0 /* Dr2 */
pushl $0 /* Dr1 */
pushl $0 /* Dr0 */
pushl $0 /* ContextFlags */
/* Set ES to kernel segment */
movw $KERNEL_DS,%bx
movw %bx,%es
/* Save pointer to user context as argument to system call */
pushl %esp
/* Allocate new Kernel stack frame */
movl %esp,%ebp
/* Users's current stack frame pointer is source */
movl %edx,%esi
/* Determine system service table to use */
cmpl $0x0fff, %eax
ja useShadowTable
/* Check to see if EAX is valid/inrange */
cmpl %es:_KeServiceDescriptorTable + 8, %eax
jbe serviceInRange
movl $STATUS_INVALID_SYSTEM_SERVICE, %eax
jmp done
serviceInRange:
/* Allocate room for argument list from kernel stack */
movl %es:_KeServiceDescriptorTable + 12, %ecx
movl %es:(%ecx, %eax, 4), %ecx
subl %ecx, %esp
/* Copy the arguments from the user stack to the kernel stack */
movl %esp,%edi
rep movsb
/* DS is now also kernel segment */
movw %bx, %ds
/* Call system call hook */
pushl %eax
call _KiSystemCallHook
popl %eax
/* Make the system service call */
movl %es:_KeServiceDescriptorTable, %ecx
movl %es:(%ecx, %eax, 4), %eax
call *%eax
#if CHECKED
/* Bump Service Counter */
#endif
/* Deallocate the kernel stack frame */
movl %ebp,%esp
/* Call the post system call hook and deliver any pending APCs */
pushl %eax
call _KiAfterSystemCallHook
addl $8,%esp
jmp done
useShadowTable:
subl $0x1000, %eax
/* Check to see if EAX is valid/inrange */
cmpl %es:_KeServiceDescriptorTableShadow + 24, %eax
jbe shadowServiceInRange
movl $STATUS_INVALID_SYSTEM_SERVICE, %eax
jmp done
shadowServiceInRange:
/* Allocate room for argument list from kernel stack */
movl %es:_KeServiceDescriptorTableShadow + 28, %ecx
movl %es:(%ecx, %eax, 4), %ecx
subl %ecx, %esp
/* Copy the arguments from the user stack to the kernel stack */
movl %esp,%edi
rep movsb
/* DS is now also kernel segment */
movw %bx,%ds
/* Call system call hook */
pushl %eax
call _KiSystemCallHook
popl %eax
/* Make the system service call */
movl %es:_KeServiceDescriptorTableShadow + 16, %ecx
movl %es:(%ecx, %eax, 4), %eax
call *%eax
#if CHECKED
/* Bump Service Counter */
#endif
/* Deallocate the kernel stack frame */
movl %ebp,%esp
/* Call the post system call hook and deliver any pending APCs */
pushl %eax
call _KiAfterSystemCallHook
addl $8,%esp
done:
/* Restore the user context */
addl $4,%esp /* UserContext */
addl $24,%esp /* Dr[0-3,6-7] */
addl $112,%esp /* FloatingSave */
popl %gs /* SegGs */
popl %fs /* SegFs */
popl %es /* SegEs */
popl %ds /* SegDs */
popl %edi /* Edi */
popl %esi /* Esi */
popl %ebx /* Ebx */
popl %edx /* Edx */
popl %ecx /* Ecx */
addl $4,%esp /* Eax (Not restored) */
popl %ebp /* Ebp */
iret
/*
*
*/
.globl _exception_handler0 .globl _exception_handler0
_exception_handler0: _exception_handler0:
pushl $0 pushl $0
@ -441,14 +60,7 @@ _exception_handler0:
movw %ax,%fs movw %ax,%fs
movw %ax,%gs movw %ax,%gs
call _exception_handler call _exception_handler
popa jmp _exception_handler_epilog
addl $4,%esp
popl %ds
popl %es
popl %fs
popl %gs
addl $4,%esp
iret
.globl _exception_handler1 .globl _exception_handler1
_exception_handler1: _exception_handler1:

View file

@ -0,0 +1,84 @@
/*
* ReactOS kernel
* Copyright (C) 2000 David Welch <welch@cwcom.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* FILE: ntoskrnl/ke/i386/tskswitch.S
* PURPOSE: Microkernel thread support
* PROGRAMMER: David Welch (welch@cwcom.net)
* UPDATE HISTORY:
* Created 09/10/00
*/
/* INCLUDES ******************************************************************/
#include <internal/i386/segment.h>
#include <internal/ps.h>
/* FUNCTIONS ****************************************************************/
.globl _Ki386ContextSwitch
_Ki386ContextSwitch:
/*
* FUNCTIONS: Switches to another thread's context
* ARGUMENTS:
* Thread = Thread to switch to
* OldThread = Thread to switch from
*/
pushl %ebp
movl %esp, %ebp
/*
* Save callee save register
*/
pushl %ebx
pushl %esi
pushl %edi
/*
* FIXME: Save debugging state
*/
/*
* FIXME: Save floating point state
*/
/*
* Switch stacks
*/
movl 12(%ebp), %ebx
movl %esp, KTHREAD_KERNEL_STACK(%ebx)
movl 8(%ebp), %ebx
movl KTHREAD_KERNEL_STACK(%ebx), %esp
/*
* FIXME: Restore floating point state
*/
/*
* FIXME: Restore debugging state
*/
/*
* Restore the saved register and exit
*/
popl %edi
popl %esi
popl %ebx
movl %ebp, %esp
popl %esp
ret

View file

@ -0,0 +1,142 @@
/*
* ReactOS kernel
* Copyright (C) 2000 David Welch <welch@cwcom.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* FILE: ntoskrnl/ke/i386/vm86_sup.S
* PURPOSE: V86 mode support
* PROGRAMMER: David Welch (welch@cwcom.net)
* UPDATE HISTORY:
* Created 09/10/00
*/
#include <internal/vm86.h>
.globl _Ki386RetToV86Mode
/*
* NTSTATUS Ki386RetToV86Mode(KV86M_REGISTERS* in_regs,
* KV86M_REGISTERS* out_regs);
*
* Starts in v86 mode with the registers set to the
* specified values.
*/
_Ki386RetToV86Mode:
/*
* Setup a stack frame
*/
pushl %ebp
movl %esp, %ebp
/*
* Save registers
*/
pusha
/*
* Get a pointer to IN_REGS
*/
movl 8(%ebp), %ebx
/*
* Save ebp
*/
pushl %ebp
/*
* The stack used for handling exceptions from v86 mode in this thread
* will be the current stack adjusted so we don't overwrite the
* existing stack frames
*/
movl %esp, TSS_ESP0(%esi)
/*
* Create the stack frame for an iret to v86 mode
*/
pushl GS(%ebx)
pushl FS(%ebx)
pushl DS(%ebx)
pushl ES(%ebx)
pushl SS(%ebx)
pushl ESP(%ebx)
pushl EFLAGS(%ebx)
pushl CS(%ebx)
pushl EIP(%ebx)
/*
* Setup the CPU registers
*/
movl EAX(%ebx), %eax
movl ECX(%ebx), %ecx
movl EDX(%ebx), %edx
movl ESI(%ebx), %esi
movl EDI(%ebx), %edi
movl EBP(%ebx), %ebp
movl EBX(%ebx), %ebx
/*
* Go to v86 mode
*/
iret
/*
* Handle the completion of a vm86 routine. We are called from
* an exception handler with the registers at the point of the
* exception on the stack.
*/
_vm86_complete:
addl $4, %esp /* Ignore pointer to registers */
addl $4, %esp /* Ignore exception number */
/* Get a pointer to the vm86_registers structure */
movl _vm86_old_ebp, %ebp
movl 8(%ebp), %ebx
/* Save the vm86 registers into the vm86_registers structure */
popl EBP(%ebx)
popl EDI(%ebx)
popl ESI(%ebx)
popl EDX(%ebx)
popl ECX(%ebx)
popl EBX(%ebx)
popl EAX(%ebx)
addl $16, %esp /* Ignore 32-bit segment registers */
addl $4, %esp /* Ignore error code */
popl EIP(%ebx)
popl CS(%ebx)
popl EFLAGS(%ebx)
popl ESP(%ebx)
popl SS(%ebx)
popl ES(%ebx)
popl DS(%ebx)
popl FS(%ebx)
popl GS(%ebx)
/* Swap back to the stack */
cli
movl _vm86_old_esp, %esp
sti
movl _vm86_old_ebp, %ebp
/* Return to caller */
popa
movl %ebp, %esp
popl %ebp
ret

View file

@ -149,6 +149,7 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread)
Thread->ProcessThreadListEntry.Blink = NULL; Thread->ProcessThreadListEntry.Blink = NULL;
KeInitializeDpc(&Thread->TimerDpc, (PKDEFERRED_ROUTINE)PiTimeoutThread, KeInitializeDpc(&Thread->TimerDpc, (PKDEFERRED_ROUTINE)PiTimeoutThread,
Thread); Thread);
Thread->LastEip = 0;
/* /*
* Do x86 specific part * Do x86 specific part

View file

@ -1,4 +1,4 @@
/* $Id: close.c,v 1.2 2000/10/22 16:36:51 ekohl Exp $ /* $Id: close.c,v 1.3 2000/12/10 23:42:00 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -33,10 +33,8 @@
* *
*/ */
VOID VOID
NiClosePort ( NiClosePort (PVOID ObjectBody,
PVOID ObjectBody, ULONG HandleCount)
ULONG HandleCount
)
{ {
PEPORT Port = (PEPORT) ObjectBody; PEPORT Port = (PEPORT) ObjectBody;
LPC_MESSAGE Message; LPC_MESSAGE Message;
@ -44,36 +42,30 @@ NiClosePort (
// DPRINT1("NiClosePort(ObjectBody %x, HandleCount %d) RefCount %d\n", // DPRINT1("NiClosePort(ObjectBody %x, HandleCount %d) RefCount %d\n",
// ObjectBody, HandleCount, ObGetReferenceCount(Port)); // ObjectBody, HandleCount, ObGetReferenceCount(Port));
if ( (HandleCount == 0) if ((HandleCount == 0) &&
&& (Port->State == EPORT_CONNECTED_CLIENT) (Port->State == EPORT_CONNECTED_CLIENT) &&
&& (ObGetReferenceCount(Port) == 2) (ObGetReferenceCount(Port) == 2))
)
{ {
// DPRINT1("All handles closed to client port\n"); // DPRINT1("All handles closed to client port\n");
Message.MessageSize = sizeof(LPC_MESSAGE); Message.MessageSize = sizeof(LPC_MESSAGE);
Message.DataSize = 0; Message.DataSize = 0;
EiReplyOrRequestPort ( EiReplyOrRequestPort (Port->OtherPort,
Port->OtherPort,
&Message, &Message,
LPC_PORT_CLOSED, LPC_PORT_CLOSED,
Port Port);
); KeSetEvent (&Port->OtherPort->Event,
KeSetEvent (
& Port->OtherPort->Event,
IO_NO_INCREMENT, IO_NO_INCREMENT,
FALSE FALSE);
);
Port->OtherPort->OtherPort = NULL; Port->OtherPort->OtherPort = NULL;
Port->OtherPort->State = EPORT_DISCONNECTED; Port->OtherPort->State = EPORT_DISCONNECTED;
ObDereferenceObject (Port); ObDereferenceObject (Port);
} }
if ( (HandleCount == 0) if ((HandleCount == 0) &&
&& (Port->State == EPORT_CONNECTED_SERVER) (Port->State == EPORT_CONNECTED_SERVER) &&
&& (ObGetReferenceCount(Port) == 2) (ObGetReferenceCount(Port) == 2))
)
{ {
// DPRINT("All handles closed to server\n"); // DPRINT("All handles closed to server\n");
@ -97,9 +89,7 @@ NiClosePort (
* *
*/ */
VOID VOID
NiDeletePort ( NiDeletePort (PVOID ObjectBody)
PVOID ObjectBody
)
{ {
// PEPORT Port = (PEPORT)ObjectBody; // PEPORT Port = (PEPORT)ObjectBody;

268
reactos/ntoskrnl/ps/debug.c Normal file
View file

@ -0,0 +1,268 @@
/*
* ReactOS kernel
* Copyright (C) 2000, 1999, 1998 David Welch <welch@cwcom.net>,
* Philip Susi <phreak@iag.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: debug.c,v 1.1 2000/12/10 23:42:01 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ps/debug.c
* PURPOSE: Thread managment
* PROGRAMMER: David Welch (welch@mcmail.com)
* REVISION HISTORY:
* 23/06/98: Created
* 12/10/99: Phillip Susi: Thread priorities, and APC work
*/
/*
* NOTE:
*
* All of the routines that manipulate the thread queue synchronize on
* a single spinlock
*
*/
/* INCLUDES ****************************************************************/
#include <ddk/ntddk.h>
#include <internal/ke.h>
#include <internal/ob.h>
#include <string.h>
#include <internal/hal.h>
#include <internal/ps.h>
#include <internal/ob.h>
#define NDEBUG
#include <internal/debug.h>
/* FUNCTIONS ***************************************************************/
VOID KeContextToTrapFrame(PCONTEXT Context,
PKTRAP_FRAME TrapFrame)
{
if (Context->ContextFlags & CONTEXT_CONTROL)
{
TrapFrame->Esp = Context->Esp;
TrapFrame->Ss = Context->SegSs;
TrapFrame->Cs = Context->SegCs;
TrapFrame->Eip = Context->Eip;
TrapFrame->Eflags = Context->EFlags;
TrapFrame->Ebp = Context->Ebp;
}
if (Context->ContextFlags & CONTEXT_INTEGER)
{
TrapFrame->Eax = Context->Eax;
TrapFrame->Ebx = Context->Ebx;
TrapFrame->Ecx = Context->Ecx;
/*
* Edx is used in the TrapFrame to hold the old trap frame pointer
* so we don't want to overwrite it here
*/
/* TrapFrame->Edx = Context->Edx; */
TrapFrame->Esi = Context->Esi;
TrapFrame->Edx = Context->Edi;
}
if (Context->ContextFlags & CONTEXT_SEGMENTS)
{
TrapFrame->Ds = Context->SegDs;
TrapFrame->Es = Context->SegEs;
TrapFrame->Fs = Context->SegFs;
TrapFrame->Gs = Context->SegGs;
}
if (Context->ContextFlags & CONTEXT_FLOATING_POINT)
{
/*
* Not handled
*/
}
if (Context->ContextFlags & CONTEXT_DEBUG_REGISTERS)
{
/*
* Not handled
*/
}
}
VOID KeTrapFrameToContext(PKTRAP_FRAME TrapFrame,
PCONTEXT Context)
{
if (Context->ContextFlags & CONTEXT_CONTROL)
{
Context->SegSs = TrapFrame->Ss;
Context->Esp = TrapFrame->Esp;
Context->SegCs = TrapFrame->Cs;
Context->Eip = TrapFrame->Eip;
Context->EFlags = TrapFrame->Eflags;
Context->Ebp = TrapFrame->Ebp;
}
if (Context->ContextFlags & CONTEXT_INTEGER)
{
Context->Eax = TrapFrame->Eax;
Context->Ebx = TrapFrame->Ebx;
Context->Ecx = TrapFrame->Ecx;
/*
* NOTE: In the trap frame which is built on entry to a system
* call TrapFrame->Edx will actually hold the address of the
* previous TrapFrame. I don't believe leaking this information
* has security implications
*/
Context->Edx = TrapFrame->Edx;
Context->Esi = TrapFrame->Esi;
Context->Edi = TrapFrame->Edi;
}
if (Context->ContextFlags & CONTEXT_SEGMENTS)
{
Context->SegDs = TrapFrame->Ds;
Context->SegEs = TrapFrame->Es;
Context->SegFs = TrapFrame->Fs;
Context->SegGs = TrapFrame->Gs;
}
if (Context->ContextFlags & CONTEXT_DEBUG_REGISTERS)
{
/*
* FIXME: Implement this case
*/
}
if (Context->ContextFlags & CONTEXT_FLOATING_POINT)
{
/*
* FIXME: Implement this case
*/
}
#if 0
if (Context->ContextFlags & CONTEXT_EXTENDED_REGISTERS)
{
/*
* FIXME: Investigate this
*/
}
#endif
}
VOID KeGetContextRundownRoutine(PKAPC Apc)
{
PKEVENT Event;
PNTSTATUS Status;
Event = (PKEVENT)Apc->SystemArgument1;
Status = (PNTSTATUS)Apc->SystemArgument2;
(*Status) = STATUS_THREAD_IS_TERMINATING;
KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
}
VOID KeGetContextKernelRoutine(PKAPC Apc,
PKNORMAL_ROUTINE* NormalRoutine,
PVOID* NormalContext,
PVOID* SystemArgument1,
PVOID* SystemArgument2)
/*
* FUNCTION: This routine is called by an APC sent by NtGetContextThread to
* copy the context of a thread into a buffer.
*/
{
PKEVENT Event;
PCONTEXT Context;
PNTSTATUS Status;
Context = (PCONTEXT)(*NormalContext);
Event = (PKEVENT)(*SystemArgument1);
Status = (PNTSTATUS)(*SystemArgument2);
KeTrapFrameToContext(KeGetCurrentThread()->TrapFrame, Context);
*Status = STATUS_SUCCESS;
KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
}
NTSTATUS STDCALL NtGetContextThread (IN HANDLE ThreadHandle,
OUT PCONTEXT Context)
{
PETHREAD Thread;
NTSTATUS Status;
Status = ObReferenceObjectByHandle(ThreadHandle,
THREAD_GET_CONTEXT,
PsThreadType,
UserMode,
(PVOID*)&Thread,
NULL);
if (!NT_SUCCESS(Status))
{
return(Status);
}
if (Thread == PsGetCurrentThread())
{
/*
* I don't know if trying to get your own context makes much
* sense but we can handle it more efficently.
*/
KeTrapFrameToContext(Thread->Tcb.TrapFrame, Context);
ObDereferenceObject(Thread);
return(STATUS_SUCCESS);
}
else
{
KAPC Apc;
KEVENT Event;
NTSTATUS AStatus;
CONTEXT KContext;
KContext.ContextFlags = Context->ContextFlags;
KeInitializeEvent(&Event,
NotificationEvent,
FALSE);
AStatus = STATUS_SUCCESS;
KeInitializeApc(&Apc,
&Thread->Tcb,
0,
KeGetContextKernelRoutine,
KeGetContextRundownRoutine,
NULL,
KernelMode,
(PVOID)&KContext);
KeInsertQueueApc(&Apc,
(PVOID)&Event,
(PVOID)&AStatus,
0);
Status = KeWaitForSingleObject(&Event,
0,
UserMode,
FALSE,
NULL);
if (!NT_SUCCESS(Status))
{
return(Status);
}
if (!NT_SUCCESS(AStatus))
{
return(AStatus);
}
memcpy(Context, &KContext, sizeof(CONTEXT));
return(STATUS_SUCCESS);
}
}
NTSTATUS STDCALL NtSetContextThread (IN HANDLE ThreadHandle,
IN PCONTEXT Context)
{
UNIMPLEMENTED;
}
/* EOF */

View file

@ -1,4 +1,4 @@
/* $Id: thread.c,v 1.59 2000/10/22 16:36:53 ekohl Exp $ /* $Id: thread.c,v 1.60 2000/12/10 23:42:01 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -53,11 +53,25 @@ static PETHREAD CurrentThread = NULL;
PKTHREAD STDCALL KeGetCurrentThread(VOID) PKTHREAD STDCALL KeGetCurrentThread(VOID)
{ {
#if 0
if (CurrentThread != NULL)
{
DbgPrint("KeGetCurrentThread() called before initialization\n");
KeBugCheck(0);
}
#endif
return(&(CurrentThread->Tcb)); return(&(CurrentThread->Tcb));
} }
PETHREAD STDCALL PsGetCurrentThread(VOID) PETHREAD STDCALL PsGetCurrentThread(VOID)
{ {
#if 0
if (CurrentThread != NULL)
{
DbgPrint("PsGetCurrentThread() called before initialization\n");
KeBugCheck(0);
}
#endif
return(CurrentThread); return(CurrentThread);
} }
@ -106,11 +120,11 @@ VOID PsDumpThreads(VOID)
DbgPrint("Too many threads on list\n"); DbgPrint("Too many threads on list\n");
return; return;
} }
DbgPrint("current %x current->Tcb.State %d eip %x ", DbgPrint("current %x current->Tcb.State %d eip %x/%x ",
current, current->Tcb.State, current, current->Tcb.State,
current->Tcb.Context.eip); current->Tcb.Context.eip, current->Tcb.LastEip);
KeDumpStackFrames((PVOID)current->Tcb.Context.esp0, // KeDumpStackFrames((PVOID)current->Tcb.Context.esp0,
16); // 16);
DbgPrint("PID %d ", current->ThreadsProcess->UniqueProcessId); DbgPrint("PID %d ", current->ThreadsProcess->UniqueProcessId);
DbgPrint("\n"); DbgPrint("\n");
@ -427,215 +441,6 @@ NTSTATUS STDCALL NtOpenThread(OUT PHANDLE ThreadHandle,
UNIMPLEMENTED; UNIMPLEMENTED;
} }
VOID KeContextToTrapFrame(PCONTEXT Context,
PKTRAP_FRAME TrapFrame)
{
if (Context->ContextFlags & CONTEXT_CONTROL)
{
TrapFrame->Esp = Context->Esp;
TrapFrame->Ss = Context->SegSs;
TrapFrame->Cs = Context->SegCs;
TrapFrame->Eip = Context->Eip;
TrapFrame->Eflags = Context->EFlags;
TrapFrame->Ebp = Context->Ebp;
}
if (Context->ContextFlags & CONTEXT_INTEGER)
{
TrapFrame->Eax = Context->Eax;
TrapFrame->Ebx = Context->Ebx;
TrapFrame->Ecx = Context->Ecx;
/*
* Edx is used in the TrapFrame to hold the old trap frame pointer
* so we don't want to overwrite it here
*/
/* TrapFrame->Edx = Context->Edx; */
TrapFrame->Esi = Context->Esi;
TrapFrame->Edx = Context->Edi;
}
if (Context->ContextFlags & CONTEXT_SEGMENTS)
{
TrapFrame->Ds = Context->SegDs;
TrapFrame->Es = Context->SegEs;
TrapFrame->Fs = Context->SegFs;
TrapFrame->Gs = Context->SegGs;
}
if (Context->ContextFlags & CONTEXT_FLOATING_POINT)
{
/*
* Not handled
*/
}
if (Context->ContextFlags & CONTEXT_DEBUG_REGISTERS)
{
/*
* Not handled
*/
}
}
VOID KeTrapFrameToContext(PKTRAP_FRAME TrapFrame,
PCONTEXT Context)
{
if (Context->ContextFlags & CONTEXT_CONTROL)
{
Context->SegSs = TrapFrame->Ss;
Context->Esp = TrapFrame->Esp;
Context->SegCs = TrapFrame->Cs;
Context->Eip = TrapFrame->Eip;
Context->EFlags = TrapFrame->Eflags;
Context->Ebp = TrapFrame->Ebp;
}
if (Context->ContextFlags & CONTEXT_INTEGER)
{
Context->Eax = TrapFrame->Eax;
Context->Ebx = TrapFrame->Ebx;
Context->Ecx = TrapFrame->Ecx;
/*
* NOTE: In the trap frame which is built on entry to a system
* call TrapFrame->Edx will actually hold the address of the
* previous TrapFrame. I don't believe leaking this information
* has security implications
*/
Context->Edx = TrapFrame->Edx;
Context->Esi = TrapFrame->Esi;
Context->Edi = TrapFrame->Edi;
}
if (Context->ContextFlags & CONTEXT_SEGMENTS)
{
Context->SegDs = TrapFrame->Ds;
Context->SegEs = TrapFrame->Es;
Context->SegFs = TrapFrame->Fs;
Context->SegGs = TrapFrame->Gs;
}
if (Context->ContextFlags & CONTEXT_DEBUG_REGISTERS)
{
/*
* FIXME: Implement this case
*/
}
if (Context->ContextFlags & CONTEXT_FLOATING_POINT)
{
/*
* FIXME: Implement this case
*/
}
#if 0
if (Context->ContextFlags & CONTEXT_EXTENDED_REGISTERS)
{
/*
* FIXME: Investigate this
*/
}
#endif
}
VOID KeGetContextRundownRoutine(PKAPC Apc)
{
PKEVENT Event;
PNTSTATUS Status;
Event = (PKEVENT)Apc->SystemArgument1;
Status = (PNTSTATUS)Apc->SystemArgument2;
(*Status) = STATUS_THREAD_IS_TERMINATING;
KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
}
VOID KeGetContextKernelRoutine(PKAPC Apc,
PKNORMAL_ROUTINE* NormalRoutine,
PVOID* NormalContext,
PVOID* SystemArgument1,
PVOID* SystemArgument2)
{
PKEVENT Event;
PCONTEXT Context;
PNTSTATUS Status;
Context = (PCONTEXT)(*NormalContext);
Event = (PKEVENT)(*SystemArgument1);
Status = (PNTSTATUS)(*SystemArgument2);
KeTrapFrameToContext(KeGetCurrentThread()->TrapFrame, Context);
*Status = STATUS_SUCCESS;
KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
}
NTSTATUS STDCALL NtGetContextThread (IN HANDLE ThreadHandle,
OUT PCONTEXT Context)
{
PETHREAD Thread;
NTSTATUS Status;
Status = ObReferenceObjectByHandle(ThreadHandle,
THREAD_GET_CONTEXT,
PsThreadType,
UserMode,
(PVOID*)&Thread,
NULL);
if (!NT_SUCCESS(Status))
{
return(Status);
}
if (Thread == PsGetCurrentThread())
{
/*
* I don't know if trying to get your own context makes much
* sense but we can handle it more efficently.
*/
KeTrapFrameToContext(Thread->Tcb.TrapFrame, Context);
ObDereferenceObject(Thread);
return(STATUS_SUCCESS);
}
else
{
KAPC Apc;
KEVENT Event;
NTSTATUS AStatus;
CONTEXT KContext;
KContext.ContextFlags = Context->ContextFlags;
KeInitializeEvent(&Event,
NotificationEvent,
FALSE);
AStatus = STATUS_SUCCESS;
KeInitializeApc(&Apc,
&Thread->Tcb,
0,
KeGetContextKernelRoutine,
KeGetContextRundownRoutine,
NULL,
KernelMode,
(PVOID)&KContext);
KeInsertQueueApc(&Apc,
(PVOID)&Event,
(PVOID)&AStatus,
0);
Status = KeWaitForSingleObject(&Event,
0,
UserMode,
FALSE,
NULL);
if (!NT_SUCCESS(Status))
{
return(Status);
}
if (!NT_SUCCESS(AStatus))
{
return(AStatus);
}
memcpy(Context, &KContext, sizeof(CONTEXT));
return(STATUS_SUCCESS);
}
}
NTSTATUS STDCALL NtSetContextThread (IN HANDLE ThreadHandle,
IN PCONTEXT Context)
{
UNIMPLEMENTED;
}
NTSTATUS STDCALL NtResumeThread (IN HANDLE ThreadHandle, NTSTATUS STDCALL NtResumeThread (IN HANDLE ThreadHandle,
IN PULONG SuspendCount) IN PULONG SuspendCount)
/* /*