4 Commits

Author SHA1 Message Date
368c8ee5b2 Eliminate unnecessary page map commits
All checks were successful
Builds / ExectOS (amd64, debug) (push) Successful in 29s
Builds / ExectOS (i686, release) (push) Successful in 37s
Builds / ExectOS (i686, debug) (push) Successful in 28s
Builds / ExectOS (amd64, release) (push) Successful in 39s
2026-03-13 14:09:45 +01:00
c71d58b737 Calculate descriptor pages strictly based on the actual map size
All checks were successful
Builds / ExectOS (i686, debug) (push) Successful in 31s
Builds / ExectOS (i686, release) (push) Successful in 30s
Builds / ExectOS (amd64, release) (push) Successful in 45s
Builds / ExectOS (amd64, debug) (push) Successful in 47s
2026-03-13 12:28:15 +01:00
b692fe4cef Update loader protocol with missing definition
All checks were successful
Builds / ExectOS (amd64, release) (push) Successful in 23s
Builds / ExectOS (i686, release) (push) Successful in 30s
Builds / ExectOS (i686, debug) (push) Successful in 39s
Builds / ExectOS (amd64, debug) (push) Successful in 40s
2026-03-12 19:17:51 +01:00
21b3b269a7 Fix critical memory corruption bug caused by overwriting active page tables marked as free memory
Some checks failed
Builds / ExectOS (i686, debug) (push) Failing after 28s
Builds / ExectOS (amd64, release) (push) Failing after 29s
Builds / ExectOS (i686, release) (push) Failing after 34s
Builds / ExectOS (amd64, debug) (push) Failing after 38s
2026-03-12 19:02:58 +01:00
53 changed files with 256 additions and 3494 deletions

View File

@@ -547,8 +547,7 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
/* Make sure it's memory type is the same */ /* Make sure it's memory type is the same */
if(Mapping1->MemoryType == Mapping2->MemoryType) if(Mapping1->MemoryType == Mapping2->MemoryType)
{ {
/* Free the unused mapping structure and return success */ /* It is already mapped */
FreePool(Mapping1);
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }
} }
@@ -575,15 +574,12 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
return Status; return Status;
} }
/* Set mapping fields */ /* Set mapping fields and insert it on the top */
Mapping3->PhysicalAddress = PhysicalAddressEnd + 1; Mapping3->PhysicalAddress = PhysicalAddressEnd + 1;
Mapping3->VirtualAddress = (ULONGLONG)NULLPTR; Mapping3->VirtualAddress = (ULONGLONG)NULLPTR;
Mapping3->NumberOfPages = NumberOfMappedPages; Mapping3->NumberOfPages = NumberOfMappedPages;
Mapping3->MemoryType = Mapping2->MemoryType; Mapping3->MemoryType = Mapping2->MemoryType;
/* Insert new mapping in front of the list and increase page map size */
RTL::LinkedList::InsertHeadList(&Mapping2->ListEntry, &Mapping3->ListEntry); RTL::LinkedList::InsertHeadList(&Mapping2->ListEntry, &Mapping3->ListEntry);
PageMap->MapSize++;
} }
/* Calculate number of pages and the end of the physical address */ /* Calculate number of pages and the end of the physical address */
@@ -614,15 +610,12 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
return Status; return Status;
} }
/* Set mapping fields */ /* Set mapping fields and insert it on the top */
Mapping3->PhysicalAddress = Mapping1->PhysicalAddress; Mapping3->PhysicalAddress = Mapping1->PhysicalAddress;
Mapping3->VirtualAddress = (ULONGLONG)NULLPTR; Mapping3->VirtualAddress = (ULONGLONG)NULLPTR;
Mapping3->NumberOfPages = NumberOfMappedPages; Mapping3->NumberOfPages = NumberOfMappedPages;
Mapping3->MemoryType = Mapping2->MemoryType; Mapping3->MemoryType = Mapping2->MemoryType;
/* Insert new mapping in front of the list and increase page map size */
RTL::LinkedList::InsertHeadList(&Mapping2->ListEntry, &Mapping3->ListEntry); RTL::LinkedList::InsertHeadList(&Mapping2->ListEntry, &Mapping3->ListEntry);
PageMap->MapSize++;
} }
/* Calculate number of pages and the end of the physical address */ /* Calculate number of pages and the end of the physical address */
@@ -650,19 +643,15 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
Status = FreePool(Mapping2); Status = FreePool(Mapping2);
ListEntry = MappingListEntry; ListEntry = MappingListEntry;
/* Decrease page map size and go to the next mapping */ /* Go to the next mapping */
PageMap->MapSize--;
continue; continue;
} }
/* Determine physical address order */ /* Determine physical address order */
if(Mapping2->PhysicalAddress > Mapping1->PhysicalAddress) if(Mapping2->PhysicalAddress > Mapping1->PhysicalAddress)
{ {
/* Insert new mapping in front of the list and increase page map size */ /* Insert new mapping in front */
RTL::LinkedList::InsertHeadList(Mapping2->ListEntry.Blink, &Mapping1->ListEntry); RTL::LinkedList::InsertHeadList(Mapping2->ListEntry.Blink, &Mapping1->ListEntry);
PageMap->MapSize++;
/* Return success */
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }
@@ -670,7 +659,7 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
ListEntry = ListEntry->Flink; ListEntry = ListEntry->Flink;
} }
/* Insert new mapping to the tail of the list and increase page map size */ /* Insert new mapping to the list and increase page map size */
RTL::LinkedList::InsertTailList(&PageMap->MemoryMap, &Mapping1->ListEntry); RTL::LinkedList::InsertTailList(&PageMap->MemoryMap, &Mapping1->ListEntry);
PageMap->MapSize++; PageMap->MapSize++;

View File

@@ -409,11 +409,8 @@ Xtos::InitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
} }
FbPages = EFI_SIZE_TO_PAGES(FbSize); FbPages = EFI_SIZE_TO_PAGES(FbSize);
/* Precommit page map to allocate memory */
XtLdrProtocol->Memory.CommitPageMap(PageMap);
/* Calculate number of pages needed for memory descriptor list */ /* Calculate number of pages needed for memory descriptor list */
DescriptorPages = EFI_SIZE_TO_PAGES(PageMap->MapSize * sizeof(LOADER_MEMORY_DESCRIPTOR) * 2); DescriptorPages = EFI_SIZE_TO_PAGES(PageMap->MapSize * sizeof(LOADER_MEMORY_DESCRIPTOR));
/* Allocate memory for the kernel initialization block and boot parameters */ /* Allocate memory for the kernel initialization block and boot parameters */
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, BlockPages, &PhysicalBlock); Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, BlockPages, &PhysicalBlock);

View File

@@ -110,15 +110,6 @@
/* Trampoline code address */ /* Trampoline code address */
#define MM_TRAMPOLINE_ADDRESS 0x80000 #define MM_TRAMPOLINE_ADDRESS 0x80000
/* Pool block size */
#define MM_POOL_BLOCK_SIZE 16
/* Number of pool lists per page */
#define MM_POOL_LISTS_PER_PAGE (MM_PAGE_SIZE / MM_POOL_BLOCK_SIZE)
/* Number of pool tracking tables */
#define MM_POOL_TRACKING_TABLES 64
/* Page size enumeration list */ /* Page size enumeration list */
typedef enum _PAGE_SIZE typedef enum _PAGE_SIZE
{ {
@@ -326,22 +317,4 @@ typedef struct _MMPFN
} u4; } u4;
} MMPFN, *PMMPFN; } MMPFN, *PMMPFN;
/* Pool descriptor structure definition */
typedef struct _POOL_DESCRIPTOR
{
LIST_ENTRY ListHeads[MM_POOL_LISTS_PER_PAGE];
PVOID LockAddress;
ULONG PoolIndex;
LONG PendingFreeDepth;
PVOID PendingFrees;
MMPOOL_TYPE PoolType;
ULONG RunningFrees;
ULONG RunningAllocations;
ULONG Threshold;
ULONG TotalPages;
ULONG TotalBigAllocations;
SIZE_T TotalBytes;
SIZE_T Reserved;
} POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
#endif /* __XTDK_AMD64_MMTYPES_H */ #endif /* __XTDK_AMD64_MMTYPES_H */

View File

@@ -61,7 +61,6 @@ typedef struct _MMPTE_PROTOTYPE MMPTE_PROTOTYPE, *PMMPTE_PROTOTYPE;
typedef struct _MMPTE_SOFTWARE MMPTE_SOFTWARE, *PMMPTE_SOFTWARE; typedef struct _MMPTE_SOFTWARE MMPTE_SOFTWARE, *PMMPTE_SOFTWARE;
typedef struct _MMPTE_SUBSECTION MMPTE_SUBSECTION, *PMMPTE_SUBSECTION; typedef struct _MMPTE_SUBSECTION MMPTE_SUBSECTION, *PMMPTE_SUBSECTION;
typedef struct _MMPTE_TRANSITION MMPTE_TRANSITION, *PMMPTE_TRANSITION; typedef struct _MMPTE_TRANSITION MMPTE_TRANSITION, *PMMPTE_TRANSITION;
typedef struct _POOL_DESCRIPTOR POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
typedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK; typedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
/* Unions forward references */ /* Unions forward references */

View File

@@ -108,15 +108,6 @@
/* Trampoline code address */ /* Trampoline code address */
#define MM_TRAMPOLINE_ADDRESS 0x80000 #define MM_TRAMPOLINE_ADDRESS 0x80000
/* Pool block size */
#define MM_POOL_BLOCK_SIZE 8
/* Number of pool lists per page */
#define MM_POOL_LISTS_PER_PAGE (MM_PAGE_SIZE / MM_POOL_BLOCK_SIZE)
/* Number of pool tracking tables */
#define MM_POOL_TRACKING_TABLES 32
/* Page size enumeration list */ /* Page size enumeration list */
typedef enum _PAGE_SIZE typedef enum _PAGE_SIZE
{ {
@@ -419,22 +410,4 @@ typedef struct _MMPFN
} u4; } u4;
} MMPFN, *PMMPFN; } MMPFN, *PMMPFN;
/* Pool descriptor structure definition */
typedef struct _POOL_DESCRIPTOR
{
LIST_ENTRY ListHeads[MM_POOL_LISTS_PER_PAGE];
PVOID LockAddress;
ULONG PoolIndex;
LONG PendingFreeDepth;
PVOID PendingFrees;
MMPOOL_TYPE PoolType;
ULONG RunningFrees;
ULONG RunningAllocations;
ULONG Threshold;
ULONG TotalPages;
ULONG TotalBigAllocations;
SIZE_T TotalBytes;
SIZE_T Reserved;
} POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
#endif /* __XTDK_I686_MMTYPES_H */ #endif /* __XTDK_I686_MMTYPES_H */

View File

@@ -70,7 +70,6 @@ typedef struct _MMPML3_PTE_PROTOTYPE MMPML3_PTE_PROTOTYPE, *PMMPML3_PTE_PROTOTYP
typedef struct _MMPML3_PTE_SOFTWARE MMPML3_PTE_SOFTWARE, *PMMPML3_PTE_SOFTWARE; typedef struct _MMPML3_PTE_SOFTWARE MMPML3_PTE_SOFTWARE, *PMMPML3_PTE_SOFTWARE;
typedef struct _MMPML3_PTE_SUBSECTION MMPML3_PTE_SUBSECTION, *PMMPML3_PTE_SUBSECTION; typedef struct _MMPML3_PTE_SUBSECTION MMPML3_PTE_SUBSECTION, *PMMPML3_PTE_SUBSECTION;
typedef struct _MMPML3_PTE_TRANSITION MMPML3_PTE_TRANSITION, *PMMPML3_PTE_TRANSITION; typedef struct _MMPML3_PTE_TRANSITION MMPML3_PTE_TRANSITION, *PMMPML3_PTE_TRANSITION;
typedef struct _POOL_DESCRIPTOR POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
typedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK; typedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
/* Unions forward references */ /* Unions forward references */

View File

@@ -1,40 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: sdk/xtdk/mmfuncs.h
* DESCRIPTION: XTOS memory manager routine definitions
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTDK_MMFUNCS_H
#define __XTDK_MMFUNCS_H
#include <xtdefs.h>
#include <xtstruct.h>
#include <xttypes.h>
/* Memory manager routines forward references */
XTAPI
XTSTATUS
MmAllocatePool(IN MMPOOL_TYPE PoolType,
IN SIZE_T Bytes,
OUT PVOID *Memory);
XTAPI
XTSTATUS
MmAllocatePoolWithTag(IN MMPOOL_TYPE PoolType,
IN SIZE_T Bytes,
OUT PVOID *Memory,
IN ULONG Tag);
XTAPI
XTSTATUS
MmFreePool(IN PVOID VirtualAddress);
XTAPI
XTSTATUS
MmFreePoolWithTag(IN PVOID VirtualAddress,
IN ULONG Tag);
#endif /* __XTDK_MMFUNCS_H */

View File

@@ -29,32 +29,9 @@
/* Memory manager pool type mask definition */ /* Memory manager pool type mask definition */
#define MM_POOL_TYPE_MASK 1 #define MM_POOL_TYPE_MASK 1
/* Bad pool caller reasons */
#define MM_POOL_INVALID_ALLOC_RUNLEVEL 8
#define MM_POOL_INVALID_FREE_RUNLEVEL 9
/* Pool flags */
#define MM_POOL_BIG_ALLOCATIONS_ENTRY_FREE 0x1
#define MM_POOL_PROTECTED 0x80000000
#define MM_POOL_RAISE_EXCEPTION 0x10
/* Number of reserved zeroed PTEs */ /* Number of reserved zeroed PTEs */
#define MM_RESERVED_ZERO_PTES 32 #define MM_RESERVED_ZERO_PTES 32
/* Memory Manager Protection Bits */
#define MM_ZERO_ACCESS 0
#define MM_READONLY 1
#define MM_EXECUTE 2
#define MM_EXECUTE_READ 3
#define MM_READWRITE 4
#define MM_WRITECOPY 5
#define MM_EXECUTE_READWRITE 6
#define MM_EXECUTE_WRITECOPY 7
#define MM_PROTECT_ACCESS 7
/* Protection field shift */
#define MM_PROTECT_FIELD_SHIFT 5
/* Memory manager page lists */ /* Memory manager page lists */
typedef enum _MMPAGELISTS typedef enum _MMPAGELISTS
{ {
@@ -85,14 +62,14 @@ typedef enum _MMPOOL_TYPE
NonPagedPoolMustSucceed = 2, NonPagedPoolMustSucceed = 2,
NonPagedPoolCacheAligned = 4, NonPagedPoolCacheAligned = 4,
PagedPoolCacheAligned = 5, PagedPoolCacheAligned = 5,
NonPagedPoolCacheAlignedMustSucceed = 6, NonPagedPoolCacheAlignedMustS = 6,
MaxPoolType = 7, MaxPoolType = 7,
NonPagedPoolSession = 32, NonPagedPoolSession = 32,
PagedPoolSession = 33, PagedPoolSession = 33,
NonPagedPoolMustSucceedSession = 34, NonPagedPoolMustSucceedSession = 34,
NonPagedPoolCacheAlignedSession = 36, NonPagedPoolCacheAlignedSession = 36,
PagedPoolCacheAlignedSession = 37, PagedPoolCacheAlignedSession = 37,
NonPagedPoolCacheAlignedMustSucceedSession = 38 NonPagedPoolCacheAlignedMustSSession = 38
} MMPOOL_TYPE, *PMMPOOL_TYPE; } MMPOOL_TYPE, *PMMPOOL_TYPE;
/* Page table pool types */ /* Page table pool types */
@@ -196,66 +173,4 @@ typedef struct _MMPFNLIST
PFN_NUMBER Blink; PFN_NUMBER Blink;
} MMPFNLIST, *PMMPFNLIST; } MMPFNLIST, *PMMPFNLIST;
/* Physical memory run structure definition */
typedef struct _PHYSICAL_MEMORY_RUN
{
PFN_NUMBER BasePage;
PFN_NUMBER PageCount;
} PHYSICAL_MEMORY_RUN, *PPHYSICAL_MEMORY_RUN;
/* Physical memory descriptor structure definition */
typedef struct _PHYSICAL_MEMORY_DESCRIPTOR
{
ULONG NumberOfRuns;
PFN_NUMBER NumberOfPages;
PHYSICAL_MEMORY_RUN Run[1];
} PHYSICAL_MEMORY_DESCRIPTOR, *PPHYSICAL_MEMORY_DESCRIPTOR;
/* Pool header structure definition */
typedef struct _POOL_HEADER
{
union
{
struct
{
USHORT PreviousSize:9;
USHORT PoolIndex:7;
USHORT BlockSize:9;
USHORT PoolType:7;
};
ULONG Long;
};
union
{
ULONG PoolTag;
PEPROCESS ProcessBilled;
struct
{
USHORT AllocatorBackTraceIndex;
USHORT PoolTagHash;
};
};
} POOL_HEADER, *PPOOL_HEADER;
/* Pool descriptor structure definition */
typedef struct _POOL_TRACKING_BIG_ALLOCATIONS
{
ULONG NumberOfPages;
PVOID QuotaObject;
ULONG Tag;
PVOID VirtualAddress;
} POOL_TRACKING_BIG_ALLOCATIONS, *PPOOL_TRACKING_BIG_ALLOCATIONS;
/* Pool tracking table structure definition */
typedef struct _POOL_TRACKING_TABLE
{
LONG NonPagedAllocations;
SIZE_T NonPagedBytes;
LONG NonPagedFrees;
LONG PagedAllocations;
SIZE_T PagedBytes;
LONG PagedFrees;
ULONG Tag;
} POOL_TRACKING_TABLE, *PPOOL_TRACKING_TABLE;
#endif /* __XTDK_MMTYPES_H */ #endif /* __XTDK_MMTYPES_H */

