From 59c08cd46231708b7c13050650192136047a72cb Mon Sep 17 00:00:00 2001 From: Adrian <78108584+AdrianCassar@users.noreply.github.com> Date: Thu, 13 Aug 2026 20:26:50 +0100 Subject: [PATCH] [Kernel] Replaced X_DISPATCHER_FLAGS with X_OBJECT_TYPES --- src/xenia/kernel/kernel_state.cc | 2 +- src/xenia/kernel/xboxkrnl/xboxkrnl_rtl.cc | 4 +- .../kernel/xboxkrnl/xboxkrnl_threading.cc | 28 ++++---- src/xenia/kernel/xevent.cc | 4 +- src/xenia/kernel/xobject.cc | 39 ++++++----- src/xenia/kernel/xobject.h | 68 +++++++++++-------- src/xenia/kernel/xthread.cc | 2 +- 7 files changed, 80 insertions(+), 67 deletions(-) diff --git a/src/xenia/kernel/kernel_state.cc b/src/xenia/kernel/kernel_state.cc index 40e695385..a870b762b 100644 --- a/src/xenia/kernel/kernel_state.cc +++ b/src/xenia/kernel/kernel_state.cc @@ -1535,7 +1535,7 @@ void KernelState::InitializeKernelGuestGlobals() { // init unknown object - block->XboxKernelDefaultObject.type = DISPATCHER_AUTO_RESET_EVENT; + block->XboxKernelDefaultObject.type = EventSynchronizationObject; block->XboxKernelDefaultObject.signal_state = 1; block->XboxKernelDefaultObject.wait_list.flink_ptr = oddobject_offset + offsetof(X_DISPATCH_HEADER, wait_list.flink_ptr); diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_rtl.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_rtl.cc index ec1178f57..d4d8f4f7e 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_rtl.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_rtl.cc @@ -544,7 +544,7 @@ static_assert_size(X_RTL_CRITICAL_SECTION, 28); void xeRtlInitializeCriticalSection(X_RTL_CRITICAL_SECTION* cs, uint32_t cs_ptr) { - cs->header.type = X_DISPATCHER_FLAGS::DISPATCHER_AUTO_RESET_EVENT; + cs->header.type = X_OBJECT_TYPES::EventSynchronizationObject; cs->header.absolute = 0; // spin count div 256 cs->header.signal_state = 0; cs->lock_count = -1; @@ -567,7 +567,7 @@ X_STATUS xeRtlInitializeCriticalSectionAndSpinCount(X_RTL_CRITICAL_SECTION* cs, spin_count_div_256 = 255; } - cs->header.type = X_DISPATCHER_FLAGS::DISPATCHER_AUTO_RESET_EVENT; + cs->header.type = X_OBJECT_TYPES::EventSynchronizationObject; cs->header.absolute = spin_count_div_256; cs->header.signal_state = 0; cs->lock_count = -1; diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.cc index 7d2b388e7..62e263b4e 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.cc @@ -251,7 +251,7 @@ DECLARE_XBOXKRNL_EXPORT1(NtResumeThread, kThreading, kImplemented); dword_result_t KeResumeThread_entry(pointer_t thread_ptr) { X_STATUS result = X_STATUS_SUCCESS; auto thread = XObject::GetNativeObject(kernel_state(), thread_ptr, - DISPATCHER_THREAD); + ThreadObject); if (thread) { result = thread->Resume(); } else { @@ -316,7 +316,7 @@ DECLARE_XBOXKRNL_EXPORT1(NtSuspendThread, kThreading, kImplemented); dword_result_t KeSuspendThread_entry(pointer_t kthread, const ppc_context_t& context) { auto thread = XObject::GetNativeObject(context->kernel_state, - kthread, DISPATCHER_THREAD); + kthread, ThreadObject); uint32_t suspend_count_out = 0; if (thread) { @@ -368,7 +368,7 @@ dword_result_t KeSetAffinityThread_entry(pointer_t thread_ptr, return X_STATUS_INVALID_PARAMETER; } auto thread = XObject::GetNativeObject(kernel_state(), thread_ptr, - DISPATCHER_THREAD); + ThreadObject); if (!thread) { XELOGW( "KeSetAffinityThread: guest thread pointer {:08X} did not resolve to " @@ -389,7 +389,7 @@ dword_result_t KeQueryBasePriorityThread_entry( int32_t priority = 0; auto thread = XObject::GetNativeObject(kernel_state(), thread_ptr, - DISPATCHER_THREAD); + ThreadObject); if (thread) { priority = thread->QueryPriority(); } @@ -402,7 +402,7 @@ dword_result_t KeSetBasePriorityThread_entry(pointer_t thread_ptr, dword_t increment) { int32_t prev_priority = 0; auto thread = XObject::GetNativeObject(kernel_state(), thread_ptr, - DISPATCHER_THREAD); + ThreadObject); if (thread) { prev_priority = thread->QueryPriority(); @@ -565,7 +565,7 @@ DECLARE_XBOXKRNL_EXPORT1(KeTlsSetValue, kThreading, kImplemented); void KeInitializeEvent_entry(pointer_t event_ptr, dword_t event_type, dword_t initial_state) { event_ptr.Zero(); - event_ptr->header.type = static_cast(event_type.value()); + event_ptr->header.type = static_cast(event_type.value()); event_ptr->header.signal_state = initial_state.value(); auto ev = XObject::GetNativeObject(kernel_state(), event_ptr, event_ptr->header.type); @@ -736,12 +736,12 @@ DECLARE_XBOXKRNL_EXPORT2(NtClearEvent, kThreading, kImplemented, // https://msdn.microsoft.com/en-us/library/windows/hardware/ff552150(v=vs.85).aspx void KeInitializeSemaphore_entry(pointer_t semaphore_ptr, dword_t count, dword_t limit) { - semaphore_ptr->header.type = DISPATCHER_SEMAPHORE; + semaphore_ptr->header.type = SemaphoreObject; semaphore_ptr->header.signal_state = (uint32_t)count; semaphore_ptr->limit = (uint32_t)limit; auto sem = XObject::GetNativeObject(kernel_state(), semaphore_ptr, - DISPATCHER_SEMAPHORE); + SemaphoreObject); if (!sem) { assert_always(); return; @@ -752,7 +752,7 @@ DECLARE_XBOXKRNL_EXPORT1(KeInitializeSemaphore, kThreading, kImplemented); uint32_t xeKeReleaseSemaphore(X_KSEMAPHORE* semaphore_ptr, uint32_t increment, uint32_t adjustment, uint32_t wait) { auto sem = XObject::GetNativeObject(kernel_state(), semaphore_ptr, - DISPATCHER_SEMAPHORE); + SemaphoreObject); if (!sem) { assert_always(); return 0; @@ -1067,7 +1067,7 @@ dword_result_t KeWaitForMultipleObjects_entry( for (uint32_t n = 0; n < count; n++) { auto object_ptr = kernel_memory()->TranslateVirtual(objects_ptr[n]); auto object_ref = XObject::GetNativeObject( - kernel_state(), object_ptr, DISPATCHER_UNDEFINED, true); + kernel_state(), object_ptr, UndefinedObject, true); if (!object_ref) { return X_STATUS_INVALID_PARAMETER; } @@ -1916,7 +1916,7 @@ dword_result_t KeSetPriorityThread_entry(pointer_t thread_ptr, return 0; } - if (thread_ptr->header.type != DISPATCHER_THREAD) { + if (thread_ptr->header.type != ThreadObject) { XELOGW("{}: Invalid object type: {}", __func__, static_cast(thread_ptr->header.type)); } @@ -1925,8 +1925,8 @@ dword_result_t KeSetPriorityThread_entry(pointer_t thread_ptr, const uint32_t old_irql = xeKeKfAcquireSpinLock(context, &prcb->spin_lock); const uint8_t old_priority = thread_ptr->priority; - auto thread_ref = XObject::GetNativeObject( - kernel_state(), thread_ptr, DISPATCHER_THREAD); + auto thread_ref = XObject::GetNativeObject(kernel_state(), + thread_ptr, ThreadObject); if (!thread_ref) { XELOGW("{}: Missing native thread: {}", __func__, @@ -1949,7 +1949,7 @@ void xeKeInitializeTimerEx(X_KTIMER* timer, uint32_t type, uint32_t proctype, timer->header.process_type = proctype; timer->header.inserted = 0; timer->header.type = - type ? DISPATCHER_AUTO_RESET_TIMER : DISPATCHER_MANUAL_RESET_TIMER; + type ? TimerSynchronizationObject : TimerNotificationObject; timer->header.signal_state = 0; util::XeInitializeListHead(&timer->header.wait_list, context); timer->due_time = 0; diff --git a/src/xenia/kernel/xevent.cc b/src/xenia/kernel/xevent.cc index a2a76cad9..dbd9c9da2 100644 --- a/src/xenia/kernel/xevent.cc +++ b/src/xenia/kernel/xevent.cc @@ -38,10 +38,10 @@ void XEvent::InitializeNative(void* native_ptr, assert_false(event_); switch (header->type) { - case X_DISPATCHER_FLAGS::DISPATCHER_MANUAL_RESET_EVENT: + case X_OBJECT_TYPES::EventNotificationObject: manual_reset_ = true; break; - case X_DISPATCHER_FLAGS::DISPATCHER_AUTO_RESET_EVENT: + case X_OBJECT_TYPES::EventSynchronizationObject: manual_reset_ = false; break; default: diff --git a/src/xenia/kernel/xobject.cc b/src/xenia/kernel/xobject.cc index 6eb522d00..77d0ae72c 100644 --- a/src/xenia/kernel/xobject.cc +++ b/src/xenia/kernel/xobject.cc @@ -396,7 +396,7 @@ void XObject::SetNativePointer(uint32_t native_ptr, bool uninitialized) { object_ref XObject::GetNativeObject(KernelState* kernel_state, void* native_ptr, - X_DISPATCHER_FLAGS as_type, + X_OBJECT_TYPES as_type, bool already_locked) { assert_not_null(native_ptr); @@ -415,9 +415,9 @@ object_ref XObject::GetNativeObject(KernelState* kernel_state, XObject* result = nullptr; auto header = reinterpret_cast(native_ptr); - X_DISPATCHER_FLAGS type = as_type; + X_OBJECT_TYPES type = as_type; - if (as_type == X_DISPATCHER_FLAGS::DISPATCHER_UNDEFINED) { + if (as_type == X_OBJECT_TYPES::UndefinedObject) { type = header->type; } @@ -432,37 +432,36 @@ object_ref XObject::GetNativeObject(KernelState* kernel_state, // First use, create new. // https://www.nirsoft.net/kernel_struct/vista/KOBJECTS.html switch (type) { - case X_DISPATCHER_FLAGS::DISPATCHER_MANUAL_RESET_EVENT: - case X_DISPATCHER_FLAGS::DISPATCHER_AUTO_RESET_EVENT: { + case X_OBJECT_TYPES::EventNotificationObject: + case X_OBJECT_TYPES::EventSynchronizationObject: { auto ev = new XEvent(kernel_state); ev->InitializeNative(native_ptr, header); result = ev; } break; - case X_DISPATCHER_FLAGS::DISPATCHER_MUTANT: { + case X_OBJECT_TYPES::MutantObject: { auto mutant = new XMutant(kernel_state); mutant->InitializeNative(native_ptr, header); result = mutant; } break; - case X_DISPATCHER_FLAGS::DISPATCHER_SEMAPHORE: { + case X_OBJECT_TYPES::SemaphoreObject: { auto sem = new XSemaphore(kernel_state); auto success = sem->InitializeNative(native_ptr, header); // Can't report failure to the guest at late initialization: assert_true(success); result = sem; } break; - case 3: // ProcessObject - case 4: // QueueObject - case 6: // ThreadObject - case 7: // GateObject - case 8: // TimerNotificationObject - case 9: // TimerSynchronizationObject - case 18: // ApcObject - case 19: // DpcObject - case 20: // DeviceQueueObject - case 21: // EventPairObject - case 22: // InterruptObject - case 23: // ProfileObject - case 24: // ThreadedDpcObject + case X_OBJECT_TYPES::ProcessObject: + case X_OBJECT_TYPES::QueueObject: + case X_OBJECT_TYPES::ThreadObject: + case X_OBJECT_TYPES::Spare1Object: + case X_OBJECT_TYPES::TimerNotificationObject: + case X_OBJECT_TYPES::TimerSynchronizationObject: + case X_OBJECT_TYPES::ApcObject: + case X_OBJECT_TYPES::DpcObject: + case X_OBJECT_TYPES::DeviceQueueObject: + case X_OBJECT_TYPES::EventPairObject: + case X_OBJECT_TYPES::InterruptObject: + case X_OBJECT_TYPES::ProfileObject: default: assert_always(); result = nullptr; diff --git a/src/xenia/kernel/xobject.h b/src/xenia/kernel/xobject.h index 8dfd786d2..780dfc775 100644 --- a/src/xenia/kernel/xobject.h +++ b/src/xenia/kernel/xobject.h @@ -34,22 +34,38 @@ class KernelState; template class object_ref; -enum X_DISPATCHER_FLAGS : uint8_t { - DISPATCHER_MANUAL_RESET_EVENT = 0, // EventNotificationObject - DISPATCHER_AUTO_RESET_EVENT = 1, // EventSynchronizationObject - DISPATCHER_MUTANT = 2, // MutantObject - DISPATCHER_QUEUE = 4, - DISPATCHER_SEMAPHORE = 5, // SemaphoreObject - DISPATCHER_THREAD = 6, - DISPATCHER_MANUAL_RESET_TIMER = 8, - DISPATCHER_AUTO_RESET_TIMER = 9, - DISPATCHER_UNDEFINED = 0xFF, +enum X_OBJECT_TYPES : uint8_t { + EventNotificationObject = 0x0, // Manual Reset + EventSynchronizationObject = 0x1, // Auto Reset + MutantObject = 0x2, + ProcessObject = 0x3, + QueueObject = 0x4, + SemaphoreObject = 0x5, + ThreadObject = 0x6, + Spare1Object = 0x7, // GateObject? + TimerNotificationObject = 0x8, + TimerSynchronizationObject = 0x9, + Spare2Object = 0xA, + Spare3Object = 0xB, + Spare4Object = 0xC, + Spare5Object = 0xD, + Spare6Object = 0xE, + Spare7Object = 0xF, + Spare8Object = 0x10, + Spare9Object = 0x11, + ApcObject = 0x12, + DpcObject = 0x13, + DeviceQueueObject = 0x14, + EventPairObject = 0x15, + InterruptObject = 0x16, + ProfileObject = 0x17, + UndefinedObject = 0xFF, }; // https://www.nirsoft.net/kernel_struct/vista/DISPATCHER_HEADER.html typedef struct { struct { - X_DISPATCHER_FLAGS type; + X_OBJECT_TYPES type; union { uint8_t abandoned; @@ -125,20 +141,20 @@ class XObject { } } - static Type MapGuestTypeToHost(X_DISPATCHER_FLAGS flag) { + static Type MapGuestTypeToHost(X_OBJECT_TYPES flag) { // TODO: This is not fully filled in. switch (flag) { - case X_DISPATCHER_FLAGS::DISPATCHER_MANUAL_RESET_EVENT: - case X_DISPATCHER_FLAGS::DISPATCHER_AUTO_RESET_EVENT: + case X_OBJECT_TYPES::EventNotificationObject: + case X_OBJECT_TYPES::EventSynchronizationObject: return Type::Event; - case X_DISPATCHER_FLAGS::DISPATCHER_MUTANT: + case X_OBJECT_TYPES::MutantObject: return Type::Mutant; - case X_DISPATCHER_FLAGS::DISPATCHER_SEMAPHORE: + case X_OBJECT_TYPES::SemaphoreObject: return Type::Semaphore; - case X_DISPATCHER_FLAGS::DISPATCHER_THREAD: + case X_OBJECT_TYPES::ThreadObject: return Type::Thread; - case X_DISPATCHER_FLAGS::DISPATCHER_MANUAL_RESET_TIMER: - case X_DISPATCHER_FLAGS::DISPATCHER_AUTO_RESET_TIMER: + case X_OBJECT_TYPES::TimerNotificationObject: + case X_OBJECT_TYPES::TimerSynchronizationObject: return Type::Timer; default: return Type::Undefined; @@ -206,13 +222,12 @@ class XObject { static object_ref GetNativeObject( KernelState* kernel_state, void* native_ptr, - X_DISPATCHER_FLAGS as_type = DISPATCHER_UNDEFINED, - bool already_locked = false); + X_OBJECT_TYPES as_type = UndefinedObject, bool already_locked = false); template - static object_ref GetNativeObject( - KernelState* kernel_state, void* native_ptr, - X_DISPATCHER_FLAGS as_type = DISPATCHER_UNDEFINED, - bool already_locked = false); + static object_ref GetNativeObject(KernelState* kernel_state, + void* native_ptr, + X_OBJECT_TYPES as_type = UndefinedObject, + bool already_locked = false); // Priority increment stored by the most recent signal operation // (KeSetEvent, KeReleaseSemaphore, etc.). Read by the waiter on wake @@ -395,8 +410,7 @@ object_ref retain_object(T* ptr) { template object_ref XObject::GetNativeObject(KernelState* kernel_state, - void* native_ptr, - X_DISPATCHER_FLAGS as_type, + void* native_ptr, X_OBJECT_TYPES as_type, bool already_locked) { return object_ref(reinterpret_cast( GetNativeObject(kernel_state, native_ptr, as_type, already_locked) diff --git a/src/xenia/kernel/xthread.cc b/src/xenia/kernel/xthread.cc index 33610bfb3..71643901d 100644 --- a/src/xenia/kernel/xthread.cc +++ b/src/xenia/kernel/xthread.cc @@ -180,7 +180,7 @@ static uint8_t GetFakeCpuNumber(uint8_t proc_mask) { void XThread::InitializeGuestObject() { auto guest_thread = guest_object(); auto thread_guest_ptr = guest_object(); - guest_thread->header.type = X_DISPATCHER_FLAGS::DISPATCHER_THREAD; + guest_thread->header.type = X_OBJECT_TYPES::ThreadObject; guest_thread->suspend_count = (creation_params_.creation_flags & X_CREATE_SUSPENDED) ? 1 : 0;