From 927acf1902287684bfc00d653d7a8b461c5c8752 Mon Sep 17 00:00:00 2001 From: gibbed Date: Tue, 20 Nov 2018 13:05:38 -0600 Subject: [PATCH 1/3] [Kernel] Fix a minor typo. --- src/xenia/kernel/xboxkrnl/xboxkrnl_hid.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_hid.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_hid.cc index 0bcf33fd9..0ce308237 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_hid.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_hid.cc @@ -25,7 +25,7 @@ dword_result_t HidReadKeys(dword_t unk1, unknown_t unk2, unknown_t unk3) { * Other errors appear to be ignored? * * unk1 is 0 - * unk2 is a pointer to &unk3[2], possibly a 6-byte vuffer + * unk2 is a pointer to &unk3[2], possibly a 6-byte buffer * unk3 is a pointer to a 20-byte buffer */ return 0xC000009D; From e1d448f630ccef4dfbda01602d9ba4eeb0de9aeb Mon Sep 17 00:00:00 2001 From: gibbed Date: Tue, 20 Nov 2018 13:50:31 -0600 Subject: [PATCH 2/3] [Kernel] Move xam_content to new shim convention. --- src/xenia/kernel/xam/xam_content.cc | 298 +++++++++++----------------- 1 file changed, 113 insertions(+), 185 deletions(-) diff --git a/src/xenia/kernel/xam/xam_content.cc b/src/xenia/kernel/xam/xam_content.cc index ec7a3d4e6..4da20c7ff 100644 --- a/src/xenia/kernel/xam/xam_content.cc +++ b/src/xenia/kernel/xam/xam_content.cc @@ -33,125 +33,100 @@ static const DeviceInfo dummy_device_info_ = { L"Dummy HDD", }; -SHIM_CALL XamContentGetLicenseMask_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t mask_ptr = SHIM_GET_ARG_32(0); - uint32_t overlapped_ptr = SHIM_GET_ARG_32(1); - - XELOGD("XamContentGetLicenseMask(%.8X, %.8X)", mask_ptr, overlapped_ptr); - +dword_result_t XamContentGetLicenseMask(lpdword_t mask_ptr, + lpunknown_t overlapped_ptr) { // Each bit in the mask represents a granted license. Available licenses // seems to vary from game to game, but most appear to use bit 0 to indicate // if the game is purchased or not. - SHIM_SET_MEM_32(mask_ptr, 0); + *mask_ptr = 0; if (overlapped_ptr) { - kernel_state->CompleteOverlappedImmediate(overlapped_ptr, X_ERROR_SUCCESS); - SHIM_SET_RETURN_32(X_ERROR_IO_PENDING); + kernel_state()->CompleteOverlappedImmediate(overlapped_ptr, + X_ERROR_SUCCESS); + return X_ERROR_IO_PENDING; } else { - SHIM_SET_RETURN_32(X_ERROR_SUCCESS); + return X_ERROR_SUCCESS; } } +DECLARE_XAM_EXPORT1(XamContentGetLicenseMask, kContent, kStub); -SHIM_CALL XamContentGetDeviceName_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t device_id = SHIM_GET_ARG_32(0); - uint32_t name_ptr = SHIM_GET_ARG_32(1); - uint32_t name_capacity = SHIM_GET_ARG_32(2); - - XELOGD("XamContentGetDeviceName(%.8X, %.8X, %d)", device_id, name_ptr, - name_capacity); - +dword_result_t XamContentGetDeviceName(dword_t device_id, + lpwstring_t name_buffer, + dword_t name_capacity) { if ((device_id & 0xFFFF0000) != dummy_device_info_.device_id) { - SHIM_SET_RETURN_32(X_ERROR_DEVICE_NOT_CONNECTED); - return; + return X_ERROR_DEVICE_NOT_CONNECTED; } if (name_capacity < dummy_device_info_.name.size() + 1) { - SHIM_SET_RETURN_32(X_ERROR_INSUFFICIENT_BUFFER); - return; + return X_ERROR_INSUFFICIENT_BUFFER; } - xe::store_and_swap(SHIM_MEM_ADDR(name_ptr), - dummy_device_info_.name); - - SHIM_SET_RETURN_32(X_ERROR_SUCCESS); + xe::store_and_swap(name_buffer, dummy_device_info_.name); + return X_ERROR_SUCCESS; } +DECLARE_XAM_EXPORT1(XamContentGetDeviceName, kContent, kImplemented); -SHIM_CALL XamContentGetDeviceState_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t device_id = SHIM_GET_ARG_32(0); - uint32_t overlapped_ptr = SHIM_GET_ARG_32(1); - - XELOGD("XamContentGetDeviceState(%.8X, %.8X)", device_id, overlapped_ptr); - +dword_result_t XamContentGetDeviceState(dword_t device_id, + lpunknown_t overlapped_ptr) { if ((device_id & 0xFFFF0000) != dummy_device_info_.device_id) { if (overlapped_ptr) { - kernel_state->CompleteOverlappedImmediateEx( + kernel_state()->CompleteOverlappedImmediateEx( overlapped_ptr, X_ERROR_FUNCTION_FAILED, X_ERROR_DEVICE_NOT_CONNECTED, 0); - SHIM_SET_RETURN_32(X_ERROR_IO_PENDING); + return X_ERROR_IO_PENDING; } else { - SHIM_SET_RETURN_32(X_ERROR_DEVICE_NOT_CONNECTED); + return X_ERROR_DEVICE_NOT_CONNECTED; } - return; } if (overlapped_ptr) { - kernel_state->CompleteOverlappedImmediate(overlapped_ptr, X_ERROR_SUCCESS); - SHIM_SET_RETURN_32(X_ERROR_IO_PENDING); + kernel_state()->CompleteOverlappedImmediate(overlapped_ptr, + X_ERROR_SUCCESS); + return X_ERROR_IO_PENDING; } else { - SHIM_SET_RETURN_32(X_ERROR_SUCCESS); + return X_ERROR_SUCCESS; } } +DECLARE_XAM_EXPORT1(XamContentGetDeviceState, kContent, kStub); -SHIM_CALL XamContentGetDeviceData_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t device_id = SHIM_GET_ARG_32(0); - uint32_t device_data_ptr = SHIM_GET_ARG_32(1); - - XELOGD("XamContentGetDeviceData(%.8X, %.8X)", device_id, device_data_ptr); +typedef struct { + xe::be device_id; + xe::be unknown; + xe::be total_bytes; + xe::be free_bytes; + xe::be name[28]; +} X_CONTENT_DEVICE_DATA; +dword_result_t XamContentGetDeviceData( + dword_t device_id, pointer_t device_data) { if ((device_id & 0xFFFF0000) != dummy_device_info_.device_id) { // TODO(benvanik): memset 0 the data? - SHIM_SET_RETURN_32(X_ERROR_DEVICE_NOT_CONNECTED); - return; + return X_ERROR_DEVICE_NOT_CONNECTED; } const auto& device_info = dummy_device_info_; - SHIM_SET_MEM_32(device_data_ptr + 0, device_info.device_id); - SHIM_SET_MEM_32(device_data_ptr + 4, device_id & 0xFFFF); // Fake it. - SHIM_SET_MEM_64(device_data_ptr + 8, device_info.total_bytes); - SHIM_SET_MEM_64(device_data_ptr + 16, device_info.free_bytes); - xe::store_and_swap(SHIM_MEM_ADDR(device_data_ptr + 24), - device_info.name); - - SHIM_SET_RETURN_32(X_ERROR_SUCCESS); + device_data->device_id = device_info.device_id; + device_data->unknown = device_id & 0xFFFF; // Fake it. + device_data->total_bytes = device_info.total_bytes; + device_data->free_bytes = device_info.free_bytes; + xe::store_and_swap(&device_data->name[0], device_info.name); + return X_ERROR_SUCCESS; } +DECLARE_XAM_EXPORT1(XamContentGetDeviceData, kContent, kImplemented); -SHIM_CALL XamContentResolve_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t user_index = SHIM_GET_ARG_32(0); - uint32_t content_data_ptr = SHIM_GET_ARG_32(1); - uint32_t buffer_ptr = SHIM_GET_ARG_32(2); - uint32_t buffer_size = SHIM_GET_ARG_32(3); - uint32_t unk1 = SHIM_GET_ARG_32(4); // 1 - uint32_t unk2 = SHIM_GET_ARG_32(5); // 0 - uint32_t unk3 = SHIM_GET_ARG_32(6); // 0 - - auto content_data = XCONTENT_DATA(SHIM_MEM_ADDR(content_data_ptr)); - - XELOGD("XamContentResolve(%d, %.8X, %.8X, %d, %.8X, %.8X, %.8X)", user_index, - content_data_ptr, buffer_ptr, buffer_size, unk1, unk2, unk3); +dword_result_t XamContentResolve(dword_t user_index, lpvoid_t content_data_ptr, + lpunknown_t buffer_ptr, dword_t buffer_size, + dword_t unk1, dword_t unk2, dword_t unk3) { + auto content_data = XCONTENT_DATA((uint8_t*)content_data_ptr); // Result of buffer_ptr is sent to RtlInitAnsiString. // buffer_size is usually 260 (max path). // Games expect zero if resolve was successful. assert_always(); XELOGW("XamContentResolve unimplemented!"); - - SHIM_SET_RETURN_32(X_ERROR_NOT_FOUND); + return X_ERROR_NOT_FOUND; } +DECLARE_XAM_EXPORT1(XamContentResolve, kContent, kStub); // http://gameservice.googlecode.com/svn-history/r14/trunk/ContentManager.cpp // https://github.com/LestaD/SourceEngine2007/blob/master/se2007/engine/xboxsystem.cpp#L499 @@ -312,104 +287,79 @@ dword_result_t XamContentOpenFile(dword_t user_index, lpstring_t root_name, } DECLARE_XAM_EXPORT1(XamContentOpenFile, kContent, kStub); -SHIM_CALL XamContentFlush_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t root_name_ptr = SHIM_GET_ARG_32(0); - uint32_t overlapped_ptr = SHIM_GET_ARG_32(1); - - auto root_name = xe::load_and_swap(SHIM_MEM_ADDR(root_name_ptr)); - - XELOGD("XamContentFlush(%.8X(%s), %.8X)", root_name_ptr, root_name.c_str(), - overlapped_ptr); - +dword_result_t XamContentFlush(lpstring_t root_name, + lpunknown_t overlapped_ptr) { X_RESULT result = X_ERROR_SUCCESS; if (overlapped_ptr) { - kernel_state->CompleteOverlappedImmediate(overlapped_ptr, result); - SHIM_SET_RETURN_32(X_ERROR_IO_PENDING); + kernel_state()->CompleteOverlappedImmediate(overlapped_ptr, result); + return X_ERROR_IO_PENDING; } else { - SHIM_SET_RETURN_32(result); + return result; } } +DECLARE_XAM_EXPORT1(XamContentFlush, kContent, kStub); -SHIM_CALL XamContentClose_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t root_name_ptr = SHIM_GET_ARG_32(0); - uint32_t overlapped_ptr = SHIM_GET_ARG_32(1); - - auto root_name = xe::load_and_swap(SHIM_MEM_ADDR(root_name_ptr)); - - XELOGD("XamContentClose(%.8X(%s), %.8X)", root_name_ptr, root_name.c_str(), - overlapped_ptr); - +dword_result_t XamContentClose(lpstring_t root_name, + lpunknown_t overlapped_ptr) { // Closes a previously opened root from XamContentCreate*. - auto result = kernel_state->content_manager()->CloseContent(root_name); + auto result = + kernel_state()->content_manager()->CloseContent(root_name.value()); if (overlapped_ptr) { - kernel_state->CompleteOverlappedImmediate(overlapped_ptr, result); - SHIM_SET_RETURN_32(X_ERROR_IO_PENDING); + kernel_state()->CompleteOverlappedImmediate(overlapped_ptr, result); + return X_ERROR_IO_PENDING; } else { - SHIM_SET_RETURN_32(result); + return result; } } +DECLARE_XAM_EXPORT1(XamContentClose, kContent, kImplemented); -SHIM_CALL XamContentGetCreator_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t user_index = SHIM_GET_ARG_32(0); - uint32_t content_data_ptr = SHIM_GET_ARG_32(1); - uint32_t is_creator_ptr = SHIM_GET_ARG_32(2); - uint32_t creator_xuid_ptr = SHIM_GET_ARG_32(3); - uint32_t overlapped_ptr = SHIM_GET_ARG_32(4); - - auto content_data = XCONTENT_DATA(SHIM_MEM_ADDR(content_data_ptr)); - - XELOGD("XamContentGetCreator(%d, %.8X, %.8X, %.8X, %.8X)", user_index, - content_data_ptr, is_creator_ptr, creator_xuid_ptr, overlapped_ptr); - +dword_result_t XamContentGetCreator(dword_t user_index, + lpvoid_t content_data_ptr, + lpdword_t is_creator_ptr, + lpqword_t creator_xuid_ptr, + lpunknown_t overlapped_ptr) { auto result = X_ERROR_SUCCESS; + auto content_data = XCONTENT_DATA((uint8_t*)content_data_ptr); + if (content_data.content_type == 1) { // User always creates saves. - SHIM_SET_MEM_32(is_creator_ptr, 1); + *is_creator_ptr = 1; if (creator_xuid_ptr) { - SHIM_SET_MEM_64(creator_xuid_ptr, kernel_state->user_profile()->xuid()); + *creator_xuid_ptr = kernel_state()->user_profile()->xuid(); } } else { - SHIM_SET_MEM_32(is_creator_ptr, 0); + *is_creator_ptr = 0; if (creator_xuid_ptr) { - SHIM_SET_MEM_64(creator_xuid_ptr, 0); + *creator_xuid_ptr = 0; } } if (overlapped_ptr) { - kernel_state->CompleteOverlappedImmediate(overlapped_ptr, result); - SHIM_SET_RETURN_32(X_ERROR_IO_PENDING); + kernel_state()->CompleteOverlappedImmediate(overlapped_ptr, result); + return X_ERROR_IO_PENDING; } else { - SHIM_SET_RETURN_32(result); + return result; } } +DECLARE_XAM_EXPORT1(XamContentGetCreator, kContent, kImplemented); -SHIM_CALL XamContentGetThumbnail_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t user_index = SHIM_GET_ARG_32(0); - uint32_t content_data_ptr = SHIM_GET_ARG_32(1); - uint32_t buffer_ptr = SHIM_GET_ARG_32(2); - uint32_t buffer_size_ptr = SHIM_GET_ARG_32(3); - uint32_t overlapped_ptr = SHIM_GET_ARG_32(4); - - assert_not_zero(buffer_size_ptr); - uint32_t buffer_size = SHIM_MEM_32(buffer_size_ptr); - auto content_data = XCONTENT_DATA(SHIM_MEM_ADDR(content_data_ptr)); - - XELOGD("XamContentGetThumbnail(%d, %.8X, %.8X, %.8X(%d), %.8X)", user_index, - content_data_ptr, buffer_ptr, buffer_size_ptr, buffer_size, - overlapped_ptr); +dword_result_t XamContentGetThumbnail(dword_t user_index, + lpvoid_t content_data_ptr, + lpvoid_t buffer_ptr, + lpdword_t buffer_size_ptr, + lpunknown_t overlapped_ptr) { + assert_not_null(buffer_size_ptr); + uint32_t buffer_size = *buffer_size_ptr; + auto content_data = XCONTENT_DATA((uint8_t*)content_data_ptr); // Get thumbnail (if it exists). std::vector buffer; - auto result = kernel_state->content_manager()->GetContentThumbnail( + auto result = kernel_state()->content_manager()->GetContentThumbnail( content_data, &buffer); - SHIM_SET_MEM_32(buffer_size_ptr, uint32_t(buffer.size())); + *buffer_size_ptr = uint32_t(buffer.size()); if (XSUCCEEDED(result)) { // Write data, if we were given a pointer. @@ -420,80 +370,58 @@ SHIM_CALL XamContentGetThumbnail_shim(PPCContext* ppc_context, result = X_ERROR_INSUFFICIENT_BUFFER; } else { // Copy data. - std::memcpy(SHIM_MEM_ADDR(buffer_ptr), buffer.data(), buffer.size()); + std::memcpy((uint8_t*)buffer_ptr, buffer.data(), buffer.size()); } } } if (overlapped_ptr) { - kernel_state->CompleteOverlappedImmediate(overlapped_ptr, result); - SHIM_SET_RETURN_32(X_ERROR_IO_PENDING); + kernel_state()->CompleteOverlappedImmediate(overlapped_ptr, result); + return X_ERROR_IO_PENDING; } else { - SHIM_SET_RETURN_32(result); + return result; } } +DECLARE_XAM_EXPORT1(XamContentGetThumbnail, kContent, kImplemented); -SHIM_CALL XamContentSetThumbnail_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t user_index = SHIM_GET_ARG_32(0); - uint32_t content_data_ptr = SHIM_GET_ARG_32(1); - uint32_t buffer_ptr = SHIM_GET_ARG_32(2); - uint32_t buffer_size = SHIM_GET_ARG_32(3); - uint32_t overlapped_ptr = SHIM_GET_ARG_32(4); - - auto content_data = XCONTENT_DATA(SHIM_MEM_ADDR(content_data_ptr)); - - XELOGD("XamContentSetThumbnail(%d, %.8X, %.8X, %d, %.8X)", user_index, - content_data_ptr, buffer_ptr, buffer_size, overlapped_ptr); +dword_result_t XamContentSetThumbnail(dword_t user_index, + lpvoid_t content_data_ptr, + lpvoid_t buffer_ptr, dword_t buffer_size, + lpunknown_t overlapped_ptr) { + auto content_data = XCONTENT_DATA((uint8_t*)content_data_ptr); // Buffer is PNG data. - auto buffer = std::vector(SHIM_MEM_ADDR(buffer_ptr), - SHIM_MEM_ADDR(buffer_ptr) + buffer_size); - auto result = kernel_state->content_manager()->SetContentThumbnail( + auto buffer = std::vector((uint8_t*)buffer_ptr, + (uint8_t*)buffer_ptr + buffer_size); + auto result = kernel_state()->content_manager()->SetContentThumbnail( content_data, std::move(buffer)); if (overlapped_ptr) { - kernel_state->CompleteOverlappedImmediate(overlapped_ptr, result); - SHIM_SET_RETURN_32(X_ERROR_IO_PENDING); + kernel_state()->CompleteOverlappedImmediate(overlapped_ptr, result); + return X_ERROR_IO_PENDING; } else { - SHIM_SET_RETURN_32(result); + return result; } } +DECLARE_XAM_EXPORT1(XamContentSetThumbnail, kContent, kImplemented); -SHIM_CALL XamContentDelete_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t user_index = SHIM_GET_ARG_32(0); - uint32_t content_data_ptr = SHIM_GET_ARG_32(1); - uint32_t overlapped_ptr = SHIM_GET_ARG_32(2); +dword_result_t XamContentDelete(dword_t user_index, lpvoid_t content_data_ptr, + lpunknown_t overlapped_ptr) { + auto content_data = XCONTENT_DATA((uint8_t*)content_data_ptr); - auto content_data = XCONTENT_DATA(SHIM_MEM_ADDR(content_data_ptr)); - - XELOGD("XamContentDelete(%d, %.8X, %.8X)", user_index, content_data_ptr, - overlapped_ptr); - - auto result = kernel_state->content_manager()->DeleteContent(content_data); + auto result = kernel_state()->content_manager()->DeleteContent(content_data); if (overlapped_ptr) { - kernel_state->CompleteOverlappedImmediate(overlapped_ptr, result); - SHIM_SET_RETURN_32(X_ERROR_IO_PENDING); + kernel_state()->CompleteOverlappedImmediate(overlapped_ptr, result); + return X_ERROR_IO_PENDING; } else { - SHIM_SET_RETURN_32(result); + return result; } } +DECLARE_XAM_EXPORT1(XamContentDelete, kContent, kImplemented); void RegisterContentExports(xe::cpu::ExportResolver* export_resolver, KernelState* kernel_state) { - SHIM_SET_MAPPING("xam.xex", XamContentGetLicenseMask, state); - SHIM_SET_MAPPING("xam.xex", XamContentGetDeviceName, state); - SHIM_SET_MAPPING("xam.xex", XamContentGetDeviceState, state); - SHIM_SET_MAPPING("xam.xex", XamContentGetDeviceData, state); - SHIM_SET_MAPPING("xam.xex", XamContentResolve, state); - SHIM_SET_MAPPING("xam.xex", XamContentFlush, state); - SHIM_SET_MAPPING("xam.xex", XamContentClose, state); - SHIM_SET_MAPPING("xam.xex", XamContentGetCreator, state); - SHIM_SET_MAPPING("xam.xex", XamContentGetThumbnail, state); - SHIM_SET_MAPPING("xam.xex", XamContentSetThumbnail, state); - SHIM_SET_MAPPING("xam.xex", XamContentDelete, state); } } // namespace xam From ff0b8a67cdffa33e8c4cd18ee942956736e6181b Mon Sep 17 00:00:00 2001 From: gibbed Date: Tue, 20 Nov 2018 13:53:46 -0600 Subject: [PATCH 3/3] [Kernel] Tag XamContentGetLicenseMask as high frequency. --- src/xenia/kernel/xam/xam_content.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xenia/kernel/xam/xam_content.cc b/src/xenia/kernel/xam/xam_content.cc index 4da20c7ff..a1675fea8 100644 --- a/src/xenia/kernel/xam/xam_content.cc +++ b/src/xenia/kernel/xam/xam_content.cc @@ -48,7 +48,7 @@ dword_result_t XamContentGetLicenseMask(lpdword_t mask_ptr, return X_ERROR_SUCCESS; } } -DECLARE_XAM_EXPORT1(XamContentGetLicenseMask, kContent, kStub); +DECLARE_XAM_EXPORT2(XamContentGetLicenseMask, kContent, kStub, kHighFrequency); dword_result_t XamContentGetDeviceName(dword_t device_id, lpwstring_t name_buffer,