Get for cpu module starting to work

This commit is contained in:
N3xoX1 2025-02-09 16:36:52 +10:30
parent ef51c91dfb
commit bafbfa623b
22 changed files with 2376 additions and 27 deletions

View File

@ -27,6 +27,7 @@
<ClInclude Include="dynamic_library.h" />
<ClInclude Include="file.h" />
<ClInclude Include="json.h" />
<ClInclude Include="maths.h" />
<ClInclude Include="padding.h" />
<ClInclude Include="path.h" />
<ClInclude Include="sha256.h" />
@ -36,6 +37,7 @@
<ClCompile Include="dynamic_library.cpp" />
<ClCompile Include="file.cpp" />
<ClCompile Include="json.cpp" />
<ClCompile Include="maths.cpp" />
<ClCompile Include="path.cpp" />
<ClCompile Include="sha256.cpp" />
<ClCompile Include="std_string.cpp" />

View File

@ -36,6 +36,9 @@
<ClInclude Include="padding.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="maths.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="file.cpp">
@ -56,5 +59,8 @@
<ClCompile Include="dynamic_library.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="maths.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

171
src/common/maths.cpp Normal file
View File

@ -0,0 +1,171 @@
#include "maths.h"
#include <intrin.h>
uint32_t clz32(uint32_t val)
{
#if defined(__GNUC__)
return val ? __builtin_clz(val) : 32;
#else
/* Binary search for the leading one bit. */
int cnt = 0;
if ((val & 0xFFFF0000U) == 0)
{
cnt += 16;
val <<= 16;
}
if ((val & 0xFF000000U) == 0)
{
cnt += 8;
val <<= 8;
}
if ((val & 0xF0000000U) == 0)
{
cnt += 4;
val <<= 4;
}
if ((val & 0xC0000000U) == 0)
{
cnt += 2;
val <<= 2;
}
if ((val & 0x80000000U) == 0)
{
cnt++;
val <<= 1;
}
if ((val & 0x80000000U) == 0)
{
cnt++;
}
return cnt;
#endif
}
uint32_t clz64(uint64_t val)
{
#if defined(__GNUC__)
return val ? __builtin_clzll(val) : 64;
#else
int cnt = 0;
if ((val >> 32) == 0)
{
cnt += 32;
}
else
{
val >>= 32;
}
return cnt + clz32((uint32_t)val);
#endif
}
uint64_t mull128_u64(uint64_t multiplier, uint64_t multiplicand, uint64_t * high)
{
#if defined(_MSC_VER)
return _umul128(multiplier, multiplicand, high);
#else
// multiplier = ab = a * 2^32 + b
// multiplicand = cd = c * 2^32 + d
// ab * cd = a * c * 2^64 + (a * d + b * c) * 2^32 + b * d
uint64_t a = multiplier >> 32;
uint64_t b = (uint32_t)multiplier; // & 0xFFFFFFFF;
uint64_t c = multiplicand >> 32;
uint64_t d = (uint32_t)multiplicand; // & 0xFFFFFFFF;
uint64_t ad = __emulu(a, d);
uint64_t bd = __emulu(b, d);
uint64_t adbc = ad + __emulu(b, c);
uint64_t adbc_carry = (adbc < ad); // ? 1 : 0;
// multiplier * multiplicand = product_hi * 2^64 + product_lo
uint64_t product_lo = bd + (adbc << 32);
uint64_t product_lo_carry = (product_lo < bd); // ? 1 : 0;
*high = __emulu(a, c) + (adbc >> 32) + (adbc_carry << 32) + product_lo_carry;
return product_lo;
#endif
}
uint64_t div128_to_64(uint64_t u1, uint64_t u0, uint64_t v, uint64_t * r)
{
const uint64_t b = (1ULL << 32); // Number base (32 bits)
uint64_t un1, un0; // Norm. dividend LSD's
uint64_t vn1, vn0; // Norm. divisor digits
uint64_t q1, q0; // Quotient digits
uint64_t un64, un21, un10; // Dividend digit pairs
uint64_t rhat; // A remainder
int32_t s; // Shift amount for norm
// If overflow, set rem. to an impossible value,
// and return the largest possible quotient
if (u1 >= v)
{
*r = (uint64_t)-1;
return (uint64_t)-1;
}
// count leading zeros
s = clz64(v);
if (s > 0)
{
// Normalize divisor
v = v << s;
un64 = (u1 << s) | (u0 >> (64 - s));
un10 = u0 << s; // Shift dividend left
}
else
{
// Avoid undefined behavior of (u0 >> 64).
// The behavior is undefined if the right operand is
// negative, or greater than or equal to the length
// in bits of the promoted left operand.
un64 = u1;
un10 = u0;
}
// Break divisor up into two 32-bit digits
vn1 = v >> 32;
vn0 = v & 0xFFFFFFFF;
// Break right half of dividend into two digits
un1 = un10 >> 32;
un0 = un10 & 0xFFFFFFFF;
// Compute the first quotient digit, q1
q1 = un64 / vn1;
rhat = un64 - q1 * vn1;
while (q1 >= b || q1 * vn0 > b * rhat + un1)
{
q1 = q1 - 1;
rhat = rhat + vn1;
if (rhat >= b)
{
break;
}
}
// Multiply and subtract
un21 = un64 * b + un1 - q1 * v;
// Compute the second quotient digit
q0 = un21 / vn1;
rhat = un21 - q0 * vn1;
while (q0 >= b || q0 * vn0 > b * rhat + un0)
{
q0 = q0 - 1;
rhat = rhat + vn1;
if (rhat >= b)
{
break;
}
}
*r = (un21 * b + un0 - q0 * v) >> s;
return q1 * b + q0;
}

5
src/common/maths.h Normal file
View File

@ -0,0 +1,5 @@
#pragma once
#include <stdint.h>
uint64_t mull128_u64(uint64_t x, uint64_t y, uint64_t * high);
uint64_t div128_to_64(uint64_t u1, uint64_t u0, uint64_t v, uint64_t * r);

View File

@ -260,7 +260,7 @@ constexpr uint32_t Nro::PageAlignSize(uint32_t size)
{
pageBits = 12,
pageSize = 1ULL << pageBits,
pageMask = pageSize,
pageMask = pageSize - 1,
};
return ((size + pageMask) & ~pageMask);
}

View File

@ -0,0 +1,158 @@
#include "arm64_registers.h"
#include "dynarmic/interface/A64/a64.h"
extern IModuleNotification * g_notify;
A64Registers::A64Registers() :
m_tpidr_el0(0),
m_tpidrro_el0(0),
m_jit(nullptr)
{
}
uint32_t A64Registers::Get32(IArm64Reg::Reg reg)
{
if (reg >= IArm64Reg::Reg::W0 && reg <= IArm64Reg::Reg::W30)
{
return (uint32_t)m_jit->GetRegister((uint32_t)reg - (uint32_t)IArm64Reg::Reg::W0);
}
if (reg == IArm64Reg::Reg::WZR)
{
return 0;
}
if (reg >= IArm64Reg::Reg::PSTATE)
{
return m_jit->GetPstate();
}
g_notify->BreakPoint(__FILE__, __LINE__);
return 0;
}
uint64_t A64Registers::Get64(IArm64Reg::Reg reg)
{
if (reg >= IArm64Reg::Reg::X0 && reg <= IArm64Reg::Reg::X30)
{
return m_jit->GetRegister((uint32_t)reg - (uint32_t)IArm64Reg::Reg::X0);
}
if (reg == IArm64Reg::Reg::SP)
{
return m_jit->GetSP();
}
if (reg == IArm64Reg::Reg::XZR)
{
return 0;
}
if (reg == IArm64Reg::Reg::PC)
{
return m_jit->GetPC();
}
if (reg == IArm64Reg::Reg::TPIDR_EL0)
{
return m_tpidr_el0;
}
if (reg == IArm64Reg::Reg::TPIDRRO_EL0)
{
return m_tpidrro_el0;
}
g_notify->BreakPoint(__FILE__, __LINE__);
return 0;
}
void A64Registers::Get128(IArm64Reg::Reg reg, uint64_t & hiValue, uint64_t & loValue)
{
if (reg >= IArm64Reg::Reg::Q0 && reg <= IArm64Reg::Reg::Q31)
{
Dynarmic::A64::Vector v = m_jit->GetVector(((uint32_t)reg - (uint32_t)IArm64Reg::Reg::Q0));
hiValue = v[0];
loValue = v[1];
}
else
{
g_notify->BreakPoint(__FILE__, __LINE__);
}
}
void A64Registers::Set32(IArm64Reg::Reg reg, uint32_t value)
{
if (reg >= IArm64Reg::Reg::W0 && reg <= IArm64Reg::Reg::W30)
{
m_jit->SetRegister((uint32_t)reg - (uint32_t)IArm64Reg::Reg::W0, value);
}
else if (reg == IArm64Reg::Reg::PSTATE)
{
m_jit->SetPstate(value);
}
else
{
g_notify->BreakPoint(__FILE__, __LINE__);
}
}
void A64Registers::Set64(IArm64Reg::Reg reg, uint64_t value)
{
if (reg >= IArm64Reg::Reg::X0 && reg <= IArm64Reg::Reg::X30)
{
m_jit->SetRegister((uint32_t)reg - (uint32_t)IArm64Reg::Reg::X0, value);
}
else if (reg == IArm64Reg::Reg::SP)
{
m_jit->SetSP(value);
}
else if (reg == IArm64Reg::Reg::PC)
{
m_jit->SetPC(value);
}
else if (reg == IArm64Reg::Reg::TPIDRRO_EL0)
{
m_tpidrro_el0 = value;
}
else if (reg == IArm64Reg::Reg::TPIDR_EL0)
{
m_tpidr_el0 = value;
}
else
{
g_notify->BreakPoint(__FILE__, __LINE__);
}
}
void A64Registers::Set128(IArm64Reg::Reg reg, uint64_t hiValue, uint64_t loValue)
{
if (reg >= IArm64Reg::Reg::Q0 && reg <= IArm64Reg::Reg::Q31)
{
m_jit->SetVector(((uint32_t)reg - (uint32_t)IArm64Reg::Reg::Q0), {hiValue, loValue});
}
else if (reg >= IArm64Reg::Reg::V0 && reg <= IArm64Reg::Reg::V31)
{
m_jit->SetVector(((uint32_t)reg - (uint32_t)IArm64Reg::Reg::V0), {hiValue, loValue});
}
else
{
g_notify->BreakPoint(__FILE__, __LINE__);
}
}
void A64Registers::SetFPCR(uint32_t value)
{
m_jit->SetFpcr(value);
}
void A64Registers::SetFPSR(uint32_t value)
{
m_jit->SetFpsr(value);
}
uint32_t A64Registers::GetFPCR() const
{
return m_jit->GetFpcr();
}
uint32_t A64Registers::GetFPSR() const
{
return m_jit->GetFpsr();
}
void A64Registers::SetJit(Dynarmic::A64::Jit * jit)
{
m_jit = jit;
}

View File

@ -0,0 +1,43 @@
#pragma once
#include <nxemu-module-spec/cpu.h>
class ArmDynarmic64;
namespace Dynarmic::A64
{
class Jit;
}
class A64Registers :
public IArm64Reg
{
friend ArmDynarmic64;
public:
A64Registers();
uint32_t Get32(IArm64Reg::Reg reg);
uint64_t Get64(IArm64Reg::Reg reg);
void Get128(IArm64Reg::Reg reg, uint64_t & hiValue, uint64_t & loValue);
uint32_t GetFPCR() const;
uint32_t GetFPSR() const;
void Set32(IArm64Reg::Reg reg, uint32_t value);
void Set64(IArm64Reg::Reg reg, uint64_t value);
void Set128(IArm64Reg::Reg reg, uint64_t hiValue, uint64_t loValue);
void SetFPCR(uint32_t value);
void SetFPSR(uint32_t value);
void SetJit(Dynarmic::A64::Jit * jit);
private:
A64Registers(const A64Registers&) = delete;
A64Registers& operator=(const A64Registers&) = delete;
Dynarmic::A64::Jit * m_jit;
//CP15
uint64_t m_tpidr_el0; /* User RW Thread register. */
uint64_t m_tpidrro_el0; /* User RO Thread register. */
};

View File

@ -0,0 +1,246 @@
#include "arm_dynarmic_64.h"
#include "dynarmic/interface/exclusive_monitor.h"
#include <common/maths.h>
extern IModuleNotification * g_notify;
ArmDynarmic64::ArmDynarmic64(Dynarmic::ExclusiveMonitor * monitor, ISwitchSystem & System, ICpuInfo & CpuInfo, uint32_t coreIndex) :
m_jit(nullptr),
m_system(System),
m_CpuInfo(CpuInfo),
m_OperatingSystem(System.OperatingSystem()),
m_monitor(monitor),
m_coreIndex(coreIndex)
{
m_jit = MakeJit(monitor);
m_reg.SetJit(m_jit.get());
}
IArm64Executor::HaltReason ArmDynarmic64::Execute()
{
m_jit->ClearExclusiveState();
Dynarmic::HaltReason Reason = m_jit->Run();
switch (Reason)
{
case Dynarmic::HaltReason::UserDefined3: return IArm64Executor::HaltReason::SupervisorCall;
}
g_notify->BreakPoint(__FILE__, __LINE__);
return HaltReason::Stopped;
}
void ArmDynarmic64::InvalidateCacheRange(uint64_t addr, uint64_t size)
{
m_jit->InvalidateCacheRange(addr, size);
}
void ArmDynarmic64::HaltExecution(HaltReason hr)
{
switch (hr)
{
case HaltReason::SupervisorCall: m_jit->HaltExecution(Dynarmic::HaltReason::UserDefined3); break;
default:
g_notify->BreakPoint(__FILE__, __LINE__);
}
}
std::unique_ptr<Dynarmic::A64::Jit> ArmDynarmic64::MakeJit(Dynarmic::ExclusiveMonitor * monitor)
{
Dynarmic::A64::UserConfig config;
config.callbacks = this;
config.page_table = nullptr; // reinterpret_cast<void **>(page_table->pointers.data());
config.page_table_address_space_bits = 27; //address_space_bits;
config.page_table_pointer_mask_bits = 2; // Common::PageTable::ATTRIBUTE_BITS;
config.silently_mirror_page_table = false;
config.absolute_offset_page_table = true;
config.detect_misaligned_access_via_page_table = 16 | 32 | 64 | 128;
config.only_detect_misalignment_via_page_table_on_page_boundary = true;
config.fastmem_pointer = nullptr; //page_table->fastmem_arena;
config.fastmem_address_space_bits = 27; //address_space_bits;
config.silently_mirror_fastmem = false;
config.fastmem_exclusive_access = config.fastmem_pointer != nullptr;
config.recompile_on_exclusive_fastmem_failure = true;
config.processor_id = m_coreIndex;
config.global_monitor = monitor;
// System registers
config.tpidrro_el0 = &m_reg.m_tpidrro_el0;
config.tpidr_el0 = &m_reg.m_tpidr_el0;
config.dczid_el0 = 4;
config.ctr_el0 = 0x8444c004;
config.cntfrq_el0 = 0x124f800; //Hardware::CNTFREQ;
// Unpredictable instructions
config.define_unpredictable_behaviour = true;
// Timing
config.wall_clock_cntpct = true; //m_uses_wall_clock;
config.enable_cycle_counting = false; //!m_uses_wall_clock;
// Code cache size
config.code_cache_size = 0x20000000;
return std::make_unique<Dynarmic::A64::Jit>(config);
}
std::uint8_t ArmDynarmic64::MemoryRead8(std::uint64_t vaddr)
{
uint8_t Value;
if (m_CpuInfo.ReadMemory(vaddr, (uint8_t *)&Value, sizeof(Value)))
{
return Value;
}
return 0;
}
std::uint16_t ArmDynarmic64::MemoryRead16(std::uint64_t vaddr)
{
uint16_t Value;
if (m_CpuInfo.ReadMemory(vaddr, (uint8_t *)&Value, sizeof(Value)))
{
return Value;
}
return 0;
}
std::uint32_t ArmDynarmic64::MemoryRead32(std::uint64_t vaddr)
{
uint32_t Value;
if (m_CpuInfo.ReadMemory(vaddr, (uint8_t *)&Value, sizeof(Value)))
{
return Value;
}
return 0;
}
std::uint64_t ArmDynarmic64::MemoryRead64(std::uint64_t vaddr)
{
uint64_t Value;
if (m_CpuInfo.ReadMemory(vaddr, (uint8_t *)&Value, sizeof(Value)))
{
return Value;
}
return 0;
}
Dynarmic::A64::Vector ArmDynarmic64::MemoryRead128(std::uint64_t vaddr)
{
Dynarmic::A64::Vector Value;
if (m_CpuInfo.ReadMemory(vaddr, (uint8_t *)&Value, sizeof(Value)))
{
return Value;
}
return {0, 0};
}
void ArmDynarmic64::MemoryWrite8(std::uint64_t vaddr, std::uint8_t value)
{
m_CpuInfo.WriteMemory(vaddr, &value, sizeof(value));
}
void ArmDynarmic64::MemoryWrite16(std::uint64_t vaddr, std::uint16_t value)
{
m_CpuInfo.WriteMemory(vaddr, (const uint8_t *)&value, sizeof(value));
}
void ArmDynarmic64::MemoryWrite32(std::uint64_t vaddr, std::uint32_t value)
{
m_CpuInfo.WriteMemory(vaddr, (const uint8_t *)&value, sizeof(value));
}
void ArmDynarmic64::MemoryWrite64(std::uint64_t vaddr, std::uint64_t value)
{
m_CpuInfo.WriteMemory(vaddr, (const uint8_t *)&value, sizeof(value));
}
void ArmDynarmic64::MemoryWrite128(std::uint64_t vaddr, Dynarmic::A64::Vector value)
{
m_CpuInfo.WriteMemory(vaddr, (const uint8_t *)&value, sizeof(value));
}
bool ArmDynarmic64::MemoryWriteExclusive8(std::uint64_t /*vaddr*/, std::uint8_t /*value*/, std::uint8_t /*expected*/)
{
g_notify->BreakPoint(__FILE__, __LINE__);
return false;
}
bool ArmDynarmic64::MemoryWriteExclusive16(std::uint64_t /*vaddr*/, std::uint16_t /*value*/, std::uint16_t /*expected*/)
{
g_notify->BreakPoint(__FILE__, __LINE__);
return false;
}
bool ArmDynarmic64::MemoryWriteExclusive32(std::uint64_t vaddr, std::uint32_t value, std::uint32_t /*expected*/)
{
return m_CpuInfo.WriteMemory(vaddr, (const uint8_t *)&value, sizeof(value));
}
bool ArmDynarmic64::MemoryWriteExclusive64(std::uint64_t vaddr, std::uint64_t value, std::uint64_t /*expected*/)
{
return m_CpuInfo.WriteMemory(vaddr, (const uint8_t *)&value, sizeof(value));
}
bool ArmDynarmic64::MemoryWriteExclusive128(std::uint64_t /*vaddr*/, Dynarmic::A64::Vector /*value*/, Dynarmic::A64::Vector /*expected*/)
{
g_notify->BreakPoint(__FILE__, __LINE__);
return false;
}
bool ArmDynarmic64::IsReadOnlyMemory(std::uint64_t /*vaddr*/)
{
g_notify->BreakPoint(__FILE__, __LINE__);
return false;
}
void ArmDynarmic64::InterpreterFallback(std::uint64_t /*pc*/, size_t /*num_instructions*/)
{
g_notify->BreakPoint(__FILE__, __LINE__);
}
void ArmDynarmic64::CallSVC(std::uint32_t swi)
{
m_CpuInfo.ServiceCall(swi);
}
void ArmDynarmic64::ExceptionRaised(std::uint64_t /*pc*/, Dynarmic::A64::Exception /*exception*/)
{
g_notify->BreakPoint(__FILE__, __LINE__);
}
void ArmDynarmic64::DataCacheOperationRaised(Dynarmic::A64::DataCacheOperation /*op*/, std::uint64_t /*value*/)
{
g_notify->BreakPoint(__FILE__, __LINE__);
}
void ArmDynarmic64::InstructionCacheOperationRaised(Dynarmic::A64::InstructionCacheOperation /*op*/, std::uint64_t /*value*/)
{
g_notify->BreakPoint(__FILE__, __LINE__);
}
void ArmDynarmic64::InstructionSynchronizationBarrierRaised()
{
g_notify->BreakPoint(__FILE__, __LINE__);
}
void ArmDynarmic64::AddTicks(std::uint64_t /*ticks*/)
{
g_notify->BreakPoint(__FILE__, __LINE__);
}
std::uint64_t ArmDynarmic64::GetTicksRemaining()
{
g_notify->BreakPoint(__FILE__, __LINE__);
return 0;
}
std::uint64_t ArmDynarmic64::GetCNTPCT()
{
const uint64_t BASE_CLOCK_RATE = 1019215872; // Switch clock speed - 1020MHz
const uint64_t COUNT_FREQ = 19200000;
uint64_t ticks = m_CpuInfo.CpuTicks();
uint64_t hi, rem;
uint64_t lo = mull128_u64(ticks, COUNT_FREQ, &hi);
return div128_to_64(hi, lo, BASE_CLOCK_RATE, &rem);
}

View File

@ -0,0 +1,61 @@
#pragma once
#include "dynarmic/interface/A64/a64.h"
#include "arm64_registers.h"
#include "cpu_manager.h"
class ArmDynarmic64 :
public IArm64Executor,
private Dynarmic::A64::UserCallbacks
{
public:
ArmDynarmic64(Dynarmic::ExclusiveMonitor * monitor, ISwitchSystem & System, ICpuInfo & CpuInfo, uint32_t coreIndex);
IArm64Reg & Reg(void) { return m_reg; }
//IArm64Executor
HaltReason Execute(void);
void InvalidateCacheRange(uint64_t addr, uint64_t size);
void HaltExecution(HaltReason hr);
private:
ArmDynarmic64() = delete;
ArmDynarmic64(const ArmDynarmic64 &) = delete;
ArmDynarmic64 & operator=(const ArmDynarmic64 &) = delete;
std::unique_ptr<Dynarmic::A64::Jit> MakeJit(Dynarmic::ExclusiveMonitor * monitor);
//Dynarmic::A64::UserCallbacks
std::uint8_t MemoryRead8(std::uint64_t vaddr);
std::uint16_t MemoryRead16(std::uint64_t vaddr);
std::uint32_t MemoryRead32(std::uint64_t vaddr);
std::uint64_t MemoryRead64(std::uint64_t vaddr);
Dynarmic::A64::Vector MemoryRead128(std::uint64_t vaddr);
void MemoryWrite8(std::uint64_t vaddr, std::uint8_t value);
void MemoryWrite16(std::uint64_t vaddr, std::uint16_t value);
void MemoryWrite32(std::uint64_t vaddr, std::uint32_t value);
void MemoryWrite64(std::uint64_t vaddr, std::uint64_t value);
void MemoryWrite128(std::uint64_t vaddr, Dynarmic::A64::Vector value);
bool MemoryWriteExclusive8(std::uint64_t /*vaddr*/, std::uint8_t /*value*/, std::uint8_t /*expected*/);
bool MemoryWriteExclusive16(std::uint64_t /*vaddr*/, std::uint16_t /*value*/, std::uint16_t /*expected*/);
bool MemoryWriteExclusive32(std::uint64_t /*vaddr*/, std::uint32_t /*value*/, std::uint32_t /*expected*/);
bool MemoryWriteExclusive64(std::uint64_t /*vaddr*/, std::uint64_t /*value*/, std::uint64_t /*expected*/);
bool MemoryWriteExclusive128(std::uint64_t /*vaddr*/, Dynarmic::A64::Vector /*value*/, Dynarmic::A64::Vector /*expected*/);
bool IsReadOnlyMemory(std::uint64_t /*vaddr*/);
void InterpreterFallback(std::uint64_t pc, size_t num_instructions);
void CallSVC(std::uint32_t swi);
void ExceptionRaised(std::uint64_t pc, Dynarmic::A64::Exception exception);
void DataCacheOperationRaised(Dynarmic::A64::DataCacheOperation /*op*/, std::uint64_t /*value*/);
void InstructionCacheOperationRaised(Dynarmic::A64::InstructionCacheOperation /*op*/, std::uint64_t /*value*/);
void InstructionSynchronizationBarrierRaised();
void AddTicks(std::uint64_t ticks);
std::uint64_t GetTicksRemaining();
std::uint64_t GetCNTPCT();
std::unique_ptr<Dynarmic::A64::Jit> m_jit{};
ISwitchSystem & m_system;
ICpuInfo & m_CpuInfo;
IOperatingSystem & m_OperatingSystem;
Dynarmic::ExclusiveMonitor * m_monitor;
A64Registers m_reg;
uint32_t m_coreIndex;
};

View File

@ -1,4 +1,6 @@
#include "cpu_manager.h"
#include "arm_dynarmic_64.h"
#include "exclusive_monitor_interface.h"
CpuManager::CpuManager(ISwitchSystem & system) :
m_system(system)
@ -14,20 +16,30 @@ bool CpuManager::Initialize(void)
return true;
}
IExclusiveMonitor * CpuManager::CreateExclusiveMonitor(IMemory & /*memory*/, uint32_t /*processorCount*/)
IExclusiveMonitor * CpuManager::CreateExclusiveMonitor(IMemory & memory, uint32_t processorCount)
{
if (m_exclusiveMonitor.get() != nullptr)
{
return nullptr;
}
m_exclusiveMonitor.reset(std::make_unique<ExclusiveMonitor>(memory, processorCount).release());
return m_exclusiveMonitor.get();
};
void CpuManager::DestroyExclusiveMonitor(IExclusiveMonitor * /*monitor*/)
void CpuManager::DestroyExclusiveMonitor(IExclusiveMonitor * monitor)
{
if (m_exclusiveMonitor.get() == monitor)
{
m_exclusiveMonitor.reset(nullptr);
}
}
IArm64Executor * CpuManager::CreateArm64Executor(IExclusiveMonitor * monitor, ICpuInfo & info, uint32_t coreIndex)
{
return nullptr;
return new ArmDynarmic64(monitor == m_exclusiveMonitor.get() ? m_exclusiveMonitor.get() : nullptr, m_system, info, coreIndex);
}
void CpuManager::DestroyArm64Executor(IArm64Executor * executor)
{
delete (ArmDynarmic64 *)executor;
}

View File

@ -23,5 +23,6 @@ private:
CpuManager(const CpuManager &) = delete;
CpuManager & operator=(const CpuManager &) = delete;
std::unique_ptr<ExclusiveMonitor> m_exclusiveMonitor;
ISwitchSystem & m_system;
};

View File

@ -6,7 +6,7 @@
#include <mcl/macro/architecture.hpp>
#if defined(MCL_ARCHITECTURE_X86_64)
# include "dynarmic/backend/x64/exception_handler_windows.cpp"
# include "dynarmic/backend/x64/exception_handler_windows_x64.cpp"
#elif defined(MCL_ARCHITECTURE_ARM64)
# include "dynarmic/backend/exception_handler_generic.cpp"
#else

View File

@ -3,7 +3,6 @@
* SPDX-License-Identifier: 0BSD
*/
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <cstring>

View File

@ -12,7 +12,7 @@
#include <cstring>
#include <vector>
#include <dynarmic/common/spin_lock.h>
#include "dynarmic/common/spin_lock.h"
namespace Dynarmic {

View File

@ -0,0 +1,59 @@
#include "exclusive_monitor_interface.h"
ExclusiveMonitor::ExclusiveMonitor(IMemory & /*memory*/, uint32_t processorCount) :
Dynarmic::ExclusiveMonitor(processorCount)
{
}
uint8_t ExclusiveMonitor::ExclusiveRead8(uint32_t /*coreIndex*/, uint64_t /*addr*/)
{
__debugbreak();
return 0;
}
uint16_t ExclusiveMonitor::ExclusiveRead16(uint32_t /*coreIndex*/, uint64_t /*addr*/)
{
__debugbreak();
return 0;
}
uint32_t ExclusiveMonitor::ExclusiveRead32(uint32_t /*coreIndex*/, uint64_t /*addr*/)
{
__debugbreak();
return 0;
}
uint64_t ExclusiveMonitor::ExclusiveRead64(uint32_t /*coreIndex*/, uint64_t /*addr*/)
{
__debugbreak();
return 0;
}
void ExclusiveMonitor::ClearExclusive(uint32_t /*coreIndex*/)
{
__debugbreak();
}
bool ExclusiveMonitor::ExclusiveWrite8(uint32_t /*coreIndex*/, uint64_t /*addr*/, uint8_t /*value*/)
{
__debugbreak();
return false;
}
bool ExclusiveMonitor::ExclusiveWrite16(uint32_t /*coreIndex*/, uint64_t /*addr*/, uint16_t /*value*/)
{
__debugbreak();
return false;
}
bool ExclusiveMonitor::ExclusiveWrite32(uint32_t /*coreIndex*/, uint64_t /*addr*/, uint32_t /*value*/)
{
__debugbreak();
return false;
}
bool ExclusiveMonitor::ExclusiveWrite64(uint32_t /*coreIndex*/, uint64_t /*addr*/, uint64_t /*value*/)
{
__debugbreak();
return false;
}

View File

@ -0,0 +1,30 @@
#pragma once
#include <nxemu-module-spec/cpu.h>
#include "dynarmic/interface/exclusive_monitor.h"
__interface IMemory;
class ExclusiveMonitor :
public Dynarmic::ExclusiveMonitor,
public IExclusiveMonitor
{
public:
ExclusiveMonitor(IMemory & memory, uint32_t processorCount);
// IExclusiveMonitor
uint8_t ExclusiveRead8(uint32_t coreIndex, uint64_t addr);
uint16_t ExclusiveRead16(uint32_t coreIndex, uint64_t addr);
uint32_t ExclusiveRead32(uint32_t coreIndex, uint64_t addr);
uint64_t ExclusiveRead64(uint32_t coreIndex, uint64_t addr);
void ClearExclusive(uint32_t coreIndex);
bool ExclusiveWrite8(uint32_t coreIndex, uint64_t vaddr, uint8_t value);
bool ExclusiveWrite16(uint32_t coreIndex, uint64_t vaddr, uint16_t value);
bool ExclusiveWrite32(uint32_t coreIndex, uint64_t vaddr, uint32_t value);
bool ExclusiveWrite64(uint32_t coreIndex, uint64_t vaddr, uint64_t value);
private:
ExclusiveMonitor() = delete;
ExclusiveMonitor(const ExclusiveMonitor &) = delete;
ExclusiveMonitor & operator=(const ExclusiveMonitor &) = delete;
};

View File

@ -28,16 +28,358 @@
<OutDir>$(SolutionDir)modules\$(Platform)\cpu\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(SolutionDir)src\3rd_party\SoftFloat-3e\source\include;$(SolutionDir)external\boost;$(SolutionDir)external\mcl\include;$(SolutionDir)external\fmt\include;$(SolutionDir)external\robin-map\include;$(SolutionDir)external\xbyak;$(SolutionDir)external\zydis\include;$(SolutionDir)external\oaknut\include;$(SolutionDir)external\zycore\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NOMINMAX;DYNARMIC_ENABLE_CPU_FEATURE_DETECTION=1;MCL_IGNORE_ASSERTS=1;FMT_STATIC_LINK;FMT_USE_WINDOWS_H=0;FMT_USE_USER_DEFINED_LITERALS=1;ARCHITECTURE_x86_64=1;BOOST_ASIO_DISABLE_CONCEPTS;_HAS_DEPRECATED_RESULT_OF;_WIN32_WINNT=0x0A00;WINVER=0x0A00;BOOST_ALL_NO_LIB;ZYDIS_STATIC_BUILD;ZYCORE_STATIC_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalOptions> /bigobj %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<PreBuildEvent>
<Command>"$(SolutionDir)src\script\update_version.cmd" "$(Configuration)" "$(Platform)" "$(SolutionDir)src\nxemu-cpu\Version.h.in" "$(SolutionDir)src\nxemu-cpu\Version.h"</Command>
<Command>"$(SolutionDir)src\script\update_version.cmd" "$(Configuration)" "$(Platform)" "$(SolutionDir)src\nxemu-cpu\version.h.in" "$(SolutionDir)src\nxemu-cpu\version.h"</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\nxemu-plugin-spec\Base.h" />
<ClInclude Include="..\nxemu-plugin-spec\Cpu.h" />
<ClInclude Include="arm64_registers.h" />
<ClInclude Include="arm_dynarmic_64.h" />
<ClInclude Include="backend\arm64\a32_jitstate.h" />
<ClInclude Include="backend\arm64\a64_address_space.h" />
<ClInclude Include="backend\arm64\a64_core.h" />
<ClInclude Include="backend\arm64\a64_jitstate.h" />
<ClInclude Include="backend\arm64\abi.h" />
<ClInclude Include="backend\arm64\address_space.h" />
<ClInclude Include="backend\arm64\devirtualize.h" />
<ClInclude Include="backend\arm64\emit_arm64.h" />
<ClInclude Include="backend\arm64\emit_context.h" />
<ClInclude Include="backend\arm64\fastmem.h" />
<ClInclude Include="backend\arm64\fpsr_manager.h" />
<ClInclude Include="backend\arm64\reg_alloc.h" />
<ClInclude Include="backend\arm64\stack_layout.h" />
<ClInclude Include="backend\arm64\verbose_debugging_output.h" />
<ClInclude Include="backend\block_range_information.h" />
<ClInclude Include="backend\exception_handler.h" />
<ClInclude Include="backend\x64\a32_emit_x64.h" />
<ClInclude Include="backend\x64\a32_jitstate.h" />
<ClInclude Include="backend\x64\a64_emit_x64.h" />
<ClInclude Include="backend\x64\a64_jitstate.h" />
<ClInclude Include="backend\x64\abi.h" />
<ClInclude Include="backend\x64\block_of_code.h" />
<ClInclude Include="backend\x64\callback.h" />
<ClInclude Include="backend\x64\constants.h" />
<ClInclude Include="backend\x64\constant_pool.h" />
<ClInclude Include="backend\x64\devirtualize.h" />
<ClInclude Include="backend\x64\emit_x64.h" />
<ClInclude Include="backend\x64\emit_x64_memory.h" />
<ClInclude Include="backend\x64\exclusive_monitor_friend.h" />
<ClInclude Include="backend\x64\hostloc.h" />
<ClInclude Include="backend\x64\host_feature.h" />
<ClInclude Include="backend\x64\jitstate_info.h" />
<ClInclude Include="backend\x64\nzcv_util.h" />
<ClInclude Include="backend\x64\oparg.h" />
<ClInclude Include="backend\x64\perf_map.h" />
<ClInclude Include="backend\x64\reg_alloc.h" />
<ClInclude Include="backend\x64\stack_layout.h" />
<ClInclude Include="backend\x64\verbose_debugging_output.h" />
<ClInclude Include="common\always_false.h" />
<ClInclude Include="common\atomic.h" />
<ClInclude Include="common\cast_util.h" />
<ClInclude Include="common\crypto\aes.h" />
<ClInclude Include="common\crypto\crc32.h" />
<ClInclude Include="common\crypto\sm4.h" />
<ClInclude Include="common\fp\fpcr.h" />
<ClInclude Include="common\fp\fpsr.h" />
<ClInclude Include="common\fp\fused.h" />
<ClInclude Include="common\fp\info.h" />
<ClInclude Include="common\fp\mantissa_util.h" />
<ClInclude Include="common\fp\op.h" />
<ClInclude Include="common\fp\op\FPCompare.h" />
<ClInclude Include="common\fp\op\FPConvert.h" />
<ClInclude Include="common\fp\op\FPMulAdd.h" />
<ClInclude Include="common\fp\op\FPNeg.h" />
<ClInclude Include="common\fp\op\FPRecipEstimate.h" />
<ClInclude Include="common\fp\op\FPRecipExponent.h" />
<ClInclude Include="common\fp\op\FPRecipStepFused.h" />
<ClInclude Include="common\fp\op\FPRoundInt.h" />
<ClInclude Include="common\fp\op\FPRSqrtEstimate.h" />
<ClInclude Include="common\fp\op\FPRSqrtStepFused.h" />
<ClInclude Include="common\fp\op\FPToFixed.h" />
<ClInclude Include="common\fp\process_exception.h" />
<ClInclude Include="common\fp\process_nan.h" />
<ClInclude Include="common\fp\rounding_mode.h" />
<ClInclude Include="common\fp\unpacked.h" />
<ClInclude Include="common\fp\util.h" />
<ClInclude Include="common\lut_from_list.h" />
<ClInclude Include="common\math_util.h" />
<ClInclude Include="common\memory_pool.h" />
<ClInclude Include="common\safe_ops.h" />
<ClInclude Include="common\spin_lock.h" />
<ClInclude Include="common\spin_lock_x64.h" />
<ClInclude Include="common\u128.h" />
<ClInclude Include="common\variant_util.h" />
<ClInclude Include="common\x64_disassemble.h" />
<ClInclude Include="cpu_manager.h" />
<ClInclude Include="exclusive_monitor_interface.h" />
<ClInclude Include="frontend\A32\a32_ir_emitter.h" />
<ClInclude Include="frontend\A32\a32_location_descriptor.h" />
<ClInclude Include="frontend\A32\a32_types.h" />
<ClInclude Include="frontend\A32\decoder\arm.h" />
<ClInclude Include="frontend\A32\decoder\asimd.h" />
<ClInclude Include="frontend\A32\decoder\thumb16.h" />
<ClInclude Include="frontend\A32\decoder\thumb32.h" />
<ClInclude Include="frontend\A32\decoder\vfp.h" />
<ClInclude Include="frontend\A32\FPSCR.h" />
<ClInclude Include="frontend\A32\ITState.h" />
<ClInclude Include="frontend\A32\PSR.h" />
<ClInclude Include="frontend\A32\translate\a32_translate.h" />
<ClInclude Include="frontend\A32\translate\conditional_state.h" />
<ClInclude Include="frontend\A32\translate\translate_callbacks.h" />
<ClInclude Include="frontend\A64\a64_ir_emitter.h" />
<ClInclude Include="frontend\A64\a64_location_descriptor.h" />
<ClInclude Include="frontend\A64\a64_types.h" />
<ClInclude Include="frontend\A64\decoder\a64.h" />
<ClInclude Include="frontend\A64\translate\a64_translate.h" />
<ClInclude Include="frontend\A64\translate\impl\impl.h" />
<ClInclude Include="frontend\decoder\decoder_detail.h" />
<ClInclude Include="frontend\decoder\matcher.h" />
<ClInclude Include="frontend\imm.h" />
<ClInclude Include="interface\A32\a32.h" />
<ClInclude Include="interface\A32\arch_version.h" />
<ClInclude Include="interface\A32\config.h" />
<ClInclude Include="interface\A32\coprocessor.h" />
<ClInclude Include="interface\A32\coprocessor_util.h" />
<ClInclude Include="interface\A64\a64.h" />
<ClInclude Include="interface\A64\config.h" />
<ClInclude Include="interface\exclusive_monitor.h" />
<ClInclude Include="interface\halt_reason.h" />
<ClInclude Include="interface\optimization_flags.h" />
<ClInclude Include="ir\acc_type.h" />
<ClInclude Include="ir\basic_block.h" />
<ClInclude Include="ir\cond.h" />
<ClInclude Include="ir\ir_emitter.h" />
<ClInclude Include="ir\location_descriptor.h" />
<ClInclude Include="ir\microinstruction.h" />
<ClInclude Include="ir\opcodes.h" />
<ClInclude Include="ir\opt\passes.h" />
<ClInclude Include="ir\terminal.h" />
<ClInclude Include="ir\type.h" />
<ClInclude Include="ir\value.h" />
<ClInclude Include="version.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="arm64_registers.cpp " />
<ClCompile Include="arm_dynarmic_64.cpp" />
<ClCompile Include="cpu_manager.cpp" />
<ClCompile Include="dynarmic\backend\block_range_information.cpp" />
<ClCompile Include="dynarmic\backend\x64\a32_emit_x64.cpp" />
<ClCompile Include="dynarmic\backend\x64\a32_emit_x64_memory.cpp" />
<ClCompile Include="dynarmic\backend\x64\a32_interface.cpp" />
<ClCompile Include="dynarmic\backend\x64\a32_jitstate.cpp" />
<ClCompile Include="dynarmic\backend\x64\a64_emit_x64.cpp" />
<ClCompile Include="dynarmic\backend\x64\a64_emit_x64_memory.cpp" />
<ClCompile Include="dynarmic\backend\x64\a64_interface.cpp" />
<ClCompile Include="dynarmic\backend\x64\a64_jitstate.cpp" />
<ClCompile Include="dynarmic\backend\x64\abi.cpp" />
<ClCompile Include="dynarmic\backend\x64\block_of_code.cpp" />
<ClCompile Include="dynarmic\backend\x64\callback.cpp" />
<ClCompile Include="dynarmic\backend\x64\constant_pool.cpp" />
<ClCompile Include="dynarmic\backend\x64\emit_x64.cpp" />
<ClCompile Include="dynarmic\backend\x64\emit_x64_aes.cpp" />
<ClCompile Include="dynarmic\backend\x64\emit_x64_crc32.cpp" />
<ClCompile Include="dynarmic\backend\x64\emit_x64_data_processing.cpp" />
<ClCompile Include="dynarmic\backend\x64\emit_x64_floating_point.cpp" />
<ClCompile Include="dynarmic\backend\x64\emit_x64_packed.cpp" />
<ClCompile Include="dynarmic\backend\x64\emit_x64_saturation.cpp" />
<ClCompile Include="dynarmic\backend\x64\emit_x64_sha.cpp" />
<ClCompile Include="dynarmic\backend\x64\emit_x64_sm4.cpp" />
<ClCompile Include="dynarmic\backend\x64\emit_x64_vector.cpp" />
<ClCompile Include="dynarmic\backend\x64\emit_x64_vector_floating_point.cpp" />
<ClCompile Include="dynarmic\backend\x64\emit_x64_vector_saturation.cpp" />
<ClCompile Include="dynarmic\backend\x64\exception_handler_windows_x64.cpp" />
<ClCompile Include="dynarmic\backend\x64\exclusive_monitor.cpp" />
<ClCompile Include="dynarmic\backend\x64\hostloc.cpp" />
<ClCompile Include="dynarmic\backend\x64\perf_map.cpp" />
<ClCompile Include="dynarmic\backend\x64\reg_alloc.cpp" />
<ClCompile Include="dynarmic\backend\x64\verbose_debugging_output.cpp" />
<ClCompile Include="dynarmic\common\crypto\aes.cpp" />
<ClCompile Include="dynarmic\common\crypto\crc32.cpp" />
<ClCompile Include="dynarmic\common\crypto\sm4.cpp" />
<ClCompile Include="dynarmic\common\fp\fused.cpp" />
<ClCompile Include="dynarmic\common\fp\op\FPCompare.cpp" />
<ClCompile Include="dynarmic\common\fp\op\FPConvert.cpp" />
<ClCompile Include="dynarmic\common\fp\op\FPMulAdd.cpp" />
<ClCompile Include="dynarmic\common\fp\op\FPRecipEstimate.cpp" />
<ClCompile Include="dynarmic\common\fp\op\FPRecipExponent.cpp" />
<ClCompile Include="dynarmic\common\fp\op\FPRecipStepFused.cpp" />
<ClCompile Include="dynarmic\common\fp\op\FPRoundInt.cpp" />
<ClCompile Include="dynarmic\common\fp\op\FPRSqrtEstimate.cpp" />
<ClCompile Include="dynarmic\common\fp\op\FPRSqrtStepFused.cpp" />
<ClCompile Include="dynarmic\common\fp\op\FPToFixed.cpp" />
<ClCompile Include="dynarmic\common\fp\process_exception.cpp" />
<ClCompile Include="dynarmic\common\fp\process_nan.cpp" />
<ClCompile Include="dynarmic\common\fp\unpacked.cpp" />
<ClCompile Include="dynarmic\common\math_util.cpp" />
<ClCompile Include="dynarmic\common\memory_pool.cpp" />
<ClCompile Include="dynarmic\common\spin_lock_x64.cpp" />
<ClCompile Include="dynarmic\common\u128.cpp" />
<ClCompile Include="dynarmic\common\x64_disassemble.cpp" />
<ClCompile Include="dynarmic\frontend\A32\a32_ir_emitter.cpp" />
<ClCompile Include="dynarmic\frontend\A32\a32_location_descriptor.cpp" />
<ClCompile Include="dynarmic\frontend\A32\a32_types.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\a32_translate.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\conditional_state.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\a32_branch.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\a32_crc32.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\a32_exception_generating.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\a32_translate_impl.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\asimd_load_store_structures.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\asimd_misc.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\asimd_one_reg_modified_immediate.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\asimd_three_regs.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\asimd_two_regs_misc.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\asimd_two_regs_scalar.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\asimd_two_regs_shift.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\barrier.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\coprocessor.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\data_processing.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\divide.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\extension.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\hint.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\load_store.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\misc.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\multiply.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\packing.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\parallel.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\reversal.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\saturated.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\status_register_access.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\synchronization.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\thumb16.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\thumb32_branch.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\thumb32_control.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\thumb32_coprocessor.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\thumb32_data_processing_modified_immediate.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\thumb32_data_processing_plain_binary_immediate.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\thumb32_data_processing_register.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\thumb32_data_processing_shifted_register.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\thumb32_load_byte.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\thumb32_load_halfword.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\thumb32_load_store_dual.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\thumb32_load_store_multiple.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\thumb32_load_word.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\thumb32_long_multiply.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\thumb32_misc.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\thumb32_multiply.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\thumb32_parallel.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\thumb32_store_single_data_item.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\impl\vfp.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\translate_arm.cpp" />
<ClCompile Include="dynarmic\frontend\A32\translate\translate_thumb.cpp" />
<ClCompile Include="dynarmic\frontend\A64\a64_ir_emitter.cpp" />
<ClCompile Include="dynarmic\frontend\A64\a64_location_descriptor.cpp" />
<ClCompile Include="dynarmic\frontend\A64\a64_types.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\a64_translate.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\a64_branch.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\a64_exception_generating.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\data_processing_addsub.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\data_processing_bitfield.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\data_processing_conditional_compare.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\data_processing_conditional_select.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\data_processing_crc32.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\data_processing_logical.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\data_processing_multiply.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\data_processing_pcrel.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\data_processing_register.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\data_processing_shift.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\floating_point_compare.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\floating_point_conditional_compare.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\floating_point_conditional_select.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\floating_point_conversion_fixed_point.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\floating_point_conversion_integer.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\floating_point_data_processing_one_register.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\floating_point_data_processing_three_register.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\floating_point_data_processing_two_register.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\impl.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\load_store_exclusive.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\load_store_load_literal.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\load_store_multiple_structures.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\load_store_no_allocate_pair.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\load_store_register_immediate.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\load_store_register_pair.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\load_store_register_register_offset.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\load_store_register_unprivileged.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\load_store_single_structure.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\move_wide.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\simd_across_lanes.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\simd_aes.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\simd_copy.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\simd_crypto_four_register.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\simd_crypto_three_register.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\simd_extract.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\simd_modified_immediate.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\simd_permute.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\simd_scalar_pairwise.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\simd_scalar_shift_by_immediate.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\simd_scalar_three_same.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\simd_scalar_two_register_misc.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\simd_scalar_x_indexed_element.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\simd_sha.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\simd_sha512.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\simd_shift_by_immediate.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\simd_table_lookup.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\simd_three_different.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\simd_three_same.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\simd_three_same_extra.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\simd_two_register_misc.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\simd_vector_x_indexed_element.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\system.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\system_flag_format.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\system_flag_manipulation.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\sys_dc.cpp" />
<ClCompile Include="dynarmic\frontend\A64\translate\impl\sys_ic.cpp" />
<ClCompile Include="dynarmic\frontend\imm.cpp" />
<ClCompile Include="dynarmic\ir\basic_block.cpp" />
<ClCompile Include="dynarmic\ir\ir_emitter.cpp" />
<ClCompile Include="dynarmic\ir\location_descriptor.cpp" />
<ClCompile Include="dynarmic\ir\microinstruction.cpp" />
<ClCompile Include="dynarmic\ir\opcodes.cpp" />
<ClCompile Include="dynarmic\ir\opt\a32_constant_memory_reads_pass.cpp" />
<ClCompile Include="dynarmic\ir\opt\a32_get_set_elimination_pass.cpp" />
<ClCompile Include="dynarmic\ir\opt\a64_callback_config_pass.cpp" />
<ClCompile Include="dynarmic\ir\opt\a64_get_set_elimination_pass.cpp" />
<ClCompile Include="dynarmic\ir\opt\a64_merge_interpret_blocks.cpp" />
<ClCompile Include="dynarmic\ir\opt\constant_propagation_pass.cpp" />
<ClCompile Include="dynarmic\ir\opt\dead_code_elimination_pass.cpp" />
<ClCompile Include="dynarmic\ir\opt\identity_removal_pass.cpp" />
<ClCompile Include="dynarmic\ir\opt\naming_pass.cpp" />
<ClCompile Include="dynarmic\ir\opt\polyfill_pass.cpp" />
<ClCompile Include="dynarmic\ir\opt\verification_pass.cpp" />
<ClCompile Include="dynarmic\ir\type.cpp" />
<ClCompile Include="dynarmic\ir\value.cpp" />
<ClCompile Include="exclusive_monitor_interface.cpp" />
<ClCompile Include="nxemu-cpu.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="cpu_manager.h" />
<None Include="dynarmic\backend\x64\emit_x64_memory.cpp.inc" />
<None Include="frontend\A32\decoder\arm.inc" />
<None Include="frontend\A32\decoder\asimd.inc" />
<None Include="frontend\A32\decoder\thumb16.inc" />
<None Include="frontend\A32\decoder\thumb32.inc" />
<None Include="frontend\A32\decoder\vfp.inc" />
<None Include="frontend\A64\decoder\a64.inc" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\nxemu-private\external\fmt.vcxproj">
<Project>{d58bdfc6-1f1e-4c55-9296-1c2411b0fda7}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\nxemu-private\external\mcl.vcxproj">
<Project>{a059b52a-fb13-4060-ac89-128570938d5d}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\nxemu-private\external\zydis.vcxproj">
<Project>{9dec236b-f924-4166-a1b1-002f3bf8f0ec}</Project>
</ProjectReference>
<ProjectReference Include="..\common\common.vcxproj">
<Project>{ec81be93-8316-4db6-8a26-b13fb5b13848}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,42 @@
#pragma once
#include "base.h"
__interface IArm64Reg
{
// clang-format off
enum class Reg
{
INVALID,
W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14, W15, W16, W17, W18, W19, W20, W21, W22, W23, W24, W25, W26, W27, W28, W29, W30, WZR,
X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, XZR,
V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30, V31,
B0, B1, B2, B3, B4, B5, B6, B7, B8, B9, B10, B11, B12, B13, B14, B15, B16, B17, B18, B19, B20, B21, B22, B23, B24, B25, B26, B27, B28, B29, B30, B31,
H0, H1, H2, H3, H4, H5, H6, H7, H8, H9, H10, H11, H12, H13, H14, H15, H16, H17, H18, H19, H20, H21, H22, H23, H24, H25, H26, H27, H28, H29, H30, H31,
S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, S12, S13, S14, S15, S16, S17, S18, S19, S20, S21, S22, S23, S24, S25, S26, S27, S28, S29, S30, S31,
D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30, D31,
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15, Q16, Q17, Q18, Q19, Q20, Q21, Q22, Q23, Q24, Q25, Q26, Q27, Q28, Q29, Q30, Q31,
WSP, SP, PC, PSTATE, TPIDR_EL0, TPIDRRO_EL0,
//Alias
FP = X29,
LR = X30,
};
// clang-format on
uint32_t Get32(Reg reg) = 0;
uint64_t Get64(Reg reg) = 0;
void Get128(Reg reg, uint64_t & hiValue, uint64_t & loValue) = 0;
uint32_t GetFPCR() const = 0;
uint32_t GetFPSR() const = 0;
void Set32(Reg reg, uint32_t value) = 0;
void Set64(Reg reg, uint64_t value) = 0;
void Set128(Reg reg, uint64_t hiValue, uint64_t loValue) = 0;
void SetFPCR(uint32_t value) = 0;
void SetFPSR(uint32_t value) = 0;
};
__interface IArm64Executor
{
enum class HaltReason
@ -9,7 +45,10 @@ __interface IArm64Executor
SupervisorCall,
};
IArm64Reg & Reg(void) = 0;
HaltReason Execute(void) = 0;
void InvalidateCacheRange(uint64_t addr, uint64_t size) = 0;
void HaltExecution(HaltReason hr) = 0;
};
__interface IMemory
@ -18,6 +57,10 @@ __interface IMemory
__interface ICpuInfo
{
uint64_t & CpuTicks() = 0;
void ServiceCall(uint32_t index) = 0;
bool ReadMemory(uint64_t addr, uint8_t * buffer, uint32_t len) = 0;
bool WriteMemory(uint64_t addr, const uint8_t * buffer, uint32_t len) = 0;
};
__interface IExclusiveMonitor
@ -28,10 +71,10 @@ __interface IExclusiveMonitor
uint64_t ExclusiveRead64(uint32_t coreIndex, uint64_t addr) = 0;
void ClearExclusive(uint32_t coreIndex) = 0;
bool ExclusiveWrite8(uint32_t coreIndex, uint64_t vaddr, uint8_t value) = 0;
bool ExclusiveWrite16(uint32_t coreIndex, uint64_t vaddr, uint16_t value) = 0;
bool ExclusiveWrite32(uint32_t coreIndex, uint64_t vaddr, uint32_t value) = 0;
bool ExclusiveWrite64(uint32_t coreIndex, uint64_t vaddr, uint64_t value) = 0;
bool ExclusiveWrite8(uint32_t coreIndex, uint64_t addr, uint8_t value) = 0;
bool ExclusiveWrite16(uint32_t coreIndex, uint64_t addr, uint16_t value) = 0;
bool ExclusiveWrite32(uint32_t coreIndex, uint64_t addr, uint32_t value) = 0;
bool ExclusiveWrite64(uint32_t coreIndex, uint64_t addr, uint64_t value) = 0;
};
__interface ICpu

View File

@ -16,6 +16,33 @@ public:
{
}
uint32_t svn()
{
return m_svn;
}
uint64_t & CpuTicks()
{
UNIMPLEMENTED();
static uint64_t ticks = 0;
return ticks;
}
void ServiceCall(uint32_t index)
{
m_svn = index;
m_arm64Executor->HaltExecution(IArm64Executor::HaltReason::SupervisorCall);
}
bool ReadMemory(uint64_t addr, uint8_t * Buffer, uint32_t Len)
{
return m_memory.ReadBlock(addr, Buffer, Len);
}
bool WriteMemory(uint64_t addr, const uint8_t * buffer, uint32_t len)
{
return m_memory.WriteBlock(addr, buffer, len);
}
IArm64Executor *& m_arm64Executor;
Kernel::KProcess * m_process{};
@ -72,34 +99,96 @@ HaltReason ArmCpuModule::StepThread(Kernel::KThread * thread)
}
void ArmCpuModule::GetContext(Kernel::Svc::ThreadContext & ctx) const
{
if (m_arm64Executor != nullptr)
{
IArm64Reg & reg = m_arm64Executor->Reg();
for (size_t i = 0; i < 29; i++)
{
ctx.r[i] = reg.Get64((IArm64Reg::Reg)(((uint32_t)IArm64Reg::Reg::X0) + i));
}
ctx.fp = reg.Get64(IArm64Reg::Reg::FP);
ctx.lr = reg.Get64(IArm64Reg::Reg::LR);
ctx.sp = reg.Get64(IArm64Reg::Reg::SP);
ctx.pc = reg.Get64(IArm64Reg::Reg::PC);
ctx.pstate = reg.Get32(IArm64Reg::Reg::PSTATE);
for (size_t i = 0; i < 32; i++)
{
reg.Get128((IArm64Reg::Reg)(((uint32_t)IArm64Reg::Reg::Q0) + i), ctx.v[i][1], ctx.v[i][0]);
}
ctx.fpcr = reg.GetFPCR();
ctx.fpsr = reg.GetFPSR();
ctx.tpidr = reg.Get64(IArm64Reg::Reg::TPIDR_EL0);
}
else
{
UNIMPLEMENTED();
}
}
void ArmCpuModule::SetContext(const Kernel::Svc::ThreadContext & ctx)
{
if (m_arm64Executor != nullptr)
{
IArm64Reg & reg = m_arm64Executor->Reg();
for (size_t i = 0; i < 29; i++)
{
reg.Set64((IArm64Reg::Reg)(((uint32_t)IArm64Reg::Reg::X0) + i), ctx.r[i]);
}
reg.Set64(IArm64Reg::Reg::FP, ctx.fp);
reg.Set64(IArm64Reg::Reg::LR, ctx.lr);
reg.Set64(IArm64Reg::Reg::SP, ctx.sp);
reg.Set64(IArm64Reg::Reg::PC, ctx.pc);
reg.Set32(IArm64Reg::Reg::PSTATE, ctx.pstate);
for (size_t i = 0; i < 32; i++)
{
reg.Set128((IArm64Reg::Reg)(((uint32_t)IArm64Reg::Reg::Q0) + i), ctx.v[i][1], ctx.v[i][0]);
}
reg.SetFPCR(ctx.fpcr);
reg.SetFPSR(ctx.fpsr);
reg.Set64(IArm64Reg::Reg::TPIDR_EL0, ctx.tpidr);
}
else
{
UNIMPLEMENTED();
}
}
void ArmCpuModule::SetTpidrroEl0(u64 value)
{
if (m_arm64Executor != nullptr)
{
IArm64Reg & reg = m_arm64Executor->Reg();
reg.Set64(IArm64Reg::Reg::TPIDRRO_EL0, value);
}
else
{
UNIMPLEMENTED();
}
}
void ArmCpuModule::GetSvcArguments(std::span<uint64_t, 8> args) const
{
UNIMPLEMENTED();
IArm64Reg & reg = m_arm64Executor->Reg();
for (size_t i = 0; i < 8; i++)
{
args[i] = reg.Get64((IArm64Reg::Reg)(((uint32_t)IArm64Reg::Reg::X0) + i));
}
}
void ArmCpuModule::SetSvcArguments(std::span<const uint64_t, 8> args)
{
UNIMPLEMENTED();
IArm64Reg & reg = m_arm64Executor->Reg();
for (size_t i = 0; i < 8; i++)
{
reg.Set64((IArm64Reg::Reg)(((uint32_t)IArm64Reg::Reg::X0) + i), args[i]);
}
}
u32 ArmCpuModule::GetSvcNumber() const
{
UNIMPLEMENTED();
return 0;
return m_cb->svn();
}
void ArmCpuModule::SignalInterrupt(Kernel::KThread * thread)
@ -113,9 +202,16 @@ void ArmCpuModule::ClearInstructionCache()
}
void ArmCpuModule::InvalidateCacheRange(u64 addr, std::size_t size)
{
if (m_arm64Executor != nullptr)
{
m_arm64Executor->InvalidateCacheRange(addr, size);
}
else
{
UNIMPLEMENTED();
}
}
const Kernel::DebugWatchpoint * ArmCpuModule::HaltedWatchpoint() const
{

View File

@ -99,7 +99,6 @@ void FrontendAppletHolder::SetCurrentAppletId(AppletId applet_id) {
}
void FrontendAppletHolder::SetDefaultAppletsIfMissing() {
UNIMPLEMENTED();
}
void FrontendAppletHolder::ClearAll() {