Merge pull request #147 from chrisps/canary_experimental

setup initial value of MSR on ppc context
This commit is contained in:
chrisps 2023-04-02 08:36:48 -04:00 committed by GitHub
commit e9d1e51c32
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 42 additions and 23 deletions

View File

@ -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<uint32_t>(-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<uint32_t>(-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;

View File

@ -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;

View File

@ -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");

View File

@ -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);

View File

@ -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<std::recursive_mutex*>(arg0);
auto global_mutex = reinterpret_cast<xe_global_mutex*>(arg0);
auto global_lock_count = reinterpret_cast<int32_t*>(arg1);
std::lock_guard<std::recursive_mutex> lock(*global_mutex);
std::lock_guard<xe_global_mutex> 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<std::recursive_mutex*>(arg0);
auto global_mutex = reinterpret_cast<xe_global_mutex*>(arg0);
auto global_lock_count = reinterpret_cast<int32_t*>(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<std::recursive_mutex*>(arg0);
auto global_mutex = reinterpret_cast<xe_global_mutex*>(arg0);
auto global_lock_count = reinterpret_cast<int32_t*>(arg1);
auto new_lock_count = xe::atomic_dec(global_lock_count);
assert_true(new_lock_count >= 0);

View File

@ -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() {