From c723c56e4ac30ba546e7be1986e8641f2e3d3353 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Tue, 15 Mar 2022 18:21:30 -0500 Subject: [PATCH 1/7] Implement RtlWalkFrameChain --- src/common/AddressRanges.h | 1 + src/core/kernel/exports/EmuKrnlRtl.cpp | 119 ++++++++++++++++++++++++- 2 files changed, 118 insertions(+), 2 deletions(-) diff --git a/src/common/AddressRanges.h b/src/common/AddressRanges.h index 6bac680bc..56b844941 100644 --- a/src/common/AddressRanges.h +++ b/src/common/AddressRanges.h @@ -145,6 +145,7 @@ inline constexpr uint32_t FLASH_DEVICE4_END = (FLASH_DEVICE4_BASE - 1 + FLA #define PAGE_SHIFT 12 // 2^12 = 4 KiB #define PAGE_SIZE (1 << PAGE_SHIFT) // = 0x00001000 = KiB(4) #define PAGE_MASK (PAGE_SIZE - 1) +#define PAGE_ALIGN(address) (PVOID) ((ulong_ptr_xt)(address) & ~PAGE_MASK)) #define LARGE_PAGE_SHIFT 22 // 2^22 = 4 MiB #define LARGE_PAGE_SIZE (1 << LARGE_PAGE_SHIFT) // = 0x00400000 = 4 MiB diff --git a/src/core/kernel/exports/EmuKrnlRtl.cpp b/src/core/kernel/exports/EmuKrnlRtl.cpp index 0f065f379..3c09b2bd2 100644 --- a/src/core/kernel/exports/EmuKrnlRtl.cpp +++ b/src/core/kernel/exports/EmuKrnlRtl.cpp @@ -58,6 +58,37 @@ xbox::dword_xt WINAPI RtlAnsiStringToUnicodeSize(const xbox::STRING *str) return (str->Length + sizeof(ANSI_NULL)) * sizeof(WCHAR); } +// Source: ReactOS (excluded DPC stack check) +xbox::boolean_xt RtlpCaptureStackLimits( + IN xbox::ulong_ptr_xt Ebp, + OUT xbox::ulong_ptr_xt* StackBegin, + OUT xbox::ulong_ptr_xt* StackEnd) +{ + using namespace xbox; + PKTHREAD Thread = KeGetCurrentThread(); + + /* Don't even try at ISR level or later */ + //if (KeGetCurrentIrql() > DISPATCH_LEVEL) return FALSE; + + /* Start with defaults */ + *StackBegin = reinterpret_cast(Thread->StackLimit); + *StackEnd = reinterpret_cast(Thread->StackBase); + + /* Check if EBP is inside the stack */ + if ((*StackBegin <= Ebp) && (Ebp <= *StackEnd)) { + /* Then make the stack start at EBP */ + *StackBegin = Ebp; + } + else { + /* We're somewhere else entirely... use EBP for safety */ + *StackBegin = Ebp; + *StackEnd = reinterpret_cast(PAGE_ALIGN((*StackBegin)); + } + + /* Return success */ + return TRUE; +} + // ****************************************************************** // * 0x0104 - RtlAnsiStringToUnicodeString() // ****************************************************************** @@ -2071,6 +2102,8 @@ XBSYSAPI EXPORTNUM(318) xbox::ushort_xt FASTCALL xbox::RtlUshortByteSwap // ****************************************************************** // * 0x013F - RtlWalkFrameChain() // ****************************************************************** +// Source: ReactOS (modified to fit in xbox compatibility layer) +// NOTE: From xbox kernel, Flags input is not used. XBSYSAPI EXPORTNUM(319) xbox::ulong_xt NTAPI xbox::RtlWalkFrameChain ( OUT PVOID *Callers, @@ -2078,15 +2111,97 @@ XBSYSAPI EXPORTNUM(319) xbox::ulong_xt NTAPI xbox::RtlWalkFrameChain IN ulong_xt Flags ) { + ulong_ptr_xt Stack; + /* Get current EBP */ +#if defined __GNUC__ + __asm__("mov %%ebp, %0" : "=r" (Stack) : ); +#elif defined(_MSC_VER) + __asm mov Stack, ebp +#endif + +#if 0 // NOTE: Disabled due to __try/__except doesn't like this for some reason. LOG_FUNC_BEGIN LOG_FUNC_ARG_OUT(Callers) LOG_FUNC_ARG(Count) LOG_FUNC_ARG(Flags) LOG_FUNC_END; +#endif - LOG_UNIMPLEMENTED(); + /* Get the actual safe limits */ + ulong_ptr_xt StackBegin, StackEnd; + RtlpCaptureStackLimits(Stack, &StackBegin, &StackEnd); - RETURN(NULL); + ulong_xt i = 0; + + /* Use a SEH block for maximum protection */ + __try { + /* Loop the frames */ + boolean_xt StopSearch = FALSE; + for (i = 0; i < Count; i++) { + /* + * Leave if we're past the stack, + * if we're before the stack, + * or if we've reached ourselves. + */ + if ((Stack >= StackEnd) || + (!i ? (Stack < StackBegin) : (Stack <= StackBegin)) || + ((StackEnd - Stack) < (2 * sizeof(ulong_ptr_xt)))) + { + /* We're done or hit a bad address */ + break; + } + + /* Get new stack and EIP */ + ulong_ptr_xt NewStack = *(ulong_ptr_xt*)Stack; + ulong_xt Eip = *(ulong_ptr_xt*)(Stack + sizeof(ulong_ptr_xt)); + + /* Check if the new pointer is above the old one and past the end */ + if (!((Stack < NewStack) && (NewStack < StackEnd))) { + /* Stop searching after this entry */ + StopSearch = TRUE; + } + + /* Also make sure that the EIP isn't a stack address */ + if ((StackBegin < Eip) && (Eip < StackEnd)) { + break; + } + + /* Save this frame */ + Callers[i] = reinterpret_cast(Eip); + + /* Check if we should continue */ + if (StopSearch) + { + /* Return the next index */ + i++; + break; + } + + /* Move to the next stack */ + Stack = NewStack; + } + } + __except (EXCEPTION_EXECUTE_HANDLER) { + /* No index */ + i = 0; + } + +#ifndef ENABLE_KTHREAD_SWITCHING + // HACK: This is necessary to exclude our own PCSTProxy startup function. + if (i) { + ulong_xt Eip = reinterpret_cast(Callers[i - 1]); + // Check if the first call is outside of xbe's system memory. + // If so, force exclude it to conform with xbox kernel test suite's result. + // NOTE: This will always occur every time. As the thread's startup function address reside behind KSWITCHFRAME structure. + // Except we are currently using our host's local variable as xbox's stack storage. + if (Eip > g_SystemMaxMemory) { + i--; + Callers[i] = zeroptr; + } + } +#endif + + return i;// RETURN(i); } // ****************************************************************** From 1d030aa41fde126560189bccb7ffef85c57e3687 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Wed, 30 Mar 2022 12:56:56 -0500 Subject: [PATCH 2/7] Implement RtlCaptureStackBackTrace --- src/core/kernel/exports/EmuKrnlRtl.cpp | 44 ++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/src/core/kernel/exports/EmuKrnlRtl.cpp b/src/core/kernel/exports/EmuKrnlRtl.cpp index 3c09b2bd2..356eb20d1 100644 --- a/src/core/kernel/exports/EmuKrnlRtl.cpp +++ b/src/core/kernel/exports/EmuKrnlRtl.cpp @@ -294,6 +294,7 @@ XBSYSAPI EXPORTNUM(265) xbox::void_xt NTAPI xbox::RtlCaptureContext // ****************************************************************** // * 0x010A - RtlCaptureStackBackTrace() // ****************************************************************** +// Source: ReactOS XBSYSAPI EXPORTNUM(266) xbox::ushort_xt NTAPI xbox::RtlCaptureStackBackTrace ( IN ulong_xt FramesToSkip, @@ -309,9 +310,48 @@ XBSYSAPI EXPORTNUM(266) xbox::ushort_xt NTAPI xbox::RtlCaptureStackBackTrace LOG_FUNC_ARG_OUT(BackTraceHash) LOG_FUNC_END; - LOG_UNIMPLEMENTED(); + PVOID Frames[2 * 64]; + ulong_xt FrameCount; + ulong_xt Hash = 0; + ushort_xt i; - RETURN(NULL); + /* Skip a frame for the caller */ + FramesToSkip++; + + /* Don't go past the limit */ + if ((FramesToCapture + FramesToSkip) >= 128) { + return 0; + } + + /* Do the back trace */ + FrameCount = RtlWalkFrameChain(Frames, FramesToCapture + FramesToSkip, 0); + + /* Make sure we're not skipping all of them */ + if (FrameCount <= FramesToSkip) { + return 0; + } + + /* Loop all the frames */ + for (i = 0; i < FramesToCapture; i++) { + /* Don't go past the limit */ + if ((FramesToSkip + i) >= FrameCount) { + break; + } + + /* Save this entry and hash it */ + BackTrace[i] = Frames[FramesToSkip + i]; + Hash += reinterpret_cast(BackTrace[i]); + } + + /* Write the hash */ + if (BackTraceHash) { + *BackTraceHash = Hash; + } + + /* Clear the other entries and return count */ + RtlFillMemoryUlong(Frames, 128, 0); + + RETURN(i); } // ****************************************************************** From 57640cad49e61b89300350b95e6e5b469a7cc79b Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Wed, 30 Mar 2022 13:11:49 -0500 Subject: [PATCH 3/7] Implement RtlGetCallersAddress --- src/core/kernel/exports/EmuKrnlRtl.cpp | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/core/kernel/exports/EmuKrnlRtl.cpp b/src/core/kernel/exports/EmuKrnlRtl.cpp index 356eb20d1..7bca75c46 100644 --- a/src/core/kernel/exports/EmuKrnlRtl.cpp +++ b/src/core/kernel/exports/EmuKrnlRtl.cpp @@ -1106,7 +1106,31 @@ XBSYSAPI EXPORTNUM(288) xbox::void_xt NTAPI xbox::RtlGetCallersAddress LOG_FUNC_ARG_OUT(CallersCaller) LOG_FUNC_END; - LOG_UNIMPLEMENTED(); + /* Get the tow back trace address */ + PVOID BackTrace[2]; + ushort_xt FrameCount = RtlCaptureStackBackTrace(2, 2, &BackTrace[0], zeroptr); + + /* Only if user want it */ + if (CallersAddress != NULL) { + /* only when first frames exist */ + if (FrameCount >= 1) { + *CallersAddress = BackTrace[0]; + } + else { + *CallersAddress = zeroptr; + } + } + + /* Only if user want it */ + if (CallersCaller != NULL) { + /* only when second frames exist */ + if (FrameCount >= 2) { + *CallersCaller = BackTrace[1]; + } + else { + *CallersCaller = zeroptr; + } + } } // ****************************************************************** From 6d395bf2eefe3344e2b393302a14bca65baad05d Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Wed, 30 Mar 2022 13:26:32 -0500 Subject: [PATCH 4/7] fix alignment from tabs to spaces --- src/core/kernel/exports/EmuKrnlRtl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/kernel/exports/EmuKrnlRtl.cpp b/src/core/kernel/exports/EmuKrnlRtl.cpp index 7bca75c46..95e70e78f 100644 --- a/src/core/kernel/exports/EmuKrnlRtl.cpp +++ b/src/core/kernel/exports/EmuKrnlRtl.cpp @@ -268,7 +268,7 @@ XBSYSAPI EXPORTNUM(265) xbox::void_xt NTAPI xbox::RtlCaptureContext mov ebx, [esp + 8] // ebx = ContextRecord; mov [ebx + CONTEXT.Eax], eax // ContextRecord->Eax = eax; - mov eax, [esp] // eax = original value of ebx + mov eax, [esp] // eax = original value of ebx mov [ebx + CONTEXT.Ebx], eax // ContextRecord->Ebx = original value of ebx mov [ebx + CONTEXT.Ecx], ecx // ContextRecord->Ecx = ecx; mov [ebx + CONTEXT.Edx], edx // ContextRecord->Edx = edx; From 351c9a7c86bdb13d813fa62e7d133389fe499804 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Tue, 5 Apr 2022 17:45:36 -0500 Subject: [PATCH 5/7] review remark --- src/common/AddressRanges.h | 10 +++++++++- src/core/kernel/exports/EmuKrnlRtl.cpp | 2 +- src/core/kernel/memory-manager/PhysicalMemory.h | 5 ----- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/common/AddressRanges.h b/src/common/AddressRanges.h index 56b844941..5ec49b80a 100644 --- a/src/common/AddressRanges.h +++ b/src/common/AddressRanges.h @@ -145,7 +145,15 @@ inline constexpr uint32_t FLASH_DEVICE4_END = (FLASH_DEVICE4_BASE - 1 + FLA #define PAGE_SHIFT 12 // 2^12 = 4 KiB #define PAGE_SIZE (1 << PAGE_SHIFT) // = 0x00001000 = KiB(4) #define PAGE_MASK (PAGE_SIZE - 1) -#define PAGE_ALIGN(address) (PVOID) ((ulong_ptr_xt)(address) & ~PAGE_MASK)) + +// Common page calculations +#define ROUND_UP_4K(size) (((size) + PAGE_MASK) & (~PAGE_MASK)) +#define ROUND_UP(size, alignment) (((size) + (alignment - 1)) & (~(alignment - 1))) +#define ROUND_DOWN_4K(size) ((size) & (~PAGE_MASK)) +#define ROUND_DOWN(size, alignment) ((size) & (~(alignment - 1))) +#define CHECK_ALIGNMENT(size, alignment) (((size) % (alignment)) == 0) + +#define PAGE_ALIGN(address) ROUND_DOWN_4K(address) #define LARGE_PAGE_SHIFT 22 // 2^22 = 4 MiB #define LARGE_PAGE_SIZE (1 << LARGE_PAGE_SHIFT) // = 0x00400000 = 4 MiB diff --git a/src/core/kernel/exports/EmuKrnlRtl.cpp b/src/core/kernel/exports/EmuKrnlRtl.cpp index 95e70e78f..dcb21cfb5 100644 --- a/src/core/kernel/exports/EmuKrnlRtl.cpp +++ b/src/core/kernel/exports/EmuKrnlRtl.cpp @@ -82,7 +82,7 @@ xbox::boolean_xt RtlpCaptureStackLimits( else { /* We're somewhere else entirely... use EBP for safety */ *StackBegin = Ebp; - *StackEnd = reinterpret_cast(PAGE_ALIGN((*StackBegin)); + *StackEnd = PAGE_ALIGN(*StackBegin); } /* Return success */ diff --git a/src/core/kernel/memory-manager/PhysicalMemory.h b/src/core/kernel/memory-manager/PhysicalMemory.h index b0a40f95b..076d97efb 100644 --- a/src/core/kernel/memory-manager/PhysicalMemory.h +++ b/src/core/kernel/memory-manager/PhysicalMemory.h @@ -126,11 +126,6 @@ typedef enum _MmLayout /* Common page calculations */ -#define ROUND_UP_4K(size) (((size) + PAGE_MASK) & (~PAGE_MASK)) -#define ROUND_UP(size, alignment) (((size) + (alignment - 1)) & (~(alignment - 1))) -#define ROUND_DOWN_4K(size) ((size) & (~PAGE_MASK)) -#define ROUND_DOWN(size, alignment) ((size) & (~(alignment - 1))) -#define CHECK_ALIGNMENT(size, alignment) (((size) % (alignment)) == 0) #define PAGES_SPANNED(Va, Size) ((ULONG)((((VAddr)(Va) & (PAGE_SIZE - 1)) + (Size) + (PAGE_SIZE - 1)) >> PAGE_SHIFT)) #define PAGES_SPANNED_LARGE(Va, Size) ((ULONG)((((VAddr)(Va) & (LARGE_PAGE_SIZE - 1)) + (Size) + (LARGE_PAGE_SIZE - 1)) >> LARGE_PAGE_SHIFT)) #define BYTE_OFFSET(Va) ((ULONG)((VAddr)(Va) & (PAGE_SIZE - 1))) From b84e80663f53d5f03588f59e1da7bee6683e46ba Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Tue, 5 Apr 2022 17:57:05 -0500 Subject: [PATCH 6/7] review remark 2 --- src/common/AddressRanges.h | 22 +++++++++++-------- .../kernel/memory-manager/PhysicalMemory.h | 12 ++-------- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/common/AddressRanges.h b/src/common/AddressRanges.h index 5ec49b80a..a1867bde0 100644 --- a/src/common/AddressRanges.h +++ b/src/common/AddressRanges.h @@ -146,15 +146,6 @@ inline constexpr uint32_t FLASH_DEVICE4_END = (FLASH_DEVICE4_BASE - 1 + FLA #define PAGE_SIZE (1 << PAGE_SHIFT) // = 0x00001000 = KiB(4) #define PAGE_MASK (PAGE_SIZE - 1) -// Common page calculations -#define ROUND_UP_4K(size) (((size) + PAGE_MASK) & (~PAGE_MASK)) -#define ROUND_UP(size, alignment) (((size) + (alignment - 1)) & (~(alignment - 1))) -#define ROUND_DOWN_4K(size) ((size) & (~PAGE_MASK)) -#define ROUND_DOWN(size, alignment) ((size) & (~(alignment - 1))) -#define CHECK_ALIGNMENT(size, alignment) (((size) % (alignment)) == 0) - -#define PAGE_ALIGN(address) ROUND_DOWN_4K(address) - #define LARGE_PAGE_SHIFT 22 // 2^22 = 4 MiB #define LARGE_PAGE_SIZE (1 << LARGE_PAGE_SHIFT) // = 0x00400000 = 4 MiB #define LARGE_PAGE_MASK (LARGE_PAGE_SIZE - 1) @@ -172,6 +163,19 @@ inline constexpr uint32_t FLASH_DEVICE4_END = (FLASH_DEVICE4_BASE - 1 + FLA #define XBOX_MEMORY_SIZE (MiB(64)) #define CHIHIRO_MEMORY_SIZE (MiB(128)) +// Common page calculations +#define ROUND_UP_4K(size) (((size) + PAGE_MASK) & (~PAGE_MASK)) +#define ROUND_UP(size, alignment) (((size) + (alignment - 1)) & (~(alignment - 1))) +#define ROUND_DOWN_4K(size) ((size) & (~PAGE_MASK)) +#define ROUND_DOWN(size, alignment) ((size) & (~(alignment - 1))) +#define CHECK_ALIGNMENT(size, alignment) (((size) % (alignment)) == 0) +#define BYTE_OFFSET(Va) ((xbox::ulong_xt)((xbox::ulong_ptr_xt)(Va) & (PAGE_SIZE - 1))) +#define BYTE_OFFSET_LARGE(Va) ((xbox::ulong_xt)((xbox::ulong_ptr_xt)(Va) & (LARGE_PAGE_SIZE - 1))) +#define PAGE_ALIGN(address) ROUND_DOWN_4K(address) +#define PAGE_END(Va) (((xbox::ulong_ptr_xt)(Va) & (PAGE_SIZE - 1)) == 0) +#define PAGES_SPANNED(Va, Size) ((xbox::ulong_xt)((((xbox::ulong_ptr_xt)(Va) & (PAGE_SIZE - 1)) + (Size) + (PAGE_SIZE - 1)) >> PAGE_SHIFT)) +#define PAGES_SPANNED_LARGE(Va, Size) ((xbox::ulong_xt)((((xbox::ulong_ptr_xt)(Va) & (LARGE_PAGE_SIZE - 1)) + (Size) + (LARGE_PAGE_SIZE - 1)) >> LARGE_PAGE_SHIFT)) + // Windows' address space allocation granularity; // See https://blogs.msdn.microsoft.com/oldnewthing/20031008-00/?p=42223 const int BLOCK_SIZE = KiB(64); diff --git a/src/core/kernel/memory-manager/PhysicalMemory.h b/src/core/kernel/memory-manager/PhysicalMemory.h index 076d97efb..5725cb4cc 100644 --- a/src/core/kernel/memory-manager/PhysicalMemory.h +++ b/src/core/kernel/memory-manager/PhysicalMemory.h @@ -37,8 +37,8 @@ /* Global typedefs */ -typedef uintptr_t VAddr; -typedef uintptr_t PAddr; +typedef xbox::ulong_ptr_xt VAddr; +typedef xbox::ulong_ptr_xt PAddr; typedef uint32_t u32; @@ -125,14 +125,6 @@ typedef enum _MmLayout #define CHIHIRO_PFN_ELEMENT(pfn) (&((PXBOX_PFN)CHIHIRO_PFN_ADDRESS)[pfn]) -/* Common page calculations */ -#define PAGES_SPANNED(Va, Size) ((ULONG)((((VAddr)(Va) & (PAGE_SIZE - 1)) + (Size) + (PAGE_SIZE - 1)) >> PAGE_SHIFT)) -#define PAGES_SPANNED_LARGE(Va, Size) ((ULONG)((((VAddr)(Va) & (LARGE_PAGE_SIZE - 1)) + (Size) + (LARGE_PAGE_SIZE - 1)) >> LARGE_PAGE_SHIFT)) -#define BYTE_OFFSET(Va) ((ULONG)((VAddr)(Va) & (PAGE_SIZE - 1))) -#define BYTE_OFFSET_LARGE(Va) ((ULONG)((VAddr)(Va) & (LARGE_PAGE_SIZE - 1))) -#define PAGE_END(Va) (((ULONG_PTR)(Va) & (PAGE_SIZE - 1)) == 0) - - /* These macros check if the supplied address is inside a known range */ #define IS_PHYSICAL_ADDRESS(Va) (((VAddr)(Va) - PHYSICAL_MAP_BASE) <= (PHYSICAL_MAP_END - PHYSICAL_MAP_BASE)) #define IS_SYSTEM_ADDRESS(Va) (((VAddr)(Va) - SYSTEM_MEMORY_BASE) <= (SYSTEM_MEMORY_END - SYSTEM_MEMORY_BASE)) From a338a12d77ec9fff560b1e1b33d8f7a554e2fc29 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Wed, 6 Apr 2022 03:42:35 -0500 Subject: [PATCH 7/7] revert partial review remark --- src/common/AddressRanges.h | 5 ----- src/core/kernel/memory-manager/PhysicalMemory.h | 8 ++++++++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/common/AddressRanges.h b/src/common/AddressRanges.h index a1867bde0..f722462e1 100644 --- a/src/common/AddressRanges.h +++ b/src/common/AddressRanges.h @@ -169,12 +169,7 @@ inline constexpr uint32_t FLASH_DEVICE4_END = (FLASH_DEVICE4_BASE - 1 + FLA #define ROUND_DOWN_4K(size) ((size) & (~PAGE_MASK)) #define ROUND_DOWN(size, alignment) ((size) & (~(alignment - 1))) #define CHECK_ALIGNMENT(size, alignment) (((size) % (alignment)) == 0) -#define BYTE_OFFSET(Va) ((xbox::ulong_xt)((xbox::ulong_ptr_xt)(Va) & (PAGE_SIZE - 1))) -#define BYTE_OFFSET_LARGE(Va) ((xbox::ulong_xt)((xbox::ulong_ptr_xt)(Va) & (LARGE_PAGE_SIZE - 1))) #define PAGE_ALIGN(address) ROUND_DOWN_4K(address) -#define PAGE_END(Va) (((xbox::ulong_ptr_xt)(Va) & (PAGE_SIZE - 1)) == 0) -#define PAGES_SPANNED(Va, Size) ((xbox::ulong_xt)((((xbox::ulong_ptr_xt)(Va) & (PAGE_SIZE - 1)) + (Size) + (PAGE_SIZE - 1)) >> PAGE_SHIFT)) -#define PAGES_SPANNED_LARGE(Va, Size) ((xbox::ulong_xt)((((xbox::ulong_ptr_xt)(Va) & (LARGE_PAGE_SIZE - 1)) + (Size) + (LARGE_PAGE_SIZE - 1)) >> LARGE_PAGE_SHIFT)) // Windows' address space allocation granularity; // See https://blogs.msdn.microsoft.com/oldnewthing/20031008-00/?p=42223 diff --git a/src/core/kernel/memory-manager/PhysicalMemory.h b/src/core/kernel/memory-manager/PhysicalMemory.h index 5725cb4cc..bea4370d9 100644 --- a/src/core/kernel/memory-manager/PhysicalMemory.h +++ b/src/core/kernel/memory-manager/PhysicalMemory.h @@ -125,6 +125,14 @@ typedef enum _MmLayout #define CHIHIRO_PFN_ELEMENT(pfn) (&((PXBOX_PFN)CHIHIRO_PFN_ADDRESS)[pfn]) +// Common page calculations +#define BYTE_OFFSET(Va) ((xbox::ulong_xt)((xbox::ulong_ptr_xt)(Va) & (PAGE_SIZE - 1))) +#define BYTE_OFFSET_LARGE(Va) ((xbox::ulong_xt)((xbox::ulong_ptr_xt)(Va) & (LARGE_PAGE_SIZE - 1))) +#define PAGE_END(Va) (((xbox::ulong_ptr_xt)(Va) & (PAGE_SIZE - 1)) == 0) +#define PAGES_SPANNED(Va, Size) ((xbox::ulong_xt)((((xbox::ulong_ptr_xt)(Va) & (PAGE_SIZE - 1)) + (Size) + (PAGE_SIZE - 1)) >> PAGE_SHIFT)) +#define PAGES_SPANNED_LARGE(Va, Size) ((xbox::ulong_xt)((((xbox::ulong_ptr_xt)(Va) & (LARGE_PAGE_SIZE - 1)) + (Size) + (LARGE_PAGE_SIZE - 1)) >> LARGE_PAGE_SHIFT)) + + /* These macros check if the supplied address is inside a known range */ #define IS_PHYSICAL_ADDRESS(Va) (((VAddr)(Va) - PHYSICAL_MAP_BASE) <= (PHYSICAL_MAP_END - PHYSICAL_MAP_BASE)) #define IS_SYSTEM_ADDRESS(Va) (((VAddr)(Va) - SYSTEM_MEMORY_BASE) <= (SYSTEM_MEMORY_END - SYSTEM_MEMORY_BASE))