V86 mode fixes

Preparation for paging support

svn path=/trunk/; revision=1728
This commit is contained in:
David Welch 2001-03-25 03:34:30 +00:00
parent 9b3c1a2a1d
commit 51f1b4ac50
37 changed files with 842 additions and 350 deletions

View file

@ -2,4 +2,5 @@ file ntoskrnl/ntoskrnl.nostrip.exe
#add-symbol-file lib/ntdll/ntdll.dll 0x77f61000 #add-symbol-file lib/ntdll/ntdll.dll 0x77f61000
#add-symbol-file apps/exp/exp.exe 0x401000 #add-symbol-file apps/exp/exp.exe 0x401000
#add-symbol-file subsys/csrss/csrss.exe 0x401000 #add-symbol-file subsys/csrss/csrss.exe 0x401000
add-symbol-file subsys/smss/smss.exe 0x401000
break exp.c:254 break exp.c:254

View file

@ -96,10 +96,14 @@ VideoMode Mode3 = {
void InitVGAMode() void InitVGAMode()
{ {
int i; int i;
VIDEO_X86_BIOS_ARGUMENTS vxba;
VP_STATUS vps;
// FIXME: Use Vidport to map the memory properly // FIXME: Use Vidport to map the memory properly
vidmem = (char *)(0xd0000000 + 0xa0000); vidmem = (char *)(0xd0000000 + 0xa0000);
setMode(Mode12); vxba.Eax = 0x0012;
vps = VideoPortInt10(NULL, &vxba);
// setMode(Mode12);
WRITE_PORT_USHORT((PUSHORT)0x3C4, 0x0f02); // index=MASK MAP, write to all bitplanes WRITE_PORT_USHORT((PUSHORT)0x3C4, 0x0f02); // index=MASK MAP, write to all bitplanes
i = vidmem[0]; i = vidmem[0];

View file

@ -1,4 +1,4 @@
/* $Id: vidport.c,v 1.17 2001/03/20 15:09:02 ekohl Exp $ /* $Id: vidport.c,v 1.18 2001/03/25 02:34:29 dwelch Exp $
* *
* VideoPort driver * VideoPort driver
* Written by Rex Jolliff * Written by Rex Jolliff
@ -19,6 +19,9 @@ static VOID STDCALL VidStartIo(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
static NTSTATUS STDCALL VidDispatchOpenClose(IN PDEVICE_OBJECT pDO, IN PIRP Irp); static NTSTATUS STDCALL VidDispatchOpenClose(IN PDEVICE_OBJECT pDO, IN PIRP Irp);
static NTSTATUS STDCALL VidDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); static NTSTATUS STDCALL VidDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
static HANDLE CsrssHandle;
static struct _EPROCESS* Csrss;
// ------------------------------------------------------- Public Interface // ------------------------------------------------------- Public Interface
// DriverEntry // DriverEntry
@ -181,6 +184,7 @@ VideoPortInitialize(IN PVOID Context1,
ULONG DeviceNumber = 0; ULONG DeviceNumber = 0;
UNICODE_STRING DeviceName; UNICODE_STRING DeviceName;
UNICODE_STRING SymlinkName; UNICODE_STRING SymlinkName;
CLIENT_ID Cid;
/* Build Dispatch table from passed data */ /* Build Dispatch table from passed data */
MPDriverObject->DriverStartIo = (PDRIVER_STARTIO) HwInitializationData->HwStartIO; MPDriverObject->DriverStartIo = (PDRIVER_STARTIO) HwInitializationData->HwStartIO;
@ -285,6 +289,32 @@ VideoPortInitialize(IN PVOID Context1,
} }
while (Again); while (Again);
/* Find a process handle for csrss */
Cid.UniqueProcess = 3;
Cid.UniqueThread = 0;
Status = ZwOpenProcess(&CsrssHandle,
PROCESS_ALL_ACCESS,
NULL,
&Cid);
if (!NT_SUCCESS(Status))
{
DbgPrint("VIDPORT: Failed to open csrss\n");
Csrss = NULL;
}
else
{
Status = ObReferenceObjectByHandle(CsrssHandle,
PROCESS_ALL_ACCESS,
NULL,
KernelMode,
(PVOID*)&Csrss,
NULL);
if (!NT_SUCCESS(Status))
{
DbgPrint("VIDPORT: Failed to reference csrss handle\n");
Csrss = NULL;
}
}
/* FIXME: initialize timer routine for MP Driver */ /* FIXME: initialize timer routine for MP Driver */
if (HwInitializationData->HwTimer != NULL) if (HwInitializationData->HwTimer != NULL)
@ -317,8 +347,7 @@ VideoPortInt10(IN PVOID HwDeviceExtension,
KV86M_REGISTERS Regs; KV86M_REGISTERS Regs;
NTSTATUS Status; NTSTATUS Status;
/* FIXME: Attach to csrss */ KeAttachProcess(Csrss);
/* FIXME: Check address space is set up */
memset(&Regs, 0, sizeof(Regs)); memset(&Regs, 0, sizeof(Regs));
Regs.Eax = BiosArguments->Eax; Regs.Eax = BiosArguments->Eax;
@ -329,6 +358,9 @@ VideoPortInt10(IN PVOID HwDeviceExtension,
Regs.Edi = BiosArguments->Edi; Regs.Edi = BiosArguments->Edi;
Regs.Ebp = BiosArguments->Ebp; Regs.Ebp = BiosArguments->Ebp;
Status = Ke386CallBios(0x10, &Regs); Status = Ke386CallBios(0x10, &Regs);
KeDetachProcess();
return(Status); return(Status);
} }

View file

@ -1,5 +1,5 @@
/* $Id: zw.h,v 1.43 2001/03/18 19:35:11 dwelch Exp $ /* $Id: zw.h,v 1.44 2001/03/25 02:34:27 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -5246,9 +5246,8 @@ NtSystemDebugControl(DEBUG_CONTROL_CODE ControlCode,
NTSTATUS NTSTATUS
STDCALL STDCALL
NtVdmControl ( NtVdmControl (ULONG ControlCode, PVOID ControlData);
VOID
);
/* --- WIN32 --- */ /* --- WIN32 --- */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: view.c,v 1.21 2001/03/16 18:11:21 dwelch Exp $ /* $Id: view.c,v 1.22 2001/03/25 02:34:27 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -167,7 +167,8 @@ CcRequestCacheSegment(PBCB Bcb,
&current->BaseAddress, &current->BaseAddress,
Bcb->CacheSegmentSize, Bcb->CacheSegmentSize,
PAGE_READWRITE, PAGE_READWRITE,
(PMEMORY_AREA*)&current->MemoryArea); (PMEMORY_AREA*)&current->MemoryArea,
FALSE);
current->Valid = FALSE; current->Valid = FALSE;
current->FileOffset = FileOffset; current->FileOffset = FileOffset;
current->Bcb = Bcb; current->Bcb = Bcb;

View file

@ -30,6 +30,51 @@
struct _KTHREAD; struct _KTHREAD;
#define KTRAP_FRAME_DEBUGEBP (0x0)
#define KTRAP_FRAME_DEBUGEIP (0x4)
#define KTRAP_FRAME_DEBUGARGMARK (0x8)
#define KTRAP_FRAME_DEBUGPOINTER (0xC)
#define KTRAP_FRAME_TEMPCS (0x10)
#define KTRAP_FRAME_TEMPEIP (0x14)
#define KTRAP_FRAME_DR0 (0x18)
#define KTRAP_FRAME_DR1 (0x1C)
#define KTRAP_FRAME_DR2 (0x20)
#define KTRAP_FRAME_DR3 (0x24)
#define KTRAP_FRAME_DR6 (0x28)
#define KTRAP_FRAME_DR7 (0x2C)
#define KTRAP_FRAME_GS (0x30)
#define KTRAP_FRAME_RESERVED1 (0x32)
#define KTRAP_FRAME_ES (0x34)
#define KTRAP_FRAME_RESERVED2 (0x36)
#define KTRAP_FRAME_DS (0x38)
#define KTRAP_FRAME_RESERVED3 (0x3A)
#define KTRAP_FRAME_EDX (0x3C)
#define KTRAP_FRAME_ECX (0x40)
#define KTRAP_FRAME_EAX (0x44)
#define KTRAP_FRAME_PREVIOUS_MODE (0x48)
#define KTRAP_FRAME_EXCEPTION_LIST (0x4C)
#define KTRAP_FRAME_FS (0x50)
#define KTRAP_FRAME_RESERVED4 (0x52)
#define KTRAP_FRAME_EDI (0x54)
#define KTRAP_FRAME_ESI (0x58)
#define KTRAP_FRAME_EBX (0x5C)
#define KTRAP_FRAME_EBP (0x60)
#define KTRAP_FRAME_ERROR_CODE (0x64)
#define KTRAP_FRAME_EIP (0x68)
#define KTRAP_FRAME_CS (0x6C)
#define KTRAP_FRAME_EFLAGS (0x70)
#define KTRAP_FRAME_ESP (0x74)
#define KTRAP_FRAME_SS (0x78)
#define KTRAP_FRAME_RESERVED5 (0x7A)
#define KTRAP_FRAME_V86_ES (0x7C)
#define KTRAP_FRAME_RESERVED6 (0x7E)
#define KTRAP_FRAME_V86_DS (0x80)
#define KTRAP_FRAME_RESERVED7 (0x82)
#define KTRAP_FRAME_V86_FS (0x84)
#define KTRAP_FRAME_RESERVED8 (0x86)
#define KTRAP_FRAME_V86_GS (0x88)
#define KTRAP_FRAME_RESERVED9 (0x8A)
typedef struct _KTRAP_FRAME typedef struct _KTRAP_FRAME
{ {
PVOID DebugEbp; PVOID DebugEbp;

View file

@ -136,6 +136,15 @@ typedef struct
} Data; } Data;
} MEMORY_AREA, *PMEMORY_AREA; } MEMORY_AREA, *PMEMORY_AREA;
typedef struct _KCIRCULAR_QUEUE
{
ULONG First;
ULONG Last;
ULONG CurrentSize;
ULONG MaximumSize;
PVOID* Mem;
} KCIRCULAR_QUEUE, *PKCIRCULAR_QUEUE;
typedef struct _MADDRESS_SPACE typedef struct _MADDRESS_SPACE
{ {
LIST_ENTRY MAreaListHead; LIST_ENTRY MAreaListHead;
@ -143,11 +152,7 @@ typedef struct _MADDRESS_SPACE
ULONG LowestAddress; ULONG LowestAddress;
struct _EPROCESS* Process; struct _EPROCESS* Process;
PMEMORY_AREA WorkingSetArea; PMEMORY_AREA WorkingSetArea;
ULONG WorkingSetSize; KCIRCULAR_QUEUE WSQueue;
ULONG WorkingSetLruFirst;
ULONG WorkingSetLruLast;
ULONG WorkingSetPagesAllocated;
ULONG WorkingSetMaximumLength;
PUSHORT PageTableRefCountTable; PUSHORT PageTableRefCountTable;
ULONG PageTableRefCountTableSize; ULONG PageTableRefCountTableSize;
} MADDRESS_SPACE, *PMADDRESS_SPACE; } MADDRESS_SPACE, *PMADDRESS_SPACE;
@ -169,7 +174,8 @@ NTSTATUS MmCreateMemoryArea(struct _EPROCESS* Process,
PVOID* BaseAddress, PVOID* BaseAddress,
ULONG Length, ULONG Length,
ULONG Attributes, ULONG Attributes,
MEMORY_AREA** Result); MEMORY_AREA** Result,
BOOL FixedAddress);
MEMORY_AREA* MmOpenMemoryAreaByAddress(PMADDRESS_SPACE AddressSpace, MEMORY_AREA* MmOpenMemoryAreaByAddress(PMADDRESS_SPACE AddressSpace,
PVOID Address); PVOID Address);
NTSTATUS MmInitMemoryAreas(VOID); NTSTATUS MmInitMemoryAreas(VOID);
@ -208,9 +214,15 @@ NTSTATUS MmCopyMmInfo(struct _EPROCESS* Src,
struct _EPROCESS* Dest); struct _EPROCESS* Dest);
NTSTATUS MmReleaseMmInfo(struct _EPROCESS* Process); NTSTATUS MmReleaseMmInfo(struct _EPROCESS* Process);
NTSTATUS Mmi386ReleaseMmInfo(struct _EPROCESS* Process); NTSTATUS Mmi386ReleaseMmInfo(struct _EPROCESS* Process);
VOID MmDeleteVirtualMapping(struct _EPROCESS* Process, VOID
MmDeleteVirtualMapping(struct _EPROCESS* Process,
PVOID Address, PVOID Address,
BOOL FreePage); BOOL FreePage,
BOOL* WasDirty,
ULONG* PhysicalPage);
#define MM_PAGE_CLEAN (0)
#define MM_PAGE_DIRTY (1)
VOID MmBuildMdlFromPages(PMDL Mdl, PULONG Pages); VOID MmBuildMdlFromPages(PMDL Mdl, PULONG Pages);
PVOID MmGetMdlPageAddress(PMDL Mdl, PVOID Offset); PVOID MmGetMdlPageAddress(PMDL Mdl, PVOID Offset);
@ -433,5 +445,13 @@ typedef struct _MM_IMAGE_SECTION_OBJECT
VOID VOID
MmFreeVirtualMemory(struct _EPROCESS* Process, PMEMORY_AREA MemoryArea); MmFreeVirtualMemory(struct _EPROCESS* Process, PMEMORY_AREA MemoryArea);
NTSTATUS
MiCopyFromUserPage(ULONG DestPhysPage, PVOID SourceAddress);
NTSTATUS
MiZeroPage(ULONG PhysPage);
BOOLEAN
MmIsAccessedAndResetAccessPage(struct _EPROCESS* Process, PVOID Address);
SWAPENTRY
MmGetSavedSwapEntryPage(PVOID PhysicalAddress);
#endif #endif

View file

@ -27,63 +27,20 @@
#ifndef __NTOSKRNL_INCLUDE_INTERNAL_TRAP_H #ifndef __NTOSKRNL_INCLUDE_INTERNAL_TRAP_H
#define __NTOSKRNL_INCLUDE_INTERNAL_TRAP_H #define __NTOSKRNL_INCLUDE_INTERNAL_TRAP_H
#define TF_EDI (0x0) #define TF_SAVED_ORIG_STACK (0x8C)
#define TF_ESI (0x4) #define TF_REGS (0x90)
#define TF_EBP (0x8) #define TF_ORIG_EBP (0x94)
#define TF_ESP (0xC)
#define TF_EBX (0x10)
#define TF_EDX (0x14)
#define TF_ECX (0x18)
#define TF_EAX (0x1C)
#define TF_TYPE (0x20)
#define TF_DS (0x24)
#define TF_ES (0x28)
#define TF_FS (0x2C)
#define TF_GS (0x30)
#define TF_ERROR_CODE (0x34)
#define TF_EIP (0x38)
#define TF_CS (0x3C)
#define TF_EFLAGS (0x40)
#define TF_ESP0 (0x44)
#define TF_SS0 (0x48)
#define TF_V86_ES (0x4C)
#define TF_V86_DS (0x50)
#define TF_V86_FS (0x54)
#define TF_V86_GS (0x58)
#define TF_REGS (0x5C)
#define TF_ORIG_EBP (0x60)
#ifndef __ASM__ #ifndef __ASM__
struct trap_frame #include <internal/ke.h>
{
ULONG edi;
ULONG esi;
ULONG ebp;
ULONG esp;
ULONG ebx;
ULONG edx;
ULONG ecx;
ULONG eax;
ULONG type;
ULONG ds;
ULONG es;
ULONG fs;
ULONG gs;
ULONG error_code;
ULONG eip;
ULONG cs;
ULONG eflags;
ULONG esp0;
ULONG ss0;
/* typedef struct _KV86M_TRAP_FRAME
* These members are only valid in v86 mode {
*/ KTRAP_FRAME Tf;
ULONG v86_es;
ULONG v86_ds; ULONG SavedInitialStack;
ULONG v86_fs;
ULONG v86_gs;
/* /*
* These are put on the top of the stack by the routine that entered * These are put on the top of the stack by the routine that entered
@ -91,10 +48,10 @@ struct trap_frame
*/ */
struct _KV86M_REGISTERS* regs; struct _KV86M_REGISTERS* regs;
ULONG orig_ebp; ULONG orig_ebp;
}; } KV86M_TRAP_FRAME, *PKV86M_TRAP_FRAME;
ULONG ULONG
KeV86Exception(struct trap_frame* tf, ULONG address); KeV86Exception(ULONG ExceptionNr, PKTRAP_FRAME Tf, ULONG address);
#endif /* not __ASM__ */ #endif /* not __ASM__ */

View file

@ -202,12 +202,10 @@ KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr)
/* /*
* If this was a V86 mode exception then handle it specially * If this was a V86 mode exception then handle it specially
*/ */
#if 0 if (Tf->Eflags & (1 << 17))
if (tf->eflags & (1 << 17))
{ {
return(KeV86Exception(tf, cr2)); return(KeV86Exception(ExceptionNr, Tf, cr2));
} }
#endif
/* /*
* Check for stack underflow * Check for stack underflow

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: trap.s,v 1.8 2001/03/22 11:14:22 dwelch Exp $ /* $Id: trap.s,v 1.9 2001/03/25 02:34:28 dwelch Exp $
* *
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/i386/trap.s * FILE: ntoskrnl/ke/i386/trap.s
@ -80,7 +80,7 @@ _KiTrapProlog:
pushl %fs pushl %fs
/* /*
* Check that the PCR exits, very early in the boot process it may * Check that the PCR exists, very early in the boot process it may
* not * not
*/ */
cmpl $0, %ss:_KiPcrInitDone cmpl $0, %ss:_KiPcrInitDone

View file

@ -43,48 +43,48 @@
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
ULONG ULONG
KeV86GPF(struct trap_frame* tf) KeV86GPF(PKV86M_TRAP_FRAME VTf, PKTRAP_FRAME Tf)
{ {
PUCHAR ip; PUCHAR ip;
PUSHORT sp; PUSHORT sp;
ip = (PUCHAR)((tf->cs & 0xFFFF) * 16 + (tf->eip & 0xFFFF)); ip = (PUCHAR)((Tf->Cs & 0xFFFF) * 16 + (Tf->Eip & 0xFFFF));
sp = (PUSHORT)((tf->ss0 & 0xFFFF) * 16 + (tf->esp0 & 0xFFFF)); sp = (PUSHORT)((Tf->Ss & 0xFFFF) * 16 + (Tf->Esp & 0xFFFF));
DPRINT("KeV86GPF handling %x at %x:%x ss:sp %x:%x\n", DPRINT("KeV86GPF handling %x at %x:%x ss:sp %x:%x\n",
ip[0], tf->cs, tf->eip, tf->ss0, tf->esp0); ip[0], Tf->Cs, Tf->Eip, Tf->Ss, Tf->Esp);
switch (ip[0]) switch (ip[0])
{ {
/* sti */ /* sti */
case 0xFB: case 0xFB:
if (tf->regs->Flags & KV86M_EMULATE_CLI_STI) if (VTf->regs->Flags & KV86M_EMULATE_CLI_STI)
{ {
tf->eip++; Tf->Eip++;
tf->regs->Vif = 1; VTf->regs->Vif = 1;
return(0); return(0);
} }
break; break;
/* cli */ /* cli */
case 0xFA: case 0xFA:
if (tf->regs->Flags & KV86M_EMULATE_CLI_STI) if (VTf->regs->Flags & KV86M_EMULATE_CLI_STI)
{ {
tf->eip++; Tf->Eip++;
tf->regs->Vif = 0; VTf->regs->Vif = 0;
return(0); return(0);
} }
break; break;
/* pushf */ /* pushf */
case 0x9C: case 0x9C:
if (tf->regs->Flags & KV86M_EMULATE_CLI_STI) if (VTf->regs->Flags & KV86M_EMULATE_CLI_STI)
{ {
tf->eip++; Tf->Eip++;
tf->esp0 = tf->esp0 - 2; Tf->Esp = Tf->Esp - 2;
sp = sp - 1; sp = sp - 1;
sp[0] = tf->eflags & 0xFFFF; sp[0] = Tf->Eflags & 0xFFFF;
if (tf->regs->Vif) if (VTf->regs->Vif)
{ {
sp[0] = sp[0] | INTERRUPT_FLAG; sp[0] = sp[0] | INTERRUPT_FLAG;
} }
@ -94,140 +94,140 @@ KeV86GPF(struct trap_frame* tf)
/* popf */ /* popf */
case 0x9D: case 0x9D:
if (tf->regs->Flags & KV86M_EMULATE_CLI_STI) if (VTf->regs->Flags & KV86M_EMULATE_CLI_STI)
{ {
tf->eip++; Tf->Eip++;
tf->eflags = tf->eflags & (~0xFFFF); Tf->Eflags = Tf->Eflags & (~0xFFFF);
tf->eflags = tf->eflags | sp[0]; Tf->Eflags = Tf->Eflags | sp[0];
if (tf->eflags & INTERRUPT_FLAG) if (Tf->Eflags & INTERRUPT_FLAG)
{ {
tf->regs->Vif = 1; VTf->regs->Vif = 1;
} }
else else
{ {
tf->regs->Vif = 0; VTf->regs->Vif = 0;
} }
tf->eflags = tf->eflags & (~INTERRUPT_FLAG); Tf->Eflags = Tf->Eflags & (~INTERRUPT_FLAG);
tf->esp0 = tf->esp0 + 2; Tf->Esp = Tf->Esp + 2;
return(0); return(0);
} }
break; break;
/* iret */ /* iret */
case 0xCF: case 0xCF:
if (tf->regs->Flags & KV86M_EMULATE_CLI_STI) if (VTf->regs->Flags & KV86M_EMULATE_CLI_STI)
{ {
tf->eip = sp[0]; Tf->Eip = sp[0];
tf->cs = sp[1]; Tf->Cs = sp[1];
tf->eflags = tf->eflags & (~0xFFFF); Tf->Eflags = Tf->Eflags & (~0xFFFF);
tf->eflags = tf->eflags | sp[2]; Tf->Eflags = Tf->Eflags | sp[2];
if (tf->eflags & INTERRUPT_FLAG) if (Tf->Eflags & INTERRUPT_FLAG)
{ {
tf->regs->Vif = 1; VTf->regs->Vif = 1;
} }
else else
{ {
tf->regs->Vif = 0; VTf->regs->Vif = 0;
} }
tf->eflags = tf->eflags & (~INTERRUPT_FLAG); Tf->Eflags = Tf->Eflags & (~INTERRUPT_FLAG);
tf->esp0 = tf->esp0 + 6; Tf->Esp = Tf->Esp + 6;
return(0); return(0);
} }
break; break;
/* out imm8, al */ /* out imm8, al */
case 0xE6: case 0xE6:
if (tf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS) if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{ {
WRITE_PORT_UCHAR((PUCHAR)(ULONG)ip[1], WRITE_PORT_UCHAR((PUCHAR)(ULONG)ip[1],
tf->eax & 0xFF); Tf->Eax & 0xFF);
tf->eip = tf->eip + 2; Tf->Eip = Tf->Eip + 2;
return(0); return(0);
} }
break; break;
/* out imm8, ax */ /* out imm8, ax */
case 0xE7: case 0xE7:
if (tf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS) if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{ {
WRITE_PORT_USHORT((PUSHORT)(ULONG)ip[1], tf->eax & 0xFFFF); WRITE_PORT_USHORT((PUSHORT)(ULONG)ip[1], Tf->Eax & 0xFFFF);
tf->eip = tf->eip + 2; Tf->Eip = Tf->Eip + 2;
return(0); return(0);
} }
break; break;
/* out dx, al */ /* out dx, al */
case 0xEE: case 0xEE:
if (tf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS) if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{ {
WRITE_PORT_UCHAR((PUCHAR)(tf->edx & 0xFFFF), tf->eax & 0xFF); WRITE_PORT_UCHAR((PUCHAR)(Tf->Edx & 0xFFFF), Tf->Eax & 0xFF);
tf->eip = tf->eip + 1; Tf->Eip = Tf->Eip + 1;
return(0); return(0);
} }
break; break;
/* out dx, ax */ /* out dx, ax */
case 0xEF: case 0xEF:
if (tf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS) if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{ {
WRITE_PORT_USHORT((PUSHORT)(tf->edx & 0xFFFF), tf->eax & 0xFFFF); WRITE_PORT_USHORT((PUSHORT)(Tf->Edx & 0xFFFF), Tf->Eax & 0xFFFF);
tf->eip = tf->eip + 1; Tf->Eip = Tf->Eip + 1;
return(0); return(0);
} }
break; break;
/* in al, imm8 */ /* in al, imm8 */
case 0xE4: case 0xE4:
if (tf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS) if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{ {
UCHAR v; UCHAR v;
v = READ_PORT_UCHAR((PUCHAR)(ULONG)ip[1]); v = READ_PORT_UCHAR((PUCHAR)(ULONG)ip[1]);
tf->eax = tf->eax & (~0xFF); Tf->Eax = Tf->Eax & (~0xFF);
tf->eax = tf->eax | v; Tf->Eax = Tf->Eax | v;
tf->eip = tf->eip + 2; Tf->Eip = Tf->Eip + 2;
return(0); return(0);
} }
break; break;
/* in ax, imm8 */ /* in ax, imm8 */
case 0xE5: case 0xE5:
if (tf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS) if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{ {
USHORT v; USHORT v;
v = READ_PORT_USHORT((PUSHORT)(ULONG)ip[1]); v = READ_PORT_USHORT((PUSHORT)(ULONG)ip[1]);
tf->eax = tf->eax & (~0xFFFF); Tf->Eax = Tf->Eax & (~0xFFFF);
tf->eax = tf->eax | v; Tf->Eax = Tf->Eax | v;
tf->eip = tf->eip + 2; Tf->Eip = Tf->Eip + 2;
return(0); return(0);
} }
break; break;
/* in al, dx */ /* in al, dx */
case 0xEC: case 0xEC:
if (tf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS) if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{ {
UCHAR v; UCHAR v;
v = READ_PORT_UCHAR((PUCHAR)(tf->edx & 0xFFFF)); v = READ_PORT_UCHAR((PUCHAR)(Tf->Edx & 0xFFFF));
tf->eax = tf->eax & (~0xFF); Tf->Eax = Tf->Eax & (~0xFF);
tf->eax = tf->eax | v; Tf->Eax = Tf->Eax | v;
tf->eip = tf->eip + 1; Tf->Eip = Tf->Eip + 1;
return(0); return(0);
} }
break; break;
/* in ax, dx */ /* in ax, dx */
case 0xED: case 0xED:
if (tf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS) if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{ {
USHORT v; USHORT v;
v = READ_PORT_USHORT((PUSHORT)(tf->edx & 0xFFFF)); v = READ_PORT_USHORT((PUSHORT)(Tf->Edx & 0xFFFF));
tf->eax = tf->eax & (~0xFFFF); Tf->Eax = Tf->Eax & (~0xFFFF);
tf->eax = tf->eax | v; Tf->Eax = Tf->Eax | v;
tf->eip = tf->eip + 1; Tf->Eip = Tf->Eip + 1;
return(0); return(0);
} }
break; break;
@ -241,20 +241,20 @@ KeV86GPF(struct trap_frame* tf)
inum = ip[1]; inum = ip[1];
entry = ((unsigned int *)0)[inum]; entry = ((unsigned int *)0)[inum];
tf->esp0 = tf->esp0 - 6; Tf->Esp = Tf->Esp - 6;
sp = sp - 3; sp = sp - 3;
sp[0] = (tf->eip & 0xFFFF) + 2; sp[0] = (Tf->Eip & 0xFFFF) + 2;
sp[1] = tf->cs & 0xFFFF; sp[1] = Tf->Cs & 0xFFFF;
sp[2] = tf->eflags & 0xFFFF; sp[2] = Tf->Eflags & 0xFFFF;
if (tf->regs->Vif == 1) if (VTf->regs->Vif == 1)
{ {
sp[2] = sp[2] | INTERRUPT_FLAG; sp[2] = sp[2] | INTERRUPT_FLAG;
} }
DPRINT("sp[0] %x sp[1] %x sp[2] %x\n", sp[0], sp[1], sp[2]); DPRINT("sp[0] %x sp[1] %x sp[2] %x\n", sp[0], sp[1], sp[2]);
tf->eip = entry & 0xFFFF; Tf->Eip = entry & 0xFFFF;
tf->cs = entry >> 16; Tf->Cs = entry >> 16;
tf->eflags = tf->eflags & (~TRAP_FLAG); Tf->Eflags = Tf->Eflags & (~TRAP_FLAG);
return(0); return(0);
} }
@ -265,103 +265,110 @@ KeV86GPF(struct trap_frame* tf)
} }
DPRINT("V86GPF unhandled\n"); DPRINT("V86GPF unhandled\n");
*tf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION; *VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1); return(1);
} }
ULONG ULONG
KeV86Exception(struct trap_frame* tf, ULONG address) KeV86Exception(ULONG ExceptionNr, PKTRAP_FRAME Tf, ULONG address)
{ {
PUCHAR Ip; PUCHAR Ip;
PKV86M_TRAP_FRAME VTf;
VTf = (PKV86M_TRAP_FRAME)Tf;
/* /*
* Check if we have reached the recovery instruction * Check if we have reached the recovery instruction
*/ */
Ip = (PUCHAR)((tf->cs & 0xFFFF) * 16 + (tf->eip & 0xFFFF)); Ip = (PUCHAR)((Tf->Cs & 0xFFFF) * 16 + (Tf->Eip & 0xFFFF));
DbgPrint("tf->type %d Ip[0] %x Ip[1] %x Ip[2] %x Ip[3] %x tf->cs %x " if (ExceptionNr != 14)
"tf->eip %x\n", tf->type, Ip[0], Ip[1], Ip[2], Ip[3], tf->cs,
tf->eip);
if (tf->type == 6 &&
memcmp(Ip, tf->regs->RecoveryInstruction, 4) == 0 &&
(tf->cs * 16 + tf->eip) == tf->regs->RecoveryAddress)
{ {
*tf->regs->PStatus = STATUS_SUCCESS; DbgPrint("ExceptionNr %d Ip[0] %x Ip[1] %x Ip[2] %x Ip[3] %x Tf->Cs %x "
"Tf->Eip %x\n", ExceptionNr, Ip[0], Ip[1], Ip[2], Ip[3], Tf->Cs,
Tf->Eip);
DbgPrint("VTf %x VTf->regs %x\n", VTf, VTf->regs);
}
if (ExceptionNr == 6 &&
memcmp(Ip, VTf->regs->RecoveryInstruction, 4) == 0 &&
(Tf->Cs * 16 + Tf->Eip) == VTf->regs->RecoveryAddress)
{
*VTf->regs->PStatus = STATUS_SUCCESS;
return(1); return(1);
} }
/* /*
* Handle the exceptions * Handle the exceptions
*/ */
switch (tf->type) switch (ExceptionNr)
{ {
/* Divide error */ /* Divide error */
case 0: case 0:
*tf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION; *VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1); return(1);
/* Single step */ /* Single step */
case 1: case 1:
*tf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION; *VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1); return(1);
/* NMI */ /* NMI */
case 2: case 2:
*tf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION; *VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1); return(1);
/* Breakpoint */ /* Breakpoint */
case 3: case 3:
*tf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION; *VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1); return(1);
/* Overflow */ /* Overflow */
case 4: case 4:
*tf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION; *VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1); return(1);
/* Array bounds check */ /* Array bounds check */
case 5: case 5:
*tf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION; *VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1); return(1);
/* Invalid opcode */ /* Invalid opcode */
case 6: case 6:
*tf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION; *VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1); return(1);
/* Device not available */ /* Device not available */
case 7: case 7:
*tf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION; *VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1); return(1);
/* Double fault */ /* Double fault */
case 8: case 8:
*tf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION; *VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1); return(1);
/* Intel reserved */ /* Intel reserved */
case 9: case 9:
*tf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION; *VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1); return(1);
/* Invalid TSS */ /* Invalid TSS */
case 10: case 10:
*tf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION; *VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1); return(1);
/* Segment not present */ /* Segment not present */
case 11: case 11:
*tf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;; *VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;;
return(1); return(1);
/* Stack fault */ /* Stack fault */
case 12: case 12:
*tf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION; *VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1); return(1);
/* General protection fault */ /* General protection fault */
case 13: case 13:
return(KeV86GPF(tf)); return(KeV86GPF(VTf, Tf));
/* Page fault */ /* Page fault */
case 14: case 14:
@ -369,14 +376,14 @@ KeV86Exception(struct trap_frame* tf, ULONG address)
NTSTATUS Status; NTSTATUS Status;
Status = MmPageFault(USER_CS, Status = MmPageFault(USER_CS,
&tf->eip, &Tf->Eip,
NULL, NULL,
address, address,
tf->error_code); Tf->ErrorCode);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("V86Exception, halting due to page fault\n"); DPRINT("V86Exception, halting due to page fault\n");
*tf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION; *VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1); return(1);
} }
return(0); return(0);
@ -385,16 +392,16 @@ KeV86Exception(struct trap_frame* tf, ULONG address)
/* Intel reserved */ /* Intel reserved */
case 15: case 15:
case 16: case 16:
*tf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION; *VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1); return(1);
/* Alignment check */ /* Alignment check */
case 17: case 17:
*tf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION; *VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1); return(1);
default: default:
*tf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION; *VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1); return(1);
} }
} }

View file

@ -27,6 +27,7 @@
#include <internal/v86m.h> #include <internal/v86m.h>
#include <ddk/i386/tss.h> #include <ddk/i386/tss.h>
#include <internal/trap.h> #include <internal/trap.h>
#include <internal/ps.h>
.globl _Ki386RetToV86Mode .globl _Ki386RetToV86Mode
.globl _KiV86Complete .globl _KiV86Complete
@ -66,6 +67,11 @@ _Ki386RetToV86Mode:
*/ */
pushl %ebx pushl %ebx
/*
* Since we are going to fiddle with the stack pointer this must be
* a critical section for this processor
*/
/* /*
* The stack used for handling exceptions from v86 mode in this thread * The stack used for handling exceptions from v86 mode in this thread
* will be the current stack adjusted so we don't overwrite the * will be the current stack adjusted so we don't overwrite the
@ -74,6 +80,18 @@ _Ki386RetToV86Mode:
movl $_KiTss, %esi movl $_KiTss, %esi
movl %esp, KTSS_ESP0(%esi) movl %esp, KTSS_ESP0(%esi)
/*
* We also need to set the stack in the kthread structure
*/
movl _CurrentThread, %esi
movl KTHREAD_INITIAL_STACK(%esi), %edi
movl %esp, KTHREAD_INITIAL_STACK(%esi)
/*
* Save the old initial stack
*/
pushl %edi
/* /*
* Create the stack frame for an iret to v86 mode * Create the stack frame for an iret to v86 mode
*/ */
@ -109,26 +127,39 @@ _Ki386RetToV86Mode:
* exception on the stack. * exception on the stack.
*/ */
_KiV86Complete: _KiV86Complete:
addl $4, %esp /* Ignore pointer to trap frame */
/* Restore the original ebp */ /* Restore the original ebp */
movl TF_ORIG_EBP(%esp), %ebp movl TF_ORIG_EBP(%esp), %ebp
/* Get a pointer to the OUT_REGS structure */ /* Get a pointer to the OUT_REGS structure */
movl 12(%ebp), %ebx movl 12(%ebp), %ebx
/* Skip debug information and unsaved registers */
addl $0x30, %esp
/* Ignore 32-bit segment registers */
addl $12, %esp
/* Save the vm86 registers into the OUT_REGS structure */ /* Save the vm86 registers into the OUT_REGS structure */
popl KV86M_REGISTERS_EDI(%ebx)
popl KV86M_REGISTERS_ESI(%ebx)
popl KV86M_REGISTERS_EBP(%ebx)
addl $4, %esp /* Ignore ring0 esp */
popl KV86M_REGISTERS_EBX(%ebx)
popl KV86M_REGISTERS_EDX(%ebx) popl KV86M_REGISTERS_EDX(%ebx)
popl KV86M_REGISTERS_ECX(%ebx) popl KV86M_REGISTERS_ECX(%ebx)
popl KV86M_REGISTERS_EAX(%ebx) popl KV86M_REGISTERS_EAX(%ebx)
addl $4, %esp /* Ignore trap code */
addl $16, %esp /* Ignore 32-bit segment registers */ /* Ignore the previous mode */
addl $4, %esp /* Ignore error code */ addl $4, %esp
/* Ignore old exception handler list */
addl $4, %esp
/* Ignore the 32-bit fs register */
addl $4, %esp
popl KV86M_REGISTERS_EDI(%ebx)
popl KV86M_REGISTERS_ESI(%ebx)
popl KV86M_REGISTERS_EBX(%ebx)
popl KV86M_REGISTERS_EBP(%ebx)
/* Ignore error code */
addl $4, %esp
popl KV86M_REGISTERS_EIP(%ebx) popl KV86M_REGISTERS_EIP(%ebx)
popl KV86M_REGISTERS_CS(%ebx) popl KV86M_REGISTERS_CS(%ebx)
@ -140,6 +171,29 @@ _KiV86Complete:
popl KV86M_REGISTERS_FS(%ebx) popl KV86M_REGISTERS_FS(%ebx)
popl KV86M_REGISTERS_GS(%ebx) popl KV86M_REGISTERS_GS(%ebx)
/*
* We are going to fiddle with the stack so this must be a critical
* section for this process
*/
cli
/*
* Restore the initial stack
*/
popl %eax
movl $_KiTss, %esi
movl %eax, KTSS_ESP0(%esi)
/*
* We also need to set the stack in the kthread structure
*/
movl $_CurrentThread, %esi
movl KTHREAD_INITIAL_STACK(%esi), %edi
movl %eax, KTHREAD_INITIAL_STACK(%esi)
/* Exit the critical section */
sti
/* Ignore IN_REGS pointer */ /* Ignore IN_REGS pointer */
addl $4, %esp addl $4, %esp

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: main.c,v 1.82 2001/03/18 21:28:30 dwelch Exp $ /* $Id: main.c,v 1.83 2001/03/25 02:34:28 dwelch Exp $
* *
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/main.c * FILE: ntoskrnl/ke/main.c
@ -41,6 +41,7 @@
#include <napi/shared_data.h> #include <napi/shared_data.h>
#include <internal/v86m.h> #include <internal/v86m.h>
#include <internal/kd.h> #include <internal/kd.h>
#include <internal/trap.h>
#define NDEBUG #define NDEBUG
#include <internal/debug.h> #include <internal/debug.h>
@ -515,6 +516,9 @@ _main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock)
assert(FIELD_OFFSET(ETHREAD, ThreadsProcess) == ETHREAD_THREADS_PROCESS); assert(FIELD_OFFSET(ETHREAD, ThreadsProcess) == ETHREAD_THREADS_PROCESS);
assert(FIELD_OFFSET(KPROCESS, PageTableDirectory) == assert(FIELD_OFFSET(KPROCESS, PageTableDirectory) ==
KPROCESS_PAGE_TABLE_DIRECTORY); KPROCESS_PAGE_TABLE_DIRECTORY);
assert(FIELD_OFFSET(KTRAP_FRAME, Reserved9) == KTRAP_FRAME_RESERVED9);
assert(FIELD_OFFSET(KV86M_TRAP_FRAME, regs) == TF_REGS);
assert(FIELD_OFFSET(KV86M_TRAP_FRAME, orig_ebp) == TF_ORIG_EBP);
last_kernel_address = KeLoaderModules[KeLoaderBlock.ModsCount - 1].ModEnd; last_kernel_address = KeLoaderModules[KeLoaderBlock.ModsCount - 1].ModEnd;

View file

@ -1,4 +1,4 @@
/* $Id: cont.c,v 1.9 2001/03/08 22:06:01 dwelch Exp $ /* $Id: cont.c,v 1.10 2001/03/25 02:34:28 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -44,7 +44,8 @@ MmAllocateContiguousAlignedMemory(IN ULONG NumberOfBytes,
&BaseAddress, &BaseAddress,
NumberOfBytes, NumberOfBytes,
0, 0,
&MArea); &MArea,
FALSE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
return(NULL); return(NULL);

View file

@ -330,7 +330,8 @@ VOID MmSetSavedSwapEntryPage(PVOID PhysicalAddress,
KeReleaseSpinLock(&PageListLock, oldIrql); KeReleaseSpinLock(&PageListLock, oldIrql);
} }
SWAPENTRY MmGetSavedSwapEntryPage(PVOID PhysicalAddress) SWAPENTRY
MmGetSavedSwapEntryPage(PVOID PhysicalAddress)
{ {
ULONG Start = (ULONG)PhysicalAddress / PAGESIZE; ULONG Start = (ULONG)PhysicalAddress / PAGESIZE;
SWAPENTRY SavedSwapEntry; SWAPENTRY SavedSwapEntry;

View file

@ -1,6 +1,23 @@
/* $Id: page.c,v 1.23 2001/03/16 18:11:24 dwelch Exp $ /*
* ReactOS kernel
* Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
*
* 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: page.c,v 1.24 2001/03/25 02:34:29 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/i386/page.c * FILE: ntoskrnl/mm/i386/page.c
* PURPOSE: low level memory managment manipulation * PURPOSE: low level memory managment manipulation
@ -318,20 +335,31 @@ ULONG MmGetPhysicalAddressForProcess(PEPROCESS Process,
return(PAGE_MASK(PageEntry)); return(PAGE_MASK(PageEntry));
} }
VOID MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage) VOID
MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage,
BOOL* WasDirty, ULONG* PhysicalAddr)
/* /*
` * FUNCTION: Delete a virtual mapping * FUNCTION: Delete a virtual mapping
*/ */
{ {
PULONG Pte; ULONG Pte;
PULONG Pde; PULONG Pde;
PEPROCESS CurrentProcess = PsGetCurrentProcess(); PEPROCESS CurrentProcess = PsGetCurrentProcess();
BOOLEAN WasValid; BOOLEAN WasValid;
/*
* If we are setting a page in another process we need to be in its
* context.
*/
if (Process != NULL && Process != CurrentProcess) if (Process != NULL && Process != CurrentProcess)
{ {
KeAttachProcess(Process); KeAttachProcess(Process);
} }
/*
* Set the page directory entry, we may have to copy the entry from
* the global page directory.
*/
Pde = ADDR_TO_PDE(Address); Pde = ADDR_TO_PDE(Address);
if ((*Pde) == 0 && if ((*Pde) == 0 &&
MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] != 0) MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] != 0)
@ -347,17 +375,24 @@ VOID MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage)
} }
return; return;
} }
Pte = ADDR_TO_PTE(Address);
WasValid = (PAGE_MASK(*Pte) != 0); /*
* Atomically set the entry to zero and get the old value.
*/
Pte = (ULONG)InterlockedExchange((PLONG)ADDR_TO_PTE(Address), 0);
WasValid = (PAGE_MASK(Pte) != 0);
if (WasValid) if (WasValid)
{ {
MmMarkPageUnmapped((PVOID)PAGE_MASK(*Pte)); MmMarkPageUnmapped((PVOID)PAGE_MASK(Pte));
} }
if (FreePage && WasValid) if (FreePage && WasValid)
{ {
MmDereferencePage((PVOID)PAGE_MASK(*Pte)); MmDereferencePage((PVOID)PAGE_MASK(Pte));
} }
*Pte = 0;
/*
* Decrement the reference count for this page table.
*/
if (Process != NULL && WasValid && if (Process != NULL && WasValid &&
Process->AddressSpace.PageTableRefCountTable != NULL && Process->AddressSpace.PageTableRefCountTable != NULL &&
ADDR_TO_PAGE_TABLE(Address) < 768) ADDR_TO_PAGE_TABLE(Address) < 768)
@ -374,10 +409,26 @@ VOID MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage)
} }
#endif #endif
} }
/*
* If necessary go back to the original context
*/
if (Process != NULL && Process != CurrentProcess) if (Process != NULL && Process != CurrentProcess)
{ {
KeDetachProcess(); KeDetachProcess();
} }
/*
* Return some information to the caller
*/
if (WasDirty != NULL)
{
*WasDirty = Pte & PA_DIRTY;
}
if (PhysicalAddr != NULL)
{
*PhysicalAddr = PAGE_MASK(Pte);
}
} }
BOOLEAN BOOLEAN
@ -483,6 +534,32 @@ BOOLEAN MmIsPageDirty(PEPROCESS Process, PVOID Address)
return((MmGetPageEntryForProcess(Process, Address)) & PA_DIRTY); return((MmGetPageEntryForProcess(Process, Address)) & PA_DIRTY);
} }
BOOLEAN
MmIsAccessedAndResetAccessPage(PEPROCESS Process, PVOID Address)
{
PULONG PageEntry;
PEPROCESS CurrentProcess = PsGetCurrentProcess();
BOOLEAN Accessed;
if (Process != CurrentProcess)
{
KeAttachProcess(Process);
}
PageEntry = MmGetPageEntry(Address);
Accessed = (*PageEntry) & PA_ACCESSED;
if (Accessed)
{
(*PageEntry) = (*PageEntry) & (~PA_ACCESSED);
FLUSH_TLB;
}
if (Process != CurrentProcess)
{
KeDetachProcess();
}
return(Accessed);
}
VOID MmSetCleanPage(PEPROCESS Process, PVOID Address) VOID MmSetCleanPage(PEPROCESS Process, PVOID Address)
{ {
PULONG PageEntry; PULONG PageEntry;

View file

@ -1,4 +1,4 @@
/* $Id: iospace.c,v 1.8 2001/02/10 22:51:10 dwelch Exp $ /* $Id: iospace.c,v 1.9 2001/03/25 02:34:28 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -65,7 +65,8 @@ MmMapIoSpace (IN PHYSICAL_ADDRESS PhysicalAddress,
&Result, &Result,
NumberOfBytes, NumberOfBytes,
0, 0,
&marea); &marea,
FALSE);
if (!NT_SUCCESS(STATUS_SUCCESS)) if (!NT_SUCCESS(STATUS_SUCCESS))
{ {
return (NULL); return (NULL);

View file

@ -1,4 +1,4 @@
/* $Id: kmap.c,v 1.8 2001/03/16 18:11:23 dwelch Exp $ /* $Id: kmap.c,v 1.9 2001/03/25 02:34:28 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -43,7 +43,7 @@ ExUnmapPage(PVOID Addr)
DPRINT("i %x\n",i); DPRINT("i %x\n",i);
KeAcquireSpinLock(&AllocMapLock, &oldIrql); KeAcquireSpinLock(&AllocMapLock, &oldIrql);
MmDeleteVirtualMapping(NULL, (PVOID)Addr, FALSE); MmDeleteVirtualMapping(NULL, (PVOID)Addr, FALSE, NULL, NULL);
clear_bit(i%32, &AllocMap[i/32]); clear_bit(i%32, &AllocMap[i/32]);
KeReleaseSpinLock(&AllocMapLock, oldIrql); KeReleaseSpinLock(&AllocMapLock, oldIrql);
} }
@ -62,6 +62,36 @@ ExAllocatePage(VOID)
return(ExAllocatePageWithPhysPage(PhysPage)); return(ExAllocatePageWithPhysPage(PhysPage));
} }
NTSTATUS
MiZeroPage(ULONG PhysPage)
{
PVOID TempAddress;
TempAddress = ExAllocatePageWithPhysPage(PhysPage);
if (TempAddress == NULL)
{
return(STATUS_NO_MEMORY);
}
memset(TempAddress, 0, PAGESIZE);
ExUnmapPage(TempAddress);
return(STATUS_SUCCESS);
}
NTSTATUS
MiCopyFromUserPage(ULONG DestPhysPage, PVOID SourceAddress)
{
PVOID TempAddress;
TempAddress = ExAllocatePageWithPhysPage(DestPhysPage);
if (TempAddress == NULL)
{
return(STATUS_NO_MEMORY);
}
memcpy(TempAddress, SourceAddress, PAGESIZE);
ExUnmapPage(TempAddress);
return(STATUS_SUCCESS);
}
PVOID PVOID
ExAllocatePageWithPhysPage(ULONG PhysPage) ExAllocatePageWithPhysPage(ULONG PhysPage)
{ {

View file

@ -1,5 +1,22 @@
/* /*
* COPYRIGHT: See COPYING in the top level directory * ReactOS kernel
* Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
*
* 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.
*/
/*
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/marea.c * FILE: ntoskrnl/mm/marea.c
* PURPOSE: Implements memory areas * PURPOSE: Implements memory areas
@ -303,7 +320,7 @@ MmFreeMemoryArea(PMADDRESS_SPACE AddressSpace,
MemoryArea->BaseAddress + (i*PAGESIZE)); MemoryArea->BaseAddress + (i*PAGESIZE));
MmDeleteVirtualMapping(AddressSpace->Process, MmDeleteVirtualMapping(AddressSpace->Process,
MemoryArea->BaseAddress + (i*PAGESIZE), MemoryArea->BaseAddress + (i*PAGESIZE),
FALSE); FALSE, NULL, NULL);
if (FreePage != NULL) if (FreePage != NULL)
{ {
FreePage(FreePageContext, FreePage(FreePageContext,
@ -374,7 +391,8 @@ NTSTATUS MmCreateMemoryArea(PEPROCESS Process,
PVOID* BaseAddress, PVOID* BaseAddress,
ULONG Length, ULONG Length,
ULONG Attributes, ULONG Attributes,
MEMORY_AREA** Result) MEMORY_AREA** Result,
BOOL FixedAddress)
/* /*
* FUNCTION: Create a memory area * FUNCTION: Create a memory area
* ARGUMENTS: * ARGUMENTS:
@ -392,7 +410,7 @@ NTSTATUS MmCreateMemoryArea(PEPROCESS Process,
"*BaseAddress %x, Length %x, Attributes %x, Result %x)\n", "*BaseAddress %x, Length %x, Attributes %x, Result %x)\n",
Type,BaseAddress,*BaseAddress,Length,Attributes,Result); Type,BaseAddress,*BaseAddress,Length,Attributes,Result);
if ((*BaseAddress)==0) if ((*BaseAddress)==0 && !FixedAddress)
{ {
*BaseAddress = MmFindGap(AddressSpace, *BaseAddress = MmFindGap(AddressSpace,
PAGE_ROUND_UP(Length) +(PAGESIZE*2)); PAGE_ROUND_UP(Length) +(PAGESIZE*2));

View file

@ -1,4 +1,4 @@
/* $Id: mdl.c,v 1.32 2001/03/21 23:06:08 chorns Exp $ /* $Id: mdl.c,v 1.33 2001/03/25 02:34:28 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -102,7 +102,8 @@ PVOID STDCALL MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode)
&Base, &Base,
Mdl->ByteCount + Mdl->ByteOffset, Mdl->ByteCount + Mdl->ByteOffset,
0, 0,
&Result); &Result,
FALSE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
MmUnlockAddressSpace(MmGetKernelAddressSpace()); MmUnlockAddressSpace(MmGetKernelAddressSpace());

View file

@ -1,4 +1,4 @@
/* $Id: mminit.c,v 1.14 2001/03/16 18:11:23 dwelch Exp $ /* $Id: mminit.c,v 1.15 2001/03/25 02:34:28 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top directory * COPYRIGHT: See COPYING in the top directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -100,7 +100,8 @@ VOID MmInitVirtualMemory(ULONG LastKernelAddress,
&BaseAddress, &BaseAddress,
Length, Length,
0, 0,
&kernel_text_desc); &kernel_text_desc,
FALSE);
Length = PAGE_ROUND_UP(((ULONG)&_bss_end__)) - Length = PAGE_ROUND_UP(((ULONG)&_bss_end__)) -
PAGE_ROUND_UP(((ULONG)&_text_end__)); PAGE_ROUND_UP(((ULONG)&_text_end__));
@ -114,7 +115,8 @@ VOID MmInitVirtualMemory(ULONG LastKernelAddress,
&BaseAddress, &BaseAddress,
Length, Length,
0, 0,
&kernel_data_desc); &kernel_data_desc,
FALSE);
BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG)&_bss_end__)); BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG)&_bss_end__));
// Length = ParamLength; // Length = ParamLength;
@ -125,7 +127,8 @@ VOID MmInitVirtualMemory(ULONG LastKernelAddress,
&BaseAddress, &BaseAddress,
Length, Length,
0, 0,
&kernel_param_desc); &kernel_param_desc,
FALSE);
BaseAddress = (PVOID)(LastKernelAddress + PAGESIZE); BaseAddress = (PVOID)(LastKernelAddress + PAGESIZE);
Length = NONPAGED_POOL_SIZE; Length = NONPAGED_POOL_SIZE;
@ -135,7 +138,8 @@ VOID MmInitVirtualMemory(ULONG LastKernelAddress,
&BaseAddress, &BaseAddress,
Length, Length,
0, 0,
&kernel_pool_desc); &kernel_pool_desc,
FALSE);
BaseAddress = (PVOID)KERNEL_SHARED_DATA_BASE; BaseAddress = (PVOID)KERNEL_SHARED_DATA_BASE;
Length = PAGESIZE; Length = PAGESIZE;
@ -145,7 +149,8 @@ VOID MmInitVirtualMemory(ULONG LastKernelAddress,
&BaseAddress, &BaseAddress,
Length, Length,
0, 0,
&kernel_shared_data_desc); &kernel_shared_data_desc,
FALSE);
MmSharedDataPagePhysicalAddress = MmAllocPage(0); MmSharedDataPagePhysicalAddress = MmAllocPage(0);
Status = MmCreateVirtualMapping(NULL, Status = MmCreateVirtualMapping(NULL,
(PVOID)KERNEL_SHARED_DATA_BASE, (PVOID)KERNEL_SHARED_DATA_BASE,
@ -257,7 +262,7 @@ VOID MmInit1(ULONG FirstKrnlPhysAddr,
i<(KERNEL_BASE + PAGE_TABLE_SIZE); i<(KERNEL_BASE + PAGE_TABLE_SIZE);
i=i+PAGESIZE) i=i+PAGESIZE)
{ {
MmDeleteVirtualMapping(NULL, (PVOID)(i), FALSE); MmDeleteVirtualMapping(NULL, (PVOID)(i), FALSE, NULL, NULL);
} }
DPRINT("Almost done MmInit()\n"); DPRINT("Almost done MmInit()\n");

View file

@ -1,4 +1,4 @@
/* $Id: ncache.c,v 1.9 2001/03/08 22:06:02 dwelch Exp $ /* $Id: ncache.c,v 1.10 2001/03/25 02:34:28 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -60,7 +60,8 @@ MmAllocateNonCachedMemory(IN ULONG NumberOfBytes)
&Result, &Result,
NumberOfBytes, NumberOfBytes,
0, 0,
&marea); &marea,
FALSE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
return (NULL); return (NULL);

View file

@ -1,4 +1,4 @@
/* $Id: npool.c,v 1.43 2001/03/16 18:11:23 dwelch Exp $ /* $Id: npool.c,v 1.44 2001/03/25 02:34:28 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -195,6 +195,10 @@ MiAddToTagHashTable(BLOCK_HDR* block)
return; return;
} }
previous = current; previous = current;
if ((PVOID)current->tag_next >= (PVOID)0xc1123160)
{
DbgPrint("previous %x\n", previous);
}
current = current->tag_next; current = current->tag_next;
} }
block->tag_next = NULL; block->tag_next = NULL;

View file

@ -1,6 +1,23 @@
/* $Id: pagefile.c,v 1.10 2001/02/06 00:11:19 dwelch Exp $ /*
* ReactOS kernel
* Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
*
* 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: pagefile.c,v 1.11 2001/03/25 02:34:28 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/pagefile.c * FILE: ntoskrnl/mm/pagefile.c
* PURPOSE: Paging file functions * PURPOSE: Paging file functions
@ -40,13 +57,16 @@ typedef struct _PAGINGFILE
/* List of paging files, both used and free */ /* List of paging files, both used and free */
static PPAGINGFILE PagingFileList[MAX_PAGING_FILES]; static PPAGINGFILE PagingFileList[MAX_PAGING_FILES];
/* Lock for examining the list of paging files */ /* Lock for examining the list of paging files */
static KSPIN_LOCK PagingFileListLock; static KSPIN_LOCK PagingFileListLock;
/* Number of pages that are available for swapping */ /* Number of pages that are available for swapping */
static ULONG MiFreeSwapPages; static ULONG MiFreeSwapPages;
/* Number of pages that have been allocated for swapping */ /* Number of pages that have been allocated for swapping */
static ULONG MiUsedSwapPages; static ULONG MiUsedSwapPages;
/* /*
* Number of pages that have been reserved for swapping but not yet allocated * Number of pages that have been reserved for swapping but not yet allocated
*/ */
@ -58,6 +78,7 @@ static ULONG MiReservedSwapPages;
* reserved. Setting this to zero turns off commit checking altogether. * reserved. Setting this to zero turns off commit checking altogether.
*/ */
#define MM_PAGEFILE_COMMIT_RATIO (1) #define MM_PAGEFILE_COMMIT_RATIO (1)
/* /*
* Number of pages that can be used for potentially swapable memory without * Number of pages that can be used for potentially swapable memory without
* pagefile space being reserved. The intention is that is allows smss * pagefile space being reserved. The intention is that is allows smss

View file

@ -1,4 +1,4 @@
/* $Id: section.c,v 1.51 2001/03/13 16:25:54 dwelch Exp $ /* $Id: section.c,v 1.52 2001/03/25 02:34:28 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -1485,7 +1485,8 @@ MmMapViewOfSegment(PEPROCESS Process,
BaseAddress, BaseAddress,
ViewSize, ViewSize,
Protect, Protect,
&MArea); &MArea,
FALSE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
MmUnlockAddressSpace(AddressSpace); MmUnlockAddressSpace(AddressSpace);
@ -1955,7 +1956,8 @@ MmAllocateSection (IN ULONG Length)
&Result, &Result,
Length, Length,
0, 0,
&marea); &marea,
FALSE);
if (!NT_SUCCESS(STATUS_SUCCESS)) if (!NT_SUCCESS(STATUS_SUCCESS))
{ {
return (NULL); return (NULL);

View file

@ -1,4 +1,4 @@
/* $Id: virtual.c,v 1.44 2001/03/16 18:11:23 dwelch Exp $ /* $Id: virtual.c,v 1.45 2001/03/25 02:34:29 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top directory * COPYRIGHT: See COPYING in the top directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -7,7 +7,7 @@
* PROGRAMMER: David Welch * PROGRAMMER: David Welch
* UPDATE HISTORY: * UPDATE HISTORY:
* 09/4/98: Created * 09/4/98: Created
* 10/6/98: Corrections from Fatahi (i_fatahi@hotmail.com) * 10/6/98: Corrections from Iwan Fatahi (i_fatahi@hotmail.com)
* 30/9/98: Implemented ZwxxxVirtualMemory functions * 30/9/98: Implemented ZwxxxVirtualMemory functions
*/ */
@ -183,24 +183,82 @@ ULONG MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
PVOID Address, PVOID Address,
PBOOLEAN Ul) PBOOLEAN Ul)
{ {
PHYSICAL_ADDRESS PhysicalAddress; ULONG PhysicalAddress;
BOOL WasDirty;
SWAPENTRY SwapEntry;
NTSTATUS Status;
PMDL Mdl;
/*
* Paging out code or readonly data is easy.
*/
if ((MemoryArea->Attributes & PAGE_READONLY) || if ((MemoryArea->Attributes & PAGE_READONLY) ||
(MemoryArea->Attributes & PAGE_EXECUTE_READ) || (MemoryArea->Attributes & PAGE_EXECUTE_READ))
!MmIsPageDirty(PsGetCurrentProcess(), Address))
{ {
PhysicalAddress = MmGetPhysicalAddress(Address); MmRemovePageFromWorkingSet(AddressSpace->Process, Address);
MmDeleteVirtualMapping(PsGetCurrentProcess(), Address, FALSE,
MmRemovePageFromWorkingSet(AddressSpace->Process, NULL, &PhysicalAddress);
Address); MmDereferencePage((PVOID)PhysicalAddress);
MmDeleteVirtualMapping(PsGetCurrentProcess(), Address, FALSE);
MmDereferencePage((PVOID)PhysicalAddress.u.LowPart);
*Ul = TRUE; *Ul = TRUE;
return(1); return(1);
} }
/*
* Otherwise this is read-write data
*/
MmDeleteVirtualMapping(PsGetCurrentProcess(), Address, FALSE,
&WasDirty, &PhysicalAddress);
if (!WasDirty)
{
MmRemovePageFromWorkingSet(AddressSpace->Process, Address);
MmDereferencePage((PVOID)PhysicalAddress);
*Ul = TRUE;
return(1);
}
/*
* If necessary, allocate an entry in the paging file for this page
*/
SwapEntry = MmGetSavedSwapEntryPage((PVOID)PhysicalAddress);
if (SwapEntry == 0)
{
SwapEntry = MmAllocSwapPage();
if (SwapEntry == 0)
{
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
Address,
MemoryArea->Attributes,
PhysicalAddress);
*Ul = FALSE; *Ul = FALSE;
return(0); return(0);
} }
}
/*
* Write the page to the pagefile
*/
Mdl = MmCreateMdl(NULL, NULL, PAGESIZE);
MmBuildMdlFromPages(Mdl, &PhysicalAddress);
Status = MmWriteToSwapPage(SwapEntry, Mdl);
if (!NT_SUCCESS(Status))
{
DPRINT1("MM: Failed to write to swap page\n");
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
Address,
MemoryArea->Attributes,
PhysicalAddress);
*Ul = FALSE;
return(0);
}
/*
* Otherwise we have succeeded, free the page
*/
MmRemovePageFromWorkingSet(AddressSpace->Process, Address);
MmDereferencePage((PVOID)PhysicalAddress);
*Ul = TRUE;
return(1);
}
NTSTATUS NTSTATUS
MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace, MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
@ -291,6 +349,7 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
*/ */
if (!NT_SUCCESS(PageOp->Status)) if (!NT_SUCCESS(PageOp->Status))
{ {
MmReleasePageOp(PageOp);
return(Status); return(Status);
} }
MmLockAddressSpace(AddressSpace); MmLockAddressSpace(AddressSpace);
@ -385,7 +444,7 @@ MmModifyAttributes(PMADDRESS_SPACE AddressSpace,
PhysicalAddr = MmGetPhysicalAddress(BaseAddress + (i*PAGESIZE)); PhysicalAddr = MmGetPhysicalAddress(BaseAddress + (i*PAGESIZE));
MmDeleteVirtualMapping(AddressSpace->Process, MmDeleteVirtualMapping(AddressSpace->Process,
BaseAddress + (i*PAGESIZE), BaseAddress + (i*PAGESIZE),
FALSE); FALSE, NULL, NULL);
if (PhysicalAddr.u.LowPart != 0) if (PhysicalAddr.u.LowPart != 0)
{ {
MmRemovePageFromWorkingSet(AddressSpace->Process, MmRemovePageFromWorkingSet(AddressSpace->Process,
@ -895,7 +954,7 @@ NtAllocateVirtualMemory(IN HANDLE ProcessHandle,
AddressSpace = &Process->AddressSpace; AddressSpace = &Process->AddressSpace;
MmLockAddressSpace(AddressSpace); MmLockAddressSpace(AddressSpace);
if (BaseAddress != 0) if (PBaseAddress != 0)
{ {
MemoryArea = MmOpenMemoryAreaByAddress(&Process->AddressSpace, MemoryArea = MmOpenMemoryAreaByAddress(&Process->AddressSpace,
BaseAddress); BaseAddress);
@ -938,7 +997,8 @@ NtAllocateVirtualMemory(IN HANDLE ProcessHandle,
&BaseAddress, &BaseAddress,
RegionSize, RegionSize,
Protect, Protect,
&MemoryArea); &MemoryArea,
PBaseAddress != 0);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {

View file

@ -1,6 +1,23 @@
/* $Id: wset.c,v 1.8 2001/03/18 21:28:30 dwelch Exp $ /*
* ReactOS kernel
* Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
*
* 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: wset.c,v 1.9 2001/03/25 02:34:29 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/wset.c * FILE: ntoskrnl/mm/wset.c
* PURPOSE: Manages working sets * PURPOSE: Manages working sets
@ -20,12 +37,76 @@
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
PVOID MmGetDirtyPagesFromWorkingSet(struct _EPROCESS* Process) VOID
KiInitializeCircularQueue(PKCIRCULAR_QUEUE Queue, ULONG MaximumSize,
PVOID* Mem)
{
Queue->MaximumSize = MaximumSize;
Queue->CurrentSize = 0;
Queue->First = Queue->Last = 0;
Queue->Mem = Mem;
}
VOID
KiInsertItemCircularQueue(PKCIRCULAR_QUEUE Queue, PVOID Item)
{
Queue->Mem[Queue->Last] = Item;
Queue->Last = (Queue->Last + 1) % Queue->MaximumSize;
Queue->CurrentSize++;
}
VOID
KiRemoveItemCircularQueue(PKCIRCULAR_QUEUE Queue, PVOID Item)
{
ULONG i, j;
j = Queue->First;
for (i = 0; i < Queue->CurrentSize; i++)
{
if (Queue->Mem[j] == Item)
{
if (j != Queue->First)
{
if (j > 0 && Queue->First <= j)
{
memmove(&Queue->Mem[Queue->First + 1],
&Queue->Mem[Queue->First],
sizeof(PVOID) * (j - Queue->First));
}
else if (j > 0 && Queue->First > j)
{
memmove(&Queue->Mem[1], &Queue->Mem[0],
sizeof(PVOID) * j);
Queue->Mem[0] = Queue->Mem[Queue->MaximumSize - 1];
memmove(&Queue[Queue->First + 1], &Queue[Queue->First],
sizeof(PVOID) *
((Queue->MaximumSize - 1) - Queue->First));
}
else if (j == 0)
{
Queue->Mem[0] = Queue->Mem[Queue->MaximumSize];
memmove(&Queue[Queue->First + 1], &Queue[Queue->First],
sizeof(PVOID) *
((Queue->MaximumSize - 1) - Queue->First));
}
}
Queue->First = (Queue->First + 1) % Queue->MaximumSize;
Queue->CurrentSize--;
return;
}
j = (j + 1) % Queue->MaximumSize;
}
KeBugCheck(0);
}
PVOID
MmGetDirtyPagesFromWorkingSet(struct _EPROCESS* Process)
{ {
return(NULL); return(NULL);
} }
VOID MmLockWorkingSet(PEPROCESS Process) VOID
MmLockWorkingSet(PEPROCESS Process)
{ {
(VOID)KeWaitForMutexObject(&Process->WorkingSetLock, (VOID)KeWaitForMutexObject(&Process->WorkingSetLock,
0, 0,
@ -49,7 +130,8 @@ MmInitializeWorkingSet(PEPROCESS Process, PMADDRESS_SPACE AddressSpace)
/* /*
* The maximum number of pages in the working set is the maximum * The maximum number of pages in the working set is the maximum
* of the size of physical memory and the size of the user address space * of the size of physical memory and the size of the user address space.
* In either case the maximum size is 3Mb.
*/ */
MaximumLength = MmStats.NrTotalPages - MmStats.NrReservedPages; MaximumLength = MmStats.NrTotalPages - MmStats.NrReservedPages;
MaximumLength = min(MaximumLength, KERNEL_BASE / PAGESIZE); MaximumLength = min(MaximumLength, KERNEL_BASE / PAGESIZE);
@ -68,15 +150,15 @@ MmInitializeWorkingSet(PEPROCESS Process, PMADDRESS_SPACE AddressSpace)
&BaseAddress, &BaseAddress,
MaximumLength, MaximumLength,
0, 0,
&AddressSpace->WorkingSetArea); &AddressSpace->WorkingSetArea,
FALSE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
KeBugCheck(0); KeBugCheck(0);
} }
AddressSpace->WorkingSetSize = 0; KiInitializeCircularQueue(&Process->AddressSpace.WSQueue,
AddressSpace->WorkingSetLruFirst = 0; MaximumLength,
AddressSpace->WorkingSetLruLast = 0; (PVOID*)BaseAddress);
AddressSpace->WorkingSetMaximumLength = MaximumLength;
KeInitializeMutex(&Process->WorkingSetLock, 1); KeInitializeMutex(&Process->WorkingSetLock, 1);
Process->WorkingSetPage = BaseAddress; Process->WorkingSetPage = BaseAddress;
Status = MmCreateVirtualMapping(NULL, Status = MmCreateVirtualMapping(NULL,
@ -90,7 +172,8 @@ MmInitializeWorkingSet(PEPROCESS Process, PMADDRESS_SPACE AddressSpace)
memset(Process->WorkingSetPage, 0, 4096); memset(Process->WorkingSetPage, 0, 4096);
} }
ULONG MmPageOutPage(PMADDRESS_SPACE AddressSpace, ULONG
MmPageOutPage(PMADDRESS_SPACE AddressSpace,
PMEMORY_AREA MArea, PMEMORY_AREA MArea,
PVOID Address, PVOID Address,
PBOOLEAN Ul) PBOOLEAN Ul)
@ -122,32 +205,58 @@ ULONG MmPageOutPage(PMADDRESS_SPACE AddressSpace,
return(0); return(0);
} }
VOID
MmLruAdjustWorkingSet(PEPROCESS Process)
{
ULONG i, j;
PVOID CurrentAddress;
MmLockWorkingSet(Process);
j = Process->AddressSpace.WSQueue.First;
for (i = 0; i < Process->AddressSpace.WSQueue.CurrentSize; i++)
{
CurrentAddress = Process->AddressSpace.WSQueue.Mem[j];
if (MmIsAccessedAndResetAccessPage(Process, CurrentAddress))
{
DbgPrint("L");
KiRemoveItemCircularQueue(&Process->AddressSpace.WSQueue,
CurrentAddress);
KiInsertItemCircularQueue(&Process->AddressSpace.WSQueue,
CurrentAddress);
}
j = (j + 1) % Process->AddressSpace.WSQueue.MaximumSize;
}
MmUnlockWorkingSet(Process);
}
ULONG ULONG
MmTrimWorkingSet(PEPROCESS Process, ULONG ReduceHint) MmTrimWorkingSet(PEPROCESS Process, ULONG ReduceHint)
/*
* Reduce the size of the working set of a process
*/
{ {
ULONG i, j; ULONG i, j;
PMADDRESS_SPACE AddressSpace; PMADDRESS_SPACE AddressSpace;
PVOID* WSet;
ULONG Count; ULONG Count;
BOOLEAN Ul; BOOLEAN Ul;
MmLockWorkingSet(Process); MmLockWorkingSet(Process);
WSet = (PVOID*)Process->WorkingSetPage;
AddressSpace = &Process->AddressSpace; AddressSpace = &Process->AddressSpace;
Count = 0; Count = 0;
j = AddressSpace->WorkingSetLruFirst; j = AddressSpace->WSQueue.First;
for (i = 0; i < AddressSpace->WorkingSetSize; ) for (i = 0; i < AddressSpace->WSQueue.CurrentSize; )
{ {
PVOID Address; PVOID Address;
PMEMORY_AREA MArea; PMEMORY_AREA MArea;
Address = WSet[j]; Address = AddressSpace->WSQueue.Mem[j];
MArea = MmOpenMemoryAreaByAddress(AddressSpace, Address); MArea = MmOpenMemoryAreaByAddress(AddressSpace, Address);
if (MArea == NULL) if (MArea == NULL)
{ {
KeBugCheck(0); KeBugCheck(0);
@ -159,12 +268,12 @@ MmTrimWorkingSet(PEPROCESS Process, ULONG ReduceHint)
{ {
MmLockWorkingSet(Process); MmLockWorkingSet(Process);
j = AddressSpace->WorkingSetLruFirst; j = AddressSpace->WSQueue.First;
i = 0; i = 0;
} }
else else
{ {
j = (j + 1) % AddressSpace->WorkingSetMaximumLength; j = (j + 1) % AddressSpace->WSQueue.MaximumSize;
i++; i++;
} }
@ -181,81 +290,48 @@ MmTrimWorkingSet(PEPROCESS Process, ULONG ReduceHint)
VOID VOID
MmRemovePageFromWorkingSet(PEPROCESS Process, PVOID Address) MmRemovePageFromWorkingSet(PEPROCESS Process, PVOID Address)
/* /*
* Remove a page from a process's working set * Remove a page from a process's working set.
*/ */
{ {
ULONG i;
PMADDRESS_SPACE AddressSpace;
PVOID* WSet;
ULONG j;
MmLockWorkingSet(Process); MmLockWorkingSet(Process);
WSet = (PVOID*)Process->WorkingSetPage; KiRemoveItemCircularQueue(&Process->AddressSpace.WSQueue, Address);
AddressSpace = &Process->AddressSpace;
j = AddressSpace->WorkingSetLruFirst;
for (i = 0; i < AddressSpace->WorkingSetSize; i++)
{
if (WSet[j] == Address)
{
WSet[j] = WSet[AddressSpace->WorkingSetLruLast - 1];
if (AddressSpace->WorkingSetLruLast != 0)
{
AddressSpace->WorkingSetLruLast--;
}
else
{
AddressSpace->WorkingSetLruLast =
AddressSpace->WorkingSetMaximumLength;
}
MmUnlockWorkingSet(Process); MmUnlockWorkingSet(Process);
return;
}
j = (j + 1) % AddressSpace->WorkingSetMaximumLength;
}
KeBugCheck(0);
} }
VOID VOID
MmAddPageToWorkingSet(PEPROCESS Process, MmAddPageToWorkingSet(PEPROCESS Process, PVOID Address)
PVOID Address)
/* /*
* Insert a page into a process's working set * insert a page into a process's working set
*/ */
{ {
PVOID* WSet;
PMADDRESS_SPACE AddressSpace; PMADDRESS_SPACE AddressSpace;
BOOLEAN Present;
ULONG Current;
PVOID NextAddress; PVOID NextAddress;
AddressSpace = &Process->AddressSpace; AddressSpace = &Process->AddressSpace;
/* /*
* This can't happen unless there is a bug * This can't happen unless there is a bug.
*/ */
if (AddressSpace->WorkingSetSize == AddressSpace->WorkingSetMaximumLength) if (AddressSpace->WSQueue.CurrentSize == AddressSpace->WSQueue.MaximumSize)
{ {
KeBugCheck(0); KeBugCheck(0);
} }
/* /*
* Lock the working set * lock the working set
*/ */
MmLockWorkingSet(Process); MmLockWorkingSet(Process);
WSet = (PVOID*)Process->WorkingSetPage;
Current = AddressSpace->WorkingSetLruLast;
/* /*
* If we are growing the working set then check to see if we need * if we are growing the working set then check to see if we need
* to allocate a page * to allocate a page
*/ */
NextAddress = (PVOID)PAGE_ROUND_DOWN((PVOID)&WSet[Current]); NextAddress =
Present = MmIsPagePresent(NULL, NextAddress); (PVOID)PAGE_ROUND_DOWN((PVOID)&
if (!Present) AddressSpace->WSQueue.Mem[AddressSpace->WSQueue.Last]);
if (!MmIsPagePresent(NULL, NextAddress))
{ {
PVOID Page; PVOID Page;
NTSTATUS Status; NTSTATUS Status;
@ -280,11 +356,7 @@ MmAddPageToWorkingSet(PEPROCESS Process,
/* /*
* Insert the page in the working set * Insert the page in the working set
*/ */
WSet[Current] = Address; KiInsertItemCircularQueue(&AddressSpace->WSQueue, Address);
AddressSpace->WorkingSetLruLast =
(Current + 1) % AddressSpace->WorkingSetMaximumLength;
AddressSpace->WorkingSetSize++;
/* /*
* And unlock * And unlock

View file

@ -32,9 +32,11 @@ NtEarlyInitVdm(VOID)
memcpy(OrigIVT, (PVOID)0x0, 1024); memcpy(OrigIVT, (PVOID)0x0, 1024);
} }
NTSTATUS STDCALL NtVdmControl(VOID) NTSTATUS STDCALL NtVdmControl(ULONG ControlCode,
PVOID ControlData)
{ {
UNIMPLEMENTED; memcpy(ControlData, OrigIVT, 1024);
return(STATUS_SUCCESS);
} }
/* EOF */ /* EOF */

View file

@ -1,4 +1,4 @@
; $Id: ntoskrnl.def,v 1.100 2001/03/07 08:57:08 dwelch Exp $ ; $Id: ntoskrnl.def,v 1.101 2001/03/25 02:34:27 dwelch Exp $
; ;
; reactos/ntoskrnl/ntoskrnl.def ; reactos/ntoskrnl/ntoskrnl.def
; ;
@ -542,7 +542,7 @@ NtSetInformationThread@16
NtSetSecurityObject@12 NtSetSecurityObject@12
NtSetSystemTime@8 NtSetSystemTime@8
NtUnlockFile@20 NtUnlockFile@20
;NtVdmControl@8 <--- ? NtVdmControl@8
NtWaitForSingleObject@12 NtWaitForSingleObject@12
NtWriteFile@36 NtWriteFile@36
;ObAssignSecurity@16 ;ObAssignSecurity@16

View file

@ -1,4 +1,4 @@
; $Id: ntoskrnl.edf,v 1.87 2001/03/07 08:57:08 dwelch Exp $ ; $Id: ntoskrnl.edf,v 1.88 2001/03/25 02:34:27 dwelch Exp $
; ;
; reactos/ntoskrnl/ntoskrnl.def ; reactos/ntoskrnl/ntoskrnl.def
; ;
@ -542,7 +542,7 @@ NtSetInformationThread=NtSetInformationThread@16
NtSetSecurityObject=NtSetSecurityObject@12 NtSetSecurityObject=NtSetSecurityObject@12
NtSetSystemTime=NtSetSystemTime@8 NtSetSystemTime=NtSetSystemTime@8
NtUnlockFile=NtUnlockFile@20 NtUnlockFile=NtUnlockFile@20
;NtVdmControl@8 <--- ? NtVdmControl=NtVdmControl@8
NtWaitForSingleObject=NtWaitForSingleObject@12 NtWaitForSingleObject=NtWaitForSingleObject@12
NtWriteFile=NtWriteFile@36 NtWriteFile=NtWriteFile@36
;ObAssignSecurity=ObAssignSecurity@16 ;ObAssignSecurity=ObAssignSecurity@16

View file

@ -1,4 +1,4 @@
/* $Id: process.c,v 1.59 2001/03/18 19:35:14 dwelch Exp $ /* $Id: process.c,v 1.60 2001/03/25 02:34:29 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -468,7 +468,8 @@ NtCreateProcess (OUT PHANDLE ProcessHandle,
&BaseAddress, &BaseAddress,
PAGESIZE, PAGESIZE,
PAGE_READONLY, PAGE_READONLY,
&MemoryArea); &MemoryArea,
FALSE);
MmUnlockAddressSpace(&Process->AddressSpace); MmUnlockAddressSpace(&Process->AddressSpace);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {

View file

@ -1,4 +1,4 @@
/* $Id: thread.c,v 1.72 2001/03/18 19:35:14 dwelch Exp $ /* $Id: thread.c,v 1.73 2001/03/25 02:34:29 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -47,7 +47,7 @@ static BOOLEAN DoneInitYet = FALSE;
ULONG PiNrThreads = 0; ULONG PiNrThreads = 0;
ULONG PiNrRunnableThreads = 0; ULONG PiNrRunnableThreads = 0;
static PETHREAD CurrentThread = NULL; PETHREAD CurrentThread = NULL;
static GENERIC_MAPPING PiThreadMapping = {THREAD_READ, static GENERIC_MAPPING PiThreadMapping = {THREAD_READ,
THREAD_WRITE, THREAD_WRITE,

View file

@ -1,4 +1,4 @@
/* $Id: init.c,v 1.10 2000/07/07 01:16:18 phreak Exp $ /* $Id: init.c,v 1.11 2001/03/25 02:34:30 dwelch Exp $
* *
* reactos/subsys/csrss/init.c * reactos/subsys/csrss/init.c
* *
@ -35,6 +35,9 @@ UNICODE_STRING CsrDirectoryName;
extern HANDLE CsrssApiHeap; extern HANDLE CsrssApiHeap;
ULONG
InitializeVideoAddressSpace(VOID);
static NTSTATUS static NTSTATUS
CsrParseCommandLine ( CsrParseCommandLine (
ULONG ArgumentCount, ULONG ArgumentCount,
@ -167,6 +170,9 @@ CsrServerInitialization (
PrintString( "CSR: Unable to create console thread\n" ); PrintString( "CSR: Unable to create console thread\n" );
return FALSE; return FALSE;
} }
InitializeVideoAddressSpace();
return TRUE; return TRUE;
} }

View file

@ -1,4 +1,4 @@
# $Id: makefile,v 1.11 2001/01/14 15:27:15 ekohl Exp $ # $Id: makefile,v 1.12 2001/03/25 02:34:30 dwelch Exp $
# #
# CSRSS: Client/server runtime subsystem # CSRSS: Client/server runtime subsystem
# #
@ -14,7 +14,7 @@ OBJECTS_API = api/process.o api/wapi.o api/conio.o api/handle.o
OBJECTS_SBAPI = OBJECTS_SBAPI =
OBJECTS_MISC = $(TARGET).o init.o print.o $(TARGET).coff OBJECTS_MISC = $(TARGET).o init.o print.o video.o $(TARGET).coff
OBJECTS = $(OBJECTS_API) $(OBJECTS_SBAPI) $(OBJECTS_MISC) OBJECTS = $(OBJECTS_API) $(OBJECTS_SBAPI) $(OBJECTS_MISC)

View file

@ -1,4 +1,4 @@
/* $Id: init.c,v 1.22 2001/02/02 20:48:38 ekohl Exp $ /* $Id: init.c,v 1.23 2001/03/25 02:34:30 dwelch Exp $
* *
* init.c - Session Manager initialization * init.c - Session Manager initialization
* *
@ -46,6 +46,75 @@ PWSTR SmSystemEnvironment = NULL;
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
static VOID
SmCreatePagingFiles (VOID)
{
UNICODE_STRING FileName;
ULONG ulCurrentSize;
ULONG i, j;
CHAR FileNameBufA[255];
ANSI_STRING FileNameA;
NTSTATUS Status;
HANDLE FileHandle;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK Iosb;
LARGE_INTEGER Offset;
static CHAR Buffer[4096];
BOOL Found = FALSE;
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
sprintf(FileNameBufA, "\\Device\\Harddisk%d\\Partition%d", i, j);
RtlInitAnsiString(&FileNameA, FileNameBufA);
RtlAnsiStringToUnicodeString(&FileName, &FileNameA, TRUE);
InitializeObjectAttributes(&ObjectAttributes,
&FileName,
0,
NULL,
NULL);
Status = ZwOpenFile(&FileHandle,
FILE_ALL_ACCESS,
&ObjectAttributes,
&Iosb,
0,
0);
if (!NT_SUCCESS(Status))
{
continue;
}
Offset.QuadPart = 0;
Status = ZwReadFile(FileHandle,
NULL,
NULL,
NULL,
&Iosb,
Buffer,
4096,
&Offset,
NULL);
if (!NT_SUCCESS(Status))
{
DbgPrint("SM: Failed to read first page of partition\n");
continue;
}
if (memcmp(&Buffer[4096 - 10], "SWAP-SPACE", 10) == 0 ||
memcmp(&Buffer[4096 - 10], "SWAPSPACE2", 10) == 0)
{
DbgPrint("SM: Found swap space at %s\n", FileNameA);
Found = TRUE;
break;
}
ZwClose(FileHandle);
}
}
}
#if 0 #if 0
static VOID static VOID
SmCreatePagingFiles (VOID) SmCreatePagingFiles (VOID)
@ -241,10 +310,8 @@ BOOL InitSessionManager (HANDLE Children[])
/* FIXME: Load the well known DLLs */ /* FIXME: Load the well known DLLs */
#if 0
/* Create paging files */ /* Create paging files */
SmCreatePagingFiles (); // SmCreatePagingFiles ();
#endif
/* Load remaining registry hives */ /* Load remaining registry hives */
NtInitializeRegistry (FALSE); NtInitializeRegistry (FALSE);