View File

@@ -23,7 +23,7 @@
#define DebugPrint(Format, ...) DbgPrint(Format, __VA_ARGS__); #define DebugPrint(Format, ...) DbgPrint(Format, __VA_ARGS__);
#else #else
#define DEBUG 0 #define DEBUG 0
#define DebugPrint(Format, ...) ((VOID)NULLPTR) #define DebugPrint(Format, ...) ((VOID)NULL)
#endif #endif
#endif /* __XTDK_XTDEBUG_H */ #endif /* __XTDK_XTDEBUG_H */

View File

@@ -50,7 +50,6 @@
#include <hlfuncs.h> #include <hlfuncs.h>
#include <kdfuncs.h> #include <kdfuncs.h>
#include <kefuncs.h> #include <kefuncs.h>
#include <mmfuncs.h>
#include <rtlfuncs.h> #include <rtlfuncs.h>
/* Architecture specific XT routines */ /* Architecture specific XT routines */

View File

@@ -310,11 +310,6 @@ typedef struct _PECOFF_IMAGE_ROM_HEADER PECOFF_IMAGE_ROM_HEADER, *PPECOFF_IMAGE_
typedef struct _PECOFF_IMAGE_ROM_OPTIONAL_HEADER PECOFF_IMAGE_ROM_OPTIONAL_HEADER, *PPECOFF_IMAGE_ROM_OPTIONAL_HEADER; typedef struct _PECOFF_IMAGE_ROM_OPTIONAL_HEADER PECOFF_IMAGE_ROM_OPTIONAL_HEADER, *PPECOFF_IMAGE_ROM_OPTIONAL_HEADER;
typedef struct _PECOFF_IMAGE_SECTION_HEADER PECOFF_IMAGE_SECTION_HEADER, *PPECOFF_IMAGE_SECTION_HEADER; typedef struct _PECOFF_IMAGE_SECTION_HEADER PECOFF_IMAGE_SECTION_HEADER, *PPECOFF_IMAGE_SECTION_HEADER;
typedef struct _PECOFF_IMAGE_VXD_HEADER PECOFF_IMAGE_VXD_HEADER, *PPECOFF_IMAGE_VXD_HEADER; typedef struct _PECOFF_IMAGE_VXD_HEADER PECOFF_IMAGE_VXD_HEADER, *PPECOFF_IMAGE_VXD_HEADER;
typedef struct _PHYSICAL_MEMORY_DESCRIPTOR PHYSICAL_MEMORY_DESCRIPTOR, *PPHYSICAL_MEMORY_DESCRIPTOR;
typedef struct _PHYSICAL_MEMORY_RUN PHYSICAL_MEMORY_RUN, *PPHYSICAL_MEMORY_RUN;
typedef struct _POOL_HEADER POOL_HEADER, *PPOOL_HEADER;
typedef struct _POOL_TRACKING_BIG_ALLOCATIONS POOL_TRACKING_BIG_ALLOCATIONS, *PPOOL_TRACKING_BIG_ALLOCATIONS;
typedef struct _POOL_TRACKING_TABLE POOL_TRACKING_TABLE, *PPOOL_TRACKING_TABLE;
typedef struct _PROCESSOR_IDENTITY PROCESSOR_IDENTITY, *PPROCESSOR_IDENTITY; typedef struct _PROCESSOR_IDENTITY PROCESSOR_IDENTITY, *PPROCESSOR_IDENTITY;
typedef struct _PROCESSOR_POWER_STATE PROCESSOR_POWER_STATE, *PPROCESSOR_POWER_STATE; typedef struct _PROCESSOR_POWER_STATE PROCESSOR_POWER_STATE, *PPROCESSOR_POWER_STATE;
typedef struct _RTL_BITMAP RTL_BITMAP, *PRTL_BITMAP; typedef struct _RTL_BITMAP RTL_BITMAP, *PRTL_BITMAP;

View File

@@ -51,23 +51,21 @@ list(APPEND XTOSKRNL_SOURCE
${XTOSKRNL_SOURCE_DIR}/ke/spinlock.cc ${XTOSKRNL_SOURCE_DIR}/ke/spinlock.cc
${XTOSKRNL_SOURCE_DIR}/ke/sysres.cc ${XTOSKRNL_SOURCE_DIR}/ke/sysres.cc
${XTOSKRNL_SOURCE_DIR}/ke/timer.cc ${XTOSKRNL_SOURCE_DIR}/ke/timer.cc
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/alloc.cc
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/mmgr.cc ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/mmgr.cc
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pagemap.cc ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pagemap.cc
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/paging.cc ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/paging.cc
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pfault.cc ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pfault.cc
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pfn.cc ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pfn.cc
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pool.cc
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pte.cc ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pte.cc
${XTOSKRNL_SOURCE_DIR}/mm/alloc.cc ${XTOSKRNL_SOURCE_DIR}/mm/alloc.cc
${XTOSKRNL_SOURCE_DIR}/mm/colors.cc ${XTOSKRNL_SOURCE_DIR}/mm/colors.cc
${XTOSKRNL_SOURCE_DIR}/mm/data.cc ${XTOSKRNL_SOURCE_DIR}/mm/data.cc
${XTOSKRNL_SOURCE_DIR}/mm/exports.cc
${XTOSKRNL_SOURCE_DIR}/mm/hlpool.cc ${XTOSKRNL_SOURCE_DIR}/mm/hlpool.cc
${XTOSKRNL_SOURCE_DIR}/mm/kpool.cc ${XTOSKRNL_SOURCE_DIR}/mm/kpool.cc
${XTOSKRNL_SOURCE_DIR}/mm/mmgr.cc ${XTOSKRNL_SOURCE_DIR}/mm/mmgr.cc
${XTOSKRNL_SOURCE_DIR}/mm/paging.cc ${XTOSKRNL_SOURCE_DIR}/mm/paging.cc
${XTOSKRNL_SOURCE_DIR}/mm/pfn.cc ${XTOSKRNL_SOURCE_DIR}/mm/pfn.cc
${XTOSKRNL_SOURCE_DIR}/mm/pool.cc
${XTOSKRNL_SOURCE_DIR}/mm/pte.cc ${XTOSKRNL_SOURCE_DIR}/mm/pte.cc
${XTOSKRNL_SOURCE_DIR}/po/idle.cc ${XTOSKRNL_SOURCE_DIR}/po/idle.cc
${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/dispatch.cc ${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/dispatch.cc

View File

@@ -104,20 +104,12 @@ ArTrap\Vector:
/* Test previous mode and swap GS if needed */ /* Test previous mode and swap GS if needed */
movl $0, TrapPreviousMode(%rbp) movl $0, TrapPreviousMode(%rbp)
mov %cs, %ax mov %cs, %ax
and $3, %al and $1, %al
mov %al, TrapPreviousMode(%rbp) mov %al, TrapPreviousMode(%rbp)
jz KernelMode$\Vector jz KernelMode$\Vector
swapgs swapgs
jmp UserMode$\Vector
KernelMode$\Vector: KernelMode$\Vector:
/* Save kernel stack pointer (SS:RSP) */
movl %ss, %eax
mov %eax, TrapSegSs(%rbp)
lea TRAP_FRAME_SIZE(%rbp), %rax
mov %rax, TrapRsp(%rbp)
UserMode$\Vector:
/* Push Frame Pointer, clear direction flag and pass to trap dispatcher */ /* Push Frame Pointer, clear direction flag and pass to trap dispatcher */
mov %rsp, %rcx mov %rsp, %rcx
cld cld

View File

@@ -75,20 +75,12 @@ _ArTrap\Vector:
/* Test previous mode and swap GS if needed */ /* Test previous mode and swap GS if needed */
movl $0, TrapPreviousMode(%ebp) movl $0, TrapPreviousMode(%ebp)
mov %cs, %ax mov %cs, %ax
and $3, %al and $1, %al
mov %al, TrapPreviousMode(%ebp) mov %al, TrapPreviousMode(%ebp)
jz KernelMode$\Vector jz KernelMode$\Vector
swapgs swapgs
jmp UserMode$\Vector
KernelMode$\Vector: KernelMode$\Vector:
/* Save kernel stack pointer (SS:ESP) as CPU did not push them */
movl %ss, %eax
mov %eax, TrapSegSs(%ebp)
lea TrapEsp(%ebp), %eax
mov %eax, TrapEsp(%ebp)
UserMode$\Vector:
/* Push Frame Pointer, clear direction flag and pass to trap dispatcher */ /* Push Frame Pointer, clear direction flag and pass to trap dispatcher */
push %esp push %esp
cld cld
@@ -108,7 +100,6 @@ KernelModeReturn$\Vector:
mov TrapSegDs(%ebp), %ds mov TrapSegDs(%ebp), %ds
mov TrapSegEs(%ebp), %es mov TrapSegEs(%ebp), %es
mov TrapSegFs(%ebp), %fs mov TrapSegFs(%ebp), %fs
mov TrapSegGs(%ebp), %gs
/* Free stack space */ /* Free stack space */
add $(TRAP_FRAME_SIZE - TRAP_REGISTERS_SIZE), %esp add $(TRAP_FRAME_SIZE - TRAP_REGISTERS_SIZE), %esp

View File

@@ -9,41 +9,6 @@
#include <xtos.hh> #include <xtos.hh>
/**
* Checks whether the APIC is supported by the processor.
*
* @return This routine returns TRUE if APIC is supported, or FALSE otherwise.
*
* @since XT 1.0
*/
XTAPI
BOOLEAN
HL::Pic::CheckApicSupport(VOID)
{
CPUID_REGISTERS CpuRegisters;
/* Prepare CPUID registers */
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
CpuRegisters.SubLeaf = 0;
CpuRegisters.Eax = 0;
CpuRegisters.Ebx = 0;
CpuRegisters.Ecx = 0;
CpuRegisters.Edx = 0;
/* Get CPUID */
AR::CpuFunc::CpuId(&CpuRegisters);
/* Check APIC status from the CPUID results */
if(!(CpuRegisters.Edx & CPUID_FEATURES_EDX_APIC))
{
/* APIC is not supported */
return FALSE;
}
/* APIC is supported */
return TRUE;
}
/** /**
* Checks whether the x2APIC extension is supported by the processor. * Checks whether the x2APIC extension is supported by the processor.
* *
@@ -159,14 +124,6 @@ HL::Pic::InitializeApic(VOID)
APIC_LVT_REGISTER LvtRegister; APIC_LVT_REGISTER LvtRegister;
ULONG CpuNumber; ULONG CpuNumber;
/* Check APIC support */
if(!CheckApicSupport())
{
/* APIC is not supported, raise kernel panic */
DebugPrint(L"FATAL ERROR: Local APIC not present.\n");
KE::Crash::Panic(0x5D, CPUID_GET_STANDARD1_FEATURES, 0x0, 0x0, CPUID_FEATURES_EDX_APIC);
}
/* Determine APIC mode (xAPIC compatibility or x2APIC) */ /* Determine APIC mode (xAPIC compatibility or x2APIC) */
if(CheckX2ApicSupport()) if(CheckX2ApicSupport())
{ {

View File

@@ -56,8 +56,6 @@
#define TrapSegEs 330 #define TrapSegEs 330
#define TrapSegFs 332 #define TrapSegFs 332
#define TrapSegGs 334 #define TrapSegGs 334
#define TrapRsp 496
#define TrapSegSs 504
/* KTRAP_FRAME length related definitions */ /* KTRAP_FRAME length related definitions */
#define TRAP_FRAME_SIZE 512 #define TRAP_FRAME_SIZE 512

View File

@@ -31,13 +31,6 @@ namespace AR
OUT PVOID *TrampolineCode, OUT PVOID *TrampolineCode,
OUT PULONG_PTR TrampolineSize); OUT PULONG_PTR TrampolineSize);
STATIC XTAPI VOID InitializeProcessor(IN PVOID ProcessorStructures); STATIC XTAPI VOID InitializeProcessor(IN PVOID ProcessorStructures);
STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt,
IN USHORT Vector,
IN PVOID Handler,
IN USHORT Selector,
IN USHORT Ist,
IN USHORT Dpl,
IN USHORT Type);
private: private:
STATIC XTAPI VOID IdentifyProcessor(VOID); STATIC XTAPI VOID IdentifyProcessor(VOID);
@@ -69,6 +62,13 @@ namespace AR
STATIC XTAPI VOID SetGdtEntryBase(IN PKGDTENTRY Gdt, STATIC XTAPI VOID SetGdtEntryBase(IN PKGDTENTRY Gdt,
IN USHORT Selector, IN USHORT Selector,
IN ULONG_PTR Base); IN ULONG_PTR Base);
STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt,
IN USHORT Vector,
IN PVOID Handler,
IN USHORT Selector,
IN USHORT Ist,
IN USHORT Dpl,
IN USHORT Type);
}; };
} }

View File

@@ -24,11 +24,9 @@
#define TrapSegEs 38 #define TrapSegEs 38
#define TrapSegFs 40 #define TrapSegFs 40
#define TrapSegGs 42 #define TrapSegGs 42
#define TrapEsp 92
#define TrapSegSs 96
/* KTRAP_FRAME length related definitions */ /* KTRAP_FRAME length related definitions */
#define TRAP_FRAME_SIZE 100 #define TRAP_FRAME_SIZE 100
#define TRAP_REGISTERS_SIZE 56 #define TRAP_REGISTERS_SIZE 56
#endif /* __XTOSKRNL_I686_ASMSUP_H */ #endif /* __XTOSKRNL_AMD64_ASMSUP_H */

View File

@@ -34,13 +34,6 @@ namespace AR
OUT PVOID *TrampolineCode, OUT PVOID *TrampolineCode,
OUT PULONG_PTR TrampolineSize); OUT PULONG_PTR TrampolineSize);
STATIC XTAPI VOID InitializeProcessor(IN PVOID ProcessorStructures); STATIC XTAPI VOID InitializeProcessor(IN PVOID ProcessorStructures);
STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt,
IN USHORT Vector,
IN PVOID Handler,
IN USHORT Selector,
IN USHORT Ist,
IN USHORT Dpl,
IN USHORT Type);
private: private:
STATIC XTAPI VOID IdentifyProcessor(VOID); STATIC XTAPI VOID IdentifyProcessor(VOID);
@@ -74,6 +67,13 @@ namespace AR
STATIC XTAPI VOID SetGdtEntryBase(IN PKGDTENTRY Gdt, STATIC XTAPI VOID SetGdtEntryBase(IN PKGDTENTRY Gdt,
IN USHORT Selector, IN USHORT Selector,
IN ULONG_PTR Base); IN ULONG_PTR Base);
STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt,
IN USHORT Vector,
IN PVOID Handler,
IN USHORT Selector,
IN USHORT Ist,
IN USHORT Dpl,
IN USHORT Type);
STATIC XTAPI VOID SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock, STATIC XTAPI VOID SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelFaultStack); IN PVOID KernelFaultStack);

View File

@@ -32,7 +32,6 @@ namespace HL
IN ULONGLONG Value); IN ULONGLONG Value);
private: private:
STATIC XTAPI BOOLEAN CheckApicSupport(VOID);
STATIC XTAPI BOOLEAN CheckX2ApicSupport(VOID); STATIC XTAPI BOOLEAN CheckX2ApicSupport(VOID);
STATIC XTCDECL VOID HandleApicSpuriousService(VOID); STATIC XTCDECL VOID HandleApicSpuriousService(VOID);
STATIC XTCDECL VOID HandlePicSpuriousService(VOID); STATIC XTCDECL VOID HandlePicSpuriousService(VOID);

View File

@@ -16,7 +16,6 @@
#include <ke/crash.hh> #include <ke/crash.hh>
#include <ke/dpc.hh> #include <ke/dpc.hh>
#include <ke/event.hh> #include <ke/event.hh>
#include <ke/guard.hh>
#include <ke/irq.hh> #include <ke/irq.hh>
#include <ke/kprocess.hh> #include <ke/kprocess.hh>
#include <ke/krnlinit.hh> #include <ke/krnlinit.hh>

View File

@@ -20,11 +20,11 @@ namespace KE
public: public:
STATIC XTAPI VOID HaltSystem(VOID); STATIC XTAPI VOID HaltSystem(VOID);
STATIC XTAPI VOID Panic(IN ULONG Code); STATIC XTAPI VOID Panic(IN ULONG Code);
STATIC XTAPI VOID Panic(IN ULONG Code, STATIC XTAPI VOID PanicEx(IN ULONG Code,
IN ULONG_PTR Parameter1, IN ULONG_PTR Parameter1,
IN ULONG_PTR Parameter2, IN ULONG_PTR Parameter2,
IN ULONG_PTR Parameter3, IN ULONG_PTR Parameter3,
IN ULONG_PTR Parameter4); IN ULONG_PTR Parameter4);
}; };
} }

View File

@@ -1,61 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ke/guard.hh
* DESCRIPTION: Kernel synchronization guard
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_GUARD_HH
#define __XTOSKRNL_KE_GUARD_HH
#include <xtos.hh>
#include <ke/spinlock.hh>
/* Kernel Library */
namespace KE
{
class QueuedSpinLockGuard
{
private:
KSPIN_LOCK_QUEUE_LEVEL QueuedLockLevel;
public:
QueuedSpinLockGuard(IN OUT KSPIN_LOCK_QUEUE_LEVEL LockLevel)
{
QueuedLockLevel = LockLevel;
KE::SpinLock::AcquireQueuedSpinLock(QueuedLockLevel);
}
~QueuedSpinLockGuard()
{
KE::SpinLock::ReleaseQueuedSpinLock(QueuedLockLevel);
}
QueuedSpinLockGuard(const QueuedSpinLockGuard&) = delete;
QueuedSpinLockGuard& operator=(const QueuedSpinLockGuard&) = delete;
};
class SpinLockGuard
{
private:
PKSPIN_LOCK Lock;
public:
SpinLockGuard(IN OUT PKSPIN_LOCK SpinLock)
{
Lock = SpinLock;
KE::SpinLock::AcquireSpinLock(Lock);
}
~SpinLockGuard()
{
KE::SpinLock::ReleaseSpinLock(Lock);
}
SpinLockGuard(const SpinLockGuard&) = delete;
SpinLockGuard& operator=(const SpinLockGuard&) = delete;
};
}
#endif /* __XTOSKRNL_KE_GUARD_HH */

View File

@@ -44,6 +44,47 @@ namespace KE
STATIC XTFASTCALL VOID ReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock); STATIC XTFASTCALL VOID ReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock);
STATIC XTFASTCALL BOOLEAN TestSpinLock(IN PKSPIN_LOCK SpinLock); STATIC XTFASTCALL BOOLEAN TestSpinLock(IN PKSPIN_LOCK SpinLock);
}; };
class QueuedSpinLockGuard
{
private:
KSPIN_LOCK_QUEUE_LEVEL QueuedLockLevel;
public:
QueuedSpinLockGuard(IN OUT KSPIN_LOCK_QUEUE_LEVEL LockLevel)
{
QueuedLockLevel = LockLevel;
KE::SpinLock::AcquireQueuedSpinLock(QueuedLockLevel);
}
~QueuedSpinLockGuard()
{
KE::SpinLock::ReleaseQueuedSpinLock(QueuedLockLevel);
}
QueuedSpinLockGuard(const QueuedSpinLockGuard&) = delete;
QueuedSpinLockGuard& operator=(const QueuedSpinLockGuard&) = delete;
};
class SpinLockGuard
{
private:
PKSPIN_LOCK SpinLock;
public:
SpinLockGuard(IN OUT PKSPIN_LOCK SpinLock)
{
KE::SpinLock::AcquireSpinLock(SpinLock);
}
~SpinLockGuard()
{
KE::SpinLock::ReleaseSpinLock(SpinLock);
}
SpinLockGuard(const SpinLockGuard&) = delete;
SpinLockGuard& operator=(const SpinLockGuard&) = delete;
};
} }
#endif /* __XTOSKRNL_KE_SPINLOCK_HH */ #endif /* __XTOSKRNL_KE_SPINLOCK_HH */

View File

@@ -17,12 +17,10 @@
#include <mm/alloc.hh> #include <mm/alloc.hh>
#include <mm/colors.hh> #include <mm/colors.hh>
#include <mm/guard.hh>
#include <mm/hlpool.hh> #include <mm/hlpool.hh>
#include <mm/kpool.hh> #include <mm/kpool.hh>
#include <mm/mmgr.hh> #include <mm/mmgr.hh>
#include <mm/pfault.hh> #include <mm/pfault.hh>
#include <mm/pfn.hh> #include <mm/pfn.hh>
#include <mm/pool.hh>
#endif /* __XTOSKRNL_MM_HH */ #endif /* __XTOSKRNL_MM_HH */

View File

@@ -2,7 +2,7 @@
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/mm/alloc.hh * FILE: xtoskrnl/includes/mm/alloc.hh
* DESCRIPTION: Memory Manager pool allocator * DESCRIPTION: Memory manager pool allocation
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com> * DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/ */
@@ -10,80 +10,34 @@
#define __XTOSKRNL_MM_ALLOC_HH #define __XTOSKRNL_MM_ALLOC_HH
#include <xtos.hh> #include <xtos.hh>
#include <mm/pool.hh>
/* Memory Manager */ /* Memory Manager */
namespace MM namespace MM
{ {
class Allocator final : private Pool class Allocator
{ {
private: private:
STATIC PPOOL_TRACKING_TABLE AllocationsTrackingExpansionTable; STATIC PFN_NUMBER NonPagedPoolFrameEnd;
STATIC SIZE_T AllocationsTrackingExpansionTableSize; STATIC PFN_NUMBER NonPagedPoolFrameStart;
STATIC PPOOL_TRACKING_TABLE AllocationsTrackingTable; STATIC LIST_ENTRY NonPagedPoolFreeList[MM_MAX_FREE_PAGE_LIST_HEADS];
STATIC KSPIN_LOCK AllocationsTrackingTableLock;
STATIC SIZE_T AllocationsTrackingTableMask;
STATIC SIZE_T AllocationsTrackingTableSize;
STATIC ULONG BigAllocationsInUse;
STATIC PPOOL_TRACKING_BIG_ALLOCATIONS BigAllocationsTrackingTable;
STATIC SIZE_T BigAllocationsTrackingTableHash;
STATIC KSPIN_LOCK BigAllocationsTrackingTableLock;
STATIC SIZE_T BigAllocationsTrackingTableSize;
STATIC PPOOL_TRACKING_TABLE TagTables[MM_POOL_TRACKING_TABLES];
public: public:
STATIC XTAPI XTSTATUS AllocatePages(IN MMPOOL_TYPE PoolType, STATIC XTAPI XTSTATUS AllocatePages(IN MMPOOL_TYPE PoolType,
IN SIZE_T Bytes, IN SIZE_T Bytes,
OUT PVOID *Memory); OUT PVOID *Memory);
STATIC XTAPI XTSTATUS AllocatePool(IN MMPOOL_TYPE PoolType,
IN SIZE_T Bytes,
OUT PVOID *Memory);
STATIC XTAPI XTSTATUS AllocatePool(IN MMPOOL_TYPE PoolType,
IN SIZE_T Bytes,
OUT PVOID *Memory,
IN ULONG Tag);
STATIC XTAPI XTSTATUS FreePages(IN PVOID VirtualAddress); STATIC XTAPI XTSTATUS FreePages(IN PVOID VirtualAddress);
STATIC XTAPI XTSTATUS FreePages(IN PVOID VirtualAddress, STATIC XTAPI VOID InitializeNonPagedPool(VOID);
OUT PPFN_NUMBER PagesFreed); STATIC XTAPI VOID InitializePagedPool(VOID);
STATIC XTAPI XTSTATUS FreePool(IN PVOID VirtualAddress);
STATIC XTAPI XTSTATUS FreePool(IN PVOID VirtualAddress,
IN ULONG Tag);
STATIC XTAPI VOID InitializeAllocationsTracking(VOID);
STATIC XTAPI VOID InitializeBigAllocationsTracking(VOID);
private: private:
STATIC XTAPI XTSTATUS AllocateNonPagedPoolPages(IN PFN_COUNT Pages, STATIC XTAPI XTSTATUS AllocateNonPagedPoolPages(IN PFN_COUNT Pages,
OUT PVOID *Memory); OUT PVOID *Memory);
STATIC XTAPI XTSTATUS AllocatePagedPoolPages(IN PFN_COUNT Pages, STATIC XTAPI XTSTATUS AllocatePagedPoolPages(IN PFN_COUNT Pages,
OUT PVOID *Memory); OUT PVOID *Memory);
STATIC XTINLINE ULONG ComputeHash(IN PVOID VirtualAddress); STATIC XTAPI XTSTATUS FreeNonPagedPoolPages(IN PVOID VirtualAddress);
STATIC XTINLINE ULONG ComputeHash(IN ULONG Tag, STATIC XTAPI XTSTATUS FreePagedPoolPages(IN PVOID VirtualAddress);
IN ULONG TableMask); STATIC XTAPI VOID MapNonPagedPool(VOID);
STATIC XTAPI BOOLEAN ExpandBigAllocationsTable(VOID);
STATIC XTAPI XTSTATUS FreeNonPagedPoolPages(IN PVOID VirtualAddress,
OUT PPFN_NUMBER PagesFreed);
STATIC XTAPI XTSTATUS FreePagedPoolPages(IN PVOID VirtualAddress,
OUT PPFN_NUMBER PagesFreed);
STATIC XTAPI VOID RegisterAllocationTag(IN ULONG Tag,
IN SIZE_T Bytes,
IN MMPOOL_TYPE PoolType);
STATIC XTAPI VOID RegisterAllocationTagExpansion(IN ULONG Tag,
IN SIZE_T Bytes,
IN MMPOOL_TYPE PoolType);
STATIC XTAPI BOOLEAN RegisterBigAllocationTag(IN PVOID VirtualAddress,
IN ULONG Tag,
IN ULONG Pages,
IN MMPOOL_TYPE PoolType);
STATIC XTAPI VOID UnregisterAllocationTag(IN ULONG Tag,
IN SIZE_T Bytes,
IN MMPOOL_TYPE PoolType);
STATIC XTAPI VOID UnregisterAllocationTagExpansion(IN ULONG Tag,
IN SIZE_T Bytes,
IN MMPOOL_TYPE PoolType);
STATIC XTAPI ULONG UnregisterBigAllocationTag(IN PVOID VirtualAddress,
OUT PULONG_PTR Pages,
IN MMPOOL_TYPE PoolType);
}; };
} }

View File

@@ -39,7 +39,7 @@ namespace MM
XTAPI PMMPPE GetPpeAddress(IN PVOID Address); XTAPI PMMPPE GetPpeAddress(IN PVOID Address);
XTAPI ULONG GetPpeOffset(IN PVOID Address); XTAPI ULONG GetPpeOffset(IN PVOID Address);
VIRTUAL XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer) = 0; VIRTUAL XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer) = 0;
XTAPI ULONGLONG GetPte(IN PMMPTE PtePointer); XTAPI ULONG_PTR GetPte(IN PMMPTE PtePointer);
XTAPI PMMPTE GetPteAddress(IN PVOID Address); XTAPI PMMPTE GetPteAddress(IN PVOID Address);
XTAPI LONG GetPteDistance(PMMPTE EndPte, XTAPI LONG GetPteDistance(PMMPTE EndPte,
PMMPTE StartPte); PMMPTE StartPte);
@@ -61,9 +61,9 @@ namespace MM
IN BOOLEAN Value); IN BOOLEAN Value);
XTAPI VOID SetPte(IN PMMPTE PtePointer, XTAPI VOID SetPte(IN PMMPTE PtePointer,
IN PFN_NUMBER PageFrameNumber, IN PFN_NUMBER PageFrameNumber,
IN ULONGLONG AttributesMask); IN ULONG_PTR AttributesMask);
XTAPI VOID SetPte(IN PMMPTE PtePointer, XTAPI VOID SetPte(IN PMMPTE PtePointer,
IN ULONGLONG Attributes); IN ULONG_PTR Attributes);
XTAPI VOID SetPteCaching(IN PMMPTE PtePointer, XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,
IN BOOLEAN CacheDisable, IN BOOLEAN CacheDisable,
IN BOOLEAN WriteThrough); IN BOOLEAN WriteThrough);

View File

@@ -25,7 +25,6 @@ namespace MM
IN LONG Count); IN LONG Count);
STATIC XTAPI BOOLEAN CanonicalAddress(IN PVOID VirtualAddress); STATIC XTAPI BOOLEAN CanonicalAddress(IN PVOID VirtualAddress);
STATIC XTAPI VOID ClearPte(IN PMMPTE PtePointer); STATIC XTAPI VOID ClearPte(IN PMMPTE PtePointer);
STATIC XTAPI VOID FlushEntireTlb(VOID);
STATIC XTAPI VOID FlushTlb(VOID); STATIC XTAPI VOID FlushTlb(VOID);
STATIC XTAPI ULONG_PTR GetNextEntry(IN PMMPTE Pte); STATIC XTAPI ULONG_PTR GetNextEntry(IN PMMPTE Pte);
STATIC XTAPI PMMPTE GetNextPte(IN PMMPTE Pte); STATIC XTAPI PMMPTE GetNextPte(IN PMMPTE Pte);
@@ -38,7 +37,7 @@ namespace MM
STATIC XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer); STATIC XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);
STATIC XTAPI PMMPPE GetPpeAddress(IN PVOID Address); STATIC XTAPI PMMPPE GetPpeAddress(IN PVOID Address);
STATIC XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer); STATIC XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer);
STATIC XTAPI ULONGLONG GetPte(IN PMMPTE PtePointer); STATIC XTAPI ULONG_PTR GetPte(IN PMMPTE PtePointer);
STATIC XTAPI PMMPTE GetPteAddress(IN PVOID Address); STATIC XTAPI PMMPTE GetPteAddress(IN PVOID Address);
STATIC XTAPI LONG GetPteDistance(PMMPTE EndPte, STATIC XTAPI LONG GetPteDistance(PMMPTE EndPte,
PMMPTE StartPte); PMMPTE StartPte);
@@ -58,9 +57,9 @@ namespace MM
IN BOOLEAN Value); IN BOOLEAN Value);
STATIC XTAPI VOID SetPte(IN PMMPTE PtePointer, STATIC XTAPI VOID SetPte(IN PMMPTE PtePointer,
IN PFN_NUMBER PageFrameNumber, IN PFN_NUMBER PageFrameNumber,
IN ULONGLONG AttributesMask); IN ULONG_PTR AttributesMask);
STATIC XTAPI VOID SetPte(IN PMMPTE PtePointer, STATIC XTAPI VOID SetPte(IN PMMPTE PtePointer,
IN ULONGLONG Attributes); IN ULONG_PTR Attributes);
STATIC XTAPI VOID SetPteCaching(IN PMMPTE PtePointer, STATIC XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,
IN BOOLEAN CacheDisable, IN BOOLEAN CacheDisable,
IN BOOLEAN WriteThrough); IN BOOLEAN WriteThrough);

View File

@@ -1,88 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/mm/guard.hh
* DESCRIPTION: Memory Manager synchronization guard
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_MM_GUARD_HH
#define __XTOSKRNL_MM_GUARD_HH
#include <xtos.hh>
#include <ke/runlevel.hh>
#include <ke/spinlock.hh>
/* Memory Manager */
namespace MM
{
class PoolLockGuard
{
private:
BOOLEAN Locked;
MMPOOL_TYPE LockPoolType;
KRUNLEVEL PreviousRunLevel;
public:
PoolLockGuard(IN MMPOOL_TYPE PoolType)
{
LockPoolType = PoolType;
/* Determine the appropriate synchronization mechanism based on the requested pool type */
if(LockPoolType == NonPagedPool)
{
/* Elevate the runlevel to DISPATCH_LEVEL */
PreviousRunLevel = KE::RunLevel::RaiseRunLevel(DISPATCH_LEVEL);
/* Acquire the global queued spinlock protecting the non-paged pool */
KE::SpinLock::AcquireQueuedSpinLock(NonPagedPoolLock);
}
else
{
/* Paged pool requires a mutex, currently unimplemented */
UNIMPLEMENTED;
}
/* Mark the guard as actively holding the lock */
Locked = TRUE;
}
~PoolLockGuard(VOID)
{
/* Automatically release the held lock upon going out of scope */
Release();
}
PoolLockGuard(const PoolLockGuard&) = delete;
PoolLockGuard& operator=(const PoolLockGuard&) = delete;
VOID Release(VOID)
{
/* Check if the guard is currently holding a lock */
if(!Locked)
{
/* Return, to prevent a double-free */
return;
}
/* Determine the appropriate synchronization mechanism based on the requested pool type */
if(LockPoolType == NonPagedPool)
{
/* Release the non-paged pool spinlock and subsequently restore the original runlevel */
KE::SpinLock::ReleaseQueuedSpinLock(NonPagedPoolLock);
KE::RunLevel::LowerRunLevel(PreviousRunLevel);
}
else
{
/* Paged pool requires a mutex, currently unimplemented */
UNIMPLEMENTED;
}
/* Update the internal state, indicating that the lock is no longer held */
Locked = FALSE;
}
};
}
#endif /* __XTOSKRNL_MM_GUARD_HH */

View File

@@ -36,7 +36,7 @@ namespace MM
XTAPI PMMPPE GetPpeAddress(IN PVOID Address); XTAPI PMMPPE GetPpeAddress(IN PVOID Address);
XTAPI ULONG GetPpeOffset(IN PVOID Address); XTAPI ULONG GetPpeOffset(IN PVOID Address);
XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer); XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer);
VIRTUAL XTAPI ULONGLONG GetPte(IN PMMPTE PtePointer) = 0; VIRTUAL XTAPI ULONG_PTR GetPte(IN PMMPTE PtePointer) = 0;
XTAPI PMMPTE GetPteAddress(IN PVOID Address); XTAPI PMMPTE GetPteAddress(IN PVOID Address);
XTAPI ULONG GetPteOffset(IN PVOID Address); XTAPI ULONG GetPteOffset(IN PVOID Address);
VIRTUAL XTAPI LONG GetPteDistance(PMMPTE EndPte, VIRTUAL XTAPI LONG GetPteDistance(PMMPTE EndPte,
@@ -55,9 +55,9 @@ namespace MM
IN BOOLEAN Value) = 0; IN BOOLEAN Value) = 0;
VIRTUAL XTAPI VOID SetPte(IN PMMPTE PtePointer, VIRTUAL XTAPI VOID SetPte(IN PMMPTE PtePointer,
IN PFN_NUMBER PageFrameNumber, IN PFN_NUMBER PageFrameNumber,
IN ULONGLONG AttributesMask) = 0; IN ULONG_PTR AttributesMask) = 0;
VIRTUAL XTAPI VOID SetPte(IN PMMPTE PtePointer, VIRTUAL XTAPI VOID SetPte(IN PMMPTE PtePointer,
IN ULONGLONG Attributes) = 0; IN ULONG_PTR Attributes) = 0;
VIRTUAL XTAPI VOID SetPteCaching(IN PMMPTE PtePointer, VIRTUAL XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,
IN BOOLEAN CacheDisable, IN BOOLEAN CacheDisable,
IN BOOLEAN WriteThrough) = 0; IN BOOLEAN WriteThrough) = 0;
@@ -79,7 +79,7 @@ namespace MM
XTAPI BOOLEAN GetOneEntry(IN PMMPTE Pte); XTAPI BOOLEAN GetOneEntry(IN PMMPTE Pte);
XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte); XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte);
XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer); XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);
XTAPI ULONGLONG GetPte(IN PMMPTE PtePointer); XTAPI ULONG_PTR GetPte(IN PMMPTE PtePointer);
XTAPI LONG GetPteDistance(PMMPTE EndPte, XTAPI LONG GetPteDistance(PMMPTE EndPte,
PMMPTE StartPte); PMMPTE StartPte);
XTAPI ULONG GetPteSize(VOID); XTAPI ULONG GetPteSize(VOID);
@@ -95,9 +95,9 @@ namespace MM
IN BOOLEAN Value); IN BOOLEAN Value);
XTAPI VOID SetPte(IN PMMPTE PtePointer, XTAPI VOID SetPte(IN PMMPTE PtePointer,
IN PFN_NUMBER PageFrameNumber, IN PFN_NUMBER PageFrameNumber,
IN ULONGLONG AttributesMask); IN ULONG_PTR AttributesMask);
XTAPI VOID SetPte(IN PMMPTE PtePointer, XTAPI VOID SetPte(IN PMMPTE PtePointer,
IN ULONGLONG Attributes); IN ULONG_PTR Attributes);
XTAPI VOID SetPteCaching(IN PMMPTE PtePointer, XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,
IN BOOLEAN CacheDisable, IN BOOLEAN CacheDisable,
IN BOOLEAN WriteThrough); IN BOOLEAN WriteThrough);
@@ -118,7 +118,7 @@ namespace MM
XTAPI BOOLEAN GetOneEntry(IN PMMPTE Pte); XTAPI BOOLEAN GetOneEntry(IN PMMPTE Pte);
XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte); XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte);
XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer); XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);
XTAPI ULONGLONG GetPte(IN PMMPTE PtePointer); XTAPI ULONG_PTR GetPte(IN PMMPTE PtePointer);
XTAPI LONG GetPteDistance(PMMPTE EndPte, XTAPI LONG GetPteDistance(PMMPTE EndPte,
PMMPTE StartPte); PMMPTE StartPte);
XTAPI ULONG GetPteSize(VOID); XTAPI ULONG GetPteSize(VOID);
@@ -134,9 +134,9 @@ namespace MM
IN BOOLEAN Value); IN BOOLEAN Value);
XTAPI VOID SetPte(IN PMMPTE PtePointer, XTAPI VOID SetPte(IN PMMPTE PtePointer,
IN PFN_NUMBER PageFrameNumber, IN PFN_NUMBER PageFrameNumber,
IN ULONGLONG AttributesMask); IN ULONG_PTR AttributesMask);
XTAPI VOID SetPte(IN PMMPTE PtePointer, XTAPI VOID SetPte(IN PMMPTE PtePointer,
IN ULONGLONG Attributes); IN ULONG_PTR Attributes);
XTAPI VOID SetPteCaching(IN PMMPTE PtePointer, XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,
IN BOOLEAN CacheDisable, IN BOOLEAN CacheDisable,
IN BOOLEAN WriteThrough); IN BOOLEAN WriteThrough);

View File

@@ -25,7 +25,6 @@ namespace MM
IN LONG Count); IN LONG Count);
STATIC XTAPI BOOLEAN CanonicalAddress(IN PVOID VirtualAddress); STATIC XTAPI BOOLEAN CanonicalAddress(IN PVOID VirtualAddress);
STATIC XTAPI VOID ClearPte(IN PMMPTE PtePointer); STATIC XTAPI VOID ClearPte(IN PMMPTE PtePointer);
STATIC XTAPI VOID FlushEntireTlb(VOID);
STATIC XTAPI VOID FlushTlb(VOID); STATIC XTAPI VOID FlushTlb(VOID);
STATIC XTAPI ULONG_PTR GetNextEntry(IN PMMPTE Pte); STATIC XTAPI ULONG_PTR GetNextEntry(IN PMMPTE Pte);
STATIC XTAPI PMMPTE GetNextPte(IN PMMPTE Pte); STATIC XTAPI PMMPTE GetNextPte(IN PMMPTE Pte);
@@ -36,7 +35,7 @@ namespace MM
STATIC XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer); STATIC XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);
STATIC XTAPI PMMPPE GetPpeAddress(IN PVOID Address); STATIC XTAPI PMMPPE GetPpeAddress(IN PVOID Address);
STATIC XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer); STATIC XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer);
STATIC XTAPI ULONGLONG GetPte(IN PMMPTE PtePointer); STATIC XTAPI ULONG_PTR GetPte(IN PMMPTE PtePointer);
STATIC XTAPI PMMPTE GetPteAddress(IN PVOID Address); STATIC XTAPI PMMPTE GetPteAddress(IN PVOID Address);
STATIC XTAPI LONG GetPteDistance(PMMPTE EndPte, STATIC XTAPI LONG GetPteDistance(PMMPTE EndPte,
PMMPTE StartPte); PMMPTE StartPte);
@@ -54,9 +53,9 @@ namespace MM
IN BOOLEAN Value); IN BOOLEAN Value);
STATIC XTAPI VOID SetPte(IN PMMPTE PtePointer, STATIC XTAPI VOID SetPte(IN PMMPTE PtePointer,
IN PFN_NUMBER PageFrameNumber, IN PFN_NUMBER PageFrameNumber,
IN ULONGLONG AttributesMask); IN ULONG_PTR AttributesMask);
STATIC XTAPI VOID SetPte(IN PMMPTE PtePointer, STATIC XTAPI VOID SetPte(IN PMMPTE PtePointer,
IN ULONGLONG Attributes); IN ULONG_PTR Attributes);
STATIC XTAPI VOID SetPteCaching(IN PMMPTE PtePointer, STATIC XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,
IN BOOLEAN CacheDisable, IN BOOLEAN CacheDisable,
IN BOOLEAN WriteThrough); IN BOOLEAN WriteThrough);

View File

@@ -17,6 +17,9 @@ namespace MM
{ {
class KernelPool class KernelPool
{ {
private:
STATIC UCHAR ProcessorStructuresData[MAXIMUM_PROCESSORS][KPROCESSOR_STRUCTURES_SIZE];
public: public:
STATIC XTAPI XTSTATUS AllocateKernelStack(OUT PVOID *Stack, STATIC XTAPI XTSTATUS AllocateKernelStack(OUT PVOID *Stack,
IN ULONG StackSize); IN ULONG StackSize);

View File

@@ -20,13 +20,11 @@ namespace MM
private: private:
STATIC MMMEMORY_LAYOUT MemoryLayout; STATIC MMMEMORY_LAYOUT MemoryLayout;
STATIC PFN_NUMBER NumberOfSystemPtes; STATIC PFN_NUMBER NumberOfSystemPtes;
STATIC PPHYSICAL_MEMORY_DESCRIPTOR PhysicalMemoryBlock;
public: public:
STATIC XTAPI ULONG_PTR GetInstalledMemorySize(VOID); STATIC XTAPI ULONG_PTR GetInstalledMemorySize(VOID);
STATIC XTAPI PMMMEMORY_LAYOUT GetMemoryLayout(VOID); STATIC XTAPI PMMMEMORY_LAYOUT GetMemoryLayout(VOID);
STATIC XTAPI PFN_NUMBER GetNumberOfSystemPtes(VOID); STATIC XTAPI PFN_NUMBER GetNumberOfSystemPtes();
STATIC XTAPI PPHYSICAL_MEMORY_DESCRIPTOR GetPhysicalMemoryBlock(VOID);
STATIC XTAPI VOID InitializeMemoryLayout(VOID); STATIC XTAPI VOID InitializeMemoryLayout(VOID);
STATIC XTAPI VOID InitializeMemoryManager(VOID); STATIC XTAPI VOID InitializeMemoryManager(VOID);
STATIC XTAPI BOOLEAN VerifyMemoryTypeFree(IN LOADER_MEMORY_TYPE MemoryType); STATIC XTAPI BOOLEAN VerifyMemoryTypeFree(IN LOADER_MEMORY_TYPE MemoryType);

View File

@@ -30,7 +30,6 @@ namespace MM
STATIC ULONGLONG NumberOfPhysicalPages; STATIC ULONGLONG NumberOfPhysicalPages;
STATIC LOADER_MEMORY_DESCRIPTOR OriginalFreeDescriptor; STATIC LOADER_MEMORY_DESCRIPTOR OriginalFreeDescriptor;
STATIC PMMPFNLIST PageLocationList[]; STATIC PMMPFNLIST PageLocationList[];
STATIC RTL_BITMAP PfnBitMap;
STATIC MMPFNLIST RomPagesList; STATIC MMPFNLIST RomPagesList;
STATIC MMPFNLIST StandbyPagesList; STATIC MMPFNLIST StandbyPagesList;
STATIC MMPFNLIST ZeroedPagesList; STATIC MMPFNLIST ZeroedPagesList;
@@ -50,7 +49,6 @@ namespace MM
STATIC XTAPI ULONG_PTR GetHighestPhysicalPage(VOID); STATIC XTAPI ULONG_PTR GetHighestPhysicalPage(VOID);
STATIC XTAPI ULONGLONG GetNumberOfPhysicalPages(VOID); STATIC XTAPI ULONGLONG GetNumberOfPhysicalPages(VOID);
STATIC XTAPI PMMPFN GetPfnEntry(IN PFN_NUMBER Pfn); STATIC XTAPI PMMPFN GetPfnEntry(IN PFN_NUMBER Pfn);
STATIC XTAPI VOID InitializePfnBitmap(VOID);
STATIC XTAPI VOID InitializePfnDatabase(VOID); STATIC XTAPI VOID InitializePfnDatabase(VOID);
STATIC XTAPI VOID LinkPfn(IN PFN_NUMBER PageFrameIndex, STATIC XTAPI VOID LinkPfn(IN PFN_NUMBER PageFrameIndex,
IN PMMPTE PointerPte, IN PMMPTE PointerPte,

View File

@@ -1,68 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/mm/pool.hh
* DESCRIPTION: Memory Manager pool manager
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_MM_POOL_HH
#define __XTOSKRNL_MM_POOL_HH
#include <xtos.hh>
/* Memory Manager */
namespace MM
{
class Pool
{
protected:
STATIC POOL_DESCRIPTOR NonPagedPoolDescriptor;
STATIC PFN_NUMBER NonPagedPoolFrameEnd;
STATIC PFN_NUMBER NonPagedPoolFrameStart;
STATIC LIST_ENTRY NonPagedPoolFreeList[MM_MAX_FREE_PAGE_LIST_HEADS];
STATIC ULONG PoolSecureCookie;
STATIC PPOOL_DESCRIPTOR PoolVector[2];
public:
STATIC XTAPI MMPOOL_TYPE DeterminePoolType(IN PVOID VirtualAddress);
STATIC XTAPI VOID InitializeNonPagedPool(VOID);
STATIC XTAPI VOID InitializePagedPool(VOID);
STATIC XTAPI VOID InitializePoolSecurity(VOID);
protected:
STATIC XTAPI PLIST_ENTRY DecodePoolLink(IN PLIST_ENTRY PoolLink);
STATIC XTAPI PLIST_ENTRY EncodePoolLink(IN PLIST_ENTRY PoolLink);
STATIC XTAPI PPOOL_HEADER GetPoolBlock(IN PPOOL_HEADER Header, IN SSIZE_T Index);
STATIC XTAPI PPOOL_HEADER GetPoolEntry(IN PVOID Payload);
STATIC XTAPI PLIST_ENTRY GetPoolFreeBlock(IN PPOOL_HEADER Header);
STATIC XTAPI PPOOL_HEADER GetPoolNextBlock(IN PPOOL_HEADER Header);
STATIC XTAPI PPOOL_HEADER GetPoolPreviousBlock(IN PPOOL_HEADER Header);
STATIC XTAPI VOID InsertPoolHeadList(IN PLIST_ENTRY ListHead,
IN PLIST_ENTRY Entry);
STATIC XTAPI VOID InsertPoolTailList(IN PLIST_ENTRY ListHead,
IN PLIST_ENTRY Entry);
STATIC XTAPI BOOLEAN PoolListEmpty(IN PLIST_ENTRY ListHead);
STATIC XTAPI VOID RemovePoolEntryList(IN PLIST_ENTRY Entry);
STATIC XTAPI PLIST_ENTRY RemovePoolHeadList(IN PLIST_ENTRY ListHead);
STATIC XTAPI PLIST_ENTRY RemovePoolTailList(IN PLIST_ENTRY ListHead);
STATIC XTAPI VOID VerifyPoolBlocks(IN PVOID Block);
STATIC XTAPI VOID VerifyPoolHeader(IN PPOOL_HEADER Entry);
STATIC XTAPI VOID VerifyPoolLinks(IN PLIST_ENTRY ListHead);
STATIC XTAPI VOID VerifyRunLevel(IN MMPOOL_TYPE PoolType,
IN SIZE_T Bytes,
IN PVOID Entry);
private:
STATIC XTAPI VOID InitializePoolDescriptor(IN PPOOL_DESCRIPTOR Descriptor,
IN MMPOOL_TYPE PoolType,
IN ULONG Index,
IN ULONG Threshold,
IN PVOID LockAddress);
STATIC XTAPI VOID InitializePoolListHead(IN PLIST_ENTRY ListHead);
STATIC XTAPI VOID MapNonPagedPool(VOID);
};
}
#endif /* __XTOSKRNL_MM_POOL_HH */

View File

@@ -33,11 +33,7 @@ KE::Irq::SetInterruptHandler(IN ULONG Vector,
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock(); ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
/* Update interrupt handler */ /* Update interrupt handler */
AR::ProcSup::SetIdtGate(ProcessorBlock->IdtBase, ProcessorBlock->IdtBase[(UCHAR) Vector].OffsetLow = ((ULONG_PTR)Handler & 0xFFFF);
Vector, ProcessorBlock->IdtBase[(UCHAR) Vector].OffsetMiddle = (((ULONG_PTR)Handler >> 16) & 0xFFFF);
Handler, ProcessorBlock->IdtBase[(UCHAR) Vector].OffsetHigh = (ULONG_PTR)Handler >> 32;
KGDT_R0_CODE,
0,
KIDT_ACCESS_RING0,
AMD64_INTERRUPT_GATE);
} }

View File

@@ -43,7 +43,7 @@ XTAPI
VOID VOID
KE::Crash::Panic(IN ULONG Code) KE::Crash::Panic(IN ULONG Code)
{ {
Panic(Code, 0, 0, 0, 0); PanicEx(Code, 0, 0, 0, 0);
} }
/** /**
@@ -70,13 +70,12 @@ KE::Crash::Panic(IN ULONG Code)
*/ */
XTAPI XTAPI
VOID VOID
KE::Crash::Panic(IN ULONG Code, KE::Crash::PanicEx(IN ULONG Code,
IN ULONG_PTR Parameter1, IN ULONG_PTR Parameter1,
IN ULONG_PTR Parameter2, IN ULONG_PTR Parameter2,
IN ULONG_PTR Parameter3, IN ULONG_PTR Parameter3,
IN ULONG_PTR Parameter4) IN ULONG_PTR Parameter4)
{ {
KD::DebugIo::KdPrint(L"Fatal System Error: 0x%08lx (0x%zx 0x%zx 0x%zx 0x%zx)\nKernel Panic!\n\n", KD::DebugIo::KdPrint(L"Fatal System Error: 0x%08lx\nKernel Panic!\n\n", Code);
Code, Parameter1, Parameter2, Parameter3, Parameter4);
HaltSystem(); HaltSystem();
} }

View File

@@ -33,11 +33,6 @@ KE::Irq::SetInterruptHandler(IN ULONG Vector,
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock(); ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
/* Update interrupt handler */ /* Update interrupt handler */
AR::ProcSup::SetIdtGate(ProcessorBlock->IdtBase, ProcessorBlock->IdtBase[(UCHAR) Vector].Offset = (USHORT)((ULONG)Handler & 0xFFFF);
Vector, ProcessorBlock->IdtBase[(UCHAR) Vector].ExtendedOffset = (USHORT)((ULONG)Handler >> 16);
Handler,
KGDT_R0_CODE,
0,
KIDT_ACCESS_RING0,
I686_INTERRUPT_GATE);
} }

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,8 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/mm/amd64/pool.cc * FILE: xtoskrnl/mm/amd64/alloc.cc
* DESCRIPTION: AMD64 Memory Manager pool manager * DESCRIPTION: Memory manager pool allocation
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com> * DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/ */
@@ -18,7 +18,7 @@
*/ */
XTAPI XTAPI
VOID VOID
MM::Pool::MapNonPagedPool(VOID) MM::Allocator::MapNonPagedPool(VOID)
{ {
PMMMEMORY_LAYOUT MemoryLayout; PMMMEMORY_LAYOUT MemoryLayout;

View File

@@ -302,7 +302,7 @@ MM::PageMap::GetPpeOffset(IN PVOID Address)
* @since XT 1.0 * @since XT 1.0
*/ */
XTAPI XTAPI
ULONGLONG ULONG_PTR
MM::PageMap::GetPte(IN PMMPTE PtePointer) MM::PageMap::GetPte(IN PMMPTE PtePointer)
{ {
/* Return PTE value */ /* Return PTE value */
@@ -574,7 +574,7 @@ XTAPI
VOID VOID
MM::PageMap::SetPte(IN PMMPTE PtePointer, MM::PageMap::SetPte(IN PMMPTE PtePointer,
IN PFN_NUMBER PageFrameNumber, IN PFN_NUMBER PageFrameNumber,
IN ULONGLONG AttributesMask) IN ULONG_PTR AttributesMask)
{ {
/* Set PTE */ /* Set PTE */
PtePointer->Hardware.PageFrameNumber = PageFrameNumber; PtePointer->Hardware.PageFrameNumber = PageFrameNumber;
@@ -598,7 +598,7 @@ MM::PageMap::SetPte(IN PMMPTE PtePointer,
XTAPI XTAPI
VOID VOID
MM::PageMap::SetPte(IN PMMPTE PtePointer, MM::PageMap::SetPte(IN PMMPTE PtePointer,
IN ULONGLONG Attributes) IN ULONG_PTR Attributes)
{ {
PtePointer->Long = Attributes; PtePointer->Long = Attributes;
} }

View File

@@ -9,41 +9,14 @@
#include <xtos.hh> #include <xtos.hh>
/* Expansion table used to track pool memory allocations */ /* PFN marking the initial non-paged pool end boundary */
PPOOL_TRACKING_TABLE MM::Allocator::AllocationsTrackingExpansionTable; PFN_NUMBER MM::Allocator::NonPagedPoolFrameEnd;
/* Total number of entries in the expansion allocations tracking table */ /* PFN marking the initial non-paged pool start boundary */
SIZE_T MM::Allocator::AllocationsTrackingExpansionTableSize; PFN_NUMBER MM::Allocator::NonPagedPoolFrameStart;
/* Global table used to track pool memory allocations */ /* Array of non-paged pool free list heads */
PPOOL_TRACKING_TABLE MM::Allocator::AllocationsTrackingTable; LIST_ENTRY MM::Allocator::NonPagedPoolFreeList[MM_MAX_FREE_PAGE_LIST_HEADS];
/* Spinlock protecting the allocations table */
KSPIN_LOCK MM::Allocator::AllocationsTrackingTableLock;
/* Bitmask used during the hashing process */
SIZE_T MM::Allocator::AllocationsTrackingTableMask;
/* Total number of entries in the global allocations tracking table */
SIZE_T MM::Allocator::AllocationsTrackingTableSize;
/* Active number of big allocations to trigger table expansion */
ULONG MM::Allocator::BigAllocationsInUse;
/* Pointer to the hash table for tracking page-aligned memory */
PPOOL_TRACKING_BIG_ALLOCATIONS MM::Allocator::BigAllocationsTrackingTable;
/* Bitmask used for fast modulo arithmetic during hash bucket lookups */
SIZE_T MM::Allocator::BigAllocationsTrackingTableHash;
/* Spinlock protecting the big allocations table */
KSPIN_LOCK MM::Allocator::BigAllocationsTrackingTableLock;
/* Maximum capacity of the tracking hash table */
SIZE_T MM::Allocator::BigAllocationsTrackingTableSize;
/* Array of CPU-local tracking tables */
PPOOL_TRACKING_TABLE MM::Allocator::TagTables[MM_POOL_TRACKING_TABLES];
/* Array of free page lists segregated by cache color */ /* Array of free page lists segregated by cache color */
PMMCOLOR_TABLES MM::Colors::FreePages[FreePageList + 1]; PMMCOLOR_TABLES MM::Colors::FreePages[FreePageList + 1];
@@ -66,15 +39,15 @@ PVOID MM::HardwarePool::HardwareHeapStart = MM_HARDWARE_HEAP_START_ADDRESS;
/* Number of used hardware allocation descriptors */ /* Number of used hardware allocation descriptors */
ULONG MM::HardwarePool::UsedHardwareAllocationDescriptors = 0; ULONG MM::HardwarePool::UsedHardwareAllocationDescriptors = 0;
/* Processor structures data (THIS IS A TEMPORARY HACK) */
UCHAR MM::KernelPool::ProcessorStructuresData[MAXIMUM_PROCESSORS][KPROCESSOR_STRUCTURES_SIZE] = {{0}};
/* Global structure describing the virtual memory layout of the system */ /* Global structure describing the virtual memory layout of the system */
MMMEMORY_LAYOUT MM::Manager::MemoryLayout; MMMEMORY_LAYOUT MM::Manager::MemoryLayout;
/* Total number of PTEs reserved for system space mapping */ /* Total number of PTEs reserved for system space mapping */
PFN_NUMBER MM::Manager::NumberOfSystemPtes; PFN_NUMBER MM::Manager::NumberOfSystemPtes;
/* Physical memory block descriptor */
PPHYSICAL_MEMORY_DESCRIPTOR MM::Manager::PhysicalMemoryBlock;
/* Instance of the page map routines for the current PML level */ /* Instance of the page map routines for the current PML level */
MM::PPAGEMAP MM::Paging::PmlRoutines; MM::PPAGEMAP MM::Paging::PmlRoutines;
@@ -118,9 +91,6 @@ PMMPFNLIST MM::Pfn::PageLocationList[] = {&ZeroedPagesList,
NULLPTR, NULLPTR,
NULLPTR}; NULLPTR};
/* Bitmap used to track physical pages */
RTL_BITMAP MM::Pfn::PfnBitMap;
/* List containing pages mapped as Read-Only (ROM) */ /* List containing pages mapped as Read-Only (ROM) */
MMPFNLIST MM::Pfn::RomPagesList = {0, StandbyPageList, MAXULONG_PTR, MAXULONG_PTR}; MMPFNLIST MM::Pfn::RomPagesList = {0, StandbyPageList, MAXULONG_PTR, MAXULONG_PTR};
@@ -130,24 +100,6 @@ MMPFNLIST MM::Pfn::StandbyPagesList = {0, StandbyPageList, MAXULONG_PTR, MAXULON
/* List containing free physical pages that have been zeroed out */ /* List containing free physical pages that have been zeroed out */
MMPFNLIST MM::Pfn::ZeroedPagesList = {0, ZeroedPageList, MAXULONG_PTR, MAXULONG_PTR}; MMPFNLIST MM::Pfn::ZeroedPagesList = {0, ZeroedPageList, MAXULONG_PTR, MAXULONG_PTR};
/* Non-paged pool descriptor */
POOL_DESCRIPTOR MM::Pool::NonPagedPoolDescriptor;
/* PFN marking the initial non-paged pool end boundary */
PFN_NUMBER MM::Pool::NonPagedPoolFrameEnd;
/* PFN marking the initial non-paged pool start boundary */
PFN_NUMBER MM::Pool::NonPagedPoolFrameStart;
/* Array of non-paged pool free list heads */
LIST_ENTRY MM::Pool::NonPagedPoolFreeList[MM_MAX_FREE_PAGE_LIST_HEADS];
/* Random cookie used to obfuscate pool links */
ULONG MM::Pool::PoolSecureCookie;
/* Array of pool descriptors */
PPOOL_DESCRIPTOR MM::Pool::PoolVector[2];
/* Array of lists for available System PTEs, separated by pool type */ /* Array of lists for available System PTEs, separated by pool type */
MMPTE MM::Pte::FirstSystemFreePte[MaximumPtePoolTypes]; MMPTE MM::Pte::FirstSystemFreePte[MaximumPtePoolTypes];

View File

@@ -1,102 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/mm/exports.cc
* DESCRIPTION: C-compatible API wrappers for exported kernel functions
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#include <xtos.hh>
/**
* Allocates a block of memory from the specified pool type.
*
* @param PoolType
* Specifies the type of pool to allocate from.
*
* @param Bytes
* Specifies the number of bytes to allocate.
*
* @param Memory
* Supplies a pointer to the allocated memory.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
MmAllocatePool(IN MMPOOL_TYPE PoolType,
IN SIZE_T Bytes,
OUT PVOID *Memory)
{
return MM::Allocator::AllocatePool(PoolType, Bytes, Memory);
}
/**
* Allocates a block of memory from the specified pool type.
*
* @param PoolType
* Specifies the type of pool to allocate from.
*
* @param Bytes
* Specifies the number of bytes to allocate.
*
* @param Memory
* Supplies a pointer to the allocated memory.
*
* @param Tag
* Specifies the allocation identifying tag.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
MmAllocatePoolWithTag(IN MMPOOL_TYPE PoolType,
IN SIZE_T Bytes,
OUT PVOID *Memory,
IN ULONG Tag)
{
return MM::Allocator::AllocatePool(PoolType, Bytes, Memory, Tag);
}
/**
* Frees a previously allocated memory pool.
*
* @param VirtualAddress
* Supplies the base virtual address of the pool allocation to free.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
MmFreePool(IN PVOID VirtualAddress)
{
return MM::Allocator::FreePool(VirtualAddress);
}
/**
* Frees a previously allocated memory pool.
*
* @param VirtualAddress
* Supplies the base virtual address of the pool allocation to free.
*
* @param Tag
* Specifies the allocation identifying tag.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
MmFreePoolWithTag(IN PVOID VirtualAddress,
IN ULONG Tag)
{
return MM::Allocator::FreePool(VirtualAddress, Tag);
}

View File

@@ -1,8 +1,8 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/mm/i686/pool.cc * FILE: xtoskrnl/mm/i686/alloc.cc
* DESCRIPTION: I686 Memory Manager pool manager * DESCRIPTION: Memory manager pool allocation
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com> * DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/ */
@@ -18,7 +18,7 @@
*/ */
XTAPI XTAPI
VOID VOID
MM::Pool::MapNonPagedPool(VOID) MM::Allocator::MapNonPagedPool(VOID)
{ {
PMMMEMORY_LAYOUT MemoryLayout; PMMMEMORY_LAYOUT MemoryLayout;

View File

@@ -80,6 +80,7 @@ MM::PageMap::GetPdeOffset(IN PVOID Address)
return ((((ULONG_PTR)(Address)) >> PageMapInfo.PdiShift) & (PageMapInfo.Xpa ? 0x1FF : 0x3FF)); return ((((ULONG_PTR)(Address)) >> PageMapInfo.PdiShift) & (PageMapInfo.Xpa ? 0x1FF : 0x3FF));
} }
/** /**
* Gets the address of the PPE (Page Directory Pointer Table Entry), that maps given address. * Gets the address of the PPE (Page Directory Pointer Table Entry), that maps given address.
* *
@@ -173,6 +174,7 @@ MM::PageMap::GetPteOffset(IN PVOID Address)
return ((((ULONG_PTR)(Address)) >> MM_PTI_SHIFT) & (PageMapInfo.Xpa ? 0x1FF : 0x3FF)); return ((((ULONG_PTR)(Address)) >> MM_PTI_SHIFT) & (PageMapInfo.Xpa ? 0x1FF : 0x3FF));
} }
/** /**
* Gets the status of Extended Paging Address (XPA) mode. * Gets the status of Extended Paging Address (XPA) mode.
* *
@@ -316,7 +318,7 @@ MM::PageMapBasic::GetPdeVirtualAddress(IN PMMPDE PdePointer)
return ((PVOID)((ULONG)(PdePointer) << 20)); return ((PVOID)((ULONG)(PdePointer) << 20));
} }
/** /**
* Gets the entire contents of a PML2 Page Table Entry (PTE) as a single value. * Gets the entire contents of a PML2 Page Table Entry (PTE) as a single value.
* *
* @param PtePointer * @param PtePointer
@@ -327,13 +329,12 @@ MM::PageMapBasic::GetPdeVirtualAddress(IN PMMPDE PdePointer)
* @since XT 1.0 * @since XT 1.0
*/ */
XTAPI XTAPI
ULONGLONG ULONG_PTR
MM::PageMapBasic::GetPte(IN PMMPTE PtePointer) MM::PageMapBasic::GetPte(IN PMMPTE PtePointer)
{ {
/* Return PTE value */ /* Return PTE value */
return (ULONGLONG)PtePointer->Pml2.Long; return PtePointer->Pml2.Long;
} }
/** /**
* Calculates the distance between two PTE pointers. * Calculates the distance between two PTE pointers.
* *
@@ -548,12 +549,12 @@ XTAPI
VOID VOID
MM::PageMapBasic::SetPte(IN PMMPTE PtePointer, MM::PageMapBasic::SetPte(IN PMMPTE PtePointer,
IN PFN_NUMBER PageFrameNumber, IN PFN_NUMBER PageFrameNumber,
IN ULONGLONG AttributesMask) IN ULONG_PTR AttributesMask)
{ {
/* Set PTE */ /* Set PTE */
PtePointer->Pml2.Hardware.PageFrameNumber = PageFrameNumber; PtePointer->Pml2.Hardware.PageFrameNumber = PageFrameNumber;
PtePointer->Pml2.Hardware.Valid = 1; PtePointer->Pml2.Hardware.Valid = 1;
PtePointer->Pml2.Long |= (ULONG)AttributesMask; PtePointer->Pml2.Long |= AttributesMask;
} }
/** /**
@@ -572,9 +573,9 @@ MM::PageMapBasic::SetPte(IN PMMPTE PtePointer,
XTAPI XTAPI
VOID VOID
MM::PageMapBasic::SetPte(IN PMMPTE PtePointer, MM::PageMapBasic::SetPte(IN PMMPTE PtePointer,
IN ULONGLONG Attributes) IN ULONG_PTR Attributes)
{ {
PtePointer->Pml2.Long = (ULONG)Attributes; PtePointer->Pml2.Long = Attributes;
} }
/** /**
@@ -625,14 +626,14 @@ MM::PageMapBasic::TransitionPte(IN PMMPTE PointerPte,
MMPTE TempPte; MMPTE TempPte;
/* Set transition PTE */ /* Set transition PTE */
TempPte.Pml2.Long = PointerPte->Pml2.Long; TempPte = *PointerPte;
TempPte.Pml2.Software.Protection = Protection; TempPte.Pml2.Software.Protection = Protection;
TempPte.Pml2.Software.Prototype = 0; TempPte.Pml2.Software.Prototype = 0;
TempPte.Pml2.Software.Transition = 1; TempPte.Pml2.Software.Transition = 1;
TempPte.Pml2.Software.Valid = 0; TempPte.Pml2.Software.Valid = 0;
/* Write PTE value */ /* Write PTE value */
PointerPte->Pml2.Long = TempPte.Pml2.Long; *PointerPte = TempPte;
} }
/** /**
@@ -797,7 +798,7 @@ MM::PageMapXpa::GetPdeVirtualAddress(IN PMMPDE PdePointer)
* @since XT 1.0 * @since XT 1.0
*/ */
XTAPI XTAPI
ULONGLONG ULONG_PTR
MM::PageMapXpa::GetPte(IN PMMPTE PtePointer) MM::PageMapXpa::GetPte(IN PMMPTE PtePointer)
{ {
/* Return PTE value */ /* Return PTE value */
@@ -1017,7 +1018,7 @@ XTAPI
VOID VOID
MM::PageMapXpa::SetPte(IN PMMPTE PtePointer, MM::PageMapXpa::SetPte(IN PMMPTE PtePointer,
IN PFN_NUMBER PageFrameNumber, IN PFN_NUMBER PageFrameNumber,
IN ULONGLONG AttributesMask) IN ULONG_PTR AttributesMask)
{ {
/* Set PTE */ /* Set PTE */
PtePointer->Pml3.Hardware.PageFrameNumber = PageFrameNumber; PtePointer->Pml3.Hardware.PageFrameNumber = PageFrameNumber;
@@ -1041,7 +1042,7 @@ MM::PageMapXpa::SetPte(IN PMMPTE PtePointer,
XTAPI XTAPI
VOID VOID
MM::PageMapXpa::SetPte(IN PMMPTE PtePointer, MM::PageMapXpa::SetPte(IN PMMPTE PtePointer,
IN ULONGLONG Attributes) IN ULONG_PTR Attributes)
{ {
PtePointer->Pml3.Long = Attributes; PtePointer->Pml3.Long = Attributes;
} }
@@ -1094,14 +1095,14 @@ MM::PageMapXpa::TransitionPte(IN PMMPTE PointerPte,
MMPTE TempPte; MMPTE TempPte;
/* Set transition PTE */ /* Set transition PTE */
TempPte.Pml3.Long = PointerPte->Pml3.Long; TempPte = *PointerPte;
TempPte.Pml3.Software.Protection = Protection; TempPte.Pml3.Software.Protection = Protection;
TempPte.Pml3.Software.Prototype = 0; TempPte.Pml3.Software.Prototype = 0;
TempPte.Pml3.Software.Transition = 1; TempPte.Pml3.Software.Transition = 1;
TempPte.Pml3.Software.Valid = 0; TempPte.Pml3.Software.Valid = 0;
/* Write PTE value */ /* Write PTE value */
PointerPte->Pml3.Long = TempPte.Pml3.Long; *PointerPte = TempPte;
} }
/** /**
@@ -1124,4 +1125,4 @@ MM::PageMapXpa::WritePte(IN PMMPTE Pte,
{ {
/* Write PTE value */ /* Write PTE value */
Pte->Pml3.Long = Value.Pml3.Long; Pte->Pml3.Long = Value.Pml3.Long;
} }

View File

@@ -113,15 +113,12 @@ MM::KernelPool::AllocateProcessorStructures(IN ULONG CpuNumber,
PKPROCESSOR_BLOCK ProcessorBlock; PKPROCESSOR_BLOCK ProcessorBlock;
PVOID ProcessorStructures; PVOID ProcessorStructures;
UINT_PTR Address; UINT_PTR Address;
XTSTATUS Status;
/* Assign memory for processor structures */ /* Not implemented yet, this is just a hack */
Status = MM::Allocator::AllocatePool(NonPagedPool, KPROCESSOR_STRUCTURES_SIZE, &ProcessorStructures); UNIMPLEMENTED;
if(Status != STATUS_SUCCESS)
{ /* Assign memory for processor structures from preallocated buffer */
/* Failed to allocate memory, return status code */ ProcessorStructures = &ProcessorStructuresData[CpuNumber - 1];
return Status;
}
/* Make sure all structures are zeroed */ /* Make sure all structures are zeroed */
RTL::Memory::ZeroMemory(ProcessorStructures, KPROCESSOR_STRUCTURES_SIZE); RTL::Memory::ZeroMemory(ProcessorStructures, KPROCESSOR_STRUCTURES_SIZE);
@@ -206,10 +203,5 @@ XTAPI
VOID VOID
MM::KernelPool::FreeProcessorStructures(IN PVOID StructuresData) MM::KernelPool::FreeProcessorStructures(IN PVOID StructuresData)
{ {
/* Check if the provided pointer is valid */ UNIMPLEMENTED;
if(StructuresData != NULLPTR)
{
/* Release the contiguous memory block back */
MM::Allocator::FreePool(StructuresData, 0);
}
} }

View File

@@ -81,146 +81,11 @@ MM::Manager::GetMemoryLayout(VOID)
*/ */
XTAPI XTAPI
PFN_NUMBER PFN_NUMBER
MM::Manager::GetNumberOfSystemPtes(VOID) MM::Manager::GetNumberOfSystemPtes()
{ {
return NumberOfSystemPtes; return NumberOfSystemPtes;
} }
/**
* Initializes and returns the system physical memory descriptor block.
*
* @return This routine returns a pointer to the structure representing the system usable physical memory block.
*
* @since XT 1.0
*/
XTAPI
PPHYSICAL_MEMORY_DESCRIPTOR
MM::Manager::GetPhysicalMemoryBlock(VOID)
{
PPHYSICAL_MEMORY_DESCRIPTOR PrimaryBuffer, SecondaryBuffer;
PKERNEL_INITIALIZATION_BLOCK InitializationBlock;
PLOADER_MEMORY_DESCRIPTOR MemoryDescriptor;
PFN_NUMBER PageFrameNumer, NumberOfPages;
ULONG DescriptorCount, RunCount;
PLIST_ENTRY ListEntry;
XTSTATUS Status;
/* Check if the physical memory block has already been initialized */
if(!PhysicalMemoryBlock)
{
/* Reset local tracking variables */
DescriptorCount = 0;
NumberOfPages = 0;
PageFrameNumer = -1;
RunCount = 0;
/* Retrieve the kernel initialization block */
InitializationBlock = KE::BootInformation::GetInitializationBlock();
/* Iterate through the loader memory descriptor list to determine its size */
ListEntry = InitializationBlock->MemoryDescriptorListHead.Flink;
while(ListEntry != &InitializationBlock->MemoryDescriptorListHead)
{
/* Count this descriptor */
DescriptorCount++;
/* Go to the next descriptor */
ListEntry = ListEntry->Flink;
}
/* Ensure the memory descriptor list is not empty */
if(DescriptorCount == 0)
{
/* Fail gracefully if no memory descriptors were found, by returning NULLPTR */
return NULLPTR;
}
/* Allocate a primary buffer sized for the maximum possible number of runs */
Status = MM::Allocator::AllocatePool(NonPagedPool,
sizeof(PHYSICAL_MEMORY_DESCRIPTOR) +
sizeof(PHYSICAL_MEMORY_RUN) *
(DescriptorCount - 1),
(PVOID*)&PrimaryBuffer,
SIGNATURE32('M', 'M', 'g', 'r'));
if(Status != STATUS_SUCCESS || !PrimaryBuffer)
{
/* Primary pool allocation failed, return NULLPTR */
return NULLPTR;
}
/* Traverse the memory descriptor list a second time to build the map */
ListEntry = InitializationBlock->MemoryDescriptorListHead.Flink;
while(ListEntry != &InitializationBlock->MemoryDescriptorListHead)
{
/* Resolve the memory descriptor record from the current list entry */
MemoryDescriptor = CONTAIN_RECORD(ListEntry, LOADER_MEMORY_DESCRIPTOR, ListEntry);
/* Filter out bad, reserved, or invisible memory types */
if((MemoryDescriptor->MemoryType < LoaderMaximum) &&
(MemoryDescriptor->MemoryType != LoaderBad) &&
!VerifyMemoryTypeInvisible(MemoryDescriptor->MemoryType))
{
/* Accumulate the total number of usable physical pages */
NumberOfPages += MemoryDescriptor->PageCount;
/* Check if the current descriptor is contiguous with the previous run */
if(RunCount > 0 && MemoryDescriptor->BasePage == PageFrameNumer)
{
/* Coalesce the contiguous descriptor into the existing physical run */
PrimaryBuffer->Run[RunCount - 1].PageCount += MemoryDescriptor->PageCount;
PageFrameNumer += MemoryDescriptor->PageCount;
}
else
{
/* Start a new physical run with the new descriptor's boundaries */
PrimaryBuffer->Run[RunCount].BasePage = MemoryDescriptor->BasePage;
PrimaryBuffer->Run[RunCount].PageCount = MemoryDescriptor->PageCount;
/* Update the expected next page frame number for future contiguity checks */
PageFrameNumer = PrimaryBuffer->Run[RunCount].BasePage + PrimaryBuffer->Run[RunCount].PageCount;
/* Increment the total number of distinct physical memory runs */
RunCount++;
}
}
/* Go to the next descriptor */
ListEntry = ListEntry->Flink;
}
/* Check if the buffer can be shrunk due to coalesced memory runs */
if(DescriptorCount > RunCount)
{
/* Allocate a secondary, more tightly sized buffer to reduce memory footprint */
Status = MM::Allocator::AllocatePool(NonPagedPool,
sizeof(PHYSICAL_MEMORY_DESCRIPTOR) +
sizeof(PHYSICAL_MEMORY_RUN) *
(RunCount - 1),
(PVOID*)&SecondaryBuffer,
SIGNATURE32('M', 'M', 'g', 'r'));
if(Status == STATUS_SUCCESS && SecondaryBuffer)
{
/* Copy the coalesced runs from the oversized primary buffer */
RtlCopyMemory(SecondaryBuffer->Run, PrimaryBuffer->Run, sizeof(PHYSICAL_MEMORY_RUN) * RunCount);
/* Free the primary buffer */
MM::Allocator::FreePool(PrimaryBuffer, SIGNATURE32('M', 'M', 'g', 'r'));
/* Update the primary buffer pointer */
PrimaryBuffer = SecondaryBuffer;
}
}
/* Populate the final metadata and save the physical memory block globally */
PrimaryBuffer->NumberOfRuns = RunCount;
PrimaryBuffer->NumberOfPages = NumberOfPages;
PhysicalMemoryBlock = PrimaryBuffer;
}
/* Return a pointer to the physical memory block */
return PhysicalMemoryBlock;
}
/** /**
* Performs an early initialization of the XTOS Memory Manager. * Performs an early initialization of the XTOS Memory Manager.
* *
@@ -240,7 +105,7 @@ MM::Manager::InitializeMemoryManager(VOID)
{ {
/* Insufficient physical pages, kernel panic */ /* Insufficient physical pages, kernel panic */
DebugPrint(L"Insufficient physical pages! Install additional memory\n"); DebugPrint(L"Insufficient physical pages! Install additional memory\n");
KE::Crash::Panic(0x7D, MM::Pfn::GetNumberOfPhysicalPages(), MM_MINIMUM_PHYSICAL_PAGES, 0x0, 0x2); KE::Crash::Panic(0);
} }
/* Compute page colors to reduce CPU cache conflicts */ /* Compute page colors to reduce CPU cache conflicts */
@@ -259,24 +124,14 @@ MM::Manager::InitializeMemoryManager(VOID)
/* Initialize system PTE space */ /* Initialize system PTE space */
MM::Pte::InitializeSystemPteSpace(); MM::Pte::InitializeSystemPteSpace();
/* Initialize memory pool security */
MM::Pool::InitializePoolSecurity();
/* Initialize non-paged pool */ /* Initialize non-paged pool */
MM::Pool::InitializeNonPagedPool(); MM::Allocator::InitializeNonPagedPool();
/* Initialize PFN database */ /* Initialize PFN database */
MM::Pfn::InitializePfnDatabase(); MM::Pfn::InitializePfnDatabase();
/* Initialize allocations tracking tables */
MM::Allocator::InitializeAllocationsTracking();
MM::Allocator::InitializeBigAllocationsTracking();
/* Initialize PFN bitmap */
MM::Pfn::InitializePfnBitmap();
/* Initialize paged pool */ /* Initialize paged pool */
MM::Pool::InitializePagedPool(); MM::Allocator::InitializePagedPool();
/* Flush TLB */ /* Flush TLB */
AR::CpuFunc::FlushTlb(); AR::CpuFunc::FlushTlb();

View File

@@ -68,22 +68,7 @@ MM::Paging::ClearPte(IN PMMPTE PtePointer)
} }
/** /**
* Flushes the entire Translation Lookaside Buffer (TLB) on all processors. * Flushes current Translation Lookaside Buffer (TLB)
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Paging::FlushEntireTlb(VOID)
{
/* Temporarily fallback to FlushTlb() as SMP is not supported yet */
FlushTlb();
}
/**
* Flushes current Translation Lookaside Buffer (TLB).
* *
* @return This routine does not return any value. * @return This routine does not return any value.
* *
@@ -336,7 +321,7 @@ MM::Paging::GetPpeVirtualAddress(IN PMMPPE PpePointer)
* @since XT 1.0 * @since XT 1.0
*/ */
XTAPI XTAPI
ULONGLONG ULONG_PTR
MM::Paging::GetPte(IN PMMPTE PtePointer) MM::Paging::GetPte(IN PMMPTE PtePointer)
{ {
/* Return PTE value */ /* Return PTE value */
@@ -593,7 +578,7 @@ XTAPI
VOID VOID
MM::Paging::SetPte(IN PMMPTE PtePointer, MM::Paging::SetPte(IN PMMPTE PtePointer,
IN PFN_NUMBER PageFrameNumber, IN PFN_NUMBER PageFrameNumber,
IN ULONGLONG AttributesMask) IN ULONG_PTR AttributesMask)
{ {
/* Set PTE */ /* Set PTE */
PmlRoutines->SetPte(PtePointer, PageFrameNumber, AttributesMask); PmlRoutines->SetPte(PtePointer, PageFrameNumber, AttributesMask);
@@ -615,7 +600,7 @@ MM::Paging::SetPte(IN PMMPTE PtePointer,
XTAPI XTAPI
VOID VOID
MM::Paging::SetPte(IN PMMPTE PtePointer, MM::Paging::SetPte(IN PMMPTE PtePointer,
IN ULONGLONG Attributes) IN ULONG_PTR Attributes)
{ {
PmlRoutines->SetPte(PtePointer, Attributes); PmlRoutines->SetPte(PtePointer, Attributes);
} }

View File

@@ -31,11 +31,7 @@ MM::Pfn::AllocateBootstrapPages(IN PFN_NUMBER NumberOfPages)
{ {
/* Not enough physical memory available, kernel panic */ /* Not enough physical memory available, kernel panic */
DebugPrint(L"Insufficient physical pages! Install additional memory\n"); DebugPrint(L"Insufficient physical pages! Install additional memory\n");
KE::Crash::Panic(0x7D, KE::Crash::Panic(0);
NumberOfPhysicalPages,
FreeDescriptor->PageCount,
OriginalFreeDescriptor.PageCount,
NumberOfPages);
} }
/* Allocate pages from the beginning of the free descriptor */ /* Allocate pages from the beginning of the free descriptor */
@@ -177,22 +173,21 @@ MM::Pfn::DecrementReferenceCount(IN PMMPFN PageFrameNumber,
if(PageFrameNumber->u2.ShareCount) if(PageFrameNumber->u2.ShareCount)
{ {
/* This indicates a bug; crash the system */ /* This indicates a bug; crash the system */
KE::Crash::Panic(0x4E, KE::Crash::PanicEx(0x4E,
0x07, 0x07,
PageFrameIndex, PageFrameIndex,
PageFrameNumber->u2.ShareCount, PageFrameNumber->u2.ShareCount,
0); 0);
} }
/* Check if the PTE is marked as being ready for removal */ /* Check if the PTE is marked as being ready for removal */
if((ULONG_PTR)PageFrameNumber->PteAddress & 0x1) if(MM::Paging::GetPte(PageFrameNumber->PteAddress) & 0x1)
{ {
/* Check the page's cache attribute */ /* Check the page's cache attribute */
if((PageFrameNumber->u3.e1.CacheAttribute != PfnCached) && if((PageFrameNumber->u3.e1.CacheAttribute != PfnCached) &&
(PageFrameNumber->u3.e1.CacheAttribute != PfnNotMapped)) (PageFrameNumber->u3.e1.CacheAttribute != PfnNotMapped))
{ {
/* Flush the TLB to prevent cache attribute conflicts from stale non-cached mappings */ UNIMPLEMENTED;
MM::Paging::FlushEntireTlb();
} }
/* The page is no longer needed, free it by linking it to the free list */ /* The page is no longer needed, free it by linking it to the free list */
@@ -261,11 +256,11 @@ MM::Pfn::DecrementShareCount(IN PMMPFN PageFrameNumber,
(PageFrameNumber->u3.e1.PageLocation != StandbyPageList)) (PageFrameNumber->u3.e1.PageLocation != StandbyPageList))
{ {
/* This indicates a bug; crash the system */ /* This indicates a bug; crash the system */
KE::Crash::Panic(0x4E, KE::Crash::PanicEx(0x4E,
0x99, 0x99,
PageFrameIndex, PageFrameIndex,
PageFrameNumber->u3.e1.PageLocation, PageFrameNumber->u3.e1.PageLocation,
0); 0);
} }
/* Decrement the PFN share count */ /* Decrement the PFN share count */
@@ -289,7 +284,7 @@ MM::Pfn::DecrementShareCount(IN PMMPFN PageFrameNumber,
if(PageFrameNumber->u3.e2.ReferenceCount == 1) if(PageFrameNumber->u3.e2.ReferenceCount == 1)
{ {
/* Check if the PTE is marked as being ready for removal */ /* Check if the PTE is marked as being ready for removal */
if((ULONG_PTR)PageFrameNumber->PteAddress & 0x1) if(MM::Paging::GetPte(PageFrameNumber->PteAddress) & 0x1)
{ {
/* Reset the reference count */ /* Reset the reference count */
PageFrameNumber->u3.e2.ReferenceCount = 0; PageFrameNumber->u3.e2.ReferenceCount = 0;
@@ -298,8 +293,7 @@ MM::Pfn::DecrementShareCount(IN PMMPFN PageFrameNumber,
if((PageFrameNumber->u3.e1.CacheAttribute != PfnCached) && if((PageFrameNumber->u3.e1.CacheAttribute != PfnCached) &&
(PageFrameNumber->u3.e1.CacheAttribute != PfnNotMapped)) (PageFrameNumber->u3.e1.CacheAttribute != PfnNotMapped))
{ {
/* Flush the TLB to prevent cache attribute conflicts from stale non-cached mappings */ UNIMPLEMENTED;
MM::Paging::FlushEntireTlb();
} }
/* Mark the page as active and valid again */ /* Mark the page as active and valid again */
@@ -425,13 +419,6 @@ MM::Pfn::GetPfnEntry(IN PFN_NUMBER Pfn)
return NULLPTR; return NULLPTR;
} }
/* Make sure this page has a PFN entry set */
if(PfnBitMap.Buffer && !RTL::BitMap::TestBit(&PfnBitMap, Pfn))
{
/* The requested page number is not set in the bitmap, return NULLPTR */
return NULLPTR;
}
/* Get the memory layout */ /* Get the memory layout */
MemoryLayout = MM::Manager::GetMemoryLayout(); MemoryLayout = MM::Manager::GetMemoryLayout();
@@ -454,60 +441,6 @@ MM::Pfn::IncrementAvailablePages(VOID)
AvailablePages++; AvailablePages++;
} }
/**
* Initializes the PFN bitmap to track available physical memory.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Pfn::InitializePfnBitmap(VOID)
{
PPHYSICAL_MEMORY_DESCRIPTOR PhysicalMemoryBlock;
XTSTATUS Status;
PVOID BitMap;
ULONG Index;
/* Retrieve the global physical memory descriptor block */
PhysicalMemoryBlock = MM::Manager::GetPhysicalMemoryBlock();
if(!PhysicalMemoryBlock)
{
/* Physical memory layout unavailable, kernel panic */
KE::Crash::Panic(0x7D, NumberOfPhysicalPages, LowestPhysicalPage, HighestPhysicalPage, 0x100);
}
/* Calculate the required bitmap size and allocate memory */
Status = MM::Allocator::AllocatePool(NonPagedPool,
(((HighestPhysicalPage + 1) + 31) / 32) * 4,
(PVOID *)&BitMap,
SIGNATURE32('M', 'M', 'g', 'r'));
if(Status != STATUS_SUCCESS || !BitMap)
{
/* Memory allocation failed, kernel panic */
DebugPrint(L"Insufficient physical pages! Install additional memory\n");
KE::Crash::Panic(0x7D, NumberOfPhysicalPages, LowestPhysicalPage, HighestPhysicalPage, 0x101);
}
/* Initialize the PFN bitmap structure and clear all bits by default */
RTL::BitMap::InitializeBitMap(&PfnBitMap, (PULONG_PTR)BitMap, (ULONG)HighestPhysicalPage + 1);
RTL::BitMap::ClearAllBits(&PfnBitMap);
/* Iterate through all contiguous physical memory runs to populate the availability map */
for(Index = 0; Index < PhysicalMemoryBlock->NumberOfRuns; Index++)
{
/* Ensure the current memory run contains at least one valid page frame */
if((&PhysicalMemoryBlock->Run[Index])->PageCount)
{
/* Set the corresponding bits to mark these physical pages as available for allocation */
RtlSetBits(&PfnBitMap,
(ULONG)(&PhysicalMemoryBlock->Run[Index])->BasePage,
(ULONG)(&PhysicalMemoryBlock->Run[Index])->PageCount);
}
}
}
/** /**
* Links a physical page to the appropriate free lists. * Links a physical page to the appropriate free lists.
* *
@@ -658,7 +591,7 @@ MM::Pfn::LinkPage(IN PMMPFNLIST ListHead,
MM::Paging::GetPteSoftwareTransition(&PageFrame->OriginalPte)) MM::Paging::GetPteSoftwareTransition(&PageFrame->OriginalPte))
{ {
/* Crash system due to corrupted PFN/PTE state */ /* Crash system due to corrupted PFN/PTE state */
KE::Crash::Panic(0x1A, 0x8888, 0, 0, 0); KE::Crash::PanicEx(0x71, 0x8888, 0, 0, 0);
} }
} }
@@ -873,11 +806,11 @@ MM::Pfn::LinkPfn(IN PFN_NUMBER PageFrameIndex,
if(Status != STATUS_SUCCESS) if(Status != STATUS_SUCCESS)
{ {
/* Could not make the page table resident, crash system */ /* Could not make the page table resident, crash system */
KE::Crash::Panic(0x1A, KE::Crash::PanicEx(0x1,
(ULONG_PTR)0x61940, (ULONG_PTR)0x61940,
(ULONG_PTR)PointerPte, (ULONG_PTR)PointerPte,
MM::Paging::GetPageFrameNumber(PointerPte), MM::Paging::GetPageFrameNumber(PointerPte),
(ULONG_PTR)MM::Paging::GetPteVirtualAddress(PointerPte)); (ULONG_PTR)MM::Paging::GetPteVirtualAddress(PointerPte));
} }
} }
@@ -923,7 +856,7 @@ MM::Pfn::LinkPfnForPageTable(IN PFN_NUMBER PageFrameIndex,
(MM::Pte::AddressValid(EndAddress)) && (Pfn->u3.e1.PageLocation == ActiveAndValid)) (MM::Pte::AddressValid(EndAddress)) && (Pfn->u3.e1.PageLocation == ActiveAndValid))
{ {
/* Initialize the PFN entry for this page table page */ /* Initialize the PFN entry for this page table page */
MM::Paging::SetPte(&Pfn->OriginalPte, MM::Paging::GetPte(PointerPte)); Pfn->OriginalPte = *PointerPte;
Pfn->PteAddress = PointerPte; Pfn->PteAddress = PointerPte;
Pfn->u1.WsIndex = 0; Pfn->u1.WsIndex = 0;
Pfn->u2.ShareCount++; Pfn->u2.ShareCount++;
@@ -1101,7 +1034,7 @@ MM::Pfn::ProcessMemoryDescriptor(IN PFN_NUMBER BasePage,
IN PFN_NUMBER PageCount, IN PFN_NUMBER PageCount,
IN LOADER_MEMORY_TYPE MemoryType) IN LOADER_MEMORY_TYPE MemoryType)
{ {
PVOID VirtualAddress, VirtualRangeStart, VirtualRangeEnd; PVOID VirtualRangeStart, VirtualRangeEnd;
PFN_NUMBER PageNumber; PFN_NUMBER PageNumber;
PMMPDE PointerPde; PMMPDE PointerPde;
PMMPFN Pfn; PMMPFN Pfn;
@@ -1154,12 +1087,8 @@ MM::Pfn::ProcessMemoryDescriptor(IN PFN_NUMBER BasePage,
/* Ensure that the page is not already in-use */ /* Ensure that the page is not already in-use */
if(Pfn->u3.e2.ReferenceCount == 0) if(Pfn->u3.e2.ReferenceCount == 0)
{ {
/* Calculate the virtual address for this page */
VirtualAddress = (PVOID)(KSEG0_BASE + ((BasePage + PageNumber) << MM_PAGE_SHIFT));
PointerPde = MM::Paging::GetPdeAddress(VirtualAddress);
/* Initialize the PFN entry to represent a ROM page */ /* Initialize the PFN entry to represent a ROM page */
Pfn->PteAddress = MM::Paging::GetPteAddress(VirtualAddress); Pfn->PteAddress = MM::Paging::GetPteAddress(VirtualRangeStart);
Pfn->u1.Flink = 0; Pfn->u1.Flink = 0;
Pfn->u2.ShareCount = 0; Pfn->u2.ShareCount = 0;
Pfn->u3.e1.CacheAttribute = PfnCached; Pfn->u3.e1.CacheAttribute = PfnCached;
@@ -1188,12 +1117,8 @@ MM::Pfn::ProcessMemoryDescriptor(IN PFN_NUMBER BasePage,
/* Ensure that the page is not already in-use */ /* Ensure that the page is not already in-use */
if(Pfn->u3.e2.ReferenceCount == 0) if(Pfn->u3.e2.ReferenceCount == 0)
{ {
/* Calculate the virtual address for this page */
VirtualAddress = (PVOID)(KSEG0_BASE + ((BasePage + PageNumber) << MM_PAGE_SHIFT));
PointerPde = MM::Paging::GetPdeAddress(VirtualAddress);
/* Initialize the PFN entry to represent an in-use page and prevent it from being allocated */ /* Initialize the PFN entry to represent an in-use page and prevent it from being allocated */
Pfn->PteAddress = MM::Paging::GetPteAddress(VirtualAddress); Pfn->PteAddress = MM::Paging::GetPteAddress(VirtualRangeStart);
Pfn->u2.ShareCount++; Pfn->u2.ShareCount++;
Pfn->u3.e1.CacheAttribute = PfnCached; Pfn->u3.e1.CacheAttribute = PfnCached;
Pfn->u3.e1.PageLocation = ActiveAndValid; Pfn->u3.e1.PageLocation = ActiveAndValid;
@@ -1288,7 +1213,7 @@ MM::Pfn::ScanMemoryDescriptors(VOID)
if(!FreeDescriptor) if(!FreeDescriptor)
{ {
/* No free memory available to bootstrap the system */ /* No free memory available to bootstrap the system */
KE::Crash::Panic(0x7D, LowestPhysicalPage, HighestPhysicalPage, FreePages, 0x1); KE::Crash::Panic(0);
} }
/* Save a copy of the original free descriptor before it gets modified */ /* Save a copy of the original free descriptor before it gets modified */

View File

@@ -1,736 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/mm/pool.cc
* DESCRIPTION: Memory Manager pool manager
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#include <xtos.hh>
/**
* Decodes an obfuscated doubly-linked pool list pointer.
*
* @param Link
* Supplies the encoded list entry pointer to be decoded.
*
* @return This routine returns the valid, properly aligned list entry pointer.
*
* @since XT 1.0
*/
XTAPI
PLIST_ENTRY
MM::Pool::DecodePoolLink(IN PLIST_ENTRY PoolLink)
{
/* XOR the obfuscated pointer with the global pool cookie to reveal the true address */
return (PLIST_ENTRY)((ULONG_PTR)PoolLink ^ PoolSecureCookie);
}
/**
* Determines the pool type for a given memory address.
*
* @param VirtualAddress
* Supplies a virtual address to determine the pool type for.
*
* @return This routine returns the determined pool type for the specified address.
*
* @since XT 1.0
*/
XTAPI
MMPOOL_TYPE
MM::Pool::DeterminePoolType(IN PVOID VirtualAddress)
{
PMMMEMORY_LAYOUT MemoryLayout;
/* Retrieve the memory layout */
MemoryLayout = MM::Manager::GetMemoryLayout();
/* Evaluate the virtual address against known pool boundaries */
if((VirtualAddress >= MemoryLayout->NonPagedPoolStart) &&
(VirtualAddress <= MemoryLayout->NonPagedPoolEnd))
{
/* Address belongs to the non-paged pool */
return NonPagedPool;
}
else if((VirtualAddress >= MemoryLayout->NonPagedExpansionPoolStart) &&
(VirtualAddress <= MemoryLayout->NonPagedExpansionPoolEnd))
{
/* Address belongs to the non-paged expansion pool */
return NonPagedPool;
}
else if((VirtualAddress >= MemoryLayout->PagedPoolStart) &&
(VirtualAddress <= MemoryLayout->PagedPoolEnd))
{
/* Address belongs to the paged pool */
return PagedPool;
}
/* Address does not belong to any known pool, kernel panic */
KE::Crash::Panic(0xC2, 0x42, (ULONG_PTR)VirtualAddress, 0, 0);
/* Return an invalid pool type to satisfy the compiler */
return (MMPOOL_TYPE)-1;
}
/**
* Encodes a doubly-linked pool list pointer to mitigate pool corruption.
*
* @param Link
* Supplies the raw list entry pointer to be encoded.
*
* @return This routine returns the obfuscated list entry pointer.
*
* @since XT 1.0
*/
XTAPI
PLIST_ENTRY
MM::Pool::EncodePoolLink(IN PLIST_ENTRY PoolLink)
{
/* XOR the raw pointer with the global pool cookie to securely obfuscate it */
return (PLIST_ENTRY)((ULONG_PTR)PoolLink ^ PoolSecureCookie);
}
/**
* Calculates the address of a pool block at a specific relative index.
*
* @param Header
* Supplies a pointer to the base pool header.
*
* @param Index
* Supplies the block index offset. This value can be negative to traverse backwards.
*
* @return This routine returns a pointer to the calculated pool header.
*
* @since XT 1.0
*/
XTAPI
PPOOL_HEADER
MM::Pool::GetPoolBlock(IN PPOOL_HEADER Header, IN SSIZE_T Index)
{
/* The destination block is located by advancing the base address by the specified index */
return (PPOOL_HEADER)((ULONG_PTR)Header + (Index * MM_POOL_BLOCK_SIZE));
}
/**
* Retrieves the pool header associated with a given pool memory address.
*
* @param Memory
* Supplies a pointer to the allocated memory region of a pool block.
*
* @return This routine returns a pointer to the originating pool header.
*
* @since XT 1.0
*/
XTAPI
PPOOL_HEADER
MM::Pool::GetPoolEntry(IN PVOID Memory)
{
/* The structural header logically precedes the allocated memory region */
return (PPOOL_HEADER)((ULONG_PTR)Memory - sizeof(POOL_HEADER));
}
/**
* Resolves the list entry structure embedded within a free pool block.
*
* @param Header
* Supplies a pointer to the pool header.
*
* @return This routine returns a pointer to the list entry directly following the header.
*
* @since XT 1.0
*/
XTAPI
PLIST_ENTRY
MM::Pool::GetPoolFreeBlock(IN PPOOL_HEADER Header)
{
/* Return the list entry pointer */
return (PLIST_ENTRY)((ULONG_PTR)Header + sizeof(POOL_HEADER));
}
/**
* Retrieves a pointer to the adjacent contiguous pool block following the specified header.
*
* @param Header
* Supplies a pointer to the current pool header.
*
* @return This routine returns a pointer to the next pool header in memory.
*
* @since XT 1.0
*/
XTAPI
PPOOL_HEADER
MM::Pool::GetPoolNextBlock(IN PPOOL_HEADER Header)
{
/* The adjacent forward header is located exactly 'BlockSize' units ahead of the current block */
return (PPOOL_HEADER)((ULONG_PTR)Header + (Header->BlockSize * MM_POOL_BLOCK_SIZE));
}
/**
* Retrieves a pointer to the adjacent contiguous pool block preceding the specified header.
*
* @param Header
* Supplies a pointer to the current pool header.
*
* @return This routine returns a pointer to the previous pool header in memory.
*
* @since XT 1.0
*/
XTAPI
PPOOL_HEADER
MM::Pool::GetPoolPreviousBlock(IN PPOOL_HEADER Header)
{
/* The adjacent backward header is located exactly 'PreviousSize' units behind the current block */
return (PPOOL_HEADER)((ULONG_PTR)Header - (Header->PreviousSize * MM_POOL_BLOCK_SIZE));
}
/**
* Initializes the non-paged pool for memory allocator.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Pool::InitializeNonPagedPool(VOID)
{
PMMFREE_POOL_ENTRY FreePage, SetupPage;
PMMMEMORY_LAYOUT MemoryLayout;
ULONG Index;
/* Retrieve memory layout */
MemoryLayout = MM::Manager::GetMemoryLayout();
/* Map PTEs for the non-paged pool */
MapNonPagedPool();
/* Iterate over the free page list heads */
for(Index = 0; Index < MM_MAX_FREE_PAGE_LIST_HEADS; Index++)
{
/* Initialize a free page list head */
RTL::LinkedList::InitializeListHead(&NonPagedPoolFreeList[Index]);
}
/* Take the first free page from the pool and set its size */
FreePage = (PMMFREE_POOL_ENTRY)MemoryLayout->NonPagedPoolStart;
FreePage->Size = MemoryLayout->NonPagedPoolSize;
/* Take number of pages in the pool */
Index = (ULONG)(MemoryLayout->NonPagedPoolSize - 1);
if(Index >= MM_MAX_FREE_PAGE_LIST_HEADS)
{
/* Number of pages exceeds the number of free page list heads */
Index = MM_MAX_FREE_PAGE_LIST_HEADS - 1;
}
/* Insert the first free page into the free page list */
RTL::LinkedList::InsertHeadList(&NonPagedPoolFreeList[Index], &FreePage->List);
/* Create a free page for each page in the pool */
SetupPage = FreePage;
for(Index = 0; Index < MemoryLayout->NonPagedPoolSize; Index++)
{
/* Initialize the owner for each page */
SetupPage->Owner = FreePage;
SetupPage = (PMMFREE_POOL_ENTRY)((ULONG_PTR)SetupPage + MM_PAGE_SIZE);
}
/* Store first and last allocated non-paged pool page */
NonPagedPoolFrameStart = MM::Paging::GetPageFrameNumber(MM::Paging::GetPteAddress(MemoryLayout->NonPagedPoolStart));
NonPagedPoolFrameEnd = MM::Paging::GetPageFrameNumber(MM::Paging::GetPteAddress(MemoryLayout->NonPagedPoolEnd));
/* Initialize system PTE pool for the non-paged expansion pool */
Pte::InitializeSystemPtePool(Paging::GetNextPte(Paging::GetPteAddress(MemoryLayout->NonPagedExpansionPoolStart)),
MemoryLayout->NonPagedExpansionPoolSize - 2,
NonPagedPoolExpansion);
/* Store non-paged pool descriptor in the pool vector and initialize it */
PoolVector[NonPagedPool] = &NonPagedPoolDescriptor;
InitializePoolDescriptor(PoolVector[NonPagedPool], NonPagedPool, 0, 0, NULLPTR);
}
/**
* Initializes the non-paged pool for memory allocator.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Pool::InitializePagedPool(VOID)
{
UNIMPLEMENTED;
}
/**
* Initializes a pool descriptor used by the memory manager.
*
* @param Descriptor
* Supplies a pointer to the pool descriptor structure to be initialized.
*
* @param PoolType
* Specifies the type of memory pool that will be managed by the descriptor.
*
* @param Index
* Supplies the zero-based index of the descriptor within the pool vector.
*
* @param Threshold
* Specifies the allocation threshold that dictates when the pool should expand.
*
* @param LockAddress
* Supplies a pointer to the synchronization primitive that will serialize access to this descriptor. *
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Pool::InitializePoolDescriptor(IN PPOOL_DESCRIPTOR Descriptor,
IN MMPOOL_TYPE PoolType,
IN ULONG Index,
IN ULONG Threshold,
IN PVOID LockAddress)
{
PLIST_ENTRY LastEntry, ListEntry;
/* Populate the core attributes of the descriptor */
Descriptor->LockAddress = LockAddress;
Descriptor->PoolIndex = Index;
Descriptor->PoolType = PoolType;
Descriptor->Threshold = Threshold;
/* Clear the deferred free list */
Descriptor->PendingFrees = NULLPTR;
Descriptor->PendingFreeDepth = 0;
/* Zero out the runtime accounting and statistical tracking counters */
Descriptor->RunningAllocations = 0;
Descriptor->RunningFrees = 0;
Descriptor->TotalBigAllocations = 0;
Descriptor->TotalBytes = 0;
Descriptor->TotalPages = 0;
/* Establish the iteration boundaries */
ListEntry = Descriptor->ListHeads;
LastEntry = ListEntry + MM_POOL_LISTS_PER_PAGE;
/* Traverse and initialize all block list heads */
while(ListEntry < LastEntry)
{
/* Initialize the empty list head */
InitializePoolListHead(ListEntry);
ListEntry++;
}
}
/**
* Initializes a doubly-linked pool list head with encoded pointers.
*
* @param ListHead
* Supplies a pointer to the pool list head that is to be initialized.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Pool::InitializePoolListHead(IN PLIST_ENTRY ListHead)
{
PLIST_ENTRY ListEntry;
/* Obfuscate the list head address and establish the empty circular linkage */
ListEntry = EncodePoolLink(ListHead);
ListHead->Flink = ListEntry;
ListHead->Blink = ListEntry;
}
/**
* Initializes the memory pool security mechanisms.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Pool::InitializePoolSecurity(VOID)
{
UNIMPLEMENTED;
/* Initialize the global pool cookie using a hard-coded value */
PoolSecureCookie = 0xDEADC0DE;
}
/**
* Inserts a pool entry at the head of a doubly-linked pool list.
*
* @param ListHead
* Supplies a pointer to the head of the pool list.
*
* @param Entry
* Supplies a pointer to the pool list entry to be inserted.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Pool::InsertPoolHeadList(IN PLIST_ENTRY ListHead,
IN PLIST_ENTRY Entry)
{
PLIST_ENTRY Flink;
/* Validate the pool list structure */
VerifyPoolLinks(ListHead);
/* Resolve the current forward link of the list head */
Flink = DecodePoolLink(ListHead->Flink);
/* Securely insert the new entry at the beginning of the pool list */
Entry->Blink = EncodePoolLink(ListHead);
Entry->Flink = EncodePoolLink(Flink);
Flink->Blink = EncodePoolLink(Entry);
ListHead->Flink = EncodePoolLink(Entry);
/* Re-validate the pool list structure */
VerifyPoolLinks(ListHead);
}
/**
* Inserts a pool entry at the tail of a doubly-linked pool list.
*
* @param ListHead
* Supplies a pointer to the head of the pool list.
*
* @param Entry
* Supplies a pointer to the pool list entry to be inserted.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Pool::InsertPoolTailList(IN PLIST_ENTRY ListHead,
IN PLIST_ENTRY Entry)
{
PLIST_ENTRY Blink;
/* Validate the pool list structure */
VerifyPoolLinks(ListHead);
/* Securely link the new entry at the end of the pool list */
Blink = DecodePoolLink(ListHead->Blink);
Blink->Flink = EncodePoolLink(Entry);
Entry->Blink = EncodePoolLink(Blink);
Entry->Flink = EncodePoolLink(ListHead);
ListHead->Blink = EncodePoolLink(Entry);
/* Re-validate the pool list structure */
VerifyPoolLinks(ListHead);
}
/**
* Determines whether a given doubly-linked pool list is empty.
*
* @param ListHead
* Supplies a pointer to the head of the pool list to be evaluated.
*
* @return This routine returns TRUE if the pool list is empty, or FALSE otherwise.
*
* @since XT 1.0
*/
XTAPI
BOOLEAN
MM::Pool::PoolListEmpty(IN PLIST_ENTRY ListHead)
{
/* Evaluate whether the pool list contains no valid entries */
return (DecodePoolLink(ListHead->Flink) == ListHead);
}
/**
* Removes a specific pool entry from a doubly-linked pool list.
*
* @param Entry
* Supplies a pointer to the pool list entry to be removed.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Pool::RemovePoolEntryList(IN PLIST_ENTRY Entry)
{
PLIST_ENTRY Blink, Flink;
/* Resolve the adjacent forward and backward links */
Blink = DecodePoolLink(Entry->Blink);
Flink = DecodePoolLink(Entry->Flink);
/* Securely link the adjacent nodes together */
Blink->Flink = EncodePoolLink(Flink);
Flink->Blink = EncodePoolLink(Blink);
}
/**
* Removes the first entry from a doubly-linked pool list.
*
* @param ListHead
* Supplies a pointer to the head of the pool list.
*
* @return This routine returns a pointer to the removed pool list entry.
*
* @since XT 1.0
*/
XTAPI
PLIST_ENTRY
MM::Pool::RemovePoolHeadList(IN PLIST_ENTRY ListHead)
{
PLIST_ENTRY Entry, Flink;
/* Securely unlink the first entry from the pool list */
Entry = DecodePoolLink(ListHead->Flink);
Flink = DecodePoolLink(Entry->Flink);
Flink->Blink = EncodePoolLink(ListHead);
ListHead->Flink = EncodePoolLink(Flink);
/* Return the removed pool list entry */
return Entry;
}
/**
* Removes the last entry from a doubly-linked pool list.
*
* @param ListHead
* Supplies a pointer to the head of the pool list.
*
* @return This routine returns a pointer to the removed pool list entry.
*
* @since XT 1.0
*/
PLIST_ENTRY
XTAPI
MM::Pool::RemovePoolTailList(IN PLIST_ENTRY ListHead)
{
PLIST_ENTRY Blink, Entry;
/* Securely unlink the last entry from the pool list */
Entry = DecodePoolLink(ListHead->Blink);
Blink = DecodePoolLink(Entry->Blink);
Blink->Flink = EncodePoolLink(ListHead);
ListHead->Blink = EncodePoolLink(Blink);
/* Return the removed pool list entry */
return Entry;
}
/**
* Verifies the structural integrity of all pool blocks residing on a specific page.
*
* @param Block
* Supplies a pointer to the specific pool block.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Pool::VerifyPoolBlocks(IN PVOID Block)
{
PPOOL_HEADER Entry;
BOOLEAN FoundBlock;
SIZE_T Size;
/* Initialize tracking variables */
FoundBlock = FALSE;
Size = 0;
/* Resolve the first pool header */
Entry = (PPOOL_HEADER)PAGE_ALIGN(Block);
/* Iterate through all contiguous pool allocations */
do
{
/* Validate the current pool header */
VerifyPoolHeader(Entry);
/* Check if the current header corresponds to the target block */
if(Entry == Block)
{
/* Mark the block as found */
FoundBlock = TRUE;
}
/* Accumulate the total block size and advance to the next entry */
Size += Entry->BlockSize;
Entry = GetPoolNextBlock(Entry);
}
while((Size < (MM_PAGE_SIZE / MM_POOL_BLOCK_SIZE)) && (PAGE_ALIGN(Entry) != Entry));
/* Ensure the block was found and the total size is aligned with the page */
if(!FoundBlock || (PAGE_ALIGN(Entry) != Entry) || (Size != (MM_PAGE_SIZE / MM_POOL_BLOCK_SIZE)))
{
/* Pool blocks corruption detected, kernel panic */
KE::Crash::Panic(0x19, 10, (ULONG_PTR)Block, (ULONG_PTR)Entry, FoundBlock);
}
}
/**
* Verifies the structural and spatial invariants of a specific pool header.
*
* @param Entry
* Supplies a pointer to the pool header to be verified.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Pool::VerifyPoolHeader(IN PPOOL_HEADER Entry)
{
PPOOL_HEADER PreviousEntry, NextEntry;
/* Verify that the current block header is valid */
if(!Entry->BlockSize)
{
/* Invalid block header size, kernel panic */
KE::Crash::Panic(0x19, 8, (ULONG_PTR)Entry->PreviousSize, Entry->BlockSize, (ULONG_PTR)Entry);
}
/* Verify that the previous block header is valid */
if(Entry->PreviousSize)
{
/* Resolve the previous block header */
PreviousEntry = GetPoolPreviousBlock(Entry);
/* Check if both adjacent blocks are within the same memory page */
if(PAGE_ALIGN(Entry) != PAGE_ALIGN(PreviousEntry))
{
/* Adjacent blocks are not on the same page, kernel panic */
KE::Crash::Panic(0x19, 6, (ULONG_PTR)PreviousEntry, (ULONG_PTR)PAGE_ALIGN(Entry), (ULONG_PTR)Entry);
}
/* Check the actual size of the previous block */
if(PreviousEntry->BlockSize != Entry->PreviousSize)
{
/* Block size mismatch, kernel panic */
KE::Crash::Panic(0x19, 5, (ULONG_PTR)PreviousEntry, (ULONG_PTR)Entry->PreviousSize, (ULONG_PTR)Entry);
}
}
else if(PAGE_ALIGN(Entry) != Entry)
{
/* Not aligned to a page boundary, kernel panic */
KE::Crash::Panic(0x19, 7, 0, (ULONG_PTR)PAGE_ALIGN(Entry), (ULONG_PTR)Entry);
}
/* Resolve the next block header */
NextEntry = GetPoolNextBlock(Entry);
/* Verify the next block header */
if(PAGE_ALIGN(NextEntry) != NextEntry)
{
/* Check if both adjacent blocks are within the same memory page */
if(PAGE_ALIGN(Entry) != PAGE_ALIGN(NextEntry))
{
/* Adjacent blocks are not on the same page, kernel panic */
KE::Crash::Panic(0x19, 9, (ULONG_PTR)NextEntry, (ULONG_PTR)PAGE_ALIGN(Entry), (ULONG_PTR)Entry);
}
/* Check the previous block size */
if(NextEntry->PreviousSize != Entry->BlockSize)
{
/* Block size mismatch, kernel panic */
KE::Crash::Panic(0x19, 5, (ULONG_PTR)NextEntry, NextEntry->PreviousSize, (ULONG_PTR)Entry);
}
}
}
/**
* Validates the structural integrity of a doubly-linked pool list.
*
* @param ListHead
* Supplies a pointer to the pool list head that is to be validated.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Pool::VerifyPoolLinks(IN PLIST_ENTRY ListHead)
{
/* Validate the doubly-linked list invariants */
if((DecodePoolLink(DecodePoolLink(ListHead->Blink)->Flink) != ListHead) ||
(DecodePoolLink(DecodePoolLink(ListHead->Flink)->Blink) != ListHead))
{
/* Pool corruption detected, raise kernel panic */
KE::Crash::Panic(0x19,
3,
(ULONG_PTR)ListHead,
(ULONG_PTR)DecodePoolLink(DecodePoolLink(ListHead->Blink)->Flink),
(ULONG_PTR)DecodePoolLink(DecodePoolLink(ListHead->Flink)->Blink));
}
}
/**
* Validates the run level for the specified pool. If the run level is invalid, the kernel panics.
*
* @param PoolType
* Supplies the pool type.
*
* @param Bytes
* Supplies the size of the allocation.
*
* @param Entry
* Supplies a pointer to the allocation entry.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Pool::VerifyRunLevel(IN MMPOOL_TYPE PoolType,
IN SIZE_T Bytes,
IN PVOID Entry)
{
KRUNLEVEL RunLevel;
/* Get current run level */
RunLevel = KE::RunLevel::GetCurrentRunLevel();
/* Validate run level */
if((PoolType & MM_POOL_TYPE_MASK) == PagedPool)
{
/* Paged pool runs up to APC level */
if(RunLevel <= APC_LEVEL)
{
/* Run level is valid */
return;
}
}
else
{
/* Non-paged pool runs up to DISPATCH_LEVEL */
if(RunLevel <= DISPATCH_LEVEL)
{
/* Run level is valid */
return;
}
}
/* Invalid run level for specified pool, raise kernel panic */
KE::Crash::Panic(0xC2,
(Entry ? MM_POOL_INVALID_FREE_RUNLEVEL : MM_POOL_INVALID_ALLOC_RUNLEVEL),
RunLevel,
PoolType,
(Entry ? (ULONG_PTR)Entry : Bytes));
}

View File

@@ -74,7 +74,7 @@ __CxxFrameHandler3(IN PEXCEPTION_RECORD ExceptionRecord,
/* Disable interrupts and hang */ /* Disable interrupts and hang */
AR::CpuFunc::ClearInterruptFlag(); AR::CpuFunc::ClearInterruptFlag();
KE::Crash::Panic(0); KE::Crash::Panic(0); // CXX_FRAME_HANDLER_CALLED
/* Continue search */ /* Continue search */
return ExceptionContinueSearch; return ExceptionContinueSearch;
@@ -129,5 +129,5 @@ _purecall(VOID)
/* Disable interrupts and hang */ /* Disable interrupts and hang */
AR::CpuFunc::ClearInterruptFlag(); AR::CpuFunc::ClearInterruptFlag();
KE::Crash::Panic(0); KE::Crash::Panic(0); // PURE_VIRTUAL_FUNCTION_CALL
} }

View File

@@ -74,7 +74,7 @@ __CxxFrameHandler3(IN PEXCEPTION_RECORD ExceptionRecord,
/* Disable interrupts and hang */ /* Disable interrupts and hang */
AR::CpuFunc::ClearInterruptFlag(); AR::CpuFunc::ClearInterruptFlag();
KE::Crash::Panic(0); KE::Crash::Panic(0); // CXX_FRAME_HANDLER_CALLED
/* Continue search */ /* Continue search */
return ExceptionContinueSearch; return ExceptionContinueSearch;
@@ -129,5 +129,5 @@ _purecall(VOID)
/* Disable interrupts and hang */ /* Disable interrupts and hang */
AR::CpuFunc::ClearInterruptFlag(); AR::CpuFunc::ClearInterruptFlag();
KE::Crash::Panic(0); KE::Crash::Panic(0); // PURE_VIRTUAL_FUNCTION_CALL
} }

View File

@@ -42,10 +42,6 @@
@ stdcall KeSetTimer(ptr long long long ptr) @ stdcall KeSetTimer(ptr long long long ptr)
@ stdcall KeSignalCallDpcDone(ptr) @ stdcall KeSignalCallDpcDone(ptr)
@ stdcall KeSignalCallDpcSynchronize(ptr) @ stdcall KeSignalCallDpcSynchronize(ptr)
@ stdcall MmAllocatePool(long long ptr)
@ stdcall MmAllocatePoolWithTag(long long ptr long)
@ stdcall MmFreePool(ptr)
@ stdcall MmFreePoolWithTag(ptr long)
@ stdcall RtlClearAllBits(ptr) @ stdcall RtlClearAllBits(ptr)
@ stdcall RtlClearBit(ptr long) @ stdcall RtlClearBit(ptr long)
@ stdcall RtlClearBits(ptr long long) @ stdcall RtlClearBits(ptr long long)