From bf48e9fbbdda75eaaa5b66ce085308e358690b3d Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 16 Aug 2014 00:11:24 -0700 Subject: [PATCH] Part 2 of kernel cleanup: merging functions into shims. --- src/xenia/kernel/kernel_state.cc | 7 +- src/xenia/kernel/kernel_state.h | 7 - src/xenia/kernel/util/shim_utils.h | 10 - src/xenia/kernel/xam_video.cc | 8 +- src/xenia/kernel/xboxkrnl_debug.cc | 6 +- src/xenia/kernel/xboxkrnl_hal.cc | 22 +- src/xenia/kernel/xboxkrnl_memory.cc | 344 ++++++--------- src/xenia/kernel/xboxkrnl_modules.cc | 65 +-- src/xenia/kernel/xboxkrnl_rtl.cc | 478 ++++++++------------ src/xenia/kernel/xboxkrnl_rtl.h | 17 +- src/xenia/kernel/xboxkrnl_threading.cc | 587 ++++++++----------------- src/xenia/kernel/xboxkrnl_video.cc | 196 +++------ src/xenia/kernel/xobject.cc | 6 +- 13 files changed, 594 insertions(+), 1159 deletions(-) diff --git a/src/xenia/kernel/kernel_state.cc b/src/xenia/kernel/kernel_state.cc index f885e03fd..92d10810f 100644 --- a/src/xenia/kernel/kernel_state.cc +++ b/src/xenia/kernel/kernel_state.cc @@ -30,8 +30,11 @@ using namespace xe::kernel; // This is a global object initialized with the XboxkrnlModule. // It references the current kernel state object that all kernel methods should // be using to stash their variables. -KernelState* xe::kernel::shared_kernel_state_ = NULL; - +namespace xe { +namespace kernel { +KernelState* shared_kernel_state_ = nullptr; +} // namespace kernel +} // namespace xe KernelState::KernelState(Emulator* emulator) : emulator_(emulator), memory_(emulator->memory()), diff --git a/src/xenia/kernel/kernel_state.h b/src/xenia/kernel/kernel_state.h index 55033aef6..097566f90 100644 --- a/src/xenia/kernel/kernel_state.h +++ b/src/xenia/kernel/kernel_state.h @@ -95,13 +95,6 @@ private: }; -// This is a global object initialized with the KernelState ctor. -// It references the current kernel state object that all kernel methods should -// be using to stash their variables. -// This sucks, but meh. -extern KernelState* shared_kernel_state_; - - } // namespace kernel } // namespace xe diff --git a/src/xenia/kernel/util/shim_utils.h b/src/xenia/kernel/util/shim_utils.h index ef44874ea..d68ea4da8 100644 --- a/src/xenia/kernel/util/shim_utils.h +++ b/src/xenia/kernel/util/shim_utils.h @@ -59,16 +59,6 @@ using PPCContext = alloy::frontend::ppc::PPCContext; #define SHIM_SET_RETURN_64(v) SHIM_SET_GPR_64(3, v) -#define IMPL_MEM_ADDR(a) (a ? state->memory()->Translate(a) : nullptr) - -#define IMPL_MEM_8(a) poly::load_and_swap(IMPL_MEM_ADDR(a)) -#define IMPL_MEM_16(a) poly::load_and_swap(IMPL_MEM_ADDR(a)) -#define IMPL_MEM_32(a) poly::load_and_swap(IMPL_MEM_ADDR(a)) -#define IMPL_SET_MEM_8(a, v) poly::store_and_swap(IMPL_MEM_ADDR(a), v) -#define IMPL_SET_MEM_16(a, v) poly::store_and_swap(IMPL_MEM_ADDR(a), v) -#define IMPL_SET_MEM_32(a, v) poly::store_and_swap(IMPL_MEM_ADDR(a), v) - - } // namespace kernel } // namespace xe diff --git a/src/xenia/kernel/xam_video.cc b/src/xenia/kernel/xam_video.cc index 2bba399cc..1106f9bb7 100644 --- a/src/xenia/kernel/xam_video.cc +++ b/src/xenia/kernel/xam_video.cc @@ -23,13 +23,13 @@ using namespace xe::kernel::xam; namespace xe { namespace kernel { + // TODO(benvanik): actually check to see if these are the same. -void xeVdQueryVideoMode(X_VIDEO_MODE *video_mode, bool swap); -SHIM_CALL XGetVideoMode_shim( - PPCContext* ppc_state, KernelState* state) { +void xeVdQueryVideoMode(X_VIDEO_MODE* video_mode); +SHIM_CALL XGetVideoMode_shim(PPCContext* ppc_state, KernelState* state) { uint32_t video_mode_ptr = SHIM_GET_ARG_32(0); X_VIDEO_MODE* video_mode = (X_VIDEO_MODE*)SHIM_MEM_ADDR(video_mode_ptr); - xeVdQueryVideoMode(video_mode, true); + xeVdQueryVideoMode(video_mode); } diff --git a/src/xenia/kernel/xboxkrnl_debug.cc b/src/xenia/kernel/xboxkrnl_debug.cc index ae594a7d0..3ff845c0d 100644 --- a/src/xenia/kernel/xboxkrnl_debug.cc +++ b/src/xenia/kernel/xboxkrnl_debug.cc @@ -244,14 +244,10 @@ SHIM_CALL DbgPrint_shim( } -void xeDbgBreakPoint() { - DebugBreak(); -} - - SHIM_CALL DbgBreakPoint_shim( PPCContext* ppc_state, KernelState* state) { XELOGD("DbgBreakPoint()"); + DebugBreak(); } diff --git a/src/xenia/kernel/xboxkrnl_hal.cc b/src/xenia/kernel/xboxkrnl_hal.cc index dbde18fca..5e208eb11 100644 --- a/src/xenia/kernel/xboxkrnl_hal.cc +++ b/src/xenia/kernel/xboxkrnl_hal.cc @@ -24,9 +24,13 @@ namespace xe { namespace kernel { -void xeHalReturnToFirmware(uint32_t routine) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); +SHIM_CALL HalReturnToFirmware_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t routine = SHIM_GET_ARG_32(0); + + XELOGD( + "HalReturnToFirmware(%d)", + routine); // void // IN FIRMWARE_REENTRY Routine @@ -41,18 +45,6 @@ void xeHalReturnToFirmware(uint32_t routine) { } -SHIM_CALL HalReturnToFirmware_shim( - PPCContext* ppc_state, KernelState* state) { - uint32_t routine = SHIM_GET_ARG_32(0); - - XELOGD( - "HalReturnToFirmware(%d)", - routine); - - xeHalReturnToFirmware(routine); -} - - } // namespace kernel } // namespace xe diff --git a/src/xenia/kernel/xboxkrnl_memory.cc b/src/xenia/kernel/xboxkrnl_memory.cc index 9cd028c9e..fba730d7e 100644 --- a/src/xenia/kernel/xboxkrnl_memory.cc +++ b/src/xenia/kernel/xboxkrnl_memory.cc @@ -25,12 +25,21 @@ namespace xe { namespace kernel { -X_STATUS xeNtAllocateVirtualMemory( - uint32_t* base_addr_ptr, uint32_t* region_size_ptr, - uint32_t allocation_type, uint32_t protect_bits, - uint32_t unknown) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); +SHIM_CALL NtAllocateVirtualMemory_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t base_addr_ptr = SHIM_GET_ARG_32(0); + uint32_t base_addr_value = SHIM_MEM_32(base_addr_ptr); + uint32_t region_size_ptr = SHIM_GET_ARG_32(1); + uint32_t region_size_value = SHIM_MEM_32(region_size_ptr); + uint32_t allocation_type = SHIM_GET_ARG_32(2); // X_MEM_* bitmask + uint32_t protect_bits = SHIM_GET_ARG_32(3); // X_PAGE_* bitmask + uint32_t unknown = SHIM_GET_ARG_32(4); + + XELOGD( + "NtAllocateVirtualMemory(%.8X(%.8X), %.8X(%.8X), %.8X, %.8X, %.8X)", + base_addr_ptr, base_addr_value, + region_size_ptr, region_size_value, + allocation_type, protect_bits, unknown); // NTSTATUS // _Inout_ PVOID *BaseAddress, @@ -48,117 +57,59 @@ X_STATUS xeNtAllocateVirtualMemory( // it's simple today we could extend it to do better things in the future. // Must request a size. - if (!*region_size_ptr) { - return X_STATUS_INVALID_PARAMETER; + if (!region_size_value) { + SHIM_SET_RETURN_32(X_STATUS_INVALID_PARAMETER); + return; } // Check allocation type. if (!(allocation_type & (X_MEM_COMMIT | X_MEM_RESET | X_MEM_RESERVE))) { - return X_STATUS_INVALID_PARAMETER; + SHIM_SET_RETURN_32(X_STATUS_INVALID_PARAMETER); + return; } // If MEM_RESET is set only MEM_RESET can be set. if (allocation_type & X_MEM_RESET && (allocation_type & ~X_MEM_RESET)) { - return X_STATUS_INVALID_PARAMETER; + SHIM_SET_RETURN_32(X_STATUS_INVALID_PARAMETER); + return; } // Don't allow games to set execute bits. if (protect_bits & (X_PAGE_EXECUTE | X_PAGE_EXECUTE_READ | X_PAGE_EXECUTE_READWRITE | X_PAGE_EXECUTE_WRITECOPY)) { - return X_STATUS_ACCESS_DENIED; + SHIM_SET_RETURN_32(X_STATUS_ACCESS_DENIED); + return; } // Adjust size. - uint32_t adjusted_size = *region_size_ptr; + uint32_t adjusted_size = region_size_value; // TODO(benvanik): adjust based on page size flags/etc? // TODO(benvanik): support different allocation types. // Right now we treat everything as a commit and ignore allocations that have // already happened. - if (*base_addr_ptr) { + if (base_addr_value) { // Having a pointer already means that this is likely a follow-on COMMIT. assert_true(!(allocation_type & X_MEM_RESERVE) && (allocation_type & X_MEM_COMMIT)); - return X_STATUS_SUCCESS; + SHIM_SET_MEM_32(base_addr_ptr, base_addr_value); + SHIM_SET_MEM_32(region_size_ptr, adjusted_size); + SHIM_SET_RETURN_32(X_STATUS_SUCCESS); + return; } // Allocate. uint32_t flags = (allocation_type & X_MEM_NOZERO); uint32_t addr = (uint32_t)state->memory()->HeapAlloc( - *base_addr_ptr, adjusted_size, flags); + base_addr_value, adjusted_size, flags); if (!addr) { // Failed - assume no memory available. - return X_STATUS_NO_MEMORY; + SHIM_SET_RETURN_32(X_STATUS_NO_MEMORY); + return; } // Stash back. // Maybe set X_STATUS_ALREADY_COMMITTED if MEM_COMMIT? - *base_addr_ptr = addr; - *region_size_ptr = adjusted_size; - return X_STATUS_SUCCESS; -} - - -SHIM_CALL NtAllocateVirtualMemory_shim( - PPCContext* ppc_state, KernelState* state) { - uint32_t base_addr_ptr = SHIM_GET_ARG_32(0); - uint32_t base_addr_value = SHIM_MEM_32(base_addr_ptr); - uint32_t region_size_ptr = SHIM_GET_ARG_32(1); - uint32_t region_size_value = SHIM_MEM_32(region_size_ptr); - uint32_t allocation_type = SHIM_GET_ARG_32(2); // X_MEM_* bitmask - uint32_t protect_bits = SHIM_GET_ARG_32(3); // X_PAGE_* bitmask - uint32_t unknown = SHIM_GET_ARG_32(4); - - XELOGD( - "NtAllocateVirtualMemory(%.8X(%.8X), %.8X(%.8X), %.8X, %.8X, %.8X)", - base_addr_ptr, base_addr_value, - region_size_ptr, region_size_value, - allocation_type, protect_bits, unknown); - - X_STATUS result = xeNtAllocateVirtualMemory( - &base_addr_value, ®ion_size_value, - allocation_type, protect_bits, unknown); - - if (XSUCCEEDED(result)) { - SHIM_SET_MEM_32(base_addr_ptr, base_addr_value); - SHIM_SET_MEM_32(region_size_ptr, region_size_value); - } - SHIM_SET_RETURN_32(result); -} - - -X_STATUS xeNtFreeVirtualMemory( - uint32_t* base_addr_ptr, uint32_t* region_size_ptr, - uint32_t free_type, uint32_t unknown) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - // NTSTATUS - // _Inout_ PVOID *BaseAddress, - // _Inout_ PSIZE_T RegionSize, - // _In_ ULONG FreeType - // ? handle? - - // I've only seen zero. - assert_true(unknown == 0); - - if (!*base_addr_ptr) { - return X_STATUS_MEMORY_NOT_ALLOCATED; - } - - // TODO(benvanik): ignore decommits for now. - if (free_type == X_MEM_DECOMMIT) { - return X_STATUS_SUCCESS; - } - - // Free. - uint32_t flags = 0; - uint32_t freed_size = state->memory()->HeapFree( - *base_addr_ptr, flags); - if (!freed_size) { - return X_STATUS_UNSUCCESSFUL; - } - - // Stash back. - *region_size_ptr = freed_size; - return X_STATUS_SUCCESS; + SHIM_SET_MEM_32(base_addr_ptr, addr); + SHIM_SET_MEM_32(region_size_ptr, adjusted_size); + SHIM_SET_RETURN_32(X_STATUS_SUCCESS); } @@ -178,28 +129,55 @@ SHIM_CALL NtFreeVirtualMemory_shim( region_size_ptr, region_size_value, free_type, unknown); - X_STATUS result = xeNtFreeVirtualMemory( - &base_addr_value, ®ion_size_value, - free_type, unknown); + // NTSTATUS + // _Inout_ PVOID *BaseAddress, + // _Inout_ PSIZE_T RegionSize, + // _In_ ULONG FreeType + // ? handle? - if (XSUCCEEDED(result)) { - SHIM_SET_MEM_32(base_addr_ptr, base_addr_value); - SHIM_SET_MEM_32(region_size_ptr, region_size_value); + // I've only seen zero. + assert_true(unknown == 0); + + if (!base_addr_value) { + SHIM_SET_RETURN_32(X_STATUS_MEMORY_NOT_ALLOCATED); + return; } - SHIM_SET_RETURN_32(result); + + // TODO(benvanik): ignore decommits for now. + if (free_type == X_MEM_DECOMMIT) { + SHIM_SET_RETURN_32(X_STATUS_SUCCESS); + return; + } + + // Free. + uint32_t flags = 0; + uint32_t freed_size = state->memory()->HeapFree( + base_addr_value, flags); + if (!freed_size) { + SHIM_SET_RETURN_32(X_STATUS_UNSUCCESSFUL); + return; + } + + SHIM_SET_MEM_32(base_addr_ptr, base_addr_value); + SHIM_SET_MEM_32(region_size_ptr, freed_size); + SHIM_SET_RETURN_32(X_STATUS_SUCCESS); } +SHIM_CALL NtQueryVirtualMemory_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t base_address = SHIM_GET_ARG_32(0); + uint32_t memory_basic_information_ptr = SHIM_GET_ARG_32(1); + X_MEMORY_BASIC_INFORMATION *memory_basic_information = (X_MEMORY_BASIC_INFORMATION*)SHIM_MEM_ADDR(memory_basic_information_ptr); -X_STATUS xeNtQueryVirtualMemory( - uint32_t base_address, X_MEMORY_BASIC_INFORMATION *memory_basic_information, bool swap) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); + XELOGD( + "NtQueryVirtualMemory(%.8X, %.8X)", + base_address, memory_basic_information_ptr); MEMORY_BASIC_INFORMATION mem_info; size_t result = state->memory()->QueryInformation(base_address, &mem_info); - if (!result) { - return STATUS_INVALID_PARAMETER; + SHIM_SET_RETURN_32(X_STATUS_INVALID_PARAMETER); + return; } auto membase = state->memory()->membase(); @@ -214,49 +192,41 @@ X_STATUS xeNtQueryVirtualMemory( memory_basic_information->protect = mem_info.Protect; memory_basic_information->type = mem_info.Type; - if (swap) { - memory_basic_information->base_address = - poly::byte_swap(memory_basic_information->base_address); - memory_basic_information->allocation_base = - poly::byte_swap(memory_basic_information->allocation_base); - memory_basic_information->allocation_protect = - poly::byte_swap(memory_basic_information->allocation_protect); - memory_basic_information->region_size = - poly::byte_swap(memory_basic_information->region_size); - memory_basic_information->state = - poly::byte_swap(memory_basic_information->state); - memory_basic_information->protect = - poly::byte_swap(memory_basic_information->protect); - memory_basic_information->type = - poly::byte_swap(memory_basic_information->type); - } + // TODO(benvanik): auto swap structure. + memory_basic_information->base_address = + poly::byte_swap(memory_basic_information->base_address); + memory_basic_information->allocation_base = + poly::byte_swap(memory_basic_information->allocation_base); + memory_basic_information->allocation_protect = + poly::byte_swap(memory_basic_information->allocation_protect); + memory_basic_information->region_size = + poly::byte_swap(memory_basic_information->region_size); + memory_basic_information->state = + poly::byte_swap(memory_basic_information->state); + memory_basic_information->protect = + poly::byte_swap(memory_basic_information->protect); + memory_basic_information->type = + poly::byte_swap(memory_basic_information->type); XELOGE("NtQueryVirtualMemory NOT IMPLEMENTED"); - return X_STATUS_SUCCESS; + SHIM_SET_RETURN_32(X_STATUS_SUCCESS); } -SHIM_CALL NtQueryVirtualMemory_shim( +SHIM_CALL MmAllocatePhysicalMemoryEx_shim( PPCContext* ppc_state, KernelState* state) { - uint32_t base_address = SHIM_GET_ARG_32(0); - uint32_t memory_basic_information_ptr = SHIM_GET_ARG_32(1); - X_MEMORY_BASIC_INFORMATION *memory_basic_information = (X_MEMORY_BASIC_INFORMATION*)SHIM_MEM_ADDR(memory_basic_information_ptr); + uint32_t type = SHIM_GET_ARG_32(0); + uint32_t region_size = SHIM_GET_ARG_32(1); + uint32_t protect_bits = SHIM_GET_ARG_32(2); + uint32_t min_addr_range = SHIM_GET_ARG_32(3); + uint32_t max_addr_range = SHIM_GET_ARG_32(4); + uint32_t alignment = SHIM_GET_ARG_32(5); XELOGD( - "NtQueryVirtualMemory(%.8X, %.8X)", - base_address, memory_basic_information_ptr); - - X_STATUS result = xeNtQueryVirtualMemory(base_address, memory_basic_information, true); - SHIM_SET_RETURN_32(result); -} - - -uint32_t xeMmAllocatePhysicalMemoryEx( - uint32_t type, uint32_t region_size, uint32_t protect_bits, - uint32_t min_addr_range, uint32_t max_addr_range, uint32_t alignment) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); + "MmAllocatePhysicalMemoryEx(%d, %.8X, %.8X, %.8X, %.8X, %.8X)", + type, region_size, protect_bits, + min_addr_range, max_addr_range, alignment); // Type will usually be 0 (user request?), where 1 and 2 are sometimes made // by D3D/etc. @@ -264,7 +234,8 @@ uint32_t xeMmAllocatePhysicalMemoryEx( // Check protection bits. if (!(protect_bits & (X_PAGE_READONLY | X_PAGE_READWRITE))) { XELOGE("MmAllocatePhysicalMemoryEx: bad protection bits"); - return 0; + SHIM_SET_RETURN_32(0); + return; } // Either may be OR'ed into protect_bits: @@ -302,7 +273,8 @@ uint32_t xeMmAllocatePhysicalMemoryEx( 0, adjusted_size, flags, adjusted_alignment); if (!base_address) { // Failed - assume no memory available. - return 0; + SHIM_SET_RETURN_32(0); + return; } // Move the address into the right range. @@ -315,36 +287,19 @@ uint32_t xeMmAllocatePhysicalMemoryEx( //} base_address += 0xA0000000; - return base_address; -} - - -SHIM_CALL MmAllocatePhysicalMemoryEx_shim( - PPCContext* ppc_state, KernelState* state) { - uint32_t type = SHIM_GET_ARG_32(0); - uint32_t region_size = SHIM_GET_ARG_32(1); - uint32_t protect_bits = SHIM_GET_ARG_32(2); - uint32_t min_addr_range = SHIM_GET_ARG_32(3); - uint32_t max_addr_range = SHIM_GET_ARG_32(4); - uint32_t alignment = SHIM_GET_ARG_32(5); - - XELOGD( - "MmAllocatePhysicalMemoryEx(%d, %.8X, %.8X, %.8X, %.8X, %.8X)", - type, region_size, protect_bits, - min_addr_range, max_addr_range, alignment); - - uint32_t base_address = xeMmAllocatePhysicalMemoryEx( - type, region_size, protect_bits, - min_addr_range, max_addr_range, alignment); - SHIM_SET_RETURN_32(base_address); } -void xeMmFreePhysicalMemory(uint32_t type, uint32_t base_address) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); +SHIM_CALL MmFreePhysicalMemory_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t type = SHIM_GET_ARG_32(0); + uint32_t base_address = SHIM_GET_ARG_32(1); + XELOGD( + "MmFreePhysicalAddress(%d, %.8X)", + type, base_address); + // base_address = result of MmAllocatePhysicalMemory. // Strip off physical bits before passing down. @@ -358,29 +313,6 @@ void xeMmFreePhysicalMemory(uint32_t type, uint32_t base_address) { } -SHIM_CALL MmFreePhysicalMemory_shim( - PPCContext* ppc_state, KernelState* state) { - uint32_t type = SHIM_GET_ARG_32(0); - uint32_t base_address = SHIM_GET_ARG_32(1); - - XELOGD( - "MmFreePhysicalAddress(%d, %.8X)", - type, base_address); - - xeMmFreePhysicalMemory(type, base_address); -} - - -uint32_t xeMmQueryAddressProtect(uint32_t base_address) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - uint32_t access = state->memory()->QueryProtect(base_address); - - return access; -} - - SHIM_CALL MmQueryAddressProtect_shim( PPCContext* ppc_state, KernelState* state) { uint32_t base_address = SHIM_GET_ARG_32(0); @@ -389,19 +321,9 @@ SHIM_CALL MmQueryAddressProtect_shim( "MmQueryAddressProtect(%.8X)", base_address); - uint32_t result = xeMmQueryAddressProtect(base_address); + uint32_t access = state->memory()->QueryProtect(base_address); - SHIM_SET_RETURN_32(result); -} - - -uint32_t xeMmQueryAllocationSize(uint32_t base_address) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - size_t size = state->memory()->QuerySize(base_address); - - return (uint32_t)size; + SHIM_SET_RETURN_32(access); } @@ -412,10 +334,10 @@ SHIM_CALL MmQueryAllocationSize_shim( XELOGD( "MmQueryAllocationSize(%.8X)", base_address); + + size_t size = state->memory()->QuerySize(base_address); - uint32_t result = xeMmQueryAllocationSize(base_address); - - SHIM_SET_RETURN_32(result); + SHIM_SET_RETURN_32(static_cast(size)); } @@ -427,7 +349,7 @@ SHIM_CALL MmQueryStatistics_shim( "MmQueryStatistics(%.8X)", stats_ptr); -uint32_t size = SHIM_MEM_32(stats_ptr + 0); + uint32_t size = SHIM_MEM_32(stats_ptr + 0); if (size != 104) { SHIM_SET_RETURN_32(X_STATUS_BUFFER_TOO_SMALL); return; @@ -475,7 +397,14 @@ uint32_t size = SHIM_MEM_32(stats_ptr + 0); // http://msdn.microsoft.com/en-us/library/windows/hardware/ff554547(v=vs.85).aspx -uint32_t xeMmGetPhysicalAddress(uint32_t base_address) { +SHIM_CALL MmGetPhysicalAddress_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t base_address = SHIM_GET_ARG_32(0); + + XELOGD( + "MmGetPhysicalAddress(%.8X)", + base_address); + // PHYSICAL_ADDRESS MmGetPhysicalAddress( // _In_ PVOID BaseAddress // ); @@ -493,21 +422,7 @@ uint32_t xeMmGetPhysicalAddress(uint32_t base_address) { base_address |= 0xE0000000; }*/ - return base_address; -} - - -SHIM_CALL MmGetPhysicalAddress_shim( - PPCContext* ppc_state, KernelState* state) { - uint32_t base_address = SHIM_GET_ARG_32(0); - - XELOGD( - "MmGetPhysicalAddress(%.8X)", - base_address); - - uint32_t result = xeMmGetPhysicalAddress(base_address); - - SHIM_SET_RETURN_32(result); + SHIM_SET_RETURN_32(base_address); } @@ -536,7 +451,6 @@ SHIM_CALL ExAllocatePoolTypeWithTag_shim( } - SHIM_CALL ExFreePool_shim( PPCContext* ppc_state, KernelState* state) { uint32_t base_address = SHIM_GET_ARG_32(0); diff --git a/src/xenia/kernel/xboxkrnl_modules.cc b/src/xenia/kernel/xboxkrnl_modules.cc index f38a6d0f8..bc659eb55 100644 --- a/src/xenia/kernel/xboxkrnl_modules.cc +++ b/src/xenia/kernel/xboxkrnl_modules.cc @@ -133,9 +133,13 @@ SHIM_CALL ExGetXConfigSetting_shim( } -int xeXexCheckExecutablePriviledge(uint32_t privilege) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); +SHIM_CALL XexCheckExecutablePrivilege_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t privilege = SHIM_GET_ARG_32(0); + + XELOGD( + "XexCheckExecutablePrivilege(%.8X)", + privilege); // BOOL // DWORD Privilege @@ -146,7 +150,8 @@ int xeXexCheckExecutablePriviledge(uint32_t privilege) { XUserModule* module = state->GetExecutableModule(); if (!module) { - return 0; + SHIM_SET_RETURN_32(0); + return; } xe_xex2_ref xex = module->xex(); @@ -156,47 +161,10 @@ int xeXexCheckExecutablePriviledge(uint32_t privilege) { xe_xex2_release(xex); module->Release(); - return result; -} - - -SHIM_CALL XexCheckExecutablePrivilege_shim( - PPCContext* ppc_state, KernelState* state) { - uint32_t privilege = SHIM_GET_ARG_32(0); - - XELOGD( - "XexCheckExecutablePrivilege(%.8X)", - privilege); - - int result = xeXexCheckExecutablePriviledge(privilege); - SHIM_SET_RETURN_32(result); } -int xeXexGetModuleHandle(const char* module_name, - X_HANDLE* module_handle_ptr) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - // BOOL - // LPCSZ ModuleName - // LPHMODULE ModuleHandle - - XModule* module = state->GetModule(module_name); - if (!module) { - return 0; - } - - // NOTE: we don't retain the handle for return. - *module_handle_ptr = module->handle(); - - module->Release(); - - return 1; -} - - SHIM_CALL XexGetModuleHandle_shim( PPCContext* ppc_state, KernelState* state) { uint32_t module_name_ptr = SHIM_GET_ARG_32(0); @@ -207,11 +175,18 @@ SHIM_CALL XexGetModuleHandle_shim( "XexGetModuleHandle(%s, %.8X)", module_name, module_handle_ptr); - X_HANDLE module_handle = 0; - int result = xeXexGetModuleHandle(module_name, &module_handle); - SHIM_SET_MEM_32(module_handle_ptr, module_handle); + XModule* module = state->GetModule(module_name); + if (!module) { + SHIM_SET_RETURN_32(X_ERROR_NOT_FOUND); + return; + } - SHIM_SET_RETURN_32(result); + // NOTE: we don't retain the handle for return. + SHIM_SET_MEM_32(module_handle_ptr, module->handle()); + + module->Release(); + + SHIM_SET_RETURN_32(X_ERROR_SUCCESS); } diff --git a/src/xenia/kernel/xboxkrnl_rtl.cc b/src/xenia/kernel/xboxkrnl_rtl.cc index 1b23dafc6..9c9285026 100644 --- a/src/xenia/kernel/xboxkrnl_rtl.cc +++ b/src/xenia/kernel/xboxkrnl_rtl.cc @@ -27,45 +27,24 @@ namespace xe { namespace kernel { -//RtlCompareMemory -struct x { -}; - -struct RtlCompareMemoryExport { - KernelState* state; - static void Call(PPCContext* ppc_state) { - uint32_t source1 = SHIM_GET_ARG_32(0); - uint32_t source2 = SHIM_GET_ARG_32(1); - uint32_t length = SHIM_GET_ARG_32(2); - - XELOGD( - "RtlCompareMemory(%.8X, %.8X, %d)", - source1, source2, length); - - uint32_t result = 0; - SHIM_SET_RETURN_64(result); - } - virtual void Log() { - // - } - X_STATUS RtlCompareMemory(uint32_t source1_ptr, uint32_t source2_ptr, uint32_t length) { - } -}; - - // http://msdn.microsoft.com/en-us/library/ff561778 -uint32_t xeRtlCompareMemory(uint32_t source1_ptr, uint32_t source2_ptr, - uint32_t length) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); +SHIM_CALL RtlCompareMemory_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t source1_ptr = SHIM_GET_ARG_32(0); + uint32_t source2_ptr = SHIM_GET_ARG_32(1); + uint32_t length = SHIM_GET_ARG_32(2); + + XELOGD( + "RtlCompareMemory(%.8X, %.8X, %d)", + source1_ptr, source2_ptr, length); // SIZE_T // _In_ const VOID *Source1, // _In_ const VOID *Source2, // _In_ SIZE_T Length - uint8_t* p1 = IMPL_MEM_ADDR(source1_ptr); - uint8_t* p2 = IMPL_MEM_ADDR(source2_ptr); + uint8_t* p1 = SHIM_MEM_ADDR(source1_ptr); + uint8_t* p2 = SHIM_MEM_ADDR(source2_ptr); // Note that the return value is the number of bytes that match, so it's best // we just do this ourselves vs. using memcmp. @@ -78,30 +57,20 @@ uint32_t xeRtlCompareMemory(uint32_t source1_ptr, uint32_t source2_ptr, } } - return c; -} - - -SHIM_CALL RtlCompareMemory_shim( - PPCContext* ppc_state, KernelState* state) { - uint32_t source1 = SHIM_GET_ARG_32(0); - uint32_t source2 = SHIM_GET_ARG_32(1); - uint32_t length = SHIM_GET_ARG_32(2); - - XELOGD( - "RtlCompareMemory(%.8X, %.8X, %d)", - source1, source2, length); - - uint32_t result = xeRtlCompareMemory(source1, source2, length); - SHIM_SET_RETURN_64(result); + SHIM_SET_RETURN_64(c); } // http://msdn.microsoft.com/en-us/library/ff552123 -uint32_t xeRtlCompareMemoryUlong(uint32_t source_ptr, uint32_t length, - uint32_t pattern) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); +SHIM_CALL RtlCompareMemoryUlong_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t source_ptr = SHIM_GET_ARG_32(0); + uint32_t length = SHIM_GET_ARG_32(1); + uint32_t pattern = SHIM_GET_ARG_32(2); + + XELOGD( + "RtlCompareMemoryUlong(%.8X, %d, %.8X)", + source_ptr, length, pattern); // SIZE_T // _In_ PVOID Source, @@ -109,10 +78,11 @@ uint32_t xeRtlCompareMemoryUlong(uint32_t source_ptr, uint32_t length, // _In_ ULONG Pattern if ((source_ptr % 4) || (length % 4)) { - return 0; + SHIM_SET_RETURN_64(0); + return; } - uint8_t* p = IMPL_MEM_ADDR(source_ptr); + uint8_t* p = SHIM_MEM_ADDR(source_ptr); // Swap pattern. // TODO(benvanik): ensure byte order of pattern is correct. @@ -128,30 +98,20 @@ uint32_t xeRtlCompareMemoryUlong(uint32_t source_ptr, uint32_t length, } } - return c; -} - - -SHIM_CALL RtlCompareMemoryUlong_shim( - PPCContext* ppc_state, KernelState* state) { - uint32_t source = SHIM_GET_ARG_32(0); - uint32_t length = SHIM_GET_ARG_32(1); - uint32_t pattern = SHIM_GET_ARG_32(2); - - XELOGD( - "RtlCompareMemoryUlong(%.8X, %d, %.8X)", - source, length, pattern); - - uint32_t result = xeRtlCompareMemoryUlong(source, length, pattern); - SHIM_SET_RETURN_64(result); + SHIM_SET_RETURN_64(c); } // http://msdn.microsoft.com/en-us/library/ff552263 -void xeRtlFillMemoryUlong(uint32_t destination_ptr, uint32_t length, - uint32_t pattern) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); +SHIM_CALL RtlFillMemoryUlong_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t destination_ptr = SHIM_GET_ARG_32(0); + uint32_t length = SHIM_GET_ARG_32(1); + uint32_t pattern = SHIM_GET_ARG_32(2); + + XELOGD( + "RtlFillMemoryUlong(%.8X, %d, %.8X)", + destination_ptr, length, pattern); // VOID // _Out_ PVOID Destination, @@ -159,7 +119,7 @@ void xeRtlFillMemoryUlong(uint32_t destination_ptr, uint32_t length, // _In_ ULONG Pattern // NOTE: length must be % 4, so we can work on uint32s. - uint32_t* p = (uint32_t*)IMPL_MEM_ADDR(destination_ptr); + uint32_t* p = (uint32_t*)SHIM_MEM_ADDR(destination_ptr); // TODO(benvanik): ensure byte order is correct - we're writing back the // swapped arg value. @@ -175,20 +135,6 @@ void xeRtlFillMemoryUlong(uint32_t destination_ptr, uint32_t length, } -SHIM_CALL RtlFillMemoryUlong_shim( - PPCContext* ppc_state, KernelState* state) { - uint32_t destination = SHIM_GET_ARG_32(0); - uint32_t length = SHIM_GET_ARG_32(1); - uint32_t pattern = SHIM_GET_ARG_32(2); - - XELOGD( - "RtlFillMemoryUlong(%.8X, %d, %.8X)", - destination, length, pattern); - - xeRtlFillMemoryUlong(destination, length, pattern); -} - - // typedef struct _STRING { // USHORT Length; // USHORT MaximumLength; @@ -197,27 +143,6 @@ SHIM_CALL RtlFillMemoryUlong_shim( // http://msdn.microsoft.com/en-us/library/ff561918 -void xeRtlInitAnsiString(uint32_t destination_ptr, uint32_t source_ptr) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - // VOID - // _Out_ PANSI_STRING DestinationString, - // _In_opt_ PCSZ SourceString - - if (source_ptr != 0) { - const char* source = (char*)IMPL_MEM_ADDR(source_ptr); - uint16_t length = (uint16_t)xestrlena(source); - IMPL_SET_MEM_16(destination_ptr + 0, length); - IMPL_SET_MEM_16(destination_ptr + 2, length + 1); - } else { - IMPL_SET_MEM_16(destination_ptr + 0, 0); - IMPL_SET_MEM_16(destination_ptr + 2, 0); - } - IMPL_SET_MEM_32(destination_ptr + 4, source_ptr); -} - - SHIM_CALL RtlInitAnsiString_shim( PPCContext* ppc_state, KernelState* state) { uint32_t destination_ptr = SHIM_GET_ARG_32(0); @@ -227,38 +152,43 @@ SHIM_CALL RtlInitAnsiString_shim( XELOGD("RtlInitAnsiString(%.8X, %.8X = %s)", destination_ptr, source_ptr, source ? source : ""); - xeRtlInitAnsiString(destination_ptr, source_ptr); + // VOID + // _Out_ PANSI_STRING DestinationString, + // _In_opt_ PCSZ SourceString + + if (source_ptr != 0) { + const char* source = (char*)SHIM_MEM_ADDR(source_ptr); + uint16_t length = (uint16_t)xestrlena(source); + SHIM_SET_MEM_16(destination_ptr + 0, length); + SHIM_SET_MEM_16(destination_ptr + 2, length + 1); + } else { + SHIM_SET_MEM_16(destination_ptr + 0, 0); + SHIM_SET_MEM_16(destination_ptr + 2, 0); + } + SHIM_SET_MEM_32(destination_ptr + 4, source_ptr); } // http://msdn.microsoft.com/en-us/library/ff561899 -void xeRtlFreeAnsiString(uint32_t string_ptr) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - // VOID - // _Inout_ PANSI_STRING AnsiString - - uint32_t buffer = IMPL_MEM_32(string_ptr + 4); - if (!buffer) { - return; - } - uint32_t length = IMPL_MEM_16(string_ptr + 2); - state->memory()->HeapFree(buffer, length); - - IMPL_SET_MEM_16(string_ptr + 0, 0); - IMPL_SET_MEM_16(string_ptr + 2, 0); - IMPL_SET_MEM_32(string_ptr + 4, 0); -} - - SHIM_CALL RtlFreeAnsiString_shim( PPCContext* ppc_state, KernelState* state) { uint32_t string_ptr = SHIM_GET_ARG_32(0); XELOGD("RtlFreeAnsiString(%.8X)", string_ptr); - xeRtlFreeAnsiString(string_ptr); + // VOID + // _Inout_ PANSI_STRING AnsiString + + uint32_t buffer = SHIM_MEM_32(string_ptr + 4); + if (!buffer) { + return; + } + uint32_t length = SHIM_MEM_16(string_ptr + 2); + state->memory()->HeapFree(buffer, length); + + SHIM_SET_MEM_16(string_ptr + 0, 0); + SHIM_SET_MEM_16(string_ptr + 2, 0); + SHIM_SET_MEM_32(string_ptr + 4, 0); } @@ -270,30 +200,6 @@ SHIM_CALL RtlFreeAnsiString_shim( // http://msdn.microsoft.com/en-us/library/ff561934 -void xeRtlInitUnicodeString(uint32_t destination_ptr, uint32_t source_ptr) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - // VOID - // _Out_ PUNICODE_STRING DestinationString, - // _In_opt_ PCWSTR SourceString - - const wchar_t* source = - source_ptr ? (const wchar_t*)IMPL_MEM_ADDR(source_ptr) : NULL; - - if (source) { - uint16_t length = (uint16_t)xestrlenw(source); - IMPL_SET_MEM_16(destination_ptr + 0, length * 2); - IMPL_SET_MEM_16(destination_ptr + 2, (length + 1) * 2); - IMPL_SET_MEM_32(destination_ptr + 4, source_ptr); - } else { - IMPL_SET_MEM_16(destination_ptr + 0, 0); - IMPL_SET_MEM_16(destination_ptr + 2, 0); - IMPL_SET_MEM_32(destination_ptr + 4, 0); - } -} - - SHIM_CALL RtlInitUnicodeString_shim( PPCContext* ppc_state, KernelState* state) { uint32_t destination_ptr = SHIM_GET_ARG_32(0); @@ -304,85 +210,47 @@ SHIM_CALL RtlInitUnicodeString_shim( XELOGD("RtlInitUnicodeString(%.8X, %.8X = %ls)", destination_ptr, source_ptr, source ? source : L""); - xeRtlInitUnicodeString(destination_ptr, source_ptr); + // VOID + // _Out_ PUNICODE_STRING DestinationString, + // _In_opt_ PCWSTR SourceString + + if (source) { + uint16_t length = (uint16_t)xestrlenw(source); + SHIM_SET_MEM_16(destination_ptr + 0, length * 2); + SHIM_SET_MEM_16(destination_ptr + 2, (length + 1) * 2); + SHIM_SET_MEM_32(destination_ptr + 4, source_ptr); + } else { + SHIM_SET_MEM_16(destination_ptr + 0, 0); + SHIM_SET_MEM_16(destination_ptr + 2, 0); + SHIM_SET_MEM_32(destination_ptr + 4, 0); + } } // http://msdn.microsoft.com/en-us/library/ff561903 -void xeRtlFreeUnicodeString(uint32_t string_ptr) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - // VOID - // _Inout_ PUNICODE_STRING UnicodeString - - uint32_t buffer = IMPL_MEM_32(string_ptr + 4); - if (!buffer) { - return; - } - uint32_t length = IMPL_MEM_16(string_ptr + 2); - state->memory()->HeapFree(buffer, length); - - IMPL_SET_MEM_16(string_ptr + 0, 0); - IMPL_SET_MEM_16(string_ptr + 2, 0); - IMPL_SET_MEM_32(string_ptr + 4, 0); -} - - SHIM_CALL RtlFreeUnicodeString_shim( PPCContext* ppc_state, KernelState* state) { uint32_t string_ptr = SHIM_GET_ARG_32(0); XELOGD("RtlFreeUnicodeString(%.8X)", string_ptr); - xeRtlFreeUnicodeString(string_ptr); + // VOID + // _Inout_ PUNICODE_STRING UnicodeString + + uint32_t buffer = SHIM_MEM_32(string_ptr + 4); + if (!buffer) { + return; + } + uint32_t length = SHIM_MEM_16(string_ptr + 2); + state->memory()->HeapFree(buffer, length); + + SHIM_SET_MEM_16(string_ptr + 0, 0); + SHIM_SET_MEM_16(string_ptr + 2, 0); + SHIM_SET_MEM_32(string_ptr + 4, 0); } // http://msdn.microsoft.com/en-us/library/ff562969 -X_STATUS xeRtlUnicodeStringToAnsiString(uint32_t destination_ptr, - uint32_t source_ptr, - uint32_t alloc_dest) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - // NTSTATUS - // _Inout_ PANSI_STRING DestinationString, - // _In_ PCUNICODE_STRING SourceString, - // _In_ BOOLEAN AllocateDestinationString - - std::wstring unicode_str = poly::load_and_swap( - IMPL_MEM_ADDR(IMPL_MEM_32(source_ptr + 4))); - std::string ansi_str = poly::to_string(unicode_str); - if (ansi_str.size() > 0xFFFF - 1) { - return X_STATUS_INVALID_PARAMETER_2; - } - - X_STATUS result = X_STATUS_SUCCESS; - if (alloc_dest) { - auto buffer_ptr = state->memory()->HeapAlloc(0, ansi_str.size() + 1, 0); - memcpy(IMPL_MEM_ADDR(buffer_ptr), ansi_str.data(), ansi_str.size() + 1); - IMPL_SET_MEM_16(destination_ptr + 0, - static_cast(ansi_str.size())); - IMPL_SET_MEM_16(destination_ptr + 2, - static_cast(ansi_str.size() + 1)); - IMPL_SET_MEM_32(destination_ptr + 4, static_cast(buffer_ptr)); - } else { - uint32_t buffer_capacity = IMPL_MEM_16(destination_ptr + 2); - uint32_t buffer_ptr = IMPL_MEM_32(destination_ptr + 4); - if (buffer_capacity < ansi_str.size() + 1) { - // Too large - we just write what we can. - result = X_STATUS_BUFFER_OVERFLOW; - memcpy(IMPL_MEM_ADDR(buffer_ptr), ansi_str.data(), buffer_capacity - 1); - } else { - memcpy(IMPL_MEM_ADDR(buffer_ptr), ansi_str.data(), ansi_str.size() + 1); - } - IMPL_SET_MEM_8(buffer_ptr + buffer_capacity - 1, 0); // \0 - } - return result; -} - - SHIM_CALL RtlUnicodeStringToAnsiString_shim( PPCContext* ppc_state, KernelState* state) { uint32_t destination_ptr = SHIM_GET_ARG_32(0); @@ -392,8 +260,40 @@ SHIM_CALL RtlUnicodeStringToAnsiString_shim( XELOGD("RtlUnicodeStringToAnsiString(%.8X, %.8X, %d)", destination_ptr, source_ptr, alloc_dest); - X_STATUS result = xeRtlUnicodeStringToAnsiString( - destination_ptr, source_ptr, alloc_dest); + // NTSTATUS + // _Inout_ PANSI_STRING DestinationString, + // _In_ PCUNICODE_STRING SourceString, + // _In_ BOOLEAN AllocateDestinationString + + std::wstring unicode_str = poly::load_and_swap( + SHIM_MEM_ADDR(SHIM_MEM_32(source_ptr + 4))); + std::string ansi_str = poly::to_string(unicode_str); + if (ansi_str.size() > 0xFFFF - 1) { + SHIM_SET_RETURN_32(X_STATUS_INVALID_PARAMETER_2); + return; + } + + X_STATUS result = X_STATUS_SUCCESS; + if (alloc_dest) { + auto buffer_ptr = state->memory()->HeapAlloc(0, ansi_str.size() + 1, 0); + memcpy(SHIM_MEM_ADDR(buffer_ptr), ansi_str.data(), ansi_str.size() + 1); + SHIM_SET_MEM_16(destination_ptr + 0, + static_cast(ansi_str.size())); + SHIM_SET_MEM_16(destination_ptr + 2, + static_cast(ansi_str.size() + 1)); + SHIM_SET_MEM_32(destination_ptr + 4, static_cast(buffer_ptr)); + } else { + uint32_t buffer_capacity = SHIM_MEM_16(destination_ptr + 2); + uint32_t buffer_ptr = SHIM_MEM_32(destination_ptr + 4); + if (buffer_capacity < ansi_str.size() + 1) { + // Too large - we just write what we can. + result = X_STATUS_BUFFER_OVERFLOW; + memcpy(SHIM_MEM_ADDR(buffer_ptr), ansi_str.data(), buffer_capacity - 1); + } else { + memcpy(SHIM_MEM_ADDR(buffer_ptr), ansi_str.data(), ansi_str.size() + 1); + } + SHIM_SET_MEM_8(buffer_ptr + buffer_capacity - 1, 0); // \0 + } SHIM_SET_RETURN_32(result); } @@ -457,22 +357,6 @@ SHIM_CALL RtlUnicodeToMultiByteN_shim( } -uint32_t xeRtlNtStatusToDosError(X_STATUS status) { - if (!status || (status & 0x20000000)) { - // Success. - return status; - } else if ((status & 0xF0000000) == 0xD0000000) { - // High bit doesn't matter. - status &= ~0x10000000; - } - - // TODO(benvanik): implement lookup table. - XELOGE("RtlNtStatusToDosError lookup NOT IMPLEMENTED"); - - return 317; // ERROR_MR_MID_NOT_FOUND -} - - SHIM_CALL RtlNtStatusToDosError_shim( PPCContext* ppc_state, KernelState* state) { uint32_t status = SHIM_GET_ARG_32(0); @@ -481,15 +365,39 @@ SHIM_CALL RtlNtStatusToDosError_shim( "RtlNtStatusToDosError(%.4X)", status); - uint32_t result = xeRtlNtStatusToDosError(status); + if (!status || (status & 0x20000000)) { + // Success. + SHIM_SET_RETURN_32(0); + return; + } else if ((status & 0xF0000000) == 0xD0000000) { + // High bit doesn't matter. + status &= ~0x10000000; + } + + // TODO(benvanik): implement lookup table. + XELOGE("RtlNtStatusToDosError lookup NOT SHIMEMENTED"); + + uint32_t result = 317; // ERROR_MR_MID_NOT_FOUND + SHIM_SET_RETURN_32(result); } -uint32_t xeRtlImageXexHeaderField(uint32_t xex_header_base_ptr, - uint32_t image_field) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); +SHIM_CALL RtlImageXexHeaderField_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t xex_header_base = SHIM_GET_ARG_32(0); + uint32_t image_field = SHIM_GET_ARG_32(1); + + // NOTE: this is totally faked! + // We set the XexExecutableModuleHandle pointer to a block that has at offset + // 0x58 a pointer to our XexHeaderBase. If the value passed doesn't match + // then die. + // The only ImageField I've seen in the wild is + // 0x20401 (XEX_HEADER_DEFAULT_HEAP_SIZE), so that's all we'll support. + + XELOGD( + "RtlImageXexHeaderField(%.8X, %.8X)", + xex_header_base, image_field); // PVOID // PVOID XexHeaderBase @@ -512,34 +420,15 @@ uint32_t xeRtlImageXexHeaderField(uint32_t xex_header_base_ptr, const xe_xex2_header_t* xex_header = module->xex_header(); for (size_t n = 0; n < xex_header->header_count; n++) { if (xex_header->headers[n].key == image_field) { + uint32_t value = xex_header->headers[n].value; module->Release(); - return xex_header->headers[n].value; + SHIM_SET_RETURN_64(value); + return; } } module->Release(); - return 0; -} - - -SHIM_CALL RtlImageXexHeaderField_shim( - PPCContext* ppc_state, KernelState* state) { - uint32_t xex_header_base = SHIM_GET_ARG_32(0); - uint32_t image_field = SHIM_GET_ARG_32(1); - - // NOTE: this is totally faked! - // We set the XexExecutableModuleHandle pointer to a block that has at offset - // 0x58 a pointer to our XexHeaderBase. If the value passed doesn't match - // then die. - // The only ImageField I've seen in the wild is - // 0x20401 (XEX_HEADER_DEFAULT_HEAP_SIZE), so that's all we'll support. - - XELOGD( - "RtlImageXexHeaderField(%.8X, %.8X)", - xex_header_base, image_field); - - uint32_t result = xeRtlImageXexHeaderField(xex_header_base, image_field); - SHIM_SET_RETURN_64(result); + SHIM_SET_RETURN_64(0); } @@ -560,9 +449,8 @@ SHIM_CALL RtlImageXexHeaderField_shim( // This structure tries to match the one on the 360 as best I can figure out. // Unfortunately some games have the critical sections pre-initialized in // their embedded data and InitializeCriticalSection will never be called. -namespace { #pragma pack(push, 1) -typedef struct { +struct X_RTL_CRITICAL_SECTION { uint8_t unknown00; uint8_t spin_count_div_256; // * 256 uint8_t __padding[6]; @@ -572,20 +460,14 @@ typedef struct { int32_t lock_count; // -1 -> 0 on first lock 0x10 uint32_t recursion_count; // 0 -> 1 on first lock 0x14 uint32_t owning_thread_id; // 0 unless locked 0x18 -} X_RTL_CRITICAL_SECTION; +}; #pragma pack(pop) -} - static_assert_size(X_RTL_CRITICAL_SECTION, 28); -void xeRtlInitializeCriticalSection(uint32_t cs_ptr) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - +void xeRtlInitializeCriticalSection(X_RTL_CRITICAL_SECTION* cs) { // VOID // _Out_ LPCRITICAL_SECTION lpCriticalSection - X_RTL_CRITICAL_SECTION* cs = (X_RTL_CRITICAL_SECTION*)IMPL_MEM_ADDR(cs_ptr); cs->unknown00 = 1; cs->spin_count_div_256 = 0; cs->lock_count = -1; @@ -600,15 +482,13 @@ SHIM_CALL RtlInitializeCriticalSection_shim( XELOGD("RtlInitializeCriticalSection(%.8X)", cs_ptr); - xeRtlInitializeCriticalSection(cs_ptr); + auto cs = (X_RTL_CRITICAL_SECTION*)SHIM_MEM_ADDR(cs_ptr); + xeRtlInitializeCriticalSection(cs); } X_STATUS xeRtlInitializeCriticalSectionAndSpinCount( - uint32_t cs_ptr, uint32_t spin_count) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - + X_RTL_CRITICAL_SECTION* cs, uint32_t spin_count) { // NTSTATUS // _Out_ LPCRITICAL_SECTION lpCriticalSection, // _In_ DWORD dwSpinCount @@ -620,7 +500,6 @@ X_STATUS xeRtlInitializeCriticalSectionAndSpinCount( spin_count_div_256 = 255; } - X_RTL_CRITICAL_SECTION* cs = (X_RTL_CRITICAL_SECTION*)IMPL_MEM_ADDR(cs_ptr); cs->unknown00 = 1; cs->spin_count_div_256 = spin_count_div_256; cs->lock_count = -1; @@ -639,22 +518,18 @@ SHIM_CALL RtlInitializeCriticalSectionAndSpinCount_shim( XELOGD("RtlInitializeCriticalSectionAndSpinCount(%.8X, %d)", cs_ptr, spin_count); + auto cs = (X_RTL_CRITICAL_SECTION*)SHIM_MEM_ADDR(cs_ptr); X_STATUS result = xeRtlInitializeCriticalSectionAndSpinCount( - cs_ptr, spin_count); + cs, spin_count); SHIM_SET_RETURN_32(result); } // TODO(benvanik): remove the need for passing in thread_id. -void xeRtlEnterCriticalSection(uint32_t cs_ptr, uint32_t thread_id) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - +void xeRtlEnterCriticalSection(X_RTL_CRITICAL_SECTION* cs, uint32_t thread_id) { // VOID // _Inout_ LPCRITICAL_SECTION lpCriticalSection - X_RTL_CRITICAL_SECTION* cs = (X_RTL_CRITICAL_SECTION*)IMPL_MEM_ADDR(cs_ptr); - uint32_t spin_wait_remaining = cs->spin_count_div_256 * 256; spin: if (poly::atomic_inc(&cs->lock_count) != 0) { @@ -693,20 +568,16 @@ SHIM_CALL RtlEnterCriticalSection_shim( const uint8_t* thread_state_block = ppc_state->membase + ppc_state->r[13]; uint32_t thread_id = XThread::GetCurrentThreadId(thread_state_block); - xeRtlEnterCriticalSection(cs_ptr, thread_id); + auto cs = (X_RTL_CRITICAL_SECTION*)SHIM_MEM_ADDR(cs_ptr); + xeRtlEnterCriticalSection(cs, thread_id); } // TODO(benvanik): remove the need for passing in thread_id. -uint32_t xeRtlTryEnterCriticalSection(uint32_t cs_ptr, uint32_t thread_id) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - +uint32_t xeRtlTryEnterCriticalSection(X_RTL_CRITICAL_SECTION* cs, uint32_t thread_id) { // DWORD // _Inout_ LPCRITICAL_SECTION lpCriticalSection - X_RTL_CRITICAL_SECTION* cs = (X_RTL_CRITICAL_SECTION*)IMPL_MEM_ADDR(cs_ptr); - if (poly::atomic_cas(-1, 0, &cs->lock_count)) { // Able to steal the lock right away. cs->owning_thread_id = thread_id; @@ -731,20 +602,16 @@ SHIM_CALL RtlTryEnterCriticalSection_shim( const uint8_t* thread_state_block = ppc_state->membase + ppc_state->r[13]; uint32_t thread_id = XThread::GetCurrentThreadId(thread_state_block); - uint32_t result = xeRtlTryEnterCriticalSection(cs_ptr, thread_id); + auto cs = (X_RTL_CRITICAL_SECTION*)SHIM_MEM_ADDR(cs_ptr); + uint32_t result = xeRtlTryEnterCriticalSection(cs, thread_id); SHIM_SET_RETURN_64(result); } -void xeRtlLeaveCriticalSection(uint32_t cs_ptr) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - +void xeRtlLeaveCriticalSection(X_RTL_CRITICAL_SECTION* cs) { // VOID // _Inout_ LPCRITICAL_SECTION lpCriticalSection - X_RTL_CRITICAL_SECTION* cs = (X_RTL_CRITICAL_SECTION*)IMPL_MEM_ADDR(cs_ptr); - // Drop recursion count - if we are still not zero'ed return. uint32_t recursion_count = --cs->recursion_count; if (recursion_count) { @@ -768,7 +635,8 @@ SHIM_CALL RtlLeaveCriticalSection_shim( // XELOGD("RtlLeaveCriticalSection(%.8X)", cs_ptr); - xeRtlLeaveCriticalSection(cs_ptr); + auto cs = (X_RTL_CRITICAL_SECTION*)SHIM_MEM_ADDR(cs_ptr); + xeRtlLeaveCriticalSection(cs); } diff --git a/src/xenia/kernel/xboxkrnl_rtl.h b/src/xenia/kernel/xboxkrnl_rtl.h index d462516e9..fa959bc3a 100644 --- a/src/xenia/kernel/xboxkrnl_rtl.h +++ b/src/xenia/kernel/xboxkrnl_rtl.h @@ -14,21 +14,20 @@ #include #include - namespace xe { namespace kernel { +struct X_RTL_CRITICAL_SECTION; -void xeRtlInitializeCriticalSection(uint32_t cs_ptr); -X_STATUS xeRtlInitializeCriticalSectionAndSpinCount( - uint32_t cs_ptr, uint32_t spin_count); -void xeRtlEnterCriticalSection(uint32_t cs_ptr, uint32_t thread_id); -uint32_t xeRtlTryEnterCriticalSection(uint32_t cs_ptr, uint32_t thread_id); -void xeRtlLeaveCriticalSection(uint32_t cs_ptr); - +void xeRtlInitializeCriticalSection(X_RTL_CRITICAL_SECTION* cs); +X_STATUS xeRtlInitializeCriticalSectionAndSpinCount(X_RTL_CRITICAL_SECTION* cs, + uint32_t spin_count); +void xeRtlEnterCriticalSection(X_RTL_CRITICAL_SECTION* cs, uint32_t thread_id); +uint32_t xeRtlTryEnterCriticalSection(X_RTL_CRITICAL_SECTION* cs, + uint32_t thread_id); +void xeRtlLeaveCriticalSection(X_RTL_CRITICAL_SECTION* cs); } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_XBOXKRNL_RTL_H_ diff --git a/src/xenia/kernel/xboxkrnl_threading.cc b/src/xenia/kernel/xboxkrnl_threading.cc index c4a087187..517345552 100644 --- a/src/xenia/kernel/xboxkrnl_threading.cc +++ b/src/xenia/kernel/xboxkrnl_threading.cc @@ -66,44 +66,6 @@ namespace kernel { // } -X_STATUS xeExCreateThread( - uint32_t* handle_ptr, uint32_t stack_size, uint32_t* thread_id_ptr, - uint32_t xapi_thread_startup, - uint32_t start_address, uint32_t start_context, uint32_t creation_flags) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - // DWORD - // LPHANDLE Handle, - // DWORD StackSize, - // LPDWORD ThreadId, - // LPVOID XapiThreadStartup, ?? often 0 - // LPVOID StartAddress, - // LPVOID StartContext, - // DWORD CreationFlags // 0x80? - - XThread* thread = new XThread( - state, stack_size, xapi_thread_startup, start_address, start_context, - creation_flags); - - X_STATUS result_code = thread->Create(); - if (XFAILED(result_code)) { - // Failed! - thread->Release(); - XELOGE("Thread creation failed: %.8X", result_code); - return result_code; - } - - if (handle_ptr) { - *handle_ptr = thread->handle(); - } - if (thread_id_ptr) { - *thread_id_ptr = thread->thread_id(); - } - return result_code; -} - - SHIM_CALL ExCreateThread_shim( PPCContext* ppc_state, KernelState* state) { uint32_t handle_ptr = SHIM_GET_ARG_32(0); @@ -124,18 +86,34 @@ SHIM_CALL ExCreateThread_shim( start_context, creation_flags); - uint32_t handle; - uint32_t thread_id; - X_STATUS result = xeExCreateThread( - &handle, stack_size, &thread_id, xapi_thread_startup, - start_address, start_context, creation_flags); + // DWORD + // LPHANDLE Handle, + // DWORD StackSize, + // LPDWORD ThreadId, + // LPVOID XapiThreadStartup, ?? often 0 + // LPVOID StartAddress, + // LPVOID StartContext, + // DWORD CreationFlags // 0x80? + + XThread* thread = new XThread( + state, stack_size, xapi_thread_startup, start_address, start_context, + creation_flags); + + X_STATUS result = thread->Create(); + if (XFAILED(result)) { + // Failed! + thread->Release(); + XELOGE("Thread creation failed: %.8X", result); + SHIM_SET_RETURN_32(result); + return; + } if (XSUCCEEDED(result)) { if (handle_ptr) { - SHIM_SET_MEM_32(handle_ptr, handle); + SHIM_SET_MEM_32(handle_ptr, thread->handle()); } if (thread_id_ptr) { - SHIM_SET_MEM_32(thread_id_ptr, thread_id); + SHIM_SET_MEM_32(thread_id_ptr, thread->thread_id()); } } SHIM_SET_RETURN_32(result); @@ -158,24 +136,6 @@ SHIM_CALL ExTerminateThread_shim( } -X_STATUS xeNtResumeThread(uint32_t handle, uint32_t* out_suspend_count) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - X_STATUS result = X_STATUS_SUCCESS; - - XThread* thread = NULL; - result = state->object_table()->GetObject( - handle, (XObject**)&thread); - if (XSUCCEEDED(result)) { - result = thread->Resume(out_suspend_count); - thread->Release(); - } - - return result; -} - - SHIM_CALL NtResumeThread_shim( PPCContext* ppc_state, KernelState* state) { uint32_t handle = SHIM_GET_ARG_32(0); @@ -186,8 +146,14 @@ SHIM_CALL NtResumeThread_shim( handle, suspend_count_ptr); + XThread* thread = NULL; + X_STATUS result = state->object_table()->GetObject( + handle, (XObject**)&thread); uint32_t suspend_count; - X_STATUS result = xeNtResumeThread(handle, &suspend_count); + if (XSUCCEEDED(result)) { + result = thread->Resume(&suspend_count); + thread->Release(); + } if (XSUCCEEDED(result)) { if (suspend_count_ptr) { SHIM_SET_MEM_32(suspend_count_ptr, suspend_count); @@ -198,34 +164,22 @@ SHIM_CALL NtResumeThread_shim( } -X_STATUS xeKeResumeThread(void* thread_ptr, uint32_t* out_suspend_count) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - X_STATUS result = X_STATUS_SUCCESS; - - XThread* thread = (XThread*)XObject::GetObject(state, thread_ptr); - if (thread) { - result = thread->Resume(out_suspend_count); - } - - return result; -} - - SHIM_CALL KeResumeThread_shim( PPCContext* ppc_state, KernelState* state) { - uint32_t thread = SHIM_GET_ARG_32(0); + uint32_t thread_ptr = SHIM_GET_ARG_32(0); uint32_t suspend_count_ptr = SHIM_GET_ARG_32(1); XELOGD( "KeResumeThread(%.8X, %.8X)", - thread, + thread_ptr, suspend_count_ptr); - void* thread_ptr = SHIM_MEM_ADDR(thread); + X_STATUS result; + XThread* thread = (XThread*)XObject::GetObject(state, SHIM_MEM_ADDR(thread_ptr)); uint32_t suspend_count; - X_STATUS result = xeKeResumeThread(thread_ptr, &suspend_count); + if (thread) { + result = thread->Resume(&suspend_count); + } if (XSUCCEEDED(result)) { if (suspend_count_ptr) { SHIM_SET_MEM_32(suspend_count_ptr, suspend_count); @@ -236,24 +190,6 @@ SHIM_CALL KeResumeThread_shim( } -X_STATUS xeNtSuspendThread(uint32_t handle, uint32_t* out_suspend_count) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - X_STATUS result = X_STATUS_SUCCESS; - - XThread* thread = NULL; - result = state->object_table()->GetObject( - handle, (XObject**)&thread); - if (XSUCCEEDED(result)) { - result = thread->Suspend(out_suspend_count); - thread->Release(); - } - - return result; -} - - SHIM_CALL NtSuspendThread_shim( PPCContext* ppc_state, KernelState* state) { uint32_t handle = SHIM_GET_ARG_32(0); @@ -264,8 +200,15 @@ SHIM_CALL NtSuspendThread_shim( handle, suspend_count_ptr); + XThread* thread = NULL; + X_STATUS result = state->object_table()->GetObject( + handle, (XObject**)&thread); uint32_t suspend_count; - X_STATUS result = xeNtSuspendThread(handle, &suspend_count); + if (XSUCCEEDED(result)) { + result = thread->Suspend(&suspend_count); + thread->Release(); + } + if (XSUCCEEDED(result)) { if (suspend_count_ptr) { SHIM_SET_MEM_32(suspend_count_ptr, suspend_count); @@ -276,32 +219,22 @@ SHIM_CALL NtSuspendThread_shim( } -uint32_t xeKeSetAffinityThread(void* thread_ptr, uint32_t affinity) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - XThread* thread = (XThread*)XObject::GetObject(state, thread_ptr); - if (thread) { - thread->SetAffinity(affinity); - } - - return affinity; -} - - SHIM_CALL KeSetAffinityThread_shim( PPCContext* ppc_state, KernelState* state) { - uint32_t thread = SHIM_GET_ARG_32(0); + uint32_t thread_ptr = SHIM_GET_ARG_32(0); uint32_t affinity = SHIM_GET_ARG_32(1); XELOGD( "KeSetAffinityThread(%.8X, %.8X)", - thread, + thread_ptr, affinity); - void* thread_ptr = SHIM_MEM_ADDR(thread); - uint32_t result = xeKeSetAffinityThread(thread_ptr, affinity); - SHIM_SET_RETURN_32(result); + XThread* thread = (XThread*)XObject::GetObject(state, SHIM_MEM_ADDR(thread_ptr)); + if (thread) { + thread->SetAffinity(affinity); + } + + SHIM_SET_RETURN_32(affinity); } @@ -325,45 +258,26 @@ SHIM_CALL KeQueryBasePriorityThread_shim( } -uint32_t xeKeSetBasePriorityThread(void* thread_ptr, int32_t increment) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); +SHIM_CALL KeSetBasePriorityThread_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t thread_ptr = SHIM_GET_ARG_32(0); + uint32_t increment = SHIM_GET_ARG_32(1); + + XELOGD( + "KeSetBasePriorityThread(%.8X, %.8X)", + thread_ptr, + increment); int32_t prev_priority = 0; - XThread* thread = (XThread*)XObject::GetObject(state, thread_ptr); + XThread* thread = + (XThread*)XObject::GetObject(state, SHIM_MEM_ADDR(thread_ptr)); if (thread) { prev_priority = thread->QueryPriority(); thread->SetPriority(increment); } - return prev_priority; -} - - -SHIM_CALL KeSetBasePriorityThread_shim( - PPCContext* ppc_state, KernelState* state) { - uint32_t thread = SHIM_GET_ARG_32(0); - uint32_t increment = SHIM_GET_ARG_32(1); - - XELOGD( - "KeSetBasePriorityThread(%.8X, %.8X)", - thread, - increment); - - void* thread_ptr = SHIM_MEM_ADDR(thread); - uint32_t result = xeKeSetBasePriorityThread(thread_ptr, increment); - SHIM_SET_RETURN_32(result); -} - - -uint32_t xeKeGetCurrentProcessType() { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - // DWORD - - return X_PROCTYPE_USER; + SHIM_SET_RETURN_32(prev_priority); } @@ -372,38 +286,27 @@ SHIM_CALL KeGetCurrentProcessType_shim( // XELOGD( // "KeGetCurrentProcessType()"); - int result = xeKeGetCurrentProcessType(); + // DWORD + + int result = X_PROCTYPE_USER; SHIM_SET_RETURN_64(result); } -uint64_t xeKeQueryPerformanceFrequency() { - LARGE_INTEGER frequency; - if (QueryPerformanceFrequency(&frequency)) { - return frequency.QuadPart; - } else { - return 0; - } -} - - SHIM_CALL KeQueryPerformanceFrequency_shim( PPCContext* ppc_state, KernelState* state) { // XELOGD( // "KeQueryPerformanceFrequency()"); - uint64_t result = xeKeQueryPerformanceFrequency(); + uint64_t result = 0; + LARGE_INTEGER frequency; + if (QueryPerformanceFrequency(&frequency)) { + result = frequency.QuadPart; + } SHIM_SET_RETURN_64(result); } -X_STATUS xeKeDelayExecutionThread( - uint32_t processor_mode, uint32_t alertable, uint64_t interval) { - XThread* thread = XThread::GetCurrentThread(); - return thread->Delay(processor_mode, alertable, interval); -} - - SHIM_CALL KeDelayExecutionThread_shim( PPCContext* ppc_state, KernelState* state) { uint32_t processor_mode = SHIM_GET_ARG_32(0); @@ -415,8 +318,8 @@ SHIM_CALL KeDelayExecutionThread_shim( // "KeDelayExecutionThread(%.8X, %d, %.8X(%.16llX)", // processor_mode, alertable, interval_ptr, interval); - X_STATUS result = xeKeDelayExecutionThread( - processor_mode, alertable, interval); + XThread* thread = XThread::GetCurrentThread(); + X_STATUS result = thread->Delay(processor_mode, alertable, interval); SHIM_SET_RETURN_32(result); } @@ -425,18 +328,12 @@ SHIM_CALL KeDelayExecutionThread_shim( SHIM_CALL NtYieldExecution_shim( PPCContext* ppc_state, KernelState* state) { XELOGD("NtYieldExecution()"); - xeKeDelayExecutionThread(0, 0, 0); + XThread* thread = XThread::GetCurrentThread(); + X_STATUS result = thread->Delay(0, 0, 0); SHIM_SET_RETURN_64(0); } -void xeKeQuerySystemTime(uint64_t* time_ptr) { - FILETIME t; - GetSystemTimeAsFileTime(&t); - *time_ptr = ((uint64_t)t.dwHighDateTime << 32) | t.dwLowDateTime; -} - - SHIM_CALL KeQuerySystemTime_shim( PPCContext* ppc_state, KernelState* state) { uint32_t time_ptr = SHIM_GET_ARG_32(0); @@ -445,8 +342,9 @@ SHIM_CALL KeQuerySystemTime_shim( "KeQuerySystemTime(%.8X)", time_ptr); - uint64_t time; - xeKeQuerySystemTime(&time); + FILETIME t; + GetSystemTimeAsFileTime(&t); + uint64_t time = ((uint64_t)t.dwHighDateTime << 32) | t.dwLowDateTime; if (time_ptr) { SHIM_SET_MEM_64(time_ptr, time); @@ -461,8 +359,10 @@ SHIM_CALL KeQuerySystemTime_shim( // http://msdn.microsoft.com/en-us/library/ms686801 -uint32_t xeKeTlsAlloc() { - // DWORD +SHIM_CALL KeTlsAlloc_shim( + PPCContext* ppc_state, KernelState* state) { + XELOGD( + "KeTlsAlloc()"); uint32_t tls_index; @@ -477,41 +377,11 @@ uint32_t xeKeTlsAlloc() { } #endif // WIN32 - return tls_index; -} - - -SHIM_CALL KeTlsAlloc_shim( - PPCContext* ppc_state, KernelState* state) { - XELOGD( - "KeTlsAlloc()"); - - uint32_t result = xeKeTlsAlloc(); - SHIM_SET_RETURN_64(result); + SHIM_SET_RETURN_64(tls_index); } // http://msdn.microsoft.com/en-us/library/ms686804 -int KeTlsFree(uint32_t tls_index) { - // BOOL - // _In_ DWORD dwTlsIndex - - if (tls_index == X_TLS_OUT_OF_INDEXES) { - return 0; - } - - int result_code = 0; - -#if XE_PLATFORM_WIN32 - result_code = TlsFree(tls_index); -#else - result_code = pthread_key_delete(tls_index) == 0; -#endif // WIN32 - - return result_code; -} - - SHIM_CALL KeTlsFree_shim( PPCContext* ppc_state, KernelState* state) { uint32_t tls_index = SHIM_GET_ARG_32(0); @@ -520,15 +390,32 @@ SHIM_CALL KeTlsFree_shim( "KeTlsFree(%.8X)", tls_index); - int result = xeKeTlsAlloc(); + if (tls_index == X_TLS_OUT_OF_INDEXES) { + SHIM_SET_RETURN_64(0); + return; + } + + int result = 0; + +#if XE_PLATFORM_WIN32 + result = TlsFree(tls_index); +#else + result = pthread_key_delete(tls_index) == 0; +#endif // WIN32 + SHIM_SET_RETURN_64(result); } // http://msdn.microsoft.com/en-us/library/ms686812 -uint64_t xeKeTlsGetValue(uint32_t tls_index) { - // LPVOID - // _In_ DWORD dwTlsIndex +SHIM_CALL KeTlsGetValue_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t tls_index = SHIM_GET_ARG_32(0); + + // Logging disabled, as some games spam this. + //XELOGD( + // "KeTlsGetValue(%.8X)", + // tls_index); uint64_t value = 0; @@ -539,46 +426,15 @@ uint64_t xeKeTlsGetValue(uint32_t tls_index) { #endif // WIN32 if (!value) { - XELOGW("KeTlsGetValue should SetLastError if result is NULL"); + // XELOGW("KeTlsGetValue should SetLastError if result is NULL"); // TODO(benvanik): SetLastError } - return value; -} - - -SHIM_CALL KeTlsGetValue_shim( - PPCContext* ppc_state, KernelState* state) { - uint32_t tls_index = SHIM_GET_ARG_32(0); - - // Logging disabled, as some games spam this. - //XELOGD( - // "KeTlsGetValue(%.8X)", - // tls_index); - - uint64_t result = xeKeTlsGetValue(tls_index); - SHIM_SET_RETURN_64(result); + SHIM_SET_RETURN_64(value); } // http://msdn.microsoft.com/en-us/library/ms686818 -int xeKeTlsSetValue(uint32_t tls_index, uint64_t tls_value) { - // BOOL - // _In_ DWORD dwTlsIndex, - // _In_opt_ LPVOID lpTlsValue - - int result_code = 0; - -#if XE_PLATFORM_WIN32 - result_code = TlsSetValue(tls_index, (LPVOID)tls_value); -#else - result_code = pthread_setspecific(tls_index, (void*)tls_value) == 0; -#endif // WIN32 - - return result_code; -} - - SHIM_CALL KeTlsSetValue_shim( PPCContext* ppc_state, KernelState* state) { uint32_t tls_index = SHIM_GET_ARG_32(0); @@ -588,30 +444,18 @@ SHIM_CALL KeTlsSetValue_shim( "KeTlsSetValue(%.8X, %.8X)", tls_index, tls_value); - int result = xeKeTlsSetValue(tls_index, tls_value); + int result = 0; + +#if XE_PLATFORM_WIN32 + result = TlsSetValue(tls_index, (LPVOID)tls_value); +#else + result = pthread_setspecific(tls_index, (void*)tls_value) == 0; +#endif // WIN32 + SHIM_SET_RETURN_64(result); } -X_STATUS xeNtCreateEvent(uint32_t* handle_ptr, void* obj_attributes, - uint32_t event_type, uint32_t initial_state) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - XEvent* ev = new XEvent(state); - ev->Initialize(!event_type, !!initial_state); - - // obj_attributes may have a name inside of it, if != NULL. - if (obj_attributes) { - //ev->SetName(...); - } - - *handle_ptr = ev->handle(); - - return X_STATUS_SUCCESS; -} - - SHIM_CALL NtCreateEvent_shim( PPCContext* ppc_state, KernelState* state) { uint32_t handle_ptr = SHIM_GET_ARG_32(0); @@ -623,31 +467,19 @@ SHIM_CALL NtCreateEvent_shim( "NtCreateEvent(%.8X, %.8X, %d, %d)", handle_ptr, obj_attributes_ptr, event_type, initial_state); - uint32_t handle; - X_STATUS result = xeNtCreateEvent( - &handle, SHIM_MEM_ADDR(obj_attributes_ptr), - event_type, initial_state); + XEvent* ev = new XEvent(state); + ev->Initialize(!event_type, !!initial_state); - if (XSUCCEEDED(result)) { - if (handle_ptr) { - SHIM_SET_MEM_32(handle_ptr, handle); - } - } - SHIM_SET_RETURN_32(result); -} - - -int32_t xeKeSetEvent(void* event_ptr, uint32_t increment, uint32_t wait) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - XEvent* ev = (XEvent*)XObject::GetObject(state, event_ptr); - assert_not_null(ev); - if (!ev) { - return 0; + // obj_attributes may have a name inside of it, if != NULL. + auto obj_attributes = SHIM_MEM_ADDR(obj_attributes_ptr); + if (obj_attributes) { + //ev->SetName(...); } - return ev->Set(increment, !!wait); + if (handle_ptr) { + SHIM_SET_MEM_32(handle_ptr, ev->handle()); + } + SHIM_SET_RETURN_32(X_STATUS_SUCCESS); } @@ -662,8 +494,15 @@ SHIM_CALL KeSetEvent_shim( event_ref, increment, wait); void* event_ptr = SHIM_MEM_ADDR(event_ref); - int32_t result = xeKeSetEvent(event_ptr, increment, wait); + XEvent* ev = (XEvent*)XObject::GetObject(state, event_ptr); + assert_not_null(ev); + if (!ev) { + SHIM_SET_RETURN_64(0); + return; + } + + auto result = ev->Set(increment, !!wait); SHIM_SET_RETURN_64(result); } @@ -745,20 +584,6 @@ SHIM_CALL NtPulseEvent_shim( } -int32_t xeKeResetEvent(void* event_ptr) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - XEvent* ev = (XEvent*)XEvent::GetObject(state, event_ptr); - assert_not_null(ev); - if (!ev) { - return 0; - } - - return ev->Reset(); -} - - SHIM_CALL KeResetEvent_shim( PPCContext* ppc_state, KernelState* state) { uint32_t event_ref = SHIM_GET_ARG_32(0); @@ -768,8 +593,14 @@ SHIM_CALL KeResetEvent_shim( event_ref); void* event_ptr = SHIM_MEM_ADDR(event_ref); - int32_t result = xeKeResetEvent(event_ptr); + XEvent* ev = (XEvent*)XEvent::GetObject(state, event_ptr); + assert_not_null(ev); + if (!ev) { + SHIM_SET_RETURN_64(0); + return; + } + auto result = ev->Reset(); SHIM_SET_RETURN_64(result); } @@ -823,22 +654,6 @@ SHIM_CALL NtCreateSemaphore_shim( } -void xeKeInitializeSemaphore( - void* semaphore_ptr, int32_t count, int32_t limit) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - XSemaphore* sem = (XSemaphore*)XSemaphore::GetObject( - state, semaphore_ptr, 5 /* SemaphoreObject */); - assert_not_null(sem); - if (!sem) { - return; - } - - sem->Initialize(count, limit); -} - - SHIM_CALL KeInitializeSemaphore_shim( PPCContext* ppc_state, KernelState* state) { uint32_t semaphore_ref = SHIM_GET_ARG_32(0); @@ -850,25 +665,14 @@ SHIM_CALL KeInitializeSemaphore_shim( semaphore_ref, count, limit); void* semaphore_ptr = SHIM_MEM_ADDR(semaphore_ref); - xeKeInitializeSemaphore(semaphore_ptr, count, limit); -} - - -int32_t xeKeReleaseSemaphore( - void* semaphore_ptr, int32_t increment, int32_t adjustment, bool wait) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - XSemaphore* sem = (XSemaphore*)XSemaphore::GetObject(state, semaphore_ptr); + XSemaphore* sem = (XSemaphore*)XSemaphore::GetObject( + state, semaphore_ptr, 5 /* SemaphoreObject */); assert_not_null(sem); if (!sem) { - return 0; + return; } - // TODO(benvanik): increment thread priority? - // TODO(benvanik): wait? - - return sem->ReleaseSemaphore(adjustment); + sem->Initialize(count, limit); } @@ -884,9 +688,17 @@ SHIM_CALL KeReleaseSemaphore_shim( semaphore_ref, increment, adjustment, wait); void* semaphore_ptr = SHIM_MEM_ADDR(semaphore_ref); - int32_t result = xeKeReleaseSemaphore( - semaphore_ptr, increment, adjustment, wait == 1); + XSemaphore* sem = (XSemaphore*)XSemaphore::GetObject(state, semaphore_ptr); + assert_not_null(sem); + if (!sem) { + SHIM_SET_RETURN_64(0); + return; + } + // TODO(benvanik): increment thread priority? + // TODO(benvanik): wait? + + int32_t result = sem->ReleaseSemaphore(adjustment); SHIM_SET_RETURN_64(result); } @@ -1072,25 +884,9 @@ SHIM_CALL NtCancelTimer_shim( } -X_STATUS xeKeWaitForSingleObject( - void* object_ptr, uint32_t wait_reason, uint32_t processor_mode, - uint32_t alertable, uint64_t* opt_timeout) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - XObject* object = XObject::GetObject(state, object_ptr); - if (!object) { - // The only kind-of failure code. - return X_STATUS_ABANDONED_WAIT_0; - } - - return object->Wait(wait_reason, processor_mode, alertable, opt_timeout); -} - - SHIM_CALL KeWaitForSingleObject_shim( PPCContext* ppc_state, KernelState* state) { - uint32_t object = SHIM_GET_ARG_32(0); + uint32_t object_ptr = SHIM_GET_ARG_32(0); uint32_t wait_reason = SHIM_GET_ARG_32(1); uint32_t processor_mode = SHIM_GET_ARG_32(2); uint32_t alertable = SHIM_GET_ARG_32(3); @@ -1098,13 +894,18 @@ SHIM_CALL KeWaitForSingleObject_shim( XELOGD( "KeWaitForSingleObject(%.8X, %.8X, %.8X, %.1X, %.8X)", - object, wait_reason, processor_mode, alertable, timeout_ptr); + object_ptr, wait_reason, processor_mode, alertable, timeout_ptr); + + XObject* object = XObject::GetObject(state, SHIM_MEM_ADDR(object_ptr)); + if (!object) { + // The only kind-of failure code. + SHIM_SET_RETURN_32(X_STATUS_ABANDONED_WAIT_0); + return; + } - void* object_ptr = SHIM_MEM_ADDR(object); uint64_t timeout = timeout_ptr ? SHIM_MEM_64(timeout_ptr) : 0; - X_STATUS result = xeKeWaitForSingleObject( - object_ptr, wait_reason, processor_mode, alertable, - timeout_ptr ? &timeout : NULL); + X_STATUS result = object->Wait(wait_reason, processor_mode, alertable, + timeout_ptr ? &timeout : nullptr); SHIM_SET_RETURN_32(result); } @@ -1259,19 +1060,6 @@ SHIM_CALL NtSignalAndWaitForSingleObjectEx_shim( } -uint32_t xeKfAcquireSpinLock(uint32_t* lock_ptr) { - // Lock. - while (!poly::atomic_cas(0, 1, lock_ptr)) { - // Spin! - // TODO(benvanik): error on deadlock? - } - - // Raise IRQL to DISPATCH. - XThread* thread = XThread::GetCurrentThread(); - return thread->RaiseIrql(2); -} - - SHIM_CALL KfAcquireSpinLock_shim( PPCContext* ppc_state, KernelState* state) { uint32_t lock_ptr = SHIM_GET_ARG_32(0); @@ -1280,23 +1068,21 @@ SHIM_CALL KfAcquireSpinLock_shim( // "KfAcquireSpinLock(%.8X)", // lock_ptr); + // Lock. auto lock = reinterpret_cast(SHIM_MEM_ADDR(lock_ptr)); - uint32_t old_irql = xeKfAcquireSpinLock(lock); + while (!poly::atomic_cas(0, 1, lock)) { + // Spin! + // TODO(benvanik): error on deadlock? + } + + // Raise IRQL to DISPATCH. + XThread* thread = XThread::GetCurrentThread(); + auto old_irql = thread->RaiseIrql(2); SHIM_SET_RETURN_64(old_irql); } -void xeKfReleaseSpinLock(uint32_t* lock_ptr, uint32_t old_irql) { - // Restore IRQL. - XThread* thread = XThread::GetCurrentThread(); - thread->LowerIrql(old_irql); - - // Unlock. - poly::atomic_dec(lock_ptr); -} - - SHIM_CALL KfReleaseSpinLock_shim( PPCContext* ppc_state, KernelState* state) { uint32_t lock_ptr = SHIM_GET_ARG_32(0); @@ -1307,8 +1093,13 @@ SHIM_CALL KfReleaseSpinLock_shim( // lock_ptr, // old_irql); - xeKfReleaseSpinLock(reinterpret_cast(SHIM_MEM_ADDR(lock_ptr)), - old_irql); + // Restore IRQL. + XThread* thread = XThread::GetCurrentThread(); + thread->LowerIrql(old_irql); + + // Unlock. + auto lock = reinterpret_cast(SHIM_MEM_ADDR(lock_ptr)); + poly::atomic_dec(lock); } @@ -1343,21 +1134,11 @@ SHIM_CALL KeReleaseSpinLockFromRaisedIrql_shim( } -void xeKeEnterCriticalRegion() { - XThread::EnterCriticalRegion(); -} - - SHIM_CALL KeEnterCriticalRegion_shim( PPCContext* ppc_state, KernelState* state) { // XELOGD( // "KeEnterCriticalRegion()"); - xeKeEnterCriticalRegion(); -} - - -void xeKeLeaveCriticalRegion() { - XThread::LeaveCriticalRegion(); + XThread::EnterCriticalRegion(); } @@ -1365,7 +1146,7 @@ SHIM_CALL KeLeaveCriticalRegion_shim( PPCContext* ppc_state, KernelState* state) { // XELOGD( // "KeLeaveCriticalRegion()"); - xeKeLeaveCriticalRegion(); + XThread::LeaveCriticalRegion(); } diff --git a/src/xenia/kernel/xboxkrnl_video.cc b/src/xenia/kernel/xboxkrnl_video.cc index 7576b21bb..cbabd6cab 100644 --- a/src/xenia/kernel/xboxkrnl_video.cc +++ b/src/xenia/kernel/xboxkrnl_video.cc @@ -43,12 +43,6 @@ namespace kernel { // http://www.microsoft.com/en-za/download/details.aspx?id=5313 -- "Stripped Down Direct3D: Xbox 360 Command Buffer and Resource Management" -void xeVdGetCurrentDisplayGamma(uint32_t* arg0, float* arg1) { - *arg0 = 2; - *arg1 = 2.22222233f; -} - - SHIM_CALL VdGetCurrentDisplayGamma_shim( PPCContext* ppc_state, KernelState* state) { uint32_t arg0_ptr = SHIM_GET_ARG_32(0); @@ -58,14 +52,8 @@ SHIM_CALL VdGetCurrentDisplayGamma_shim( "VdGetCurrentDisplayGamma(%.8X, %.8X)", arg0_ptr, arg1_ptr); - uint32_t arg0 = 0; - union { - float float_value; - uint32_t uint_value; - } arg1; - xeVdGetCurrentDisplayGamma(&arg0, &arg1.float_value); - SHIM_SET_MEM_32(arg0_ptr, arg0); - SHIM_SET_MEM_32(arg1_ptr, arg1.uint_value); + SHIM_SET_MEM_32(arg0_ptr, 2); + SHIM_SET_MEM_F32(arg1_ptr, 2.22222233f); } @@ -103,22 +91,16 @@ SHIM_CALL VdGetCurrentDisplayInformation_shim( } -uint32_t xeVdQueryVideoFlags() { - // ? - return 0x00000006; -} - - SHIM_CALL VdQueryVideoFlags_shim( PPCContext* ppc_state, KernelState* state) { XELOGD( "VdQueryVideoFlags()"); - SHIM_SET_RETURN_64(xeVdQueryVideoFlags()); + SHIM_SET_RETURN_64(0x00000006); } -void xeVdQueryVideoMode(X_VIDEO_MODE *video_mode, bool swap) { +void xeVdQueryVideoMode(X_VIDEO_MODE* video_mode) { if (video_mode == NULL) { return; } @@ -134,17 +116,16 @@ void xeVdQueryVideoMode(X_VIDEO_MODE *video_mode, bool swap) { video_mode->unknown_0x8a = 0x8A; video_mode->unknown_0x01 = 0x01; - if (swap) { - video_mode->display_width = poly::byte_swap(video_mode->display_width); - video_mode->display_height = poly::byte_swap(video_mode->display_height); - video_mode->is_interlaced = poly::byte_swap(video_mode->is_interlaced); - video_mode->is_widescreen = poly::byte_swap(video_mode->is_widescreen); - video_mode->is_hi_def = poly::byte_swap(video_mode->is_hi_def); - video_mode->refresh_rate = poly::byte_swap(video_mode->refresh_rate); - video_mode->video_standard = poly::byte_swap(video_mode->video_standard); - video_mode->unknown_0x8a = poly::byte_swap(video_mode->unknown_0x8a); - video_mode->unknown_0x01 = poly::byte_swap(video_mode->unknown_0x01); - } + // TODO(benvanik): auto swap structure. + video_mode->display_width = poly::byte_swap(video_mode->display_width); + video_mode->display_height = poly::byte_swap(video_mode->display_height); + video_mode->is_interlaced = poly::byte_swap(video_mode->is_interlaced); + video_mode->is_widescreen = poly::byte_swap(video_mode->is_widescreen); + video_mode->is_hi_def = poly::byte_swap(video_mode->is_hi_def); + video_mode->refresh_rate = poly::byte_swap(video_mode->refresh_rate); + video_mode->video_standard = poly::byte_swap(video_mode->video_standard); + video_mode->unknown_0x8a = poly::byte_swap(video_mode->unknown_0x8a); + video_mode->unknown_0x01 = poly::byte_swap(video_mode->unknown_0x01); } @@ -157,23 +138,7 @@ SHIM_CALL VdQueryVideoMode_shim( "VdQueryVideoMode(%.8X)", video_mode_ptr); - xeVdQueryVideoMode(video_mode, true); -} - - -void xeVdInitializeEngines(uint32_t unk0, uint32_t callback, uint32_t unk1, - uint32_t unk2_ptr, uint32_t unk3_ptr) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - GraphicsSystem* gs = state->emulator()->graphics_system(); - if (!gs) { - return; - } - - // r3 = 0x4F810000 - // r4 = function ptr (cleanup callback?) - // r5 = 0 - // r6/r7 = some binary data in .data + xeVdQueryVideoMode(video_mode); } @@ -188,8 +153,11 @@ SHIM_CALL VdInitializeEngines_shim( XELOGD( "VdInitializeEngines(%.8X, %.8X, %.8X, %.8X, %.8X)", unk0, callback, unk1, unk2_ptr, unk3_ptr); - - xeVdInitializeEngines(unk0, callback, unk1, unk2_ptr, unk3_ptr); + + // r3 = 0x4F810000 + // r4 = function ptr (cleanup callback?) + // r5 = 0 + // r6/r7 = some binary data in .data } @@ -204,9 +172,15 @@ SHIM_CALL VdShutdownEngines_shim( } -void xeVdSetGraphicsInterruptCallback(uint32_t callback, uint32_t user_data) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); +SHIM_CALL VdSetGraphicsInterruptCallback_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t callback = SHIM_GET_ARG_32(0); + uint32_t user_data = SHIM_GET_ARG_32(1); + + XELOGD( + "VdSetGraphicsInterruptCallback(%.8X, %.8X)", + callback, user_data); + GraphicsSystem* gs = state->emulator()->graphics_system(); if (!gs) { return; @@ -220,22 +194,15 @@ void xeVdSetGraphicsInterruptCallback(uint32_t callback, uint32_t user_data) { } -SHIM_CALL VdSetGraphicsInterruptCallback_shim( +SHIM_CALL VdInitializeRingBuffer_shim( PPCContext* ppc_state, KernelState* state) { - uint32_t callback = SHIM_GET_ARG_32(0); - uint32_t user_data = SHIM_GET_ARG_32(1); + uint32_t ptr = SHIM_GET_ARG_32(0); + uint32_t page_count = SHIM_GET_ARG_32(1); XELOGD( - "VdSetGraphicsInterruptCallback(%.8X, %.8X)", - callback, user_data); - - xeVdSetGraphicsInterruptCallback(callback, user_data); -} - - -void xeVdInitializeRingBuffer(uint32_t ptr, uint32_t page_count) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); + "VdInitializeRingBuffer(%.8X, %.8X)", + ptr, page_count); + GraphicsSystem* gs = state->emulator()->graphics_system(); if (!gs) { return; @@ -252,22 +219,15 @@ void xeVdInitializeRingBuffer(uint32_t ptr, uint32_t page_count) { } -SHIM_CALL VdInitializeRingBuffer_shim( +SHIM_CALL VdEnableRingBufferRPtrWriteBack_shim( PPCContext* ppc_state, KernelState* state) { uint32_t ptr = SHIM_GET_ARG_32(0); - uint32_t page_count = SHIM_GET_ARG_32(1); + uint32_t block_size = SHIM_GET_ARG_32(1); XELOGD( - "VdInitializeRingBuffer(%.8X, %.8X)", - ptr, page_count); + "VdEnableRingBufferRPtrWriteBack(%.8X, %.8X)", + ptr, block_size); - xeVdInitializeRingBuffer(ptr, page_count); -} - - -void xeVdEnableRingBufferRPtrWriteBack(uint32_t ptr, uint32_t block_size) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); GraphicsSystem* gs = state->emulator()->graphics_system(); if (!gs) { return; @@ -284,37 +244,18 @@ void xeVdEnableRingBufferRPtrWriteBack(uint32_t ptr, uint32_t block_size) { //((p + 0x3C) & 0x1FFFFFFF) + ((((p + 0x3C) >> 20) + 0x200) & 0x1000) //also 0x3C offset into WriteBacks is PrimaryRingBufferReadIndex -//(1:17:38 AM) Rick: .text:8201B348 lwz r11, 0x2B10(r31) -//(1:17:38 AM) Rick: .text:8201B34C addi r11, r11, 0x3C -//(1:17:38 AM) Rick: .text:8201B350 srwi r10, r11, 20 # r10 = r11 >> 20 -//(1:17:38 AM) Rick: .text:8201B354 clrlwi r11, r11, 3 # r11 = r11 & 0x1FFFFFFF -//(1:17:38 AM) Rick: .text:8201B358 addi r10, r10, 0x200 -//(1:17:39 AM) Rick: .text:8201B35C rlwinm r10, r10, 0,19,19 # r10 = r10 & 0x1000 -//(1:17:39 AM) Rick: .text:8201B360 add r3, r10, r11 -//(1:17:39 AM) Rick: .text:8201B364 bl VdEnableRingBufferRPtrWriteBack + //(1:17:38 AM) Rick: .text:8201B348 lwz r11, 0x2B10(r31) + //(1:17:38 AM) Rick: .text:8201B34C addi r11, r11, 0x3C + //(1:17:38 AM) Rick: .text:8201B350 srwi r10, r11, 20 # r10 = r11 >> 20 + //(1:17:38 AM) Rick: .text:8201B354 clrlwi r11, r11, 3 # r11 = r11 & 0x1FFFFFFF + //(1:17:38 AM) Rick: .text:8201B358 addi r10, r10, 0x200 + //(1:17:39 AM) Rick: .text:8201B35C rlwinm r10, r10, 0,19,19 # r10 = r10 & 0x1000 + //(1:17:39 AM) Rick: .text:8201B360 add r3, r10, r11 + //(1:17:39 AM) Rick: .text:8201B364 bl VdEnableRingBufferRPtrWriteBack // TODO(benvanik): something? } -SHIM_CALL VdEnableRingBufferRPtrWriteBack_shim( - PPCContext* ppc_state, KernelState* state) { - uint32_t ptr = SHIM_GET_ARG_32(0); - uint32_t block_size = SHIM_GET_ARG_32(1); - - XELOGD( - "VdEnableRingBufferRPtrWriteBack(%.8X, %.8X)", - ptr, block_size); - - xeVdEnableRingBufferRPtrWriteBack(ptr, block_size); -} - - -void xeVdGetSystemCommandBuffer(uint32_t* p0, uint32_t* p1) { - *p0 = 0xBEEF0000; - *p1 = 0xBEEF0001; -} - - SHIM_CALL VdGetSystemCommandBuffer_shim( PPCContext* ppc_state, KernelState* state) { uint32_t p0_ptr = SHIM_GET_ARG_32(0); @@ -325,23 +266,8 @@ SHIM_CALL VdGetSystemCommandBuffer_shim( p0_ptr, p1_ptr); - uint32_t p0 = 0; - uint32_t p1 = 0; - xeVdGetSystemCommandBuffer(&p0, &p1); - SHIM_SET_MEM_32(p0_ptr, p0); - SHIM_SET_MEM_32(p1_ptr, p1); -} - - -void xeVdSetSystemCommandBufferGpuIdentifierAddress(uint32_t unk) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - GraphicsSystem* gs = state->emulator()->graphics_system(); - if (!gs) { - return; - } - - // r3 = 0x2B10(d3d?) + 8 + SHIM_SET_MEM_32(p0_ptr, 0xBEEF0000); + SHIM_SET_MEM_32(p1_ptr, 0xBEEF0001); } @@ -352,8 +278,8 @@ SHIM_CALL VdSetSystemCommandBufferGpuIdentifierAddress_shim( XELOGD( "VdSetSystemCommandBufferGpuIdentifierAddress(%.8X)", unk); - - xeVdSetSystemCommandBufferGpuIdentifierAddress(unk); + + // r3 = 0x2B10(d3d?) + 8 } @@ -487,32 +413,30 @@ void xe::kernel::xboxkrnl::RegisterVideoExports( // Pointer to a global D3D device. Games only seem to set this, so we don't // have to do anything. We may want to read it back later, though. uint32_t pVdGlobalDevice = (uint32_t)memory->HeapAlloc(0, 4, 0); - export_resolver->SetVariableMapping( - "xboxkrnl.exe", ordinals::VdGlobalDevice, - pVdGlobalDevice); + export_resolver->SetVariableMapping("xboxkrnl.exe", ordinals::VdGlobalDevice, + pVdGlobalDevice); poly::store_and_swap(mem + pVdGlobalDevice, 0); // VdGlobalXamDevice (4b) // Pointer to the XAM D3D device, which we don't have. uint32_t pVdGlobalXamDevice = (uint32_t)memory->HeapAlloc(0, 4, 0); export_resolver->SetVariableMapping( - "xboxkrnl.exe", ordinals::VdGlobalXamDevice, - pVdGlobalXamDevice); + "xboxkrnl.exe", ordinals::VdGlobalXamDevice, pVdGlobalXamDevice); poly::store_and_swap(mem + pVdGlobalXamDevice, 0); // VdGpuClockInMHz (4b) // GPU clock. Xenos is 500MHz. Hope nothing is relying on this timing... uint32_t pVdGpuClockInMHz = (uint32_t)memory->HeapAlloc(0, 4, 0); - export_resolver->SetVariableMapping( - "xboxkrnl.exe", ordinals::VdGpuClockInMHz, - pVdGpuClockInMHz); + export_resolver->SetVariableMapping("xboxkrnl.exe", ordinals::VdGpuClockInMHz, + pVdGpuClockInMHz); poly::store_and_swap(mem + pVdGpuClockInMHz, 500); // VdHSIOCalibrationLock (28b) // CriticalSection. uint32_t pVdHSIOCalibrationLock = (uint32_t)memory->HeapAlloc(0, 28, 0); export_resolver->SetVariableMapping( - "xboxkrnl.exe", ordinals::VdHSIOCalibrationLock, - pVdHSIOCalibrationLock); - xeRtlInitializeCriticalSectionAndSpinCount(pVdHSIOCalibrationLock, 10000); + "xboxkrnl.exe", ordinals::VdHSIOCalibrationLock, pVdHSIOCalibrationLock); + auto hsio_lock = + reinterpret_cast(mem + pVdHSIOCalibrationLock); + xeRtlInitializeCriticalSectionAndSpinCount(hsio_lock, 10000); } diff --git a/src/xenia/kernel/xobject.cc b/src/xenia/kernel/xobject.cc index 048e4cd4d..8f2b1eccf 100644 --- a/src/xenia/kernel/xobject.cc +++ b/src/xenia/kernel/xobject.cc @@ -68,7 +68,7 @@ void XObject::Release() { } X_STATUS XObject::Delete() { - return shared_kernel_state_->object_table()->RemoveHandle(handle_); + return kernel_state_->object_table()->RemoveHandle(handle_); } uint32_t XObject::TimeoutTicksToMs(int64_t timeout_ticks) { @@ -149,11 +149,11 @@ X_STATUS XObject::WaitMultiple( } void XObject::LockType() { - xe_mutex_lock(shared_kernel_state_->object_mutex_); + xe_mutex_lock(KernelState::shared()->object_mutex_); } void XObject::UnlockType() { - xe_mutex_unlock(shared_kernel_state_->object_mutex_); + xe_mutex_unlock(KernelState::shared()->object_mutex_); } void XObject::SetNativePointer(uint32_t native_ptr) {