diff --git a/reactos/include/ddk/ioctrl.h b/reactos/include/ddk/ioctrl.h new file mode 100644 index 00000000000..d7c76454f95 --- /dev/null +++ b/reactos/include/ddk/ioctrl.h @@ -0,0 +1,18 @@ +#ifndef __INCLUDE_DDK_IOCTRL_H +#define __INCLUDE_DDK_IOCTRL_H + + +#define CTL_CODE(Dev, Func, Meth, Acc) ( ((Dev)<<16) | ((Acc)<<14) | ((Func)<<2) | (Meth)) + +// IOCTL Parameter buffering methods +#define METHOD_BUFFERED 0 +#define METHOD_IN_DIRECT 1 +#define METHOD_OUT_DIRECT 2 +#define METHOD_NEITHER 3 + +// IOCTL File access type +#define FILE_ANY_ACCESS 0 +#define FILE_READ_ACCESS 1 +#define FILE_WRITE_ACCESS 2 + +#endif /* __INCLUDE_DDK_IOCTRL_H */ diff --git a/reactos/include/ddk/ntdef.h b/reactos/include/ddk/ntdef.h new file mode 100644 index 00000000000..c64c7c1490b --- /dev/null +++ b/reactos/include/ddk/ntdef.h @@ -0,0 +1,10 @@ +#ifndef __INCLUDE_DDK_NTDEF_H +#define __INCLUDE_DDK_NTDEF_H + +struct _KTHREAD; +struct _ETHREAD; +struct _EPROCESS; + +#define NTKERNELAPI + +#endif diff --git a/reactos/include/ddk/status.h b/reactos/include/ddk/status.h new file mode 100644 index 00000000000..6b6d3496acf --- /dev/null +++ b/reactos/include/ddk/status.h @@ -0,0 +1,159 @@ +#ifndef __INCLUDE_DDK_STATUS_H +#define __INCLUDE_DDK_STATUS_H + +#define NT_SUCCESS(StatCode) ((NTSTATUS)(StatCode) >= 0) + +/* + * Possible status codes + * FIXME: These may not be the actual values used by NT + */ +enum +{ + STATUS_SUCCESS = 0x0, + STATUS_INSUFFICIENT_RESOURCES = 0x80000000, + STATUS_OBJECT_NAME_EXISTS, + STATUS_OBJECT_NAME_COLLISION, +// STATUS_DATATYPE_MISALIGNMENT, + STATUS_CTL_FILE_NOT_SUPPORTED, +// STATUS_ACCESS_VIOLATION, + STATUS_PORT_ALREADY_SET, + STATUS_SECTION_NOT_IMAGE, + STATUS_BAD_WORKING_SET_LIMIT, + STATUS_INCOMPATIBLE_FILE_MAP, + STATUS_HANDLE_NOT_WAITABLE, + STATUS_PORT_DISCONNECTED, + STATUS_NOT_LOCKED, + STATUS_NOT_MAPPED_VIEW, + STATUS_UNABLE_TO_FREE_VM, + STATUS_UNABLE_TO_DELETE_SECTION, + STATUS_MORE_PROCESSING_REQUIRED, + STATUS_INVALID_CID, + STATUS_BAD_INITIAL_STACK, + STATUS_INVALID_VOLUME_LABEL, + STATUS_SECTION_NOT_EXTENDED, + STATUS_NOT_MAPPED_DATA, + STATUS_INFO_LENGTH_MISMATCH, + STATUS_INVALID_INFO_CLASS, + STATUS_SUSPEND_COUNT_EXCEEDED, + STATUS_NOTIFY_ENUM_DIR, + STATUS_REGISTRY_RECOVERED, + STATUS_REGISTRY_IO_FAILED, + STATUS_KEY_DELETED, + STATUS_NO_LOG_SPACE, + STATUS_KEY_HAS_CHILDREN, + STATUS_CHILD_MUST_BE_VOLATILE, + STATUS_REGISTRY_CORRUPT, + STATUS_DLL_NOT_FOUND, + STATUS_DLL_INIT_FAILED, + STATUS_ORDINAL_NOT_FOUND, + STATUS_ENTRYPOINT_NOT_FOUND, +// STATUS_PENDING, + STATUS_MORE_ENTRIES, +// STATUS_INTEGER_OVERFLOW, + STATUS_BUFFER_OVERFLOW, + STATUS_NO_MORE_FILES, + STATUS_NO_INHERITANCE, + STATUS_NO_MORE_EAS, + STATUS_NO_MORE_ENTRIES, + STATUS_GUIDS_EXHAUSTED, + STATUS_AGENTS_EXHAUSTED, + STATUS_UNSUCCESSFUL, + STATUS_NOT_IMPLEMENTED, + STATUS_ILLEGAL_FUNCTION, +// STATUS_IN_PAGE_ERROR, + STATUS_PAGEFILE_QUOTA, + STATUS_COMMITMENT_LIMIT, + STATUS_SECTION_TOO_BIG, + RPC_NT_SS_IN_NULL_CONTEXT, + RPC_NT_INVALID_BINDING, +// STATUS_INVALID_HANDLE, + STATUS_OBJECT_FILE_MISMATCH, + STATUS_FILE_CLOSED, + STATUS_INVALID_PORT_HANDLE, + STATUS_NOT_COMMITTED, + STATUS_INVALID_PARAMETER, + STATUS_INVALID_PARAMETER_1, + STATUS_INVALID_PARAMETER_2, + STATUS_INVALID_PARAMETER_3, + STATUS_INVALID_PARAMETER_4, + STATUS_INVALID_PARAMETER_5, + STATUS_INVALID_PARAMETER_6, + STATUS_INVALID_PARAMETER_7, + STATUS_INVALID_PARAMETER_8, + STATUS_INVALID_PARAMETER_9, + STATUS_INVALID_PARAMETER_10, + STATUS_INVALID_PARAMETER_11, + STATUS_INVALID_PARAMETER_12, + STATUS_INVALID_PARAMETER_MAX, + STATUS_INVALID_PAGE_PROTECTION, + STATUS_RESOURCE_DATA_NOT_FOUND, + STATUS_RESOURCE_TYPE_NOT_FOUND, + STATUS_RESOURCE_NAME_NOT_FOUND, + STATUS_RESOURCE_LANG_NOT_FOUND, + STATUS_NO_SUCH_DEVICE, + STATUS_NO_SUCH_FILE, + STATUS_INVALID_DEVICE_REQUEST, + STATUS_END_OF_FILE, + STATUS_FILE_FORCED_CLOSED, + STATUS_WRONG_VOLUME, + STATUS_NO_MEDIA, + STATUS_NO_MEDIA_IN_DEVICE, + STATUS_NONEXISTENT_SECTOR, + STATUS_WORKING_SET_QUOTA, +// STATUS_NO_MEMORY, + STATUS_CONFLICTING_ADDRESS, + STATUS_INVALID_SYSTEM_SERVICE, + STATUS_THREAD_IS_TERMINATING, + STATUS_PROCESS_IS_TERMINATING, + STATUS_INVALID_LOCK_SEQUENCE, + STATUS_INVALID_VIEW_SIZE, + STATUS_ALREADY_COMMITTED, + STATUS_ACCESS_DENIED, + STATUS_FILE_IS_A_DIRECTORY, + STATUS_CANNOT_DELETE, + STATUS_INVALID_COMPUTER_NAME, + STATUS_FILE_DELETED, + STATUS_DELETE_PENDING, + STATUS_PORT_CONNECTION_REFUSED, + STATUS_NO_SUCH_PRIVILEGE, + STATUS_PRIVILEGE_NOT_HELD, + STATUS_CANNOT_IMPERSONATE, + STATUS_LOGON_FAILURE, + STATUS_ACCOUNT_RESTRICTION, + STATUS_INVALID_LOGON_HOURS, + STATUS_INVALID_WORKSTATION, + STATUS_BUFFER_TOO_SMALL, + STATUS_UNABLE_TO_DECOMMIT_VM, + STATUS_DISK_CORRUPT_ERROR, + STATUS_OBJECT_NAME_INVALID, + STATUS_OBJECT_NAME_NOT_FOUND, +// STATUS_OBJECT_NAME_COLLISION, + STATUS_OBJECT_PATH_INVALID, + STATUS_OBJECT_PATH_NOT_FOUND, + STATUS_DFS_EXIT_PATH_FOUND, + STATUS_OBJECT_PATH_SYNTAX_BAD, + STATUS_DATA_OVERRUN, + STATUS_DATA_LATE_ERROR, + STATUS_DATA_ERROR, + STATUS_CRC_ERROR, + STATUS_SHARING_VIOLATION, + STATUS_QUOTA_EXCEEDED, + STATUS_MUTANT_NOT_OWNED, + STATUS_SEMAPHORE_LIMIT_EXCEEDED, + STATUS_DISK_FULL, + STATUS_LOCK_NOT_GRANTED, + + STATUS_DEVICE_NOT_READY, + STATUS_IO_TIMEOUT, + STATUS_MEDIA_WRITE_PROTECTED, + STATUS_NO_MEDIA_IN_DRIVE, + STATUS_VERIFY_REQUIRED, + STATUS_UNRECOGNIZED_MEDIA, + STATUS_UNRECOGNIZED_VOLUME, +// STATUS_WRONG_VOLUME, + STATUS_FS_DRIVER_REQUIRED, + STATUS_NOT_SUPPORTED = 9999, + STATUS_DISK_OPERATION_FAILED +}; + +#endif /* __INCLUDE_DDK_STATUS_H */ diff --git a/reactos/include/internal/hal.h b/reactos/include/internal/hal.h new file mode 100644 index 00000000000..5218b7dd302 --- /dev/null +++ b/reactos/include/internal/hal.h @@ -0,0 +1,10 @@ +#ifndef __INCLUDE_INTERNAL_HAL_H +#define __INCLUDE_INTERNAL_HAL_H + +#ifdef i386 +#include +#else +#error "Unknown processor" +#endif + +#endif diff --git a/reactos/include/internal/i386/hal.h b/reactos/include/internal/i386/hal.h new file mode 100644 index 00000000000..21ea94a7546 --- /dev/null +++ b/reactos/include/internal/i386/hal.h @@ -0,0 +1,71 @@ +/* + * + */ + +#ifndef __INTERNAL_HAL_HAL_H +#define __INTERNAL_HAL_HAL_H + +typedef struct +{ + unsigned short previous_task; + unsigned short reserved1; + unsigned long esp0; + unsigned short ss0; + unsigned short reserved2; + unsigned long esp1; + unsigned short ss1; + unsigned short reserved3; + unsigned long esp2; + unsigned short ss2; + unsigned short reserved4; + unsigned long cr3; + unsigned long eip; + unsigned long eflags; + unsigned long eax; + unsigned long ecx; + unsigned long edx; + unsigned long ebx; + unsigned long esp; + unsigned long ebp; + unsigned long esi; + unsigned long edi; + unsigned short es; + unsigned short reserved5; + unsigned short cs; + unsigned short reserved6; + unsigned short ss; + unsigned short reserved7; + unsigned short ds; + unsigned short reserved8; + unsigned short fs; + unsigned short reserved9; + unsigned short gs; + unsigned short reserved10; + unsigned short ldt; + unsigned short reserved11; + unsigned short trap; + unsigned short iomap_base; + + unsigned short nr; + + unsigned char io_bitmap[1]; +} hal_thread_state; + +/* + * FUNCTION: Probes for a PCI bus + * RETURNS: True if found + */ +BOOL HalPciProbe(void); + +/* + * FUNCTION: Probes for a BIOS32 extension + */ +VOID Hal_bios32_probe(VOID); + +/* + * FUNCTION: Determines if a a bios32 service is present + */ +BOOLEAN Hal_bios32_is_service_present(ULONG service); + + +#endif /* __INTERNAL_HAL_HAL_H */ diff --git a/reactos/include/internal/ke.h b/reactos/include/internal/ke.h new file mode 100644 index 00000000000..7061b11e29a --- /dev/null +++ b/reactos/include/internal/ke.h @@ -0,0 +1,43 @@ +/* + * Various useful prototypes + */ + +#ifndef __INCLUDE_INTERNAL_KERNEL_H +#define __INCLUDE_INTERNAL_KERNEL_H + +/* INCLUDES *****************************************************************/ + +#include +#include + +#include +#include + +/* INTERNAL KERNEL FUNCTIONS ************************************************/ + +VOID KiInterruptDispatch(ULONG irq); +VOID KiDispatchInterrupt(ULONG irq); +VOID KiTimerInterrupt(VOID); +VOID KeDrainDpcQueue(VOID); +VOID KeExpireTimers(VOID); +NTSTATUS KeAddThreadTimeout(PKTHREAD Thread, PLARGE_INTEGER Interval); +VOID KeInitializeDispatcherHeader(DISPATCHER_HEADER* Header, ULONG Type, + ULONG Size, ULONG SignalState); + +/* INITIALIZATION FUNCTIONS *************************************************/ + +VOID KeInitExceptions(VOID); +VOID KeInitIRQ(VOID); +VOID KeInitTimer(VOID); +VOID KeInitDpc(VOID); +VOID KeInitBugCheck(VOID); +VOID KeInitDispatcher(VOID); +VOID KeCalibrateTimerLoop(VOID); + + + + + + + +#endif diff --git a/reactos/include/internal/ntoskrnl.h b/reactos/include/internal/ntoskrnl.h new file mode 100644 index 00000000000..36322ecdc72 --- /dev/null +++ b/reactos/include/internal/ntoskrnl.h @@ -0,0 +1,89 @@ +/* + * Various useful prototypes + */ + +#ifndef __KERNEL_H +#define __KERNEL_H + +#include +#include + +#include +#include + +/* + * Use these to place a function in a specific section of the executable + */ +#define PLACE_IN_SECTION(s) __attribute__((section (s))) +#define INIT_FUNCTION (PLACE_IN_SECTION("init")) +#define PAGE_LOCKED_FUNCTION (PLACE_IN_SECTION("pagelk")) +#define PAGE_UNLOCKED_FUNCTION (PLACE_IN_SECTION("pagepo")) + +/* + * Maximum size of the kmalloc area (this is totally arbitary) + */ +#define NONPAGED_POOL_SIZE (4*1024*1024) + +/* + * Defines a descriptor as it appears in the processor tables + */ +typedef struct +{ + unsigned int a; + unsigned int b; +} descriptor; + +extern descriptor idt[256]; +extern descriptor gdt[256]; + +/* + * printf style functions + */ +asmlinkage void printk(const char* fmt, ...); +int vsprintf(char *buf, const char *fmt, va_list args); +int sprintf(char* buf, const char* fmt, ...); + +typedef struct +{ + /* + * Magic value (useless really) + */ + unsigned int magic; + + /* + * Cursor position + */ + unsigned int cursorx; + unsigned int cursory; + + /* + * Number of files (including the kernel) loaded + */ + unsigned int nr_files; + + /* + * Range of physical memory being used by the system + */ + unsigned int start_mem; + unsigned int end_mem; + + /* + * List of module lengths (terminated by a 0) + */ + unsigned int module_length[64]; +} boot_param; + + +/* + * Initalization functions (called once by main()) + */ +void MmInitalize(boot_param* bp); +void HalInit(boot_param* bp); +void IoInit(void); +void ObInit(void); +void PsInit(void); +void TstBegin(void); +VOID KeInit(VOID); +VOID HalInitConsole(boot_param* bp); + +#endif diff --git a/reactos/ntoskrnl/ke/kernel.c b/reactos/ntoskrnl/ke/kernel.c new file mode 100644 index 00000000000..ab891966b65 --- /dev/null +++ b/reactos/ntoskrnl/ke/kernel.c @@ -0,0 +1,33 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/ke/kernel.c + * PURPOSE: Initializes the kernel + * PROGRAMMER: David Welch (welch@mcmail.com) + * UPDATE HISTORY: + * Created 22/05/98 + */ + +/* INCLUDES *****************************************************************/ + +#include +#include + +#include + +/* FUNCTIONS *****************************************************************/ + +VOID KeInit() +{ + KeInitDpc(); + KeInitializeBugCheck(); + KeInitializeDispatcher(); + InitializeTimer(); + + /* + * Allow interrupts + */ + KeLowerIrql(PASSIVE_LEVEL); + + KeCalibrateTimerLoop(); +} diff --git a/reactos/ntoskrnl/mm/marea.c b/reactos/ntoskrnl/mm/marea.c new file mode 100644 index 00000000000..0152a77455a --- /dev/null +++ b/reactos/ntoskrnl/mm/marea.c @@ -0,0 +1,404 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/mm/marea.c + * PURPOSE: Implements memory areas + * PROGRAMMER: David Welch (welch@mcmail.com) + * UPDATE HISTORY: + * Created 22/05/98 + */ + +/* INCLUDES *****************************************************************/ + +#include +#include +#include + +#define NDEBUG +#include + +/* GLOBALS *******************************************************************/ + +static LIST_ENTRY SystemAreaList = {NULL,NULL}; +static KSPIN_LOCK SystemAreaListLock = {0,}; + +/* FUNCTIONS *****************************************************************/ + +VOID MmDumpMemoryAreas(VOID) +{ + PLIST_ENTRY current_entry; + MEMORY_AREA* current; + PLIST_ENTRY ListHead = &SystemAreaList; + ULONG i; + + current_entry = ListHead->Flink; + i=0; + while (current_entry!=ListHead) + { + current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry); + DPRINT("Base %x Length %x End %x Attributes %x Flink %x\n", + current->BaseAddress,current->Length, + current->BaseAddress+current->Length,current->Attributes, + current->Entry.Flink); + current_entry = current_entry->Flink; + i++; + if (i>6) + { + CHECKPOINT; + for(;;); + } + } + CHECKPOINT; +} + +VOID MmLockMemoryAreaList(ULONG Address, PKIRQL oldlvl) +{ + if (Address >= KERNEL_BASE) + { + KeAcquireSpinLock(&SystemAreaListLock,oldlvl); + } + else + { + PKPROCESS CurrentProcess = KeGetCurrentProcess(); + + KeAcquireSpinLock(&(CurrentProcess->SpinLock),oldlvl); + } +} + +VOID MmUnlockMemoryAreaList(ULONG Address, PKIRQL oldlvl) +{ + if (Address >= KERNEL_BASE) + { + KeReleaseSpinLock(&SystemAreaListLock,*oldlvl); + } + else + { + PKPROCESS CurrentProcess = KeGetCurrentProcess(); + KeReleaseSpinLock(&(CurrentProcess->SpinLock),*oldlvl); + } + +} + + +static PLIST_ENTRY MmGetRelatedListHead(ULONG BaseAddress) +{ + if (BaseAddress >= KERNEL_BASE) + { + return(&SystemAreaList); + } + else + { + PKPROCESS CurrentProcess = KeGetCurrentProcess(); + return(&(CurrentProcess->MemoryAreaList)); + } +} + +static MEMORY_AREA* MmInternalOpenMemoryAreaByAddress(PLIST_ENTRY ListHead, + ULONG Address) +{ + PLIST_ENTRY current_entry; + MEMORY_AREA* current; + + current_entry = ListHead->Flink; + while (current_entry!=ListHead) + { + current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry); + if (current->BaseAddress <= Address && + (current->BaseAddress + current->Length) > Address) + { + return(current); + } + if (current->BaseAddress > Address) + { + return(NULL); + } + current_entry = current_entry->Flink; + } + return(NULL); +} + + +MEMORY_AREA* MmInternalOpenMemoryAreaByRegion(PLIST_ENTRY ListHead, + ULONG Address, + ULONG Length) +{ + PLIST_ENTRY current_entry; + MEMORY_AREA* current; + ULONG Extent; + + DPRINT("MmInternalOpenMemoryAreaByRegion()\n",0); + + MmDumpMemoryAreas(); + + current_entry = ListHead->Flink; + while (current_entry!=ListHead) + { + current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry); + if (current->BaseAddress >= Address && + current->BaseAddress < (Address+Length)) + { + DPRINT("Finished MmInternalOpenMemoryAreaByRegion()\n",0); + return(current); + } + Extent = current->BaseAddress + current->Length; + if (Extent >= Address && + Extent < (Address+Length)) + { + DPRINT("Finished MmInternalOpenMemoryAreaByRegion()\n",0); + return(current); + } + if (current->BaseAddress <= Address && + Extent >= (Address+Length)) + { + DPRINT("Finished MmInternalOpenMemoryAreaByRegion()\n",0); + return(current); + } + if (current->BaseAddress >= (Address+Length)) + { + DPRINT("Finished MmInternalOpenMemoryAreaByRegion()\n",0); + return(NULL); + } + current_entry = current_entry->Flink; + } + DPRINT("Finished MmInternalOpenMemoryAreaByRegion()\n",0); + return(NULL); +} + +MEMORY_AREA* MmOpenMemoryAreaByRegion(ULONG Address, ULONG Length) +{ + KIRQL oldlvl; + MEMORY_AREA* Result; + PLIST_ENTRY ListHead; + + MmLockMemoryAreaList(Address,&oldlvl); + ListHead = MmGetRelatedListHead(Address); + Result = MmInternalOpenMemoryAreaByRegion(ListHead,Address,Length); + MmUnlockMemoryAreaList(Address,&oldlvl); + return(Result); +} + + +MEMORY_AREA* MmOpenMemoryAreaByRegionWithoutLock(ULONG Address, ULONG Length) +{ + MEMORY_AREA* Result; + PLIST_ENTRY ListHead; + + ListHead = MmGetRelatedListHead(Address); + Result = MmInternalOpenMemoryAreaByRegion(ListHead,Address,Length); + return(Result); +} + +MEMORY_AREA* MmOpenMemoryAreaByAddress(ULONG Address) +{ + KIRQL oldlvl; + MEMORY_AREA* Result; + PLIST_ENTRY ListHead; + + DPRINT("MmOpenMemoryAreaByAddress(Address %x)\n",Address); + + MmLockMemoryAreaList(Address,&oldlvl); + ListHead = MmGetRelatedListHead(Address); + Result = MmInternalOpenMemoryAreaByAddress(ListHead,Address); + MmUnlockMemoryAreaList(Address,&oldlvl); + return(Result); +} + +MEMORY_AREA* MmOpenMemoryAreaByAddressWithoutLock(ULONG Address) +{ + MEMORY_AREA* Result; + PLIST_ENTRY ListHead; + + ListHead = MmGetRelatedListHead(Address); + Result = MmInternalOpenMemoryAreaByAddress(ListHead,Address); + return(Result); +} + +static VOID MmInsertMemoryAreaWithoutLock(MEMORY_AREA* marea) +{ + PLIST_ENTRY ListHead; + PLIST_ENTRY current_entry; + PLIST_ENTRY inserted_entry = &(marea->Entry); + MEMORY_AREA* current; + MEMORY_AREA* next; + + DPRINT("MmInsertMemoryAreaWithoutLock(marea %x)\n",marea); + DPRINT("marea->BaseAddress %x\n",marea->BaseAddress); + DPRINT("marea->Length %x\n",marea->Length); + + ListHead=MmGetRelatedListHead(marea->BaseAddress); + current_entry = ListHead->Flink; + CHECKPOINT; + if (IsListEmpty(ListHead)) + { + CHECKPOINT; + InsertHeadList(ListHead,&marea->Entry); + CHECKPOINT; + return; + } + CHECKPOINT; + current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry); + CHECKPOINT; + if (current->BaseAddress > marea->BaseAddress) + { + CHECKPOINT; + InsertHeadList(ListHead,&marea->Entry); + CHECKPOINT; + return; + } + CHECKPOINT; + while (current_entry->Flink!=ListHead) + { +// CHECKPOINT; + current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry); + next = CONTAINING_RECORD(current_entry->Flink,MEMORY_AREA,Entry); + if (current->BaseAddress < marea->BaseAddress && + current->Entry.Flink==ListHead) + { + current_entry->Flink = inserted_entry; + inserted_entry->Flink=&ListHead; + inserted_entry->Blink=current_entry; + return; + } + if (current->BaseAddress < marea->BaseAddress && + next->BaseAddress > marea->BaseAddress) + { + inserted_entry->Flink = current_entry->Flink; + inserted_entry->Blink = current_entry->Blink; + inserted_entry->Flink->Blink = inserted_entry; + current_entry->Flink=inserted_entry; + return; + } + current_entry = current_entry->Flink; + } + CHECKPOINT; + InsertTailList(ListHead,inserted_entry); +} + +static ULONG MmFindGapWithoutLock(KPROCESSOR_MODE Mode, ULONG Length) +{ + PLIST_ENTRY ListHead; + PLIST_ENTRY current_entry; + MEMORY_AREA* current; + MEMORY_AREA* next; + ULONG Gap; + + DPRINT("MmFindGapWithoutLock(Mode %x Length %x)\n",Mode,Length); + + if (Mode == KernelMode) + { + ListHead = &SystemAreaList; + } + else + { + ListHead = &(KeGetCurrentProcess()->MemoryAreaList); + } + + + current_entry = ListHead->Flink; + while (current_entry->Flink!=ListHead) + { + current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry); + next = CONTAINING_RECORD(current_entry->Flink,MEMORY_AREA,Entry); + DPRINT("current %x current->BaseAddress %x\n",current, + current->BaseAddress); + DPRINT("current->Length %x\n",current->Length); + DPRINT("next %x next->BaseAddress %x\n",next,next->BaseAddress); + Gap = (next->BaseAddress ) -(current->BaseAddress + current->Length); + DPRINT("Gap %x\n",Gap); + if (Gap >= Length) + { + return(current->BaseAddress + current->Length); + } + current_entry = current_entry->Flink; + } + current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry); + return(current->BaseAddress + current->Length); +} + +NTSTATUS MmInitMemoryAreas(VOID) +{ + DPRINT("MmInitMemoryAreas()\n",0); + InitializeListHead(&SystemAreaList); + KeInitializeSpinLock(&SystemAreaListLock); + return(STATUS_SUCCESS); +} + +NTSTATUS MmFreeMemoryArea(PVOID BaseAddress, + ULONG Length, + BOOLEAN FreePages) +{ + MEMORY_AREA* MemoryArea; + ULONG i; + KIRQL oldlvl; + + MmLockMemoryAreaList((ULONG)BaseAddress,&oldlvl); + + MemoryArea = MmOpenMemoryAreaByAddressWithoutLock((ULONG)BaseAddress); + if (MemoryArea!=NULL) + { + MmUnlockMemoryAreaList((ULONG)BaseAddress,&oldlvl); + return(STATUS_UNSUCCESSFUL); + } + if (FreePages) + { + for (i=0;i<=(MemoryArea->Length/PAGESIZE);i++) + { + free_page(MmGetPhysicalAddress(MemoryArea->BaseAddress+ + (i*PAGESIZE)).LowPart,1); + } + } + + RemoveEntryList(&(MemoryArea->Entry)); + ExFreePool(MemoryArea); + MmUnlockMemoryAreaList((ULONG)BaseAddress,&oldlvl); + return(STATUS_SUCCESS); +} + +NTSTATUS MmCreateMemoryArea(KPROCESSOR_MODE Mode, + ULONG Type, + PULONG BaseAddress, + ULONG Length, + ULONG Attributes, + MEMORY_AREA** Result) +{ + KIRQL oldlvl; + + DPRINT("MmCreateMemoryArea(Mode %x, Type %d, BaseAddress %x," + "*BaseAddress %x, Length %x, Attributes %x, Result %x)\n", + Mode,Type,BaseAddress,*BaseAddress,Length,Attributes,Result); + + MmLockMemoryAreaList(*BaseAddress,&oldlvl); + if ((*BaseAddress)==0) + { + *BaseAddress = MmFindGapWithoutLock(Mode,Length+(PAGESIZE*2)); + if ((*BaseAddress)==0) + { + MmUnlockMemoryAreaList(*BaseAddress,&oldlvl); + return(STATUS_UNSUCCESSFUL); + } + (*BaseAddress)=(*BaseAddress)+PAGESIZE; + } + else + { + if (MmOpenMemoryAreaByRegionWithoutLock(*BaseAddress,Length)!=NULL) + { + MmUnlockMemoryAreaList(*BaseAddress,&oldlvl); + return(STATUS_UNSUCCESSFUL); + } + } + + *Result = ExAllocatePool(NonPagedPool,sizeof(MEMORY_AREA)); + RtlZeroMemory(*Result,sizeof(MEMORY_AREA)); + (*Result)->Type=Type; + (*Result)->BaseAddress=*BaseAddress; + (*Result)->Length=Length; + (*Result)->Attributes=Attributes; + DPRINT("&SystemAreaList %x ",&SystemAreaList); + DPRINT("SystemAreaList.Flink %x ",SystemAreaList.Flink); + MmInsertMemoryAreaWithoutLock(*Result); + MmUnlockMemoryAreaList(*BaseAddress,&oldlvl); + DPRINT("SystemAreaList.Flink %x ",SystemAreaList.Flink); + DPRINT("(*Result)->Entry.Flink %x\n",(*Result)->Entry.Flink); + MmDumpMemoryAreas(); + return(STATUS_SUCCESS); +} diff --git a/reactos/ntoskrnl/mm/special.c b/reactos/ntoskrnl/mm/special.c new file mode 100644 index 00000000000..55cdfdcbb6c --- /dev/null +++ b/reactos/ntoskrnl/mm/special.c @@ -0,0 +1,130 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/mm/special.c + * PURPOSE: Special types of memory region + * PROGRAMMER: David Welch (welch@mcmail.com) + * UPDATE HISTORY: + * Created 22/05/98 + */ + +/* INCLUDES *****************************************************************/ + +#include +#include + +#define NDEBUG +#include + +/* FUNCTIONS *****************************************************************/ + +PVOID MmAllocateSection(ULONG Length) +{ + ULONG Result; + MEMORY_AREA* marea; + NTSTATUS Status; + ULONG i; + ULONG Attributes; + + DPRINT("MmAllocateSection(Length %x)\n",Length); + + Result = 0; + Status = MmCreateMemoryArea(KernelMode, + MEMORY_AREA_SYSTEM, + &Result, + Length, + 0, + &marea); + if (Status!=STATUS_SUCCESS) + { + return(NULL); + } + CHECKPOINT; + Attributes = PA_WRITE | PA_READ | PA_EXECUTE | PA_SYSTEM; + for (i=0;i<=(Length/PAGESIZE);i++) + { + set_page(Result+(i*PAGESIZE),Attributes,get_free_page()); + } + return((PVOID)Result); +} + +PVOID MmAllocateContiguousMemory(ULONG NumberOfBytes, + PHYSICAL_ADDRESS HighestAcceptableAddress) +{ + UNIMPLEMENTED; +} + +VOID MmFreeContiguousMemory(PVOID BaseAddress) +{ + UNIMPLEMENTED; +} + +PVOID MmMapIoSpace(PHYSICAL_ADDRESS PhysicalAddress, + ULONG NumberOfBytes, + BOOLEAN CacheEnable) +{ + ULONG Result; + MEMORY_AREA* marea; + NTSTATUS Status; + ULONG i; + ULONG Attributes; + + Result=0; + Status = MmCreateMemoryArea(KernelMode, + MEMORY_AREA_IO_MAPPING, + &Result, + NumberOfBytes, + 0, + &marea); + if (Status!=STATUS_SUCCESS) + { + return(NULL); + } + Attributes = PA_WRITE | PA_READ | PA_EXECUTE | PA_SYSTEM; + if (!CacheEnable) + { + Attributes = Attributes | PA_PWT | PA_PCD; + } + for (i=0;i<=(NumberOfBytes/PAGESIZE);i++) + { + set_page(Result+(i*PAGESIZE),Attributes,PhysicalAddress.LowPart); + } + return((PVOID)Result); +} + +VOID MmUnmapIoSpace(PVOID BaseAddress, ULONG NumberOfBytes) +{ + (void)MmFreeMemoryArea(BaseAddress,NumberOfBytes,FALSE); +} + +PVOID MmAllocateNonCachedMemory(ULONG NumberOfBytes) +{ + ULONG Result; + MEMORY_AREA* marea; + NTSTATUS Status; + ULONG i; + + Result=0; + Status = MmCreateMemoryArea(KernelMode, + MEMORY_AREA_NO_CACHE, + &Result, + NumberOfBytes, + 0, + &marea); + if (Status!=STATUS_SUCCESS) + { + return(NULL); + } + for (i=0;i<=(NumberOfBytes/PAGESIZE);i++) + { + set_page(Result+(i*PAGESIZE), + PA_WRITE | PA_READ | PA_EXECUTE | PA_SYSTEM | PA_PCD | PA_PWT, + get_free_page()); + } + return((PVOID)Result); +} + +VOID MmFreeNonCachedMemory(PVOID BaseAddress, ULONG NumberOfBytes) +{ + MmFreeMemoryArea(BaseAddress,NumberOfBytes,TRUE); +} diff --git a/reactos/ntoskrnl/ps/idle.c b/reactos/ntoskrnl/ps/idle.c new file mode 100644 index 00000000000..bf15d475850 --- /dev/null +++ b/reactos/ntoskrnl/ps/idle.c @@ -0,0 +1,37 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/ke/bug.c + * PURPOSE: Graceful system shutdown if a bug is detected + * PROGRAMMER: David Welch (welch@mcmail.com) + * UPDATE HISTORY: + * Created 22/05/98 + */ + +/* INCLUDES *****************************************************************/ + +#include + +#include + +/* GLOBALS *******************************************************************/ + +HANDLE IdleThreadHandle = NULL; + +/* FUNCTIONS *****************************************************************/ + +static VOID PsIdleThreadMain(PVOID Context) +{ + for(;;); +} + +VOID PsInitIdleThread(VOID) +{ + PsCreateSystemThread(&IdleThreadHandle, + 0, + NULL, + NULL, + NULL, + PsIdleThreadMain, + NULL); +}