diff --git a/src/xenia/base/main_init_win.cc b/src/xenia/base/main_init_win.cc index 6b0a9059a..6335958d2 100644 --- a/src/xenia/base/main_init_win.cc +++ b/src/xenia/base/main_init_win.cc @@ -14,20 +14,32 @@ // Includes Windows headers, so it goes after platform_win.h. #include "third_party/xbyak/xbyak/xbyak_util.h" -class StartupAvxCheck { +class StartupCpuFeatureCheck { public: - StartupAvxCheck() { + StartupCpuFeatureCheck() { Xbyak::util::Cpu cpu; - if (cpu.has(Xbyak::util::Cpu::tAVX)) { - return; + const char* error_message = nullptr; + if (!cpu.has(Xbyak::util::Cpu::tAVX)) { + error_message = + "Your CPU does not support AVX, which is required by Xenia. See " + "the " + "FAQ for system requirements at https://xenia.jp"; + } + unsigned int data[4]; + Xbyak::util::Cpu::getCpuid(0x80000001, data); + if (!(data[2] & (1U << 8))) { + error_message = + "Your cpu does not support PrefetchW, which Xenia Canary " + "requires."; + } + if (error_message == nullptr) { + return; + } else { + // TODO(gibbed): detect app type and printf instead, if needed? + MessageBoxA(nullptr, error_message, "Xenia Error", + MB_OK | MB_ICONERROR | MB_SETFOREGROUND); + ExitProcess(static_cast(-1)); } - // TODO(gibbed): detect app type and printf instead, if needed? - MessageBoxA( - nullptr, - "Your CPU does not support AVX, which is required by Xenia. See the " - "FAQ for system requirements at https://xenia.jp", - "Xenia Error", MB_OK | MB_ICONERROR | MB_SETFOREGROUND); - ExitProcess(static_cast(-1)); } }; @@ -38,4 +50,4 @@ class StartupAvxCheck { // https://docs.microsoft.com/en-us/cpp/preprocessor/init-seg #pragma warning(suppress : 4073) #pragma init_seg(lib) -static StartupAvxCheck gStartupAvxCheck; +static StartupCpuFeatureCheck gStartupAvxCheck; \ No newline at end of file diff --git a/src/xenia/base/platform_amd64.cc b/src/xenia/base/platform_amd64.cc index c6b41ca21..48b1c6102 100644 --- a/src/xenia/base/platform_amd64.cc +++ b/src/xenia/base/platform_amd64.cc @@ -71,6 +71,13 @@ void InitFeatureFlags() { unsigned int data[4]; Xbyak::util::Cpu::getCpuid(0x80000001, data); unsigned amd_flags = data[2]; + // chrispy: do prefetchw manually, prefetchw is one of the features xbyak + // ignores if you have an amd cpu. + + if (amd_flags & (1U << 8)) { + // no mask for prefetchw + feature_flags_ |= kX64EmitPrefetchW; + } if (amd_flags & (1U << 5)) { if ((cvars::x64_extension_mask & kX64EmitLZCNT) == kX64EmitLZCNT) { feature_flags_ |= kX64EmitLZCNT; diff --git a/src/xenia/cpu/cpu_flags.cc b/src/xenia/cpu/cpu_flags.cc index 614dabae8..02c9d2b18 100644 --- a/src/xenia/cpu/cpu_flags.cc +++ b/src/xenia/cpu/cpu_flags.cc @@ -30,11 +30,6 @@ DEFINE_bool(trace_function_references, false, DEFINE_bool(trace_function_data, false, "Generate tracing for function result data.", "CPU"); -DEFINE_bool( - disable_global_lock, false, - "Disables global lock usage in guest code. Does not affect host code.", - "CPU"); - DEFINE_bool(validate_hir, false, "Perform validation checks on the HIR during compilation.", "CPU"); diff --git a/src/xenia/cpu/cpu_flags.h b/src/xenia/cpu/cpu_flags.h index 811e97756..38c4f98ba 100644 --- a/src/xenia/cpu/cpu_flags.h +++ b/src/xenia/cpu/cpu_flags.h @@ -22,8 +22,6 @@ DECLARE_bool(trace_function_coverage); DECLARE_bool(trace_function_references); DECLARE_bool(trace_function_data); -DECLARE_bool(disable_global_lock); - DECLARE_bool(validate_hir); DECLARE_uint64(pvr); diff --git a/src/xenia/cpu/ppc/ppc_frontend.cc b/src/xenia/cpu/ppc/ppc_frontend.cc index bd65919dd..b2c1094ce 100644 --- a/src/xenia/cpu/ppc/ppc_frontend.cc +++ b/src/xenia/cpu/ppc/ppc_frontend.cc @@ -11,6 +11,7 @@ #include "xenia/base/atomic.h" #include "xenia/base/logging.h" +#include "xenia/base/mutex.h" #include "xenia/cpu/ppc/ppc_context.h" #include "xenia/cpu/ppc/ppc_emit.h" #include "xenia/cpu/ppc/ppc_opcode_info.h" @@ -56,15 +57,15 @@ Memory* PPCFrontend::memory() const { return processor_->memory(); } // Checks the state of the global lock and sets scratch to the current MSR // value. void CheckGlobalLock(PPCContext* ppc_context, void* arg0, void* arg1) { - auto global_mutex = reinterpret_cast(arg0); + auto global_mutex = reinterpret_cast(arg0); auto global_lock_count = reinterpret_cast(arg1); - std::lock_guard lock(*global_mutex); + std::lock_guard lock(*global_mutex); ppc_context->scratch = *global_lock_count ? 0 : 0x8000; } // Enters the global lock. Safe to recursion. void EnterGlobalLock(PPCContext* ppc_context, void* arg0, void* arg1) { - auto global_mutex = reinterpret_cast(arg0); + auto global_mutex = reinterpret_cast(arg0); auto global_lock_count = reinterpret_cast(arg1); global_mutex->lock(); xe::atomic_inc(global_lock_count); @@ -72,7 +73,7 @@ void EnterGlobalLock(PPCContext* ppc_context, void* arg0, void* arg1) { // Leaves the global lock. Safe to recursion. void LeaveGlobalLock(PPCContext* ppc_context, void* arg0, void* arg1) { - auto global_mutex = reinterpret_cast(arg0); + auto global_mutex = reinterpret_cast(arg0); auto global_lock_count = reinterpret_cast(arg1); auto new_lock_count = xe::atomic_dec(global_lock_count); assert_true(new_lock_count >= 0); diff --git a/src/xenia/cpu/thread_state.cc b/src/xenia/cpu/thread_state.cc index 08338a0a0..6083d7e9d 100644 --- a/src/xenia/cpu/thread_state.cc +++ b/src/xenia/cpu/thread_state.cc @@ -95,6 +95,12 @@ ThreadState::ThreadState(Processor* processor, uint32_t thread_id, context_->r[1] = stack_base; context_->r[13] = pcr_address; // fixme: VSCR must be set here! + context_->msr = 0x9030; // dumped from a real 360, 0x8000 + + //this register can be used for arbitrary data according to the PPC docs + //but the suggested use is to mark which vector registers are in use, for faster save/restore + //it seems unlikely anything uses this, especially since we have way more than 32 vrs, but setting it to all ones seems closer to correct than 0 + context_->vrsave = ~0u; } ThreadState::~ThreadState() {