mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
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:
parent
4ac4987dd2
commit
488f0ac078
28 changed files with 2053 additions and 1465 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
41
reactos/drivers/fs/minix/Makefile
Normal file
41
reactos/drivers/fs/minix/Makefile
Normal 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
|
203
reactos/drivers/fs/minix/bitops.c
Normal file
203
reactos/drivers/fs/minix/bitops.c
Normal 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;
|
||||||
|
}
|
30
reactos/drivers/fs/minix/bitops.h
Normal file
30
reactos/drivers/fs/minix/bitops.h
Normal 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 */
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
|
@ -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/
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
@ -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 = \
|
||||||
|
|
|
@ -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*)¤t->MemoryArea);
|
(PMEMORY_AREA*)¤t->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(¤t->Lock, SynchronizationEvent, FALSE);
|
KeInitializeEvent(¤t->Lock, SynchronizationEvent, FALSE);
|
||||||
current->ReferenceCount = 1;
|
current->ReferenceCount = 1;
|
||||||
CHECKPOINT;
|
|
||||||
InsertTailList(&Bcb->CacheSegmentListHead, ¤t->ListEntry);
|
InsertTailList(&Bcb->CacheSegmentListHead, ¤t->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);
|
||||||
|
|
||||||
|
|
|
@ -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 *************************************************/
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
76
reactos/ntoskrnl/include/internal/vm86.h
Normal file
76
reactos/ntoskrnl/include/internal/vm86.h
Normal 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 */
|
|
@ -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)
|
||||||
/*
|
/*
|
||||||
|
@ -44,13 +70,14 @@ VOID STDCALL KeInitializeDpc (PKDPC Dpc,
|
||||||
* NOTE: Callers must be running at IRQL PASSIVE_LEVEL
|
* NOTE: Callers must be running at IRQL PASSIVE_LEVEL
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
Dpc->Type=0;
|
Dpc->Type = 0;
|
||||||
Dpc->DeferredRoutine=DeferredRoutine;
|
Dpc->DeferredRoutine = DeferredRoutine;
|
||||||
Dpc->DeferredContext=DeferredContext;
|
Dpc->DeferredContext = DeferredContext;
|
||||||
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
|
||||||
*/
|
*/
|
||||||
|
|
64
reactos/ntoskrnl/ke/i386/bthread.S
Normal file
64
reactos/ntoskrnl/ke/i386/bthread.S
Normal 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
|
|
@ -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
|
||||||
|
|
|
@ -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" \
|
||||||
|
|
246
reactos/ntoskrnl/ke/i386/syscall.S
Normal file
246
reactos/ntoskrnl/ke/i386/syscall.S
Normal 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
|
|
@ -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:
|
||||||
|
|
84
reactos/ntoskrnl/ke/i386/tskswitch.S
Normal file
84
reactos/ntoskrnl/ke/i386/tskswitch.S
Normal 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
|
142
reactos/ntoskrnl/ke/i386/vm86_sup.S
Normal file
142
reactos/ntoskrnl/ke/i386/vm86_sup.S
Normal 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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,49 +33,41 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
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;
|
||||||
|
|
||||||
// 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");
|
||||||
|
|
||||||
Port->OtherPort->OtherPort = NULL;
|
Port->OtherPort->OtherPort = NULL;
|
||||||
Port->OtherPort->State = EPORT_DISCONNECTED;
|
Port->OtherPort->State = EPORT_DISCONNECTED;
|
||||||
|
@ -97,13 +89,11 @@ NiClosePort (
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
VOID
|
VOID
|
||||||
NiDeletePort (
|
NiDeletePort (PVOID ObjectBody)
|
||||||
PVOID ObjectBody
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
// PEPORT Port = (PEPORT)ObjectBody;
|
// PEPORT Port = (PEPORT)ObjectBody;
|
||||||
|
|
||||||
// DPRINT1("Deleting port %x\n", Port);
|
// DPRINT1("Deleting port %x\n", Port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
268
reactos/ntoskrnl/ps/debug.c
Normal file
268
reactos/ntoskrnl/ps/debug.c
Normal 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 */
|
|
@ -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)
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue