HW/ProcessorInterface: Refactor to class, move to Core::System.
This commit is contained in:
parent
908cec04cb
commit
74e1577a2c
|
@ -155,8 +155,9 @@ namespace
|
||||||
{
|
{
|
||||||
void UpdateInterrupts()
|
void UpdateInterrupts()
|
||||||
{
|
{
|
||||||
auto& state = Core::System::GetInstance().GetAudioInterfaceState().GetData();
|
auto& system = Core::System::GetInstance();
|
||||||
ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_AI,
|
auto& state = system.GetAudioInterfaceState().GetData();
|
||||||
|
system.GetProcessorInterface().SetInterrupt(ProcessorInterface::INT_CAUSE_AI,
|
||||||
state.control.AIINT & state.control.AIINTMSK);
|
state.control.AIINT & state.control.AIINTMSK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -465,7 +465,8 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
||||||
// UpdateInterrupts
|
// UpdateInterrupts
|
||||||
static void UpdateInterrupts()
|
static void UpdateInterrupts()
|
||||||
{
|
{
|
||||||
auto& state = Core::System::GetInstance().GetDSPState().GetData();
|
auto& system = Core::System::GetInstance();
|
||||||
|
auto& state = system.GetDSPState().GetData();
|
||||||
|
|
||||||
// For each interrupt bit in DSP_CONTROL, the interrupt enablemask is the bit directly
|
// For each interrupt bit in DSP_CONTROL, the interrupt enablemask is the bit directly
|
||||||
// to the left of it. By doing:
|
// to the left of it. By doing:
|
||||||
|
@ -474,7 +475,7 @@ static void UpdateInterrupts()
|
||||||
bool ints_set = (((state.dsp_control.Hex >> 1) & state.dsp_control.Hex &
|
bool ints_set = (((state.dsp_control.Hex >> 1) & state.dsp_control.Hex &
|
||||||
(INT_DSP | INT_ARAM | INT_AID)) != 0);
|
(INT_DSP | INT_ARAM | INT_AID)) != 0);
|
||||||
|
|
||||||
ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_DSP, ints_set);
|
system.GetProcessorInterface().SetInterrupt(ProcessorInterface::INT_CAUSE_DSP, ints_set);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GenerateDSPInterrupt(Core::System& system, u64 DSPIntType, s64 cyclesLate)
|
static void GenerateDSPInterrupt(Core::System& system, u64 DSPIntType, s64 cyclesLate)
|
||||||
|
|
|
@ -737,7 +737,7 @@ static void UpdateInterrupts()
|
||||||
(state.DISR.BRKINT & state.DISR.BRKINTMASK) != 0 ||
|
(state.DISR.BRKINT & state.DISR.BRKINTMASK) != 0 ||
|
||||||
(state.DICVR.CVRINT & state.DICVR.CVRINTMASK) != 0;
|
(state.DICVR.CVRINT & state.DICVR.CVRINTMASK) != 0;
|
||||||
|
|
||||||
ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_DI, set_mask);
|
system.GetProcessorInterface().SetInterrupt(ProcessorInterface::INT_CAUSE_DI, set_mask);
|
||||||
|
|
||||||
// Required for Summoner: A Goddess Reborn
|
// Required for Summoner: A Goddess Reborn
|
||||||
system.GetCoreTiming().ForceExceptionCheck(50);
|
system.GetCoreTiming().ForceExceptionCheck(50);
|
||||||
|
|
|
@ -263,14 +263,15 @@ void UpdateInterrupts()
|
||||||
// Channel 0 Device 0 generates interrupt on channel 0
|
// Channel 0 Device 0 generates interrupt on channel 0
|
||||||
// Channel 0 Device 2 generates interrupt on channel 2
|
// Channel 0 Device 2 generates interrupt on channel 2
|
||||||
// Channel 1 Device 0 generates interrupt on channel 1
|
// Channel 1 Device 0 generates interrupt on channel 1
|
||||||
auto& state = Core::System::GetInstance().GetExpansionInterfaceState().GetData();
|
auto& system = Core::System::GetInstance();
|
||||||
|
auto& state = system.GetExpansionInterfaceState().GetData();
|
||||||
state.channels[2]->SetEXIINT(state.channels[0]->GetDevice(4)->IsInterruptSet());
|
state.channels[2]->SetEXIINT(state.channels[0]->GetDevice(4)->IsInterruptSet());
|
||||||
|
|
||||||
bool causeInt = false;
|
bool causeInt = false;
|
||||||
for (auto& channel : state.channels)
|
for (auto& channel : state.channels)
|
||||||
causeInt |= channel->IsCausingInterrupt();
|
causeInt |= channel->IsCausingInterrupt();
|
||||||
|
|
||||||
ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_EXI, causeInt);
|
system.GetProcessorInterface().SetInterrupt(ProcessorInterface::INT_CAUSE_EXI, causeInt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void UpdateInterruptsCallback(Core::System& system, u64 userdata, s64 cycles_late)
|
static void UpdateInterruptsCallback(Core::System& system, u64 userdata, s64 cycles_late)
|
||||||
|
|
|
@ -85,10 +85,11 @@ void UpdateGatherPipe()
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = Core::System::GetInstance();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
auto& processor_interface = system.GetProcessorInterface();
|
||||||
|
|
||||||
size_t pipe_count = GetGatherPipeCount();
|
size_t pipe_count = GetGatherPipeCount();
|
||||||
size_t processed;
|
size_t processed;
|
||||||
u8* cur_mem = memory.GetPointer(ProcessorInterface::Fifo_CPUWritePointer);
|
u8* cur_mem = memory.GetPointer(processor_interface.Fifo_CPUWritePointer);
|
||||||
for (processed = 0; pipe_count >= GATHER_PIPE_SIZE; processed += GATHER_PIPE_SIZE)
|
for (processed = 0; pipe_count >= GATHER_PIPE_SIZE; processed += GATHER_PIPE_SIZE)
|
||||||
{
|
{
|
||||||
// copy the GatherPipe
|
// copy the GatherPipe
|
||||||
|
@ -96,15 +97,15 @@ void UpdateGatherPipe()
|
||||||
pipe_count -= GATHER_PIPE_SIZE;
|
pipe_count -= GATHER_PIPE_SIZE;
|
||||||
|
|
||||||
// increase the CPUWritePointer
|
// increase the CPUWritePointer
|
||||||
if (ProcessorInterface::Fifo_CPUWritePointer == ProcessorInterface::Fifo_CPUEnd)
|
if (processor_interface.Fifo_CPUWritePointer == processor_interface.Fifo_CPUEnd)
|
||||||
{
|
{
|
||||||
ProcessorInterface::Fifo_CPUWritePointer = ProcessorInterface::Fifo_CPUBase;
|
processor_interface.Fifo_CPUWritePointer = processor_interface.Fifo_CPUBase;
|
||||||
cur_mem = memory.GetPointer(ProcessorInterface::Fifo_CPUWritePointer);
|
cur_mem = memory.GetPointer(processor_interface.Fifo_CPUWritePointer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cur_mem += GATHER_PIPE_SIZE;
|
cur_mem += GATHER_PIPE_SIZE;
|
||||||
ProcessorInterface::Fifo_CPUWritePointer += GATHER_PIPE_SIZE;
|
processor_interface.Fifo_CPUWritePointer += GATHER_PIPE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
system.GetCommandProcessor().GatherPipeBursted(system);
|
system.GetCommandProcessor().GatherPipeBursted(system);
|
||||||
|
|
|
@ -43,7 +43,7 @@ void Init(const Sram* override_sram)
|
||||||
AudioInterface::Init();
|
AudioInterface::Init();
|
||||||
VideoInterface::Init();
|
VideoInterface::Init();
|
||||||
SerialInterface::Init();
|
SerialInterface::Init();
|
||||||
ProcessorInterface::Init();
|
system.GetProcessorInterface().Init();
|
||||||
ExpansionInterface::Init(override_sram); // Needs to be initialized before Memory
|
ExpansionInterface::Init(override_sram); // Needs to be initialized before Memory
|
||||||
HSP::Init();
|
HSP::Init();
|
||||||
system.GetMemory().Init(); // Needs to be initialized before AddressSpace
|
system.GetMemory().Init(); // Needs to be initialized before AddressSpace
|
||||||
|
@ -97,7 +97,7 @@ void DoState(PointerWrap& p)
|
||||||
p.DoMarker("VideoInterface");
|
p.DoMarker("VideoInterface");
|
||||||
SerialInterface::DoState(p);
|
SerialInterface::DoState(p);
|
||||||
p.DoMarker("SerialInterface");
|
p.DoMarker("SerialInterface");
|
||||||
ProcessorInterface::DoState(p);
|
system.GetProcessorInterface().DoState(p);
|
||||||
p.DoMarker("ProcessorInterface");
|
p.DoMarker("ProcessorInterface");
|
||||||
DSP::DoState(p);
|
DSP::DoState(p);
|
||||||
p.DoMarker("DSP");
|
p.DoMarker("DSP");
|
||||||
|
|
|
@ -52,7 +52,7 @@ void MemoryManager::InitMMIO(bool is_wii)
|
||||||
system.GetCommandProcessor().RegisterMMIO(system, m_mmio_mapping.get(), 0x0C000000);
|
system.GetCommandProcessor().RegisterMMIO(system, m_mmio_mapping.get(), 0x0C000000);
|
||||||
system.GetPixelEngine().RegisterMMIO(m_mmio_mapping.get(), 0x0C001000);
|
system.GetPixelEngine().RegisterMMIO(m_mmio_mapping.get(), 0x0C001000);
|
||||||
VideoInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0C002000);
|
VideoInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0C002000);
|
||||||
ProcessorInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0C003000);
|
system.GetProcessorInterface().RegisterMMIO(m_mmio_mapping.get(), 0x0C003000);
|
||||||
MemoryInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0C004000);
|
MemoryInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0C004000);
|
||||||
DSP::RegisterMMIO(m_mmio_mapping.get(), 0x0C005000);
|
DSP::RegisterMMIO(m_mmio_mapping.get(), 0x0C005000);
|
||||||
DVDInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0C006000, false);
|
DVDInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0C006000, false);
|
||||||
|
|
|
@ -27,30 +27,7 @@ constexpr u32 FLIPPER_REV_A = 0x046500B0;
|
||||||
constexpr u32 FLIPPER_REV_B = 0x146500B1;
|
constexpr u32 FLIPPER_REV_B = 0x146500B1;
|
||||||
constexpr u32 FLIPPER_REV_C = 0x246500B1;
|
constexpr u32 FLIPPER_REV_C = 0x246500B1;
|
||||||
|
|
||||||
// STATE_TO_SAVE
|
void ProcessorInterfaceManager::DoState(PointerWrap& p)
|
||||||
u32 m_InterruptCause;
|
|
||||||
u32 m_InterruptMask;
|
|
||||||
// addresses for CPU fifo accesses
|
|
||||||
u32 Fifo_CPUBase;
|
|
||||||
u32 Fifo_CPUEnd;
|
|
||||||
u32 Fifo_CPUWritePointer;
|
|
||||||
|
|
||||||
static u32 m_ResetCode;
|
|
||||||
|
|
||||||
// ID and callback for scheduling reset button presses/releases
|
|
||||||
static CoreTiming::EventType* toggleResetButton;
|
|
||||||
static void ToggleResetButtonCallback(Core::System& system, u64 userdata, s64 cyclesLate);
|
|
||||||
|
|
||||||
static CoreTiming::EventType* iosNotifyResetButton;
|
|
||||||
static void IOSNotifyResetButtonCallback(Core::System& system, u64 userdata, s64 cyclesLate);
|
|
||||||
|
|
||||||
static CoreTiming::EventType* iosNotifyPowerButton;
|
|
||||||
static void IOSNotifyPowerButtonCallback(Core::System& system, u64 userdata, s64 cyclesLate);
|
|
||||||
|
|
||||||
// Let the PPC know that an external exception is set/cleared
|
|
||||||
void UpdateException();
|
|
||||||
|
|
||||||
void DoState(PointerWrap& p)
|
|
||||||
{
|
{
|
||||||
p.Do(m_InterruptMask);
|
p.Do(m_InterruptMask);
|
||||||
p.Do(m_InterruptCause);
|
p.Do(m_InterruptCause);
|
||||||
|
@ -60,7 +37,7 @@ void DoState(PointerWrap& p)
|
||||||
p.Do(m_ResetCode);
|
p.Do(m_ResetCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Init()
|
void ProcessorInterfaceManager::Init()
|
||||||
{
|
{
|
||||||
m_InterruptMask = 0;
|
m_InterruptMask = 0;
|
||||||
m_InterruptCause = 0;
|
m_InterruptCause = 0;
|
||||||
|
@ -81,18 +58,20 @@ void Init()
|
||||||
core_timing.RegisterEvent("IOSNotifyPowerButton", IOSNotifyPowerButtonCallback);
|
core_timing.RegisterEvent("IOSNotifyPowerButton", IOSNotifyPowerButtonCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
void ProcessorInterfaceManager::RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
||||||
{
|
{
|
||||||
mmio->Register(base | PI_INTERRUPT_CAUSE, MMIO::DirectRead<u32>(&m_InterruptCause),
|
mmio->Register(base | PI_INTERRUPT_CAUSE, MMIO::DirectRead<u32>(&m_InterruptCause),
|
||||||
MMIO::ComplexWrite<u32>([](Core::System&, u32, u32 val) {
|
MMIO::ComplexWrite<u32>([](Core::System& system, u32, u32 val) {
|
||||||
m_InterruptCause &= ~val;
|
auto& processor_interface = system.GetProcessorInterface();
|
||||||
UpdateException();
|
processor_interface.m_InterruptCause &= ~val;
|
||||||
|
processor_interface.UpdateException();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
mmio->Register(base | PI_INTERRUPT_MASK, MMIO::DirectRead<u32>(&m_InterruptMask),
|
mmio->Register(base | PI_INTERRUPT_MASK, MMIO::DirectRead<u32>(&m_InterruptMask),
|
||||||
MMIO::ComplexWrite<u32>([](Core::System&, u32, u32 val) {
|
MMIO::ComplexWrite<u32>([](Core::System& system, u32, u32 val) {
|
||||||
m_InterruptMask = val;
|
auto& processor_interface = system.GetProcessorInterface();
|
||||||
UpdateException();
|
processor_interface.m_InterruptMask = val;
|
||||||
|
processor_interface.UpdateException();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
mmio->Register(base | PI_FIFO_BASE, MMIO::DirectRead<u32>(&Fifo_CPUBase),
|
mmio->Register(base | PI_FIFO_BASE, MMIO::DirectRead<u32>(&Fifo_CPUBase),
|
||||||
|
@ -127,14 +106,18 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
mmio->Register(base | PI_RESET_CODE, MMIO::ComplexRead<u32>([](Core::System&, u32) {
|
mmio->Register(base | PI_RESET_CODE, MMIO::ComplexRead<u32>([](Core::System& system, u32) {
|
||||||
DEBUG_LOG_FMT(PROCESSORINTERFACE, "Read PI_RESET_CODE: {:08x}", m_ResetCode);
|
auto& processor_interface = system.GetProcessorInterface();
|
||||||
return m_ResetCode;
|
DEBUG_LOG_FMT(PROCESSORINTERFACE, "Read PI_RESET_CODE: {:08x}",
|
||||||
|
processor_interface.m_ResetCode);
|
||||||
|
return processor_interface.m_ResetCode;
|
||||||
}),
|
}),
|
||||||
MMIO::ComplexWrite<u32>([](Core::System&, u32, u32 val) {
|
MMIO::ComplexWrite<u32>([](Core::System& system, u32, u32 val) {
|
||||||
m_ResetCode = val;
|
auto& processor_interface = system.GetProcessorInterface();
|
||||||
INFO_LOG_FMT(PROCESSORINTERFACE, "Wrote PI_RESET_CODE: {:08x}", m_ResetCode);
|
processor_interface.m_ResetCode = val;
|
||||||
if (!SConfig::GetInstance().bWii && ~m_ResetCode & 0x4)
|
INFO_LOG_FMT(PROCESSORINTERFACE, "Wrote PI_RESET_CODE: {:08x}",
|
||||||
|
processor_interface.m_ResetCode);
|
||||||
|
if (!SConfig::GetInstance().bWii && ~processor_interface.m_ResetCode & 0x4)
|
||||||
{
|
{
|
||||||
DVDInterface::ResetDrive(true);
|
DVDInterface::ResetDrive(true);
|
||||||
}
|
}
|
||||||
|
@ -153,7 +136,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateException()
|
void ProcessorInterfaceManager::UpdateException()
|
||||||
{
|
{
|
||||||
if ((m_InterruptCause & m_InterruptMask) != 0)
|
if ((m_InterruptCause & m_InterruptMask) != 0)
|
||||||
PowerPC::ppcState.Exceptions |= EXCEPTION_EXTERNAL_INT;
|
PowerPC::ppcState.Exceptions |= EXCEPTION_EXTERNAL_INT;
|
||||||
|
@ -202,7 +185,7 @@ static const char* Debug_GetInterruptName(u32 cause_mask)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetInterrupt(u32 cause_mask, bool set)
|
void ProcessorInterfaceManager::SetInterrupt(u32 cause_mask, bool set)
|
||||||
{
|
{
|
||||||
DEBUG_ASSERT_MSG(POWERPC, Core::IsCPUThread(), "SetInterrupt from wrong thread");
|
DEBUG_ASSERT_MSG(POWERPC, Core::IsCPUThread(), "SetInterrupt from wrong thread");
|
||||||
|
|
||||||
|
@ -227,17 +210,19 @@ void SetInterrupt(u32 cause_mask, bool set)
|
||||||
UpdateException();
|
UpdateException();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetResetButton(bool set)
|
void ProcessorInterfaceManager::SetResetButton(bool set)
|
||||||
{
|
{
|
||||||
SetInterrupt(INT_CAUSE_RST_BUTTON, !set);
|
SetInterrupt(INT_CAUSE_RST_BUTTON, !set);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ToggleResetButtonCallback(Core::System& system, u64 userdata, s64 cyclesLate)
|
void ProcessorInterfaceManager::ToggleResetButtonCallback(Core::System& system, u64 userdata,
|
||||||
|
s64 cyclesLate)
|
||||||
{
|
{
|
||||||
SetResetButton(!!userdata);
|
system.GetProcessorInterface().SetResetButton(!!userdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void IOSNotifyResetButtonCallback(Core::System& system, u64 userdata, s64 cyclesLate)
|
void ProcessorInterfaceManager::IOSNotifyResetButtonCallback(Core::System& system, u64 userdata,
|
||||||
|
s64 cyclesLate)
|
||||||
{
|
{
|
||||||
const auto ios = IOS::HLE::GetIOS();
|
const auto ios = IOS::HLE::GetIOS();
|
||||||
if (!ios)
|
if (!ios)
|
||||||
|
@ -248,7 +233,8 @@ static void IOSNotifyResetButtonCallback(Core::System& system, u64 userdata, s64
|
||||||
std::static_pointer_cast<IOS::HLE::STMEventHookDevice>(stm)->ResetButton();
|
std::static_pointer_cast<IOS::HLE::STMEventHookDevice>(stm)->ResetButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void IOSNotifyPowerButtonCallback(Core::System& system, u64 userdata, s64 cyclesLate)
|
void ProcessorInterfaceManager::IOSNotifyPowerButtonCallback(Core::System& system, u64 userdata,
|
||||||
|
s64 cyclesLate)
|
||||||
{
|
{
|
||||||
const auto ios = IOS::HLE::GetIOS();
|
const auto ios = IOS::HLE::GetIOS();
|
||||||
if (!ios)
|
if (!ios)
|
||||||
|
@ -259,7 +245,7 @@ static void IOSNotifyPowerButtonCallback(Core::System& system, u64 userdata, s64
|
||||||
std::static_pointer_cast<IOS::HLE::STMEventHookDevice>(stm)->PowerButton();
|
std::static_pointer_cast<IOS::HLE::STMEventHookDevice>(stm)->PowerButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResetButton_Tap()
|
void ProcessorInterfaceManager::ResetButton_Tap()
|
||||||
{
|
{
|
||||||
if (!Core::IsRunning())
|
if (!Core::IsRunning())
|
||||||
return;
|
return;
|
||||||
|
@ -272,7 +258,7 @@ void ResetButton_Tap()
|
||||||
CoreTiming::FromThread::ANY);
|
CoreTiming::FromThread::ANY);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PowerButton_Tap()
|
void ProcessorInterfaceManager::PowerButton_Tap()
|
||||||
{
|
{
|
||||||
if (!Core::IsRunning())
|
if (!Core::IsRunning())
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -7,6 +7,14 @@
|
||||||
|
|
||||||
class PointerWrap;
|
class PointerWrap;
|
||||||
|
|
||||||
|
namespace Core
|
||||||
|
{
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
namespace CoreTiming
|
||||||
|
{
|
||||||
|
struct EventType;
|
||||||
|
}
|
||||||
namespace MMIO
|
namespace MMIO
|
||||||
{
|
{
|
||||||
class Mapping;
|
class Mapping;
|
||||||
|
@ -52,30 +60,46 @@ enum
|
||||||
PI_FLIPPER_UNK = 0x30 // BS1 writes 0x0245248A to it - prolly some bootstrap thing
|
PI_FLIPPER_UNK = 0x30 // BS1 writes 0x0245248A to it - prolly some bootstrap thing
|
||||||
};
|
};
|
||||||
|
|
||||||
extern u32 m_InterruptCause;
|
class ProcessorInterfaceManager
|
||||||
extern u32 m_InterruptMask;
|
|
||||||
extern u32 Fifo_CPUBase;
|
|
||||||
extern u32 Fifo_CPUEnd;
|
|
||||||
extern u32 Fifo_CPUWritePointer;
|
|
||||||
|
|
||||||
void Init();
|
|
||||||
void DoState(PointerWrap& p);
|
|
||||||
|
|
||||||
void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
|
|
||||||
|
|
||||||
inline u32 GetMask()
|
|
||||||
{
|
{
|
||||||
return m_InterruptMask;
|
public:
|
||||||
}
|
void Init();
|
||||||
inline u32 GetCause()
|
void DoState(PointerWrap& p);
|
||||||
{
|
|
||||||
return m_InterruptCause;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetInterrupt(u32 cause_mask, bool set = true);
|
void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
|
||||||
|
|
||||||
// Thread-safe func which sets and clears reset button state automagically
|
u32 GetMask() const { return m_InterruptMask; }
|
||||||
void ResetButton_Tap();
|
u32 GetCause() const { return m_InterruptCause; }
|
||||||
void PowerButton_Tap();
|
|
||||||
|
|
||||||
|
void SetInterrupt(u32 cause_mask, bool set = true);
|
||||||
|
|
||||||
|
// Thread-safe func which sets and clears reset button state automagically
|
||||||
|
void ResetButton_Tap();
|
||||||
|
void PowerButton_Tap();
|
||||||
|
|
||||||
|
u32 m_InterruptCause = 0;
|
||||||
|
u32 m_InterruptMask = 0;
|
||||||
|
|
||||||
|
// addresses for CPU fifo accesses
|
||||||
|
u32 Fifo_CPUBase = 0;
|
||||||
|
u32 Fifo_CPUEnd = 0;
|
||||||
|
u32 Fifo_CPUWritePointer = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Let the PPC know that an external exception is set/cleared
|
||||||
|
void UpdateException();
|
||||||
|
|
||||||
|
void SetResetButton(bool set);
|
||||||
|
|
||||||
|
// ID and callback for scheduling reset button presses/releases
|
||||||
|
static void ToggleResetButtonCallback(Core::System& system, u64 userdata, s64 cyclesLate);
|
||||||
|
static void IOSNotifyResetButtonCallback(Core::System& system, u64 userdata, s64 cyclesLate);
|
||||||
|
static void IOSNotifyPowerButtonCallback(Core::System& system, u64 userdata, s64 cyclesLate);
|
||||||
|
|
||||||
|
CoreTiming::EventType* toggleResetButton = nullptr;
|
||||||
|
CoreTiming::EventType* iosNotifyResetButton = nullptr;
|
||||||
|
CoreTiming::EventType* iosNotifyPowerButton = nullptr;
|
||||||
|
|
||||||
|
u32 m_ResetCode = 0;
|
||||||
|
};
|
||||||
} // namespace ProcessorInterface
|
} // namespace ProcessorInterface
|
||||||
|
|
|
@ -253,7 +253,8 @@ static void ChangeDeviceCallback(Core::System& system, u64 user_data, s64 cycles
|
||||||
static void UpdateInterrupts()
|
static void UpdateInterrupts()
|
||||||
{
|
{
|
||||||
// check if we have to update the RDSTINT flag
|
// check if we have to update the RDSTINT flag
|
||||||
auto& state = Core::System::GetInstance().GetSerialInterfaceState().GetData();
|
auto& system = Core::System::GetInstance();
|
||||||
|
auto& state = system.GetSerialInterfaceState().GetData();
|
||||||
if (state.status_reg.RDST0 || state.status_reg.RDST1 || state.status_reg.RDST2 ||
|
if (state.status_reg.RDST0 || state.status_reg.RDST1 || state.status_reg.RDST2 ||
|
||||||
state.status_reg.RDST3)
|
state.status_reg.RDST3)
|
||||||
{
|
{
|
||||||
|
@ -268,7 +269,7 @@ static void UpdateInterrupts()
|
||||||
const bool generate_interrupt = (state.com_csr.RDSTINT & state.com_csr.RDSTINTMSK) != 0 ||
|
const bool generate_interrupt = (state.com_csr.RDSTINT & state.com_csr.RDSTINTMSK) != 0 ||
|
||||||
(state.com_csr.TCINT & state.com_csr.TCINTMSK) != 0;
|
(state.com_csr.TCINT & state.com_csr.TCINTMSK) != 0;
|
||||||
|
|
||||||
ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_SI, generate_interrupt);
|
system.GetProcessorInterface().SetInterrupt(ProcessorInterface::INT_CAUSE_SI, generate_interrupt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GenerateSIInterrupt(SIInterruptType type)
|
static void GenerateSIInterrupt(SIInterruptType type)
|
||||||
|
|
|
@ -269,13 +269,14 @@ CSIDevice_GCController::HandleButtonCombos(const GCPadStatus& pad_status)
|
||||||
|
|
||||||
if (m_last_button_combo != COMBO_NONE)
|
if (m_last_button_combo != COMBO_NONE)
|
||||||
{
|
{
|
||||||
const u64 current_time = Core::System::GetInstance().GetCoreTiming().GetTicks();
|
auto& system = Core::System::GetInstance();
|
||||||
|
const u64 current_time = system.GetCoreTiming().GetTicks();
|
||||||
if (u32(current_time - m_timer_button_combo_start) > SystemTimers::GetTicksPerSecond() * 3)
|
if (u32(current_time - m_timer_button_combo_start) > SystemTimers::GetTicksPerSecond() * 3)
|
||||||
{
|
{
|
||||||
if (m_last_button_combo == COMBO_RESET)
|
if (m_last_button_combo == COMBO_RESET)
|
||||||
{
|
{
|
||||||
INFO_LOG_FMT(SERIALINTERFACE, "PAD - COMBO_RESET");
|
INFO_LOG_FMT(SERIALINTERFACE, "PAD - COMBO_RESET");
|
||||||
ProcessorInterface::ResetButton_Tap();
|
system.GetProcessorInterface().ResetButton_Tap();
|
||||||
}
|
}
|
||||||
else if (m_last_button_combo == COMBO_ORIGIN)
|
else if (m_last_button_combo == COMBO_ORIGIN)
|
||||||
{
|
{
|
||||||
|
|
|
@ -424,17 +424,18 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
||||||
|
|
||||||
void UpdateInterrupts()
|
void UpdateInterrupts()
|
||||||
{
|
{
|
||||||
auto& state = Core::System::GetInstance().GetVideoInterfaceState().GetData();
|
auto& system = Core::System::GetInstance();
|
||||||
|
auto& state = system.GetVideoInterfaceState().GetData();
|
||||||
if ((state.interrupt_register[0].IR_INT && state.interrupt_register[0].IR_MASK) ||
|
if ((state.interrupt_register[0].IR_INT && state.interrupt_register[0].IR_MASK) ||
|
||||||
(state.interrupt_register[1].IR_INT && state.interrupt_register[1].IR_MASK) ||
|
(state.interrupt_register[1].IR_INT && state.interrupt_register[1].IR_MASK) ||
|
||||||
(state.interrupt_register[2].IR_INT && state.interrupt_register[2].IR_MASK) ||
|
(state.interrupt_register[2].IR_INT && state.interrupt_register[2].IR_MASK) ||
|
||||||
(state.interrupt_register[3].IR_INT && state.interrupt_register[3].IR_MASK))
|
(state.interrupt_register[3].IR_INT && state.interrupt_register[3].IR_MASK))
|
||||||
{
|
{
|
||||||
ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_VI, true);
|
system.GetProcessorInterface().SetInterrupt(ProcessorInterface::INT_CAUSE_VI, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_VI, false);
|
system.GetProcessorInterface().SetInterrupt(ProcessorInterface::INT_CAUSE_VI, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -298,7 +298,7 @@ static void UpdateInterrupts(Core::System& system, u64 userdata, s64 cyclesLate)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate interrupt on PI if any of the devices behind starlet have an interrupt and mask is set
|
// Generate interrupt on PI if any of the devices behind starlet have an interrupt and mask is set
|
||||||
ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_WII_IPC,
|
system.GetProcessorInterface().SetInterrupt(ProcessorInterface::INT_CAUSE_WII_IPC,
|
||||||
!!(ppc_irq_flags & ppc_irq_masks));
|
!!(ppc_irq_flags & ppc_irq_masks));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1273,7 +1273,10 @@ void PlayController(GCPadStatus* PadStatus, int controllerID)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s_padState.reset)
|
if (s_padState.reset)
|
||||||
ProcessorInterface::ResetButton_Tap();
|
{
|
||||||
|
auto& system = Core::System::GetInstance();
|
||||||
|
system.GetProcessorInterface().ResetButton_Tap();
|
||||||
|
}
|
||||||
|
|
||||||
SetInputDisplayString(s_padState, controllerID);
|
SetInputDisplayString(s_padState, controllerID);
|
||||||
CheckInputEnd();
|
CheckInputEnd();
|
||||||
|
|
|
@ -1044,7 +1044,8 @@ bool Jit64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
|
||||||
SetJumpTarget(extException);
|
SetJumpTarget(extException);
|
||||||
TEST(32, PPCSTATE(msr), Imm32(0x0008000));
|
TEST(32, PPCSTATE(msr), Imm32(0x0008000));
|
||||||
FixupBranch noExtIntEnable = J_CC(CC_Z, true);
|
FixupBranch noExtIntEnable = J_CC(CC_Z, true);
|
||||||
MOV(64, R(RSCRATCH), ImmPtr(&ProcessorInterface::m_InterruptCause));
|
auto& system = Core::System::GetInstance();
|
||||||
|
MOV(64, R(RSCRATCH), ImmPtr(&system.GetProcessorInterface().m_InterruptCause));
|
||||||
TEST(32, MatR(RSCRATCH),
|
TEST(32, MatR(RSCRATCH),
|
||||||
Imm32(ProcessorInterface::INT_CAUSE_CP | ProcessorInterface::INT_CAUSE_PE_TOKEN |
|
Imm32(ProcessorInterface::INT_CAUSE_CP | ProcessorInterface::INT_CAUSE_PE_TOKEN |
|
||||||
ProcessorInterface::INT_CAUSE_PE_FINISH));
|
ProcessorInterface::INT_CAUSE_PE_FINISH));
|
||||||
|
|
|
@ -452,7 +452,8 @@ void Jit64::mtmsr(UGeckoInstruction inst)
|
||||||
FixupBranch noExceptionsPending = J_CC(CC_Z, true);
|
FixupBranch noExceptionsPending = J_CC(CC_Z, true);
|
||||||
|
|
||||||
// Check if a CP interrupt is waiting and keep the GPU emulation in sync (issue 4336)
|
// Check if a CP interrupt is waiting and keep the GPU emulation in sync (issue 4336)
|
||||||
MOV(64, R(RSCRATCH), ImmPtr(&ProcessorInterface::m_InterruptCause));
|
auto& system = Core::System::GetInstance();
|
||||||
|
MOV(64, R(RSCRATCH), ImmPtr(&system.GetProcessorInterface().m_InterruptCause));
|
||||||
TEST(32, MatR(RSCRATCH), Imm32(ProcessorInterface::INT_CAUSE_CP));
|
TEST(32, MatR(RSCRATCH), Imm32(ProcessorInterface::INT_CAUSE_CP));
|
||||||
FixupBranch cpInt = J_CC(CC_NZ);
|
FixupBranch cpInt = J_CC(CC_NZ);
|
||||||
|
|
||||||
|
|
|
@ -979,8 +979,9 @@ bool JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
|
||||||
SetJumpTarget(exception);
|
SetJumpTarget(exception);
|
||||||
LDR(IndexType::Unsigned, ARM64Reg::W30, PPC_REG, PPCSTATE_OFF(msr));
|
LDR(IndexType::Unsigned, ARM64Reg::W30, PPC_REG, PPCSTATE_OFF(msr));
|
||||||
TBZ(ARM64Reg::W30, 15, done_here); // MSR.EE
|
TBZ(ARM64Reg::W30, 15, done_here); // MSR.EE
|
||||||
|
auto& system = Core::System::GetInstance();
|
||||||
LDR(IndexType::Unsigned, ARM64Reg::W30, ARM64Reg::X30,
|
LDR(IndexType::Unsigned, ARM64Reg::W30, ARM64Reg::X30,
|
||||||
MOVPage2R(ARM64Reg::X30, &ProcessorInterface::m_InterruptCause));
|
MOVPage2R(ARM64Reg::X30, &system.GetProcessorInterface().m_InterruptCause));
|
||||||
constexpr u32 cause_mask = ProcessorInterface::INT_CAUSE_CP |
|
constexpr u32 cause_mask = ProcessorInterface::INT_CAUSE_CP |
|
||||||
ProcessorInterface::INT_CAUSE_PE_TOKEN |
|
ProcessorInterface::INT_CAUSE_PE_TOKEN |
|
||||||
ProcessorInterface::INT_CAUSE_PE_FINISH;
|
ProcessorInterface::INT_CAUSE_PE_FINISH;
|
||||||
|
@ -1015,7 +1016,9 @@ bool JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
|
||||||
SetJumpTarget(exception);
|
SetJumpTarget(exception);
|
||||||
LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(msr));
|
LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(msr));
|
||||||
TBZ(WA, 15, done_here); // MSR.EE
|
TBZ(WA, 15, done_here); // MSR.EE
|
||||||
LDR(IndexType::Unsigned, WA, XA, MOVPage2R(XA, &ProcessorInterface::m_InterruptCause));
|
auto& system = Core::System::GetInstance();
|
||||||
|
LDR(IndexType::Unsigned, WA, XA,
|
||||||
|
MOVPage2R(XA, &system.GetProcessorInterface().m_InterruptCause));
|
||||||
constexpr u32 cause_mask = ProcessorInterface::INT_CAUSE_CP |
|
constexpr u32 cause_mask = ProcessorInterface::INT_CAUSE_CP |
|
||||||
ProcessorInterface::INT_CAUSE_PE_TOKEN |
|
ProcessorInterface::INT_CAUSE_PE_TOKEN |
|
||||||
ProcessorInterface::INT_CAUSE_PE_FINISH;
|
ProcessorInterface::INT_CAUSE_PE_FINISH;
|
||||||
|
|
|
@ -255,8 +255,8 @@ static T ReadFromHardware(Memory::MemoryManager& memory, u32 em_address)
|
||||||
}
|
}
|
||||||
|
|
||||||
template <XCheckTLBFlag flag, bool never_translate = false>
|
template <XCheckTLBFlag flag, bool never_translate = false>
|
||||||
static void WriteToHardware(Memory::MemoryManager& memory, u32 em_address, const u32 data,
|
static void WriteToHardware(Core::System& system, Memory::MemoryManager& memory, u32 em_address,
|
||||||
const u32 size)
|
const u32 data, const u32 size)
|
||||||
{
|
{
|
||||||
DEBUG_ASSERT(size <= 4);
|
DEBUG_ASSERT(size <= 4);
|
||||||
|
|
||||||
|
@ -269,9 +269,10 @@ static void WriteToHardware(Memory::MemoryManager& memory, u32 em_address, const
|
||||||
// Note that "word" means 32-bit, so paired singles or doubles might still be 32-bit aligned!
|
// Note that "word" means 32-bit, so paired singles or doubles might still be 32-bit aligned!
|
||||||
const u32 first_half_size = em_address_end_page - em_address;
|
const u32 first_half_size = em_address_end_page - em_address;
|
||||||
const u32 second_half_size = size - first_half_size;
|
const u32 second_half_size = size - first_half_size;
|
||||||
WriteToHardware<flag, never_translate>(memory, em_address,
|
WriteToHardware<flag, never_translate>(system, memory, em_address,
|
||||||
std::rotr(data, second_half_size * 8), first_half_size);
|
std::rotr(data, second_half_size * 8), first_half_size);
|
||||||
WriteToHardware<flag, never_translate>(memory, em_address_end_page, data, second_half_size);
|
WriteToHardware<flag, never_translate>(system, memory, em_address_end_page, data,
|
||||||
|
second_half_size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,7 +377,7 @@ static void WriteToHardware(Memory::MemoryManager& memory, u32 em_address, const
|
||||||
// TODO: This interrupt is supposed to have associated cause and address registers
|
// TODO: This interrupt is supposed to have associated cause and address registers
|
||||||
// TODO: This should trigger the hwtest's interrupt handling, but it does not seem to
|
// TODO: This should trigger the hwtest's interrupt handling, but it does not seem to
|
||||||
// (https://github.com/dolphin-emu/hwtests/pull/42)
|
// (https://github.com/dolphin-emu/hwtests/pull/42)
|
||||||
ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_PI);
|
system.GetProcessorInterface().SetInterrupt(ProcessorInterface::INT_CAUSE_PI);
|
||||||
|
|
||||||
const u32 rotated_data = std::rotr(data, ((em_address & 0x3) + size) * 8);
|
const u32 rotated_data = std::rotr(data, ((em_address & 0x3) + size) * 8);
|
||||||
|
|
||||||
|
@ -384,8 +385,8 @@ static void WriteToHardware(Memory::MemoryManager& memory, u32 em_address, const
|
||||||
const u32 end_addr = Common::AlignUp(em_address + size, 8);
|
const u32 end_addr = Common::AlignUp(em_address + size, 8);
|
||||||
for (u32 addr = start_addr; addr != end_addr; addr += 8)
|
for (u32 addr = start_addr; addr != end_addr; addr += 8)
|
||||||
{
|
{
|
||||||
WriteToHardware<flag, true>(memory, addr, rotated_data, 4);
|
WriteToHardware<flag, true>(system, memory, addr, rotated_data, 4);
|
||||||
WriteToHardware<flag, true>(memory, addr + 4, rotated_data, 4);
|
WriteToHardware<flag, true>(system, memory, addr + 4, rotated_data, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -688,7 +689,7 @@ void Write_U8(const u32 var, const u32 address)
|
||||||
Memcheck(address, var, true, 1);
|
Memcheck(address, var, true, 1);
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = Core::System::GetInstance();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
WriteToHardware<XCheckTLBFlag::Write>(memory, address, var, 1);
|
WriteToHardware<XCheckTLBFlag::Write>(system, memory, address, var, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Write_U16(const u32 var, const u32 address)
|
void Write_U16(const u32 var, const u32 address)
|
||||||
|
@ -696,7 +697,7 @@ void Write_U16(const u32 var, const u32 address)
|
||||||
Memcheck(address, var, true, 2);
|
Memcheck(address, var, true, 2);
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = Core::System::GetInstance();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
WriteToHardware<XCheckTLBFlag::Write>(memory, address, var, 2);
|
WriteToHardware<XCheckTLBFlag::Write>(system, memory, address, var, 2);
|
||||||
}
|
}
|
||||||
void Write_U16_Swap(const u32 var, const u32 address)
|
void Write_U16_Swap(const u32 var, const u32 address)
|
||||||
{
|
{
|
||||||
|
@ -708,7 +709,7 @@ void Write_U32(const u32 var, const u32 address)
|
||||||
Memcheck(address, var, true, 4);
|
Memcheck(address, var, true, 4);
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = Core::System::GetInstance();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
WriteToHardware<XCheckTLBFlag::Write>(memory, address, var, 4);
|
WriteToHardware<XCheckTLBFlag::Write>(system, memory, address, var, 4);
|
||||||
}
|
}
|
||||||
void Write_U32_Swap(const u32 var, const u32 address)
|
void Write_U32_Swap(const u32 var, const u32 address)
|
||||||
{
|
{
|
||||||
|
@ -720,8 +721,9 @@ void Write_U64(const u64 var, const u32 address)
|
||||||
Memcheck(address, var, true, 8);
|
Memcheck(address, var, true, 8);
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = Core::System::GetInstance();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
WriteToHardware<XCheckTLBFlag::Write>(memory, address, static_cast<u32>(var >> 32), 4);
|
WriteToHardware<XCheckTLBFlag::Write>(system, memory, address, static_cast<u32>(var >> 32), 4);
|
||||||
WriteToHardware<XCheckTLBFlag::Write>(memory, address + sizeof(u32), static_cast<u32>(var), 4);
|
WriteToHardware<XCheckTLBFlag::Write>(system, memory, address + sizeof(u32),
|
||||||
|
static_cast<u32>(var), 4);
|
||||||
}
|
}
|
||||||
void Write_U64_Swap(const u64 var, const u32 address)
|
void Write_U64_Swap(const u64 var, const u32 address)
|
||||||
{
|
{
|
||||||
|
@ -781,30 +783,31 @@ void HostWrite_U8(const u32 var, const u32 address)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = Core::System::GetInstance();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
WriteToHardware<XCheckTLBFlag::NoException>(memory, address, var, 1);
|
WriteToHardware<XCheckTLBFlag::NoException>(system, memory, address, var, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HostWrite_U16(const u32 var, const u32 address)
|
void HostWrite_U16(const u32 var, const u32 address)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = Core::System::GetInstance();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
WriteToHardware<XCheckTLBFlag::NoException>(memory, address, var, 2);
|
WriteToHardware<XCheckTLBFlag::NoException>(system, memory, address, var, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HostWrite_U32(const u32 var, const u32 address)
|
void HostWrite_U32(const u32 var, const u32 address)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = Core::System::GetInstance();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
WriteToHardware<XCheckTLBFlag::NoException>(memory, address, var, 4);
|
WriteToHardware<XCheckTLBFlag::NoException>(system, memory, address, var, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HostWrite_U64(const u64 var, const u32 address)
|
void HostWrite_U64(const u64 var, const u32 address)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = Core::System::GetInstance();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
WriteToHardware<XCheckTLBFlag::NoException>(memory, address, static_cast<u32>(var >> 32), 4);
|
WriteToHardware<XCheckTLBFlag::NoException>(system, memory, address, static_cast<u32>(var >> 32),
|
||||||
WriteToHardware<XCheckTLBFlag::NoException>(memory, address + sizeof(u32), static_cast<u32>(var),
|
|
||||||
4);
|
4);
|
||||||
|
WriteToHardware<XCheckTLBFlag::NoException>(system, memory, address + sizeof(u32),
|
||||||
|
static_cast<u32>(var), 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HostWrite_F32(const float var, const u32 address)
|
void HostWrite_F32(const float var, const u32 address)
|
||||||
|
@ -833,15 +836,15 @@ static std::optional<WriteResult> HostTryWriteUX(const u32 var, const u32 addres
|
||||||
switch (space)
|
switch (space)
|
||||||
{
|
{
|
||||||
case RequestedAddressSpace::Effective:
|
case RequestedAddressSpace::Effective:
|
||||||
WriteToHardware<XCheckTLBFlag::NoException>(memory, address, var, size);
|
WriteToHardware<XCheckTLBFlag::NoException>(system, memory, address, var, size);
|
||||||
return WriteResult(!!MSR.DR);
|
return WriteResult(!!MSR.DR);
|
||||||
case RequestedAddressSpace::Physical:
|
case RequestedAddressSpace::Physical:
|
||||||
WriteToHardware<XCheckTLBFlag::NoException, true>(memory, address, var, size);
|
WriteToHardware<XCheckTLBFlag::NoException, true>(system, memory, address, var, size);
|
||||||
return WriteResult(false);
|
return WriteResult(false);
|
||||||
case RequestedAddressSpace::Virtual:
|
case RequestedAddressSpace::Virtual:
|
||||||
if (!MSR.DR)
|
if (!MSR.DR)
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
WriteToHardware<XCheckTLBFlag::NoException>(memory, address, var, size);
|
WriteToHardware<XCheckTLBFlag::NoException>(system, memory, address, var, size);
|
||||||
return WriteResult(true);
|
return WriteResult(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1130,7 +1133,7 @@ void ClearCacheLine(u32 address)
|
||||||
// TODO: This isn't precisely correct for non-RAM regions, but the difference
|
// TODO: This isn't precisely correct for non-RAM regions, but the difference
|
||||||
// is unlikely to matter.
|
// is unlikely to matter.
|
||||||
for (u32 i = 0; i < 32; i += 4)
|
for (u32 i = 0; i < 32; i += 4)
|
||||||
WriteToHardware<XCheckTLBFlag::Write, true>(memory, address + i, 0, 4);
|
WriteToHardware<XCheckTLBFlag::Write, true>(system, memory, address + i, 0, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 IsOptimizableMMIOAccess(u32 address, u32 access_size)
|
u32 IsOptimizableMMIOAccess(u32 address, u32 access_size)
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "Core/HW/EXI/EXI.h"
|
#include "Core/HW/EXI/EXI.h"
|
||||||
#include "Core/HW/Memmap.h"
|
#include "Core/HW/Memmap.h"
|
||||||
#include "Core/HW/MemoryInterface.h"
|
#include "Core/HW/MemoryInterface.h"
|
||||||
|
#include "Core/HW/ProcessorInterface.h"
|
||||||
#include "Core/HW/SI/SI.h"
|
#include "Core/HW/SI/SI.h"
|
||||||
#include "Core/HW/Sram.h"
|
#include "Core/HW/Sram.h"
|
||||||
#include "Core/HW/VideoInterface.h"
|
#include "Core/HW/VideoInterface.h"
|
||||||
|
@ -46,6 +47,7 @@ struct System::Impl
|
||||||
MemoryInterface::MemoryInterfaceState m_memory_interface_state;
|
MemoryInterface::MemoryInterfaceState m_memory_interface_state;
|
||||||
PixelEngine::PixelEngineManager m_pixel_engine;
|
PixelEngine::PixelEngineManager m_pixel_engine;
|
||||||
PixelShaderManager m_pixel_shader_manager;
|
PixelShaderManager m_pixel_shader_manager;
|
||||||
|
ProcessorInterface::ProcessorInterfaceManager m_processor_interface;
|
||||||
SerialInterface::SerialInterfaceState m_serial_interface_state;
|
SerialInterface::SerialInterfaceState m_serial_interface_state;
|
||||||
Sram m_sram;
|
Sram m_sram;
|
||||||
VertexShaderManager m_vertex_shader_manager;
|
VertexShaderManager m_vertex_shader_manager;
|
||||||
|
@ -160,6 +162,11 @@ PixelShaderManager& System::GetPixelShaderManager() const
|
||||||
return m_impl->m_pixel_shader_manager;
|
return m_impl->m_pixel_shader_manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ProcessorInterface::ProcessorInterfaceManager& System::GetProcessorInterface() const
|
||||||
|
{
|
||||||
|
return m_impl->m_processor_interface;
|
||||||
|
}
|
||||||
|
|
||||||
SerialInterface::SerialInterfaceState& System::GetSerialInterfaceState() const
|
SerialInterface::SerialInterfaceState& System::GetSerialInterfaceState() const
|
||||||
{
|
{
|
||||||
return m_impl->m_serial_interface_state;
|
return m_impl->m_serial_interface_state;
|
||||||
|
|
|
@ -55,6 +55,10 @@ namespace PixelEngine
|
||||||
{
|
{
|
||||||
class PixelEngineManager;
|
class PixelEngineManager;
|
||||||
};
|
};
|
||||||
|
namespace ProcessorInterface
|
||||||
|
{
|
||||||
|
class ProcessorInterfaceManager;
|
||||||
|
}
|
||||||
namespace SerialInterface
|
namespace SerialInterface
|
||||||
{
|
{
|
||||||
class SerialInterfaceState;
|
class SerialInterfaceState;
|
||||||
|
@ -111,6 +115,7 @@ public:
|
||||||
MemoryInterface::MemoryInterfaceState& GetMemoryInterfaceState() const;
|
MemoryInterface::MemoryInterfaceState& GetMemoryInterfaceState() const;
|
||||||
PixelEngine::PixelEngineManager& GetPixelEngine() const;
|
PixelEngine::PixelEngineManager& GetPixelEngine() const;
|
||||||
PixelShaderManager& GetPixelShaderManager() const;
|
PixelShaderManager& GetPixelShaderManager() const;
|
||||||
|
ProcessorInterface::ProcessorInterfaceManager& GetProcessorInterface() const;
|
||||||
SerialInterface::SerialInterfaceState& GetSerialInterfaceState() const;
|
SerialInterface::SerialInterfaceState& GetSerialInterfaceState() const;
|
||||||
Sram& GetSRAM() const;
|
Sram& GetSRAM() const;
|
||||||
VertexShaderManager& GetVertexShaderManager() const;
|
VertexShaderManager& GetVertexShaderManager() const;
|
||||||
|
|
|
@ -2,14 +2,11 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include "DolphinNoGUI/Platform.h"
|
#include "DolphinNoGUI/Platform.h"
|
||||||
|
#include "Core/HW/ProcessorInterface.h"
|
||||||
#include "Core/IOS/IOS.h"
|
#include "Core/IOS/IOS.h"
|
||||||
#include "Core/IOS/STM/STM.h"
|
#include "Core/IOS/STM/STM.h"
|
||||||
#include "Core/State.h"
|
#include "Core/State.h"
|
||||||
|
#include "Core/System.h"
|
||||||
namespace ProcessorInterface
|
|
||||||
{
|
|
||||||
void PowerButton_Tap();
|
|
||||||
}
|
|
||||||
|
|
||||||
Platform::~Platform() = default;
|
Platform::~Platform() = default;
|
||||||
|
|
||||||
|
@ -31,7 +28,8 @@ void Platform::UpdateRunningFlag()
|
||||||
if (!m_tried_graceful_shutdown.IsSet() && stm &&
|
if (!m_tried_graceful_shutdown.IsSet() && stm &&
|
||||||
std::static_pointer_cast<IOS::HLE::STMEventHookDevice>(stm)->HasHookInstalled())
|
std::static_pointer_cast<IOS::HLE::STMEventHookDevice>(stm)->HasHookInstalled())
|
||||||
{
|
{
|
||||||
ProcessorInterface::PowerButton_Tap();
|
auto& system = Core::System::GetInstance();
|
||||||
|
system.GetProcessorInterface().PowerButton_Tap();
|
||||||
m_tried_graceful_shutdown.Set();
|
m_tried_graceful_shutdown.Set();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "Core/Core.h"
|
#include "Core/Core.h"
|
||||||
#include "Core/HW/ProcessorInterface.h"
|
#include "Core/HW/ProcessorInterface.h"
|
||||||
#include "Core/PowerPC/PowerPC.h"
|
#include "Core/PowerPC/PowerPC.h"
|
||||||
|
#include "Core/System.h"
|
||||||
#include "DolphinQt/Host.h"
|
#include "DolphinQt/Host.h"
|
||||||
#include "DolphinQt/Settings.h"
|
#include "DolphinQt/Settings.h"
|
||||||
|
|
||||||
|
@ -448,12 +449,20 @@ void RegisterWidget::PopulateTable()
|
||||||
|
|
||||||
// Int Mask
|
// Int Mask
|
||||||
AddRegister(
|
AddRegister(
|
||||||
27, 5, RegisterType::int_mask, "Int Mask", [] { return ProcessorInterface::GetMask(); },
|
27, 5, RegisterType::int_mask, "Int Mask",
|
||||||
|
[] {
|
||||||
|
auto& system = Core::System::GetInstance();
|
||||||
|
return system.GetProcessorInterface().GetMask();
|
||||||
|
},
|
||||||
nullptr);
|
nullptr);
|
||||||
|
|
||||||
// Int Cause
|
// Int Cause
|
||||||
AddRegister(
|
AddRegister(
|
||||||
28, 5, RegisterType::int_cause, "Int Cause", [] { return ProcessorInterface::GetCause(); },
|
28, 5, RegisterType::int_cause, "Int Cause",
|
||||||
|
[] {
|
||||||
|
auto& system = Core::System::GetInstance();
|
||||||
|
return system.GetProcessorInterface().GetCause();
|
||||||
|
},
|
||||||
nullptr);
|
nullptr);
|
||||||
|
|
||||||
// DSISR
|
// DSISR
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
#include "Core/NetPlayProto.h"
|
#include "Core/NetPlayProto.h"
|
||||||
#include "Core/NetPlayServer.h"
|
#include "Core/NetPlayServer.h"
|
||||||
#include "Core/State.h"
|
#include "Core/State.h"
|
||||||
|
#include "Core/System.h"
|
||||||
#include "Core/WiiUtils.h"
|
#include "Core/WiiUtils.h"
|
||||||
|
|
||||||
#include "DiscIO/DirectoryBlob.h"
|
#include "DiscIO/DirectoryBlob.h"
|
||||||
|
@ -942,7 +943,8 @@ void MainWindow::Reset()
|
||||||
{
|
{
|
||||||
if (Movie::IsRecordingInput())
|
if (Movie::IsRecordingInput())
|
||||||
Movie::SetReset(true);
|
Movie::SetReset(true);
|
||||||
ProcessorInterface::ResetButton_Tap();
|
auto& system = Core::System::GetInstance();
|
||||||
|
system.GetProcessorInterface().ResetButton_Tap();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::FrameAdvance()
|
void MainWindow::FrameAdvance()
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include "Core/HotkeyManager.h"
|
#include "Core/HotkeyManager.h"
|
||||||
#include "Core/IOS/IOS.h"
|
#include "Core/IOS/IOS.h"
|
||||||
#include "Core/IOS/STM/STM.h"
|
#include "Core/IOS/STM/STM.h"
|
||||||
|
#include "Core/System.h"
|
||||||
#include "Core/WiiRoot.h"
|
#include "Core/WiiRoot.h"
|
||||||
|
|
||||||
#include "InputCommon/ControllerInterface/ControllerInterface.h"
|
#include "InputCommon/ControllerInterface/ControllerInterface.h"
|
||||||
|
@ -433,7 +434,8 @@ bool TriggerSTMPowerEvent()
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Core::DisplayMessage("Shutting down", 30000);
|
Core::DisplayMessage("Shutting down", 30000);
|
||||||
ProcessorInterface::PowerButton_Tap();
|
auto& system = Core::System::GetInstance();
|
||||||
|
system.GetProcessorInterface().PowerButton_Tap();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -363,6 +363,8 @@ void CommandProcessorManager::GatherPipeBursted(Core::System& system)
|
||||||
|
|
||||||
SetCPStatusFromCPU(system);
|
SetCPStatusFromCPU(system);
|
||||||
|
|
||||||
|
auto& processor_interface = system.GetProcessorInterface();
|
||||||
|
|
||||||
// if we aren't linked, we don't care about gather pipe data
|
// if we aren't linked, we don't care about gather pipe data
|
||||||
if (!m_cp_ctrl_reg.GPLinkEnable)
|
if (!m_cp_ctrl_reg.GPLinkEnable)
|
||||||
{
|
{
|
||||||
|
@ -370,8 +372,8 @@ void CommandProcessorManager::GatherPipeBursted(Core::System& system)
|
||||||
{
|
{
|
||||||
// In multibuffer mode is not allowed write in the same FIFO attached to the GPU.
|
// In multibuffer mode is not allowed write in the same FIFO attached to the GPU.
|
||||||
// Fix Pokemon XD in DC mode.
|
// Fix Pokemon XD in DC mode.
|
||||||
if ((ProcessorInterface::Fifo_CPUEnd == fifo.CPEnd.load(std::memory_order_relaxed)) &&
|
if ((processor_interface.Fifo_CPUEnd == fifo.CPEnd.load(std::memory_order_relaxed)) &&
|
||||||
(ProcessorInterface::Fifo_CPUBase == fifo.CPBase.load(std::memory_order_relaxed)) &&
|
(processor_interface.Fifo_CPUBase == fifo.CPBase.load(std::memory_order_relaxed)) &&
|
||||||
fifo.CPReadWriteDistance.load(std::memory_order_relaxed) > 0)
|
fifo.CPReadWriteDistance.load(std::memory_order_relaxed) > 0)
|
||||||
{
|
{
|
||||||
system.GetFifo().FlushGpu(system);
|
system.GetFifo().FlushGpu(system);
|
||||||
|
@ -394,9 +396,9 @@ void CommandProcessorManager::GatherPipeBursted(Core::System& system)
|
||||||
|
|
||||||
if (m_cp_ctrl_reg.GPReadEnable && m_cp_ctrl_reg.GPLinkEnable)
|
if (m_cp_ctrl_reg.GPReadEnable && m_cp_ctrl_reg.GPLinkEnable)
|
||||||
{
|
{
|
||||||
ProcessorInterface::Fifo_CPUWritePointer = fifo.CPWritePointer.load(std::memory_order_relaxed);
|
processor_interface.Fifo_CPUWritePointer = fifo.CPWritePointer.load(std::memory_order_relaxed);
|
||||||
ProcessorInterface::Fifo_CPUBase = fifo.CPBase.load(std::memory_order_relaxed);
|
processor_interface.Fifo_CPUBase = fifo.CPBase.load(std::memory_order_relaxed);
|
||||||
ProcessorInterface::Fifo_CPUEnd = fifo.CPEnd.load(std::memory_order_relaxed);
|
processor_interface.Fifo_CPUEnd = fifo.CPEnd.load(std::memory_order_relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the game is running close to overflowing, make the exception checking more frequent.
|
// If the game is running close to overflowing, make the exception checking more frequent.
|
||||||
|
@ -416,13 +418,13 @@ void CommandProcessorManager::GatherPipeBursted(Core::System& system)
|
||||||
// check if we are in sync
|
// check if we are in sync
|
||||||
ASSERT_MSG(COMMANDPROCESSOR,
|
ASSERT_MSG(COMMANDPROCESSOR,
|
||||||
fifo.CPWritePointer.load(std::memory_order_relaxed) ==
|
fifo.CPWritePointer.load(std::memory_order_relaxed) ==
|
||||||
ProcessorInterface::Fifo_CPUWritePointer,
|
processor_interface.Fifo_CPUWritePointer,
|
||||||
"FIFOs linked but out of sync");
|
"FIFOs linked but out of sync");
|
||||||
ASSERT_MSG(COMMANDPROCESSOR,
|
ASSERT_MSG(COMMANDPROCESSOR,
|
||||||
fifo.CPBase.load(std::memory_order_relaxed) == ProcessorInterface::Fifo_CPUBase,
|
fifo.CPBase.load(std::memory_order_relaxed) == processor_interface.Fifo_CPUBase,
|
||||||
"FIFOs linked but out of sync");
|
"FIFOs linked but out of sync");
|
||||||
ASSERT_MSG(COMMANDPROCESSOR,
|
ASSERT_MSG(COMMANDPROCESSOR,
|
||||||
fifo.CPEnd.load(std::memory_order_relaxed) == ProcessorInterface::Fifo_CPUEnd,
|
fifo.CPEnd.load(std::memory_order_relaxed) == processor_interface.Fifo_CPUEnd,
|
||||||
"FIFOs linked but out of sync");
|
"FIFOs linked but out of sync");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,13 +434,13 @@ void CommandProcessorManager::UpdateInterrupts(Core::System& system, u64 userdat
|
||||||
{
|
{
|
||||||
m_interrupt_set.Set();
|
m_interrupt_set.Set();
|
||||||
DEBUG_LOG_FMT(COMMANDPROCESSOR, "Interrupt set");
|
DEBUG_LOG_FMT(COMMANDPROCESSOR, "Interrupt set");
|
||||||
ProcessorInterface::SetInterrupt(INT_CAUSE_CP, true);
|
system.GetProcessorInterface().SetInterrupt(INT_CAUSE_CP, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_interrupt_set.Clear();
|
m_interrupt_set.Clear();
|
||||||
DEBUG_LOG_FMT(COMMANDPROCESSOR, "Interrupt cleared");
|
DEBUG_LOG_FMT(COMMANDPROCESSOR, "Interrupt cleared");
|
||||||
ProcessorInterface::SetInterrupt(INT_CAUSE_CP, false);
|
system.GetProcessorInterface().SetInterrupt(INT_CAUSE_CP, false);
|
||||||
}
|
}
|
||||||
system.GetCoreTiming().ForceExceptionCheck(0);
|
system.GetCoreTiming().ForceExceptionCheck(0);
|
||||||
m_interrupt_waiting.Clear();
|
m_interrupt_waiting.Clear();
|
||||||
|
@ -563,7 +565,7 @@ void CommandProcessorManager::SetCPStatusFromCPU(Core::System& system)
|
||||||
{
|
{
|
||||||
m_interrupt_set.Set(interrupt);
|
m_interrupt_set.Set(interrupt);
|
||||||
DEBUG_LOG_FMT(COMMANDPROCESSOR, "Interrupt set");
|
DEBUG_LOG_FMT(COMMANDPROCESSOR, "Interrupt set");
|
||||||
ProcessorInterface::SetInterrupt(INT_CAUSE_CP, interrupt);
|
system.GetProcessorInterface().SetInterrupt(INT_CAUSE_CP, interrupt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -157,12 +157,15 @@ void PixelEngineManager::RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
||||||
|
|
||||||
void PixelEngineManager::UpdateInterrupts()
|
void PixelEngineManager::UpdateInterrupts()
|
||||||
{
|
{
|
||||||
|
auto& system = Core::System::GetInstance();
|
||||||
|
auto& processor_interface = system.GetProcessorInterface();
|
||||||
|
|
||||||
// check if there is a token-interrupt
|
// check if there is a token-interrupt
|
||||||
ProcessorInterface::SetInterrupt(INT_CAUSE_PE_TOKEN,
|
processor_interface.SetInterrupt(INT_CAUSE_PE_TOKEN,
|
||||||
m_signal_token_interrupt && m_control.pe_token_enable);
|
m_signal_token_interrupt && m_control.pe_token_enable);
|
||||||
|
|
||||||
// check if there is a finish-interrupt
|
// check if there is a finish-interrupt
|
||||||
ProcessorInterface::SetInterrupt(INT_CAUSE_PE_FINISH,
|
processor_interface.SetInterrupt(INT_CAUSE_PE_FINISH,
|
||||||
m_signal_finish_interrupt && m_control.pe_finish_enable);
|
m_signal_finish_interrupt && m_control.pe_finish_enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue