Minor decoder optimizations, kernel fixes, cpu backend fixes

This commit is contained in:
chss95cs@gmail.com
2022-11-05 10:50:33 -07:00
parent ba66373d8c
commit c1d922eebf
62 changed files with 1254 additions and 802 deletions

View File

@@ -421,6 +421,9 @@ X_RESULT KernelState::FinishLoadingUserModule(
emulator_->patcher()->ApplyPatchesForTitle(memory_, module->title_id(),
module->hash());
emulator_->on_patch_apply();
if (module->xex_module()) {
module->xex_module()->Precompile();
}
if (module->is_dll_module() && module->entry_point() && call_entry) {
// Call DllMain(DLL_PROCESS_ATTACH):

View File

@@ -36,7 +36,7 @@ using PPCContext = xe::cpu::ppc::PPCContext;
(xe::cpu::xe_kernel_export_shim_fn)export_name##_entry);
#define SHIM_MEM_ADDR(a) \
((a) ? ppc_context->kernel_state->memory()->TranslateVirtual(a) : nullptr)
((a) ? ppc_context->TranslateVirtual(a) : nullptr)
#define SHIM_MEM_8(a) xe::load_and_swap<uint8_t>(SHIM_MEM_ADDR(a))
#define SHIM_MEM_16(a) xe::load_and_swap<uint16_t>(SHIM_MEM_ADDR(a))
@@ -159,7 +159,7 @@ class Param {
uint32_t stack_ptr =
uint32_t(init.ppc_context->r[1]) + 0x54 + (ordinal_ - 8) * 8;
*out_value = xe::load_and_swap<V>(
init.ppc_context->kernel_state->memory()->TranslateVirtual(
init.ppc_context->TranslateVirtual(
stack_ptr));
}
}
@@ -212,7 +212,7 @@ class PointerParam : public ParamBase<uint32_t> {
PointerParam(Init& init) : ParamBase(init) {
host_ptr_ =
value_
? init.ppc_context->kernel_state->memory()->TranslateVirtual(value_)
? init.ppc_context->TranslateVirtual(value_)
: nullptr;
}
PointerParam(void* host_ptr) : ParamBase(), host_ptr_(host_ptr) {}
@@ -251,8 +251,7 @@ template <typename T>
class PrimitivePointerParam : public ParamBase<uint32_t> {
public:
PrimitivePointerParam(Init& init) : ParamBase(init) {
host_ptr_ = value_ ? init.ppc_context->kernel_state->memory()
->TranslateVirtual<xe::be<T>*>(value_)
host_ptr_ = value_ ? init.ppc_context->TranslateVirtual<xe::be<T>*>(value_)
: nullptr;
}
PrimitivePointerParam(T* host_ptr) : ParamBase() {
@@ -285,7 +284,7 @@ class StringPointerParam : public ParamBase<uint32_t> {
StringPointerParam(Init& init) : ParamBase(init) {
host_ptr_ =
value_
? init.ppc_context->kernel_state->memory()->TranslateVirtual<CHAR*>(
? init.ppc_context->TranslateVirtual<CHAR*>(
value_)
: nullptr;
}
@@ -311,7 +310,7 @@ class TypedPointerParam : public ParamBase<uint32_t> {
public:
TypedPointerParam(Init& init) : ParamBase(init) {
host_ptr_ =
value_ ? init.ppc_context->kernel_state->memory()->TranslateVirtual<T*>(
value_ ? init.ppc_context->TranslateVirtual<T*>(
value_)
: nullptr;
}

View File

@@ -195,7 +195,8 @@ void XCustomRegisterDynamicActions_entry() {
DECLARE_XAM_EXPORT1(XCustomRegisterDynamicActions, kNone, kStub);
dword_result_t XGetAVPack_entry() {
// Value from https://github.com/Free60Project/libxenon/blob/920146f/libxenon/drivers/xenos/xenos_videomodes.h
// Value from
// https://github.com/Free60Project/libxenon/blob/920146f/libxenon/drivers/xenos/xenos_videomodes.h
// DWORD
// Not sure what the values are for this, but 6 is VGA.
// Other likely values are 3/4/8 for HDMI or something.
@@ -321,11 +322,16 @@ void XamLoaderTerminateTitle_entry() {
}
DECLARE_XAM_EXPORT1(XamLoaderTerminateTitle, kNone, kSketchy);
dword_result_t XamAlloc_entry(dword_t unk, dword_t size, lpdword_t out_ptr) {
assert_true(unk == 0);
dword_result_t XamAlloc_entry(dword_t flags, dword_t size, lpdword_t out_ptr) {
if (flags & 0x00100000) { // HEAP_ZERO_memory used unless this flag
// do nothing!
// maybe we ought to fill it with nonzero garbage, but otherwise this is a
// flag we can safely ignore
}
// Allocate from the heap. Not sure why XAM does this specially, perhaps
// it keeps stuff in a separate heap?
//chrispy: there is a set of different heaps it uses, an array of them. the top 4 bits of the 32 bit flags seems to select the heap
uint32_t ptr = kernel_state()->memory()->SystemHeapAlloc(size);
*out_ptr = ptr;

View File

@@ -55,6 +55,7 @@ class XamDialog : public xe::ui::ImGuiDialog {
XamDialog(xe::ui::ImGuiDrawer* imgui_drawer)
: xe::ui::ImGuiDialog(imgui_drawer) {}
virtual ~XamDialog() {}
void OnClose() override {
if (close_callback_) {
close_callback_();
@@ -254,6 +255,7 @@ class MessageBoxDialog : public XamDialog {
Close();
}
}
virtual ~MessageBoxDialog() {}
private:
bool has_opened_ = false;
@@ -264,8 +266,7 @@ class MessageBoxDialog : public XamDialog {
uint32_t chosen_button_ = 0;
};
// https://www.se7ensins.com/forums/threads/working-xshowmessageboxui.844116/
dword_result_t XamShowMessageBoxUI_entry(
static dword_result_t XamShowMessageBoxUi(
dword_t user_index, lpu16string_t title_ptr, lpu16string_t text_ptr,
dword_t button_count, lpdword_t button_ptrs, dword_t active_button,
dword_t flags, lpdword_t result_ptr, pointer_t<XAM_OVERLAPPED> overlapped) {
@@ -321,8 +322,28 @@ dword_result_t XamShowMessageBoxUI_entry(
}
return result;
}
// https://www.se7ensins.com/forums/threads/working-xshowmessageboxui.844116/
dword_result_t XamShowMessageBoxUI_entry(
dword_t user_index, lpu16string_t title_ptr, lpu16string_t text_ptr,
dword_t button_count, lpdword_t button_ptrs, dword_t active_button,
dword_t flags, lpdword_t result_ptr, pointer_t<XAM_OVERLAPPED> overlapped) {
return XamShowMessageBoxUi(user_index, title_ptr, text_ptr, button_count,
button_ptrs, active_button, flags, result_ptr,
overlapped);
}
DECLARE_XAM_EXPORT1(XamShowMessageBoxUI, kUI, kImplemented);
dword_result_t XamShowMessageBoxUIEx_entry(
dword_t user_index, lpu16string_t title_ptr, lpu16string_t text_ptr,
dword_t button_count, lpdword_t button_ptrs, dword_t active_button,
dword_t flags, dword_t unknown_unused, lpdword_t result_ptr,
pointer_t<XAM_OVERLAPPED> overlapped) {
return XamShowMessageBoxUi(user_index, title_ptr, text_ptr, button_count,
button_ptrs, active_button, flags, result_ptr,
overlapped);
}
DECLARE_XAM_EXPORT1(XamShowMessageBoxUIEx, kUI, kImplemented);
class KeyboardInputDialog : public XamDialog {
public:
KeyboardInputDialog(xe::ui::ImGuiDrawer* imgui_drawer, std::string title,
@@ -347,6 +368,7 @@ class KeyboardInputDialog : public XamDialog {
xe::string_util::copy_truncating(text_buffer_.data(), default_text_,
text_buffer_.size());
}
virtual ~KeyboardInputDialog() {}
const std::string& text() const { return text_; }
bool cancelled() const { return cancelled_; }

View File

@@ -13,11 +13,12 @@
#include "xenia/kernel/xbdm/xbdm_private.h"
#include "xenia/kernel/xthread.h"
#include "xenia/xbox.h"
//chrispy: no idea what a real valid value is for this
static constexpr const char DmXboxName[] = "Xbox360Name";
namespace xe {
namespace kernel {
namespace kernel {
namespace xbdm {
#define XBDM_SUCCESSFULL 0x02DA0000
#define MAKE_DUMMY_STUB_PTR(x) \
dword_result_t x##_entry() { return 0; } \
DECLARE_XBDM_EXPORT1(x, kDebug, kStub)
@@ -36,11 +37,27 @@ MAKE_DUMMY_STUB_STATUS(DmFreePool);
dword_result_t DmGetXbeInfo_entry() {
// TODO(gibbed): 4D5307DC appears to expect this as success?
// Unknown arguments -- let's hope things don't explode.
return 0x02DA0000;
return XBDM_SUCCESSFULL;
}
DECLARE_XBDM_EXPORT1(DmGetXbeInfo, kDebug, kStub);
MAKE_DUMMY_STUB_STATUS(DmGetXboxName);
dword_result_t DmGetXboxName_entry(const ppc_context_t& ctx) {
uint64_t arg1 = ctx->r[3];
uint64_t arg2 = ctx->r[4];
if (!arg1 || !arg2) {
return 0x80070057;
}
char* name_out = ctx->TranslateVirtualGPR<char*>(arg1);
uint32_t* max_name_chars_ptr = ctx->TranslateVirtualGPR<uint32_t*>(arg2);
uint32_t max_name_chars = xe::load_and_swap<uint32_t>(max_name_chars_ptr);
strncpy(name_out, DmXboxName, sizeof(DmXboxName));
return XBDM_SUCCESSFULL;
}
DECLARE_XBDM_EXPORT1(DmGetXboxName, kDebug, kImplemented)
dword_result_t DmIsDebuggerPresent_entry() { return 0; }
DECLARE_XBDM_EXPORT1(DmIsDebuggerPresent, kDebug, kStub);
@@ -49,15 +66,15 @@ void DmSendNotificationString_entry(lpdword_t unk0_ptr) {}
DECLARE_XBDM_EXPORT1(DmSendNotificationString, kDebug, kStub);
dword_result_t DmRegisterCommandProcessor_entry(lpdword_t name_ptr,
lpdword_t handler_fn) {
lpdword_t handler_fn) {
// Return success to prevent some games from crashing
return X_STATUS_SUCCESS;
}
DECLARE_XBDM_EXPORT1(DmRegisterCommandProcessor, kDebug, kStub);
dword_result_t DmRegisterCommandProcessorEx_entry(lpdword_t name_ptr,
lpdword_t handler_fn,
dword_t unk3) {
lpdword_t handler_fn,
dword_t unk3) {
// Return success to prevent some games from stalling
return X_STATUS_SUCCESS;
}
@@ -65,9 +82,12 @@ DECLARE_XBDM_EXPORT1(DmRegisterCommandProcessorEx, kDebug, kStub);
MAKE_DUMMY_STUB_STATUS(DmStartProfiling);
MAKE_DUMMY_STUB_STATUS(DmStopProfiling);
dword_result_t DmCaptureStackBackTrace_entry(lpdword_t unk0_ptr,
lpdword_t unk1_ptr) {
// two arguments, first is num frames i think, second is some kind of pointer to
// where to capture
dword_result_t DmCaptureStackBackTrace_entry(const ppc_context_t& ctx) {
uint32_t nframes = static_cast<uint32_t>(ctx->r[3]);
uint8_t* unknown_addr =
ctx->TranslateVirtual(static_cast<uint32_t>(ctx->r[4]));
return X_STATUS_INVALID_PARAMETER;
}
DECLARE_XBDM_EXPORT1(DmCaptureStackBackTrace, kDebug, kStub);
@@ -82,7 +102,10 @@ dword_result_t DmWalkLoadedModules_entry(lpdword_t unk0_ptr,
}
DECLARE_XBDM_EXPORT1(DmWalkLoadedModules, kDebug, kStub);
void DmMapDevkitDrive_entry() {}
void DmMapDevkitDrive_entry(const ppc_context_t& ctx) {
// games check for nonzero result, failure if nz
ctx->r[3] = 0ULL;
}
DECLARE_XBDM_EXPORT1(DmMapDevkitDrive, kDebug, kStub);
dword_result_t DmFindPdbSignature_entry(lpdword_t unk0_ptr,

View File

@@ -28,7 +28,11 @@
namespace xe {
namespace kernel {
namespace xboxkrnl {
struct X_STRING {
unsigned short length;
unsigned short pad;
uint32_t ptr;
};
// https://msdn.microsoft.com/en-us/library/ff561778
dword_result_t RtlCompareMemory_entry(lpvoid_t source1, lpvoid_t source2,
dword_t length) {
@@ -142,38 +146,80 @@ dword_result_t RtlLowerChar_entry(dword_t in) {
}
DECLARE_XBOXKRNL_EXPORT1(RtlLowerChar, kNone, kImplemented);
dword_result_t RtlCompareString_entry(lpstring_t string_1, lpstring_t string_2,
dword_t case_insensitive) {
int ret = case_insensitive ? xe_strcasecmp(string_1, string_2)
: std::strcmp(string_1, string_2);
return ret;
static int RtlCompareStringN_impl(uint8_t* string_1, unsigned int string_1_len,
uint8_t* string_2, unsigned int string_2_len,
int case_insensitive) {
if (string_1_len == 0xFFFFFFFF) {
uint8_t* string1_strlen_iter = string_1;
while (*string1_strlen_iter++)
;
string_1_len =
static_cast<unsigned int>(string1_strlen_iter - string_1 - 1);
}
if (string_2_len == 0xFFFFFFFF) {
uint8_t* string2_strlen_iter = string_2;
while (*string2_strlen_iter++)
;
string_2_len =
static_cast<unsigned int>(string2_strlen_iter - string_2 - 1);
}
uint8_t* string1_end = &string_1[std::min(string_2_len, string_1_len)];
if (case_insensitive) {
while (string_1 < string1_end) {
unsigned c1 = *string_1++;
unsigned c2 = *string_2++;
if (c1 != c2) {
unsigned cu1 = rtl_upper_table[c1];
unsigned cu2 = rtl_upper_table[c2];
if (cu1 != cu2) {
return cu1 - cu2;
}
}
}
} else {
while (string_1 < string1_end) {
unsigned c1 = *string_1++;
unsigned c2 = *string_2++;
if (c1 != c2) {
return c1 - c2;
}
}
}
// why? not sure, but its the original logic
return string_1_len - string_2_len;
}
DECLARE_XBOXKRNL_EXPORT1(RtlCompareString, kNone, kImplemented);
dword_result_t RtlCompareStringN_entry(lpstring_t string_1,
dword_t string_1_len,
lpstring_t string_2,
dword_t string_2_len,
dword_t case_insensitive) {
uint32_t len1 = string_1_len;
uint32_t len2 = string_2_len;
if (string_1_len == 0xFFFF) {
len1 = uint32_t(std::strlen(string_1));
}
if (string_2_len == 0xFFFF) {
len2 = uint32_t(std::strlen(string_2));
}
auto len = std::min(string_1_len, string_2_len);
int ret = case_insensitive ? xe_strncasecmp(string_1, string_2, len)
: std::strncmp(string_1, string_2, len);
return ret;
return RtlCompareStringN_impl(
reinterpret_cast<uint8_t*>(string_1.host_address()), string_1_len,
reinterpret_cast<uint8_t*>(string_2.host_address()), string_2_len,
case_insensitive);
}
DECLARE_XBOXKRNL_EXPORT1(RtlCompareStringN, kNone, kImplemented);
dword_result_t RtlCompareString_entry(lpvoid_t string_1, lpvoid_t string_2,
dword_t case_insensitive) {
X_STRING* xs1 = string_1.as<X_STRING*>();
X_STRING* xs2 = string_2.as<X_STRING*>();
unsigned length_1 = xe::load_and_swap<uint16_t>(&xs1->length);
unsigned length_2 = xe::load_and_swap<uint16_t>(&xs2->length);
uint32_t ptr_1 = xe::load_and_swap<uint32_t>(&xs1->ptr);
uint32_t ptr_2 = xe::load_and_swap<uint32_t>(&xs2->ptr);
auto kmem = kernel_memory();
return RtlCompareStringN_impl(
kmem->TranslateVirtual<uint8_t*>(ptr_1), length_1,
kmem->TranslateVirtual<uint8_t*>(ptr_2), length_2, case_insensitive);
}
DECLARE_XBOXKRNL_EXPORT1(RtlCompareString, kNone, kImplemented);
// https://msdn.microsoft.com/en-us/library/ff561918
void RtlInitAnsiString_entry(pointer_t<X_ANSI_STRING> destination,
lpstring_t source) {
@@ -188,13 +234,13 @@ void RtlInitAnsiString_entry(pointer_t<X_ANSI_STRING> destination,
destination->pointer = source.guest_address();
}
DECLARE_XBOXKRNL_EXPORT1(RtlInitAnsiString, kNone, kImplemented);
//https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-rtlupcaseunicodechar
// https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-rtlupcaseunicodechar
dword_result_t RtlUpcaseUnicodeChar_entry(dword_t SourceCharacter) {
return std::use_facet<std::ctype<char16_t>>(std::locale()).toupper(SourceCharacter);
return std::use_facet<std::ctype<char16_t>>(std::locale())
.toupper(SourceCharacter);
}
DECLARE_XBOXKRNL_EXPORT1(RtlUpcaseUnicodeChar, kNone, kImplemented);
// https://msdn.microsoft.com/en-us/library/ff561899
void RtlFreeAnsiString_entry(pointer_t<X_ANSI_STRING> string) {
if (string->pointer) {
@@ -206,8 +252,8 @@ void RtlFreeAnsiString_entry(pointer_t<X_ANSI_STRING> string) {
DECLARE_XBOXKRNL_EXPORT1(RtlFreeAnsiString, kNone, kImplemented);
// https://msdn.microsoft.com/en-us/library/ff561934
void RtlInitUnicodeString_entry(pointer_t<X_UNICODE_STRING> destination,
lpu16string_t source) {
pointer_result_t RtlInitUnicodeString_entry(
pointer_t<X_UNICODE_STRING> destination, lpu16string_t source) {
if (source) {
destination->length = (uint16_t)source.value().size() * 2;
destination->maximum_length = (uint16_t)(source.value().size() + 1) * 2;
@@ -215,6 +261,7 @@ void RtlInitUnicodeString_entry(pointer_t<X_UNICODE_STRING> destination,
} else {
destination->reset();
}
return destination.guest_address();
}
DECLARE_XBOXKRNL_EXPORT1(RtlInitUnicodeString, kNone, kImplemented);
@@ -671,6 +718,26 @@ dword_result_t RtlComputeCrc32_entry(dword_t seed, lpvoid_t buffer,
}
DECLARE_XBOXKRNL_EXPORT1(RtlComputeCrc32, kNone, kImplemented);
static void RtlRip_entry(const ppc_context_t& ctx) {
uint32_t arg1 = static_cast<uint32_t>(ctx->r[3]);
uint32_t arg2 = static_cast<uint32_t>(ctx->r[4]);
const char* msg_str1 = "";
const char* msg_str2 = "";
if (arg1) {
msg_str1 = ctx->TranslateVirtual<const char*>(arg1);
}
if (arg2) {
msg_str2 = ctx->TranslateVirtual<const char*>(arg2);
}
XELOGE("RtlRip called, arg1 = {}, arg2 = {}\n", msg_str1, msg_str2);
//we should break here... not sure what to do exactly
}
DECLARE_XBOXKRNL_EXPORT1(RtlRip, kNone, kImportant);
} // namespace xboxkrnl
} // namespace kernel
} // namespace xe

View File

@@ -9,7 +9,6 @@
#include <algorithm>
#include <vector>
#include "xenia/base/atomic.h"
#include "xenia/base/clock.h"
#include "xenia/base/logging.h"
@@ -913,7 +912,7 @@ dword_result_t NtWaitForMultipleObjectsEx_entry(
dword_t count, lpdword_t handles, dword_t wait_type, dword_t wait_mode,
dword_t alertable, lpqword_t timeout_ptr) {
uint64_t timeout = timeout_ptr ? static_cast<uint64_t>(*timeout_ptr) : 0u;
if (!count || count > 64 || wait_type != 1 && wait_type) {
if (!count || count > 64 || (wait_type != 1 && wait_type)) {
return X_STATUS_INVALID_PARAMETER;
}
return xeNtWaitForMultipleObjectsEx(count, handles, wait_type, wait_mode,
@@ -964,7 +963,7 @@ uint32_t xeKeKfAcquireSpinLock(uint32_t* lock, uint64_t r13 = 1) {
PrefetchForCAS(lock);
assert_true(*lock != static_cast<uint32_t>(r13));
// Lock.
while (!xe::atomic_cas(0, static_cast<uint32_t>(r13), lock)) {
while (!xe::atomic_cas(0, xe::byte_swap(static_cast<uint32_t>(r13)), lock)) {
// Spin!
// TODO(benvanik): error on deadlock?
xe::threading::MaybeYield();
@@ -978,7 +977,7 @@ uint32_t xeKeKfAcquireSpinLock(uint32_t* lock, uint64_t r13 = 1) {
}
dword_result_t KfAcquireSpinLock_entry(lpdword_t lock_ptr,
ppc_context_t& ppc_context) {
const ppc_context_t& ppc_context) {
auto lock = reinterpret_cast<uint32_t*>(lock_ptr.host_address());
return xeKeKfAcquireSpinLock(lock, ppc_context->r[13]);
}
@@ -997,9 +996,7 @@ void xeKeKfReleaseSpinLock(uint32_t* lock, dword_t old_irql) {
}
void KfReleaseSpinLock_entry(lpdword_t lock_ptr, dword_t old_irql,
ppc_context_t& ppc_ctx) {
auto lock = reinterpret_cast<uint32_t*>(lock_ptr.host_address());
const ppc_context_t& ppc_ctx) {
assert_true(*lock_ptr == static_cast<uint32_t>(ppc_ctx->r[13]));
*lock_ptr = 0;
@@ -1014,14 +1011,14 @@ DECLARE_XBOXKRNL_EXPORT2(KfReleaseSpinLock, kThreading, kImplemented,
kHighFrequency);
// todo: this is not accurate
void KeAcquireSpinLockAtRaisedIrql_entry(lpdword_t lock_ptr,
ppc_context_t& ppc_ctx) {
const ppc_context_t& ppc_ctx) {
// Lock.
auto lock = reinterpret_cast<uint32_t*>(lock_ptr.host_address());
// must not be our own thread
assert_true(*lock_ptr != static_cast<uint32_t>(ppc_ctx->r[13]));
PrefetchForCAS(lock);
while (!xe::atomic_cas(0, static_cast<uint32_t>(ppc_ctx->r[13]), lock)) {
while (!xe::atomic_cas(0, xe::byte_swap(static_cast<uint32_t>(ppc_ctx->r[13])), lock)) {
#if XE_ARCH_AMD64 == 1
// todo: this is just a nop if they don't have SMT, which is not great
// either...
@@ -1036,12 +1033,12 @@ DECLARE_XBOXKRNL_EXPORT3(KeAcquireSpinLockAtRaisedIrql, kThreading,
kImplemented, kBlocking, kHighFrequency);
dword_result_t KeTryToAcquireSpinLockAtRaisedIrql_entry(
lpdword_t lock_ptr, ppc_context_t& ppc_ctx) {
lpdword_t lock_ptr, const ppc_context_t& ppc_ctx) {
// Lock.
auto lock = reinterpret_cast<uint32_t*>(lock_ptr.host_address());
assert_true(*lock_ptr != static_cast<uint32_t>(ppc_ctx->r[13]));
PrefetchForCAS(lock);
if (!xe::atomic_cas(0, static_cast<uint32_t>(ppc_ctx->r[13]), lock)) {
if (!xe::atomic_cas(0, xe::byte_swap(static_cast<uint32_t>(ppc_ctx->r[13])), lock)) {
return 0;
}
return 1;
@@ -1050,10 +1047,9 @@ DECLARE_XBOXKRNL_EXPORT4(KeTryToAcquireSpinLockAtRaisedIrql, kThreading,
kImplemented, kBlocking, kHighFrequency, kSketchy);
void KeReleaseSpinLockFromRaisedIrql_entry(lpdword_t lock_ptr,
ppc_context_t& ppc_ctx) {
const ppc_context_t& ppc_ctx) {
// Unlock.
assert_true(*lock_ptr == static_cast<uint32_t>(ppc_ctx->r[13]));
auto lock = reinterpret_cast<uint32_t*>(lock_ptr.host_address());
*lock_ptr = 0;
}
DECLARE_XBOXKRNL_EXPORT2(KeReleaseSpinLockFromRaisedIrql, kThreading,
@@ -1283,7 +1279,8 @@ void ExInitializeReadWriteLock_entry(pointer_t<X_ERWLOCK> lock_ptr) {
}
DECLARE_XBOXKRNL_EXPORT1(ExInitializeReadWriteLock, kThreading, kImplemented);
void ExAcquireReadWriteLockExclusive_entry(pointer_t<X_ERWLOCK> lock_ptr, ppc_context_t& ppc_context) {
void ExAcquireReadWriteLockExclusive_entry(pointer_t<X_ERWLOCK> lock_ptr,
const ppc_context_t& ppc_context) {
auto old_irql = xeKeKfAcquireSpinLock(&lock_ptr->spin_lock, ppc_context->r[13]);
int32_t lock_count = ++lock_ptr->lock_count;
@@ -1301,7 +1298,7 @@ DECLARE_XBOXKRNL_EXPORT2(ExAcquireReadWriteLockExclusive, kThreading,
kImplemented, kBlocking);
dword_result_t ExTryToAcquireReadWriteLockExclusive_entry(
pointer_t<X_ERWLOCK> lock_ptr, ppc_context_t& ppc_context) {
pointer_t<X_ERWLOCK> lock_ptr, const ppc_context_t& ppc_context) {
auto old_irql =
xeKeKfAcquireSpinLock(&lock_ptr->spin_lock, ppc_context->r[13]);
@@ -1320,7 +1317,7 @@ DECLARE_XBOXKRNL_EXPORT1(ExTryToAcquireReadWriteLockExclusive, kThreading,
kImplemented);
void ExAcquireReadWriteLockShared_entry(pointer_t<X_ERWLOCK> lock_ptr,
ppc_context_t& ppc_context) {
const ppc_context_t& ppc_context) {
auto old_irql = xeKeKfAcquireSpinLock(&lock_ptr->spin_lock, ppc_context->r[13]);
int32_t lock_count = ++lock_ptr->lock_count;
@@ -1340,7 +1337,7 @@ DECLARE_XBOXKRNL_EXPORT2(ExAcquireReadWriteLockShared, kThreading, kImplemented,
kBlocking);
dword_result_t ExTryToAcquireReadWriteLockShared_entry(
pointer_t<X_ERWLOCK> lock_ptr, ppc_context_t& ppc_context) {
pointer_t<X_ERWLOCK> lock_ptr, const ppc_context_t& ppc_context) {
auto old_irql =
xeKeKfAcquireSpinLock(&lock_ptr->spin_lock, ppc_context->r[13]);
@@ -1361,7 +1358,7 @@ DECLARE_XBOXKRNL_EXPORT1(ExTryToAcquireReadWriteLockShared, kThreading,
kImplemented);
void ExReleaseReadWriteLock_entry(pointer_t<X_ERWLOCK> lock_ptr,
ppc_context_t& ppc_context) {
const ppc_context_t& ppc_context) {
auto old_irql =
xeKeKfAcquireSpinLock(&lock_ptr->spin_lock, ppc_context->r[13]);
@@ -1404,7 +1401,7 @@ pointer_result_t InterlockedPushEntrySList_entry(
assert_not_null(entry);
alignas(8) X_SLIST_HEADER old_hdr = *plist_ptr;
alignas(8) X_SLIST_HEADER new_hdr = {0};
alignas(8) X_SLIST_HEADER new_hdr = {{0}, 0, 0};
uint32_t old_head = 0;
do {
old_hdr = *plist_ptr;
@@ -1428,8 +1425,8 @@ pointer_result_t InterlockedPopEntrySList_entry(
assert_not_null(plist_ptr);
uint32_t popped = 0;
alignas(8) X_SLIST_HEADER old_hdr = {0};
alignas(8) X_SLIST_HEADER new_hdr = {0};
alignas(8) X_SLIST_HEADER old_hdr = {{0}, 0, 0};
alignas(8) X_SLIST_HEADER new_hdr = {{0}, 0, 0};
do {
old_hdr = *plist_ptr;
auto next = kernel_memory()->TranslateVirtual<X_SINGLE_LIST_ENTRY*>(
@@ -1456,7 +1453,7 @@ pointer_result_t InterlockedFlushSList_entry(
assert_not_null(plist_ptr);
alignas(8) X_SLIST_HEADER old_hdr = *plist_ptr;
alignas(8) X_SLIST_HEADER new_hdr = {0};
alignas(8) X_SLIST_HEADER new_hdr = {{0}, 0, 0};
uint32_t first = 0;
do {
old_hdr = *plist_ptr;

View File

@@ -433,7 +433,7 @@ void VdSwap_entry(
return;
}
gpu_fetch.base_address = frontbuffer_physical_address >> 12;
XE_MAYBE_UNUSED
auto texture_format = gpu::xenos::TextureFormat(texture_format_ptr.value());
auto color_space = *color_space_ptr;
assert_true(texture_format == gpu::xenos::TextureFormat::k_8_8_8_8 ||

View File

@@ -41,8 +41,7 @@ struct XAPC {
// KAPC is 0x28(40) bytes? (what's passed to ExAllocatePoolWithTag)
// This is 4b shorter than NT - looks like the reserved dword at +4 is gone.
// NOTE: stored in guest memory.
uint8_t type; // +0
uint8_t unk1; // +1
uint16_t type; // +0
uint8_t processor_mode; // +2
uint8_t enqueued; // +3
xe::be<uint32_t> thread_ptr; // +4
@@ -57,7 +56,6 @@ struct XAPC {
void Initialize() {
type = 18; // ApcObject
unk1 = 0;
processor_mode = 0;
enqueued = 0;
thread_ptr = 0;