From 6d8d692b7c452c3669c6c6d45c0c760087c4a393 Mon Sep 17 00:00:00 2001 From: Fisherman166 Date: Sat, 6 Jun 2020 13:34:40 -0700 Subject: [PATCH 1/3] Implement FscSetCacheSize matching original kernel implementation. --- src/core/kernel/exports/EmuKrnlFs.cpp | 32 +++++++++++++++++++++------ 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/src/core/kernel/exports/EmuKrnlFs.cpp b/src/core/kernel/exports/EmuKrnlFs.cpp index 5ec1d9938..960894e2f 100644 --- a/src/core/kernel/exports/EmuKrnlFs.cpp +++ b/src/core/kernel/exports/EmuKrnlFs.cpp @@ -70,6 +70,9 @@ XBSYSAPI EXPORTNUM(36) xboxkrnl::VOID NTAPI xboxkrnl::FscInvalidateIdleBlocks() LOG_UNIMPLEMENTED(); } +static xboxkrnl::KEVENT FscCacheEvent; +static xboxkrnl::PKEVENT FscCacheEventPtr = nullptr; + // ****************************************************************** // * 0x0025 - FscSetCacheSize() // ****************************************************************** @@ -80,18 +83,33 @@ XBSYSAPI EXPORTNUM(37) xboxkrnl::NTSTATUS NTAPI xboxkrnl::FscSetCacheSize { LOG_FUNC_ONE_ARG(NumberOfCachePages); - NTSTATUS ret = STATUS_SUCCESS; + if (FscCacheEventPtr == nullptr) { + KeInitializeEvent(&FscCacheEvent, SynchronizationEvent, 1); + FscCacheEventPtr = &FscCacheEvent; + } - if (NumberOfCachePages > FSCACHE_MAXIMUM_NUMBER_OF_CACHE_PAGES) + NTSTATUS ret = STATUS_SUCCESS; + KeWaitForSingleObject(FscCacheEventPtr, Executive, 0, 0, 0); + UCHAR orig_irql = KeRaiseIrqlToDpcLevel(); + + if (NumberOfCachePages > FSCACHE_MAXIMUM_NUMBER_OF_CACHE_PAGES) { ret = STATUS_INVALID_PARAMETER; - else - { - // TODO : Actually allocate file system cache pages, for example do something like this : - // if (NumberOfCachePages < g_FscNumberOfCachePages) FscShrinkCacheSize(NumberOfCachePages) - // if (NumberOfCachePages > g_FscNumberOfCachePages) FscGrowCacheSize(NumberOfCachePages), possibly return STATUS_INSUFFICIENT_RESOURCES + } + else { + // TODO : Actually allocate file system cache pages. +#if 0 + if (NumberOfCachePages > g_FscNumberOfCachePages) { + ret = FscGrowCacheSize(NumberOfCachePages); + } + else if (NumberOfCachePages < g_FscNumberOfCachePages) { + ret = FscShrinkCacheSize(NumberOfCachePages); + } +#endif g_FscNumberOfCachePages = NumberOfCachePages; } + KfLowerIrql(orig_irql); + KeSetEvent(FscCacheEventPtr, 0, 0); RETURN(ret); } From 326f645b8f1e29ecf4f716c26b7153a4e9ad15e2 Mon Sep 17 00:00:00 2001 From: Fisherman166 Date: Sat, 6 Jun 2020 16:09:01 -0700 Subject: [PATCH 2/3] Initialize FscCacheEvent at emulation start to match the real kernel implementation. --- import/OpenXDK/include/xboxkrnl/xbox.h | 2 ++ src/core/kernel/exports/EmuKrnlFs.cpp | 15 +++++++-------- src/core/kernel/init/CxbxKrnl.cpp | 2 ++ 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/import/OpenXDK/include/xboxkrnl/xbox.h b/import/OpenXDK/include/xboxkrnl/xbox.h index 322b7a6cb..56f868277 100644 --- a/import/OpenXDK/include/xboxkrnl/xbox.h +++ b/import/OpenXDK/include/xboxkrnl/xbox.h @@ -73,6 +73,8 @@ #define AV_OPTION_CGMS 18 #define AV_OPTION_WIDESCREEN 19 +VOID InitializeFscCacheEvent(); + // ****************************************************************** // * 0x0001 - AvGetSavedDataAddress() // ****************************************************************** diff --git a/src/core/kernel/exports/EmuKrnlFs.cpp b/src/core/kernel/exports/EmuKrnlFs.cpp index 960894e2f..1e838f9a5 100644 --- a/src/core/kernel/exports/EmuKrnlFs.cpp +++ b/src/core/kernel/exports/EmuKrnlFs.cpp @@ -71,7 +71,11 @@ XBSYSAPI EXPORTNUM(36) xboxkrnl::VOID NTAPI xboxkrnl::FscInvalidateIdleBlocks() } static xboxkrnl::KEVENT FscCacheEvent; -static xboxkrnl::PKEVENT FscCacheEventPtr = nullptr; + +xboxkrnl::VOID xboxkrnl::InitializeFscCacheEvent() +{ + KeInitializeEvent(&FscCacheEvent, SynchronizationEvent, TRUE); +} // ****************************************************************** // * 0x0025 - FscSetCacheSize() @@ -83,13 +87,8 @@ XBSYSAPI EXPORTNUM(37) xboxkrnl::NTSTATUS NTAPI xboxkrnl::FscSetCacheSize { LOG_FUNC_ONE_ARG(NumberOfCachePages); - if (FscCacheEventPtr == nullptr) { - KeInitializeEvent(&FscCacheEvent, SynchronizationEvent, 1); - FscCacheEventPtr = &FscCacheEvent; - } - NTSTATUS ret = STATUS_SUCCESS; - KeWaitForSingleObject(FscCacheEventPtr, Executive, 0, 0, 0); + KeWaitForSingleObject(&FscCacheEvent, Executive, 0, 0, 0); UCHAR orig_irql = KeRaiseIrqlToDpcLevel(); if (NumberOfCachePages > FSCACHE_MAXIMUM_NUMBER_OF_CACHE_PAGES) { @@ -109,7 +108,7 @@ XBSYSAPI EXPORTNUM(37) xboxkrnl::NTSTATUS NTAPI xboxkrnl::FscSetCacheSize } KfLowerIrql(orig_irql); - KeSetEvent(FscCacheEventPtr, 0, 0); + KeSetEvent(&FscCacheEvent, 0, 0); RETURN(ret); } diff --git a/src/core/kernel/init/CxbxKrnl.cpp b/src/core/kernel/init/CxbxKrnl.cpp index ce669da36..27c5fc560 100644 --- a/src/core/kernel/init/CxbxKrnl.cpp +++ b/src/core/kernel/init/CxbxKrnl.cpp @@ -1285,6 +1285,8 @@ __declspec(noreturn) void CxbxKrnlInit // But with this, we can replace some busy loops with sleeps. timeBeginPeriod(1); + xboxkrnl::InitializeFscCacheEvent(); + // update caches CxbxKrnl_TLS = pTLS; CxbxKrnl_TLSData = pTLSData; From a981607e51c0783ef4f1865206096a1df5d93323 Mon Sep 17 00:00:00 2001 From: Fisherman166 Date: Sun, 7 Jun 2020 09:40:55 -0700 Subject: [PATCH 3/3] Add g_ prefix to FscCacheEvent. --- src/core/kernel/exports/EmuKrnlFs.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/kernel/exports/EmuKrnlFs.cpp b/src/core/kernel/exports/EmuKrnlFs.cpp index 1e838f9a5..4365a2596 100644 --- a/src/core/kernel/exports/EmuKrnlFs.cpp +++ b/src/core/kernel/exports/EmuKrnlFs.cpp @@ -70,11 +70,11 @@ XBSYSAPI EXPORTNUM(36) xboxkrnl::VOID NTAPI xboxkrnl::FscInvalidateIdleBlocks() LOG_UNIMPLEMENTED(); } -static xboxkrnl::KEVENT FscCacheEvent; +static xboxkrnl::KEVENT g_FscCacheEvent; xboxkrnl::VOID xboxkrnl::InitializeFscCacheEvent() { - KeInitializeEvent(&FscCacheEvent, SynchronizationEvent, TRUE); + KeInitializeEvent(&g_FscCacheEvent, SynchronizationEvent, TRUE); } // ****************************************************************** @@ -88,7 +88,7 @@ XBSYSAPI EXPORTNUM(37) xboxkrnl::NTSTATUS NTAPI xboxkrnl::FscSetCacheSize LOG_FUNC_ONE_ARG(NumberOfCachePages); NTSTATUS ret = STATUS_SUCCESS; - KeWaitForSingleObject(&FscCacheEvent, Executive, 0, 0, 0); + KeWaitForSingleObject(&g_FscCacheEvent, Executive, 0, 0, 0); UCHAR orig_irql = KeRaiseIrqlToDpcLevel(); if (NumberOfCachePages > FSCACHE_MAXIMUM_NUMBER_OF_CACHE_PAGES) { @@ -108,7 +108,7 @@ XBSYSAPI EXPORTNUM(37) xboxkrnl::NTSTATUS NTAPI xboxkrnl::FscSetCacheSize } KfLowerIrql(orig_irql); - KeSetEvent(&FscCacheEvent, 0, 0); + KeSetEvent(&g_FscCacheEvent, 0, 0); RETURN(ret); }