Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #11404 from AdmiralCurtiss/globals-processor-inter…
…face

HW/ProcessorInterface: Refactor to class, move to Core::System.
  • Loading branch information
lioncash committed Jan 4, 2023
2 parents 908cec0 + 2fdaf0a commit b6b46d8
Show file tree
Hide file tree
Showing 26 changed files with 235 additions and 175 deletions.
7 changes: 4 additions & 3 deletions Source/Core/Core/HW/AudioInterface.cpp
Expand Up @@ -155,9 +155,10 @@ namespace
{
void UpdateInterrupts()
{
auto& state = Core::System::GetInstance().GetAudioInterfaceState().GetData();
ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_AI,
state.control.AIINT & state.control.AIINTMSK);
auto& system = Core::System::GetInstance();
auto& state = system.GetAudioInterfaceState().GetData();
system.GetProcessorInterface().SetInterrupt(ProcessorInterface::INT_CAUSE_AI,
state.control.AIINT & state.control.AIINTMSK);
}

void GenerateAudioInterrupt()
Expand Down
5 changes: 3 additions & 2 deletions Source/Core/Core/HW/DSP.cpp
Expand Up @@ -465,7 +465,8 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
// 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
// to the left of it. By doing:
Expand All @@ -474,7 +475,7 @@ static void UpdateInterrupts()
bool ints_set = (((state.dsp_control.Hex >> 1) & state.dsp_control.Hex &
(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)
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/Core/HW/DVD/DVDInterface.cpp
Expand Up @@ -737,7 +737,7 @@ static void UpdateInterrupts()
(state.DISR.BRKINT & state.DISR.BRKINTMASK) != 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
system.GetCoreTiming().ForceExceptionCheck(50);
Expand Down
5 changes: 3 additions & 2 deletions Source/Core/Core/HW/EXI/EXI.cpp
Expand Up @@ -263,14 +263,15 @@ void UpdateInterrupts()
// Channel 0 Device 0 generates interrupt on channel 0
// Channel 0 Device 2 generates interrupt on channel 2
// 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());

bool causeInt = false;
for (auto& channel : state.channels)
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)
Expand Down
11 changes: 6 additions & 5 deletions Source/Core/Core/HW/GPFifo.cpp
Expand Up @@ -85,26 +85,27 @@ void UpdateGatherPipe()
{
auto& system = Core::System::GetInstance();
auto& memory = system.GetMemory();
auto& processor_interface = system.GetProcessorInterface();

size_t pipe_count = GetGatherPipeCount();
size_t processed;
u8* cur_mem = memory.GetPointer(ProcessorInterface::Fifo_CPUWritePointer);
u8* cur_mem = memory.GetPointer(processor_interface.m_fifo_cpu_write_pointer);
for (processed = 0; pipe_count >= GATHER_PIPE_SIZE; processed += GATHER_PIPE_SIZE)
{
// copy the GatherPipe
memcpy(cur_mem, s_gather_pipe + processed, GATHER_PIPE_SIZE);
pipe_count -= GATHER_PIPE_SIZE;

// increase the CPUWritePointer
if (ProcessorInterface::Fifo_CPUWritePointer == ProcessorInterface::Fifo_CPUEnd)
if (processor_interface.m_fifo_cpu_write_pointer == processor_interface.m_fifo_cpu_end)
{
ProcessorInterface::Fifo_CPUWritePointer = ProcessorInterface::Fifo_CPUBase;
cur_mem = memory.GetPointer(ProcessorInterface::Fifo_CPUWritePointer);
processor_interface.m_fifo_cpu_write_pointer = processor_interface.m_fifo_cpu_base;
cur_mem = memory.GetPointer(processor_interface.m_fifo_cpu_write_pointer);
}
else
{
cur_mem += GATHER_PIPE_SIZE;
ProcessorInterface::Fifo_CPUWritePointer += GATHER_PIPE_SIZE;
processor_interface.m_fifo_cpu_write_pointer += GATHER_PIPE_SIZE;
}

system.GetCommandProcessor().GatherPipeBursted(system);
Expand Down
4 changes: 2 additions & 2 deletions Source/Core/Core/HW/HW.cpp
Expand Up @@ -43,7 +43,7 @@ void Init(const Sram* override_sram)
AudioInterface::Init();
VideoInterface::Init();
SerialInterface::Init();
ProcessorInterface::Init();
system.GetProcessorInterface().Init();
ExpansionInterface::Init(override_sram); // Needs to be initialized before Memory
HSP::Init();
system.GetMemory().Init(); // Needs to be initialized before AddressSpace
Expand Down Expand Up @@ -97,7 +97,7 @@ void DoState(PointerWrap& p)
p.DoMarker("VideoInterface");
SerialInterface::DoState(p);
p.DoMarker("SerialInterface");
ProcessorInterface::DoState(p);
system.GetProcessorInterface().DoState(p);
p.DoMarker("ProcessorInterface");
DSP::DoState(p);
p.DoMarker("DSP");
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/Core/HW/Memmap.cpp
Expand Up @@ -52,7 +52,7 @@ void MemoryManager::InitMMIO(bool is_wii)
system.GetCommandProcessor().RegisterMMIO(system, m_mmio_mapping.get(), 0x0C000000);
system.GetPixelEngine().RegisterMMIO(m_mmio_mapping.get(), 0x0C001000);
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);
DSP::RegisterMMIO(m_mmio_mapping.get(), 0x0C005000);
DVDInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0C006000, false);
Expand Down
151 changes: 70 additions & 81 deletions Source/Core/Core/HW/ProcessorInterface.cpp
Expand Up @@ -27,82 +27,62 @@ constexpr u32 FLIPPER_REV_A = 0x046500B0;
constexpr u32 FLIPPER_REV_B = 0x146500B1;
constexpr u32 FLIPPER_REV_C = 0x246500B1;

// STATE_TO_SAVE
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)
void ProcessorInterfaceManager::DoState(PointerWrap& p)
{
p.Do(m_InterruptMask);
p.Do(m_InterruptCause);
p.Do(Fifo_CPUBase);
p.Do(Fifo_CPUEnd);
p.Do(Fifo_CPUWritePointer);
p.Do(m_ResetCode);
p.Do(m_interrupt_mask);
p.Do(m_interrupt_cause);
p.Do(m_fifo_cpu_base);
p.Do(m_fifo_cpu_end);
p.Do(m_fifo_cpu_write_pointer);
p.Do(m_reset_code);
}

void Init()
void ProcessorInterfaceManager::Init()
{
m_InterruptMask = 0;
m_InterruptCause = 0;
m_interrupt_mask = 0;
m_interrupt_cause = 0;

Fifo_CPUBase = 0;
Fifo_CPUEnd = 0;
Fifo_CPUWritePointer = 0;
m_fifo_cpu_base = 0;
m_fifo_cpu_end = 0;
m_fifo_cpu_write_pointer = 0;

m_ResetCode = 0; // Cold reset
m_InterruptCause = INT_CAUSE_RST_BUTTON | INT_CAUSE_VI;
m_reset_code = 0; // Cold reset
m_interrupt_cause = INT_CAUSE_RST_BUTTON | INT_CAUSE_VI;

auto& system = Core::System::GetInstance();
auto& core_timing = system.GetCoreTiming();
toggleResetButton = core_timing.RegisterEvent("ToggleResetButton", ToggleResetButtonCallback);
iosNotifyResetButton =
m_event_type_toggle_reset_button =
core_timing.RegisterEvent("ToggleResetButton", ToggleResetButtonCallback);
m_event_type_ios_notify_reset_button =
core_timing.RegisterEvent("IOSNotifyResetButton", IOSNotifyResetButtonCallback);
iosNotifyPowerButton =
m_event_type_ios_notify_power_button =
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::ComplexWrite<u32>([](Core::System&, u32, u32 val) {
m_InterruptCause &= ~val;
UpdateException();
mmio->Register(base | PI_INTERRUPT_CAUSE, MMIO::DirectRead<u32>(&m_interrupt_cause),
MMIO::ComplexWrite<u32>([](Core::System& system, u32, u32 val) {
auto& processor_interface = system.GetProcessorInterface();
processor_interface.m_interrupt_cause &= ~val;
processor_interface.UpdateException();
}));

mmio->Register(base | PI_INTERRUPT_MASK, MMIO::DirectRead<u32>(&m_InterruptMask),
MMIO::ComplexWrite<u32>([](Core::System&, u32, u32 val) {
m_InterruptMask = val;
UpdateException();
mmio->Register(base | PI_INTERRUPT_MASK, MMIO::DirectRead<u32>(&m_interrupt_mask),
MMIO::ComplexWrite<u32>([](Core::System& system, u32, u32 val) {
auto& processor_interface = system.GetProcessorInterface();
processor_interface.m_interrupt_mask = val;
processor_interface.UpdateException();
}));

mmio->Register(base | PI_FIFO_BASE, MMIO::DirectRead<u32>(&Fifo_CPUBase),
MMIO::DirectWrite<u32>(&Fifo_CPUBase, 0xFFFFFFE0));
mmio->Register(base | PI_FIFO_BASE, MMIO::DirectRead<u32>(&m_fifo_cpu_base),
MMIO::DirectWrite<u32>(&m_fifo_cpu_base, 0xFFFFFFE0));

mmio->Register(base | PI_FIFO_END, MMIO::DirectRead<u32>(&Fifo_CPUEnd),
MMIO::DirectWrite<u32>(&Fifo_CPUEnd, 0xFFFFFFE0));
mmio->Register(base | PI_FIFO_END, MMIO::DirectRead<u32>(&m_fifo_cpu_end),
MMIO::DirectWrite<u32>(&m_fifo_cpu_end, 0xFFFFFFE0));

mmio->Register(base | PI_FIFO_WPTR, MMIO::DirectRead<u32>(&Fifo_CPUWritePointer),
MMIO::DirectWrite<u32>(&Fifo_CPUWritePointer, 0xFFFFFFE0));
mmio->Register(base | PI_FIFO_WPTR, MMIO::DirectRead<u32>(&m_fifo_cpu_write_pointer),
MMIO::DirectWrite<u32>(&m_fifo_cpu_write_pointer, 0xFFFFFFE0));

mmio->Register(base | PI_FIFO_RESET, MMIO::InvalidRead<u32>(),
MMIO::ComplexWrite<u32>([](Core::System&, u32, u32 val) {
Expand All @@ -127,14 +107,18 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
}
}));

mmio->Register(base | PI_RESET_CODE, MMIO::ComplexRead<u32>([](Core::System&, u32) {
DEBUG_LOG_FMT(PROCESSORINTERFACE, "Read PI_RESET_CODE: {:08x}", m_ResetCode);
return m_ResetCode;
mmio->Register(base | PI_RESET_CODE, MMIO::ComplexRead<u32>([](Core::System& system, u32) {
auto& processor_interface = system.GetProcessorInterface();
DEBUG_LOG_FMT(PROCESSORINTERFACE, "Read PI_RESET_CODE: {:08x}",
processor_interface.m_reset_code);
return processor_interface.m_reset_code;
}),
MMIO::ComplexWrite<u32>([](Core::System&, u32, u32 val) {
m_ResetCode = val;
INFO_LOG_FMT(PROCESSORINTERFACE, "Wrote PI_RESET_CODE: {:08x}", m_ResetCode);
if (!SConfig::GetInstance().bWii && ~m_ResetCode & 0x4)
MMIO::ComplexWrite<u32>([](Core::System& system, u32, u32 val) {
auto& processor_interface = system.GetProcessorInterface();
processor_interface.m_reset_code = val;
INFO_LOG_FMT(PROCESSORINTERFACE, "Wrote PI_RESET_CODE: {:08x}",
processor_interface.m_reset_code);
if (!SConfig::GetInstance().bWii && ~processor_interface.m_reset_code & 0x4)
{
DVDInterface::ResetDrive(true);
}
Expand All @@ -153,9 +137,9 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
}
}

void UpdateException()
void ProcessorInterfaceManager::UpdateException()
{
if ((m_InterruptCause & m_InterruptMask) != 0)
if ((m_interrupt_cause & m_interrupt_mask) != 0)
PowerPC::ppcState.Exceptions |= EXCEPTION_EXTERNAL_INT;
else
PowerPC::ppcState.Exceptions &= ~EXCEPTION_EXTERNAL_INT;
Expand Down Expand Up @@ -202,42 +186,44 @@ 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");

if (set && !(m_InterruptCause & cause_mask))
if (set && !(m_interrupt_cause & cause_mask))
{
DEBUG_LOG_FMT(PROCESSORINTERFACE, "Setting Interrupt {} (set)",
Debug_GetInterruptName(cause_mask));
}

if (!set && (m_InterruptCause & cause_mask))
if (!set && (m_interrupt_cause & cause_mask))
{
DEBUG_LOG_FMT(PROCESSORINTERFACE, "Setting Interrupt {} (clear)",
Debug_GetInterruptName(cause_mask));
}

if (set)
m_InterruptCause |= cause_mask;
m_interrupt_cause |= cause_mask;
else
m_InterruptCause &= ~cause_mask; // is there any reason to have this possibility?
m_interrupt_cause &= ~cause_mask; // is there any reason to have this possibility?
// F|RES: i think the hw devices reset the interrupt in the PI to 0
// if the interrupt cause is eliminated. that isn't done by software (afaik)
UpdateException();
}

static void SetResetButton(bool set)
void ProcessorInterfaceManager::SetResetButton(bool 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();
if (!ios)
Expand All @@ -248,7 +234,8 @@ static void IOSNotifyResetButtonCallback(Core::System& system, u64 userdata, s64
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();
if (!ios)
Expand All @@ -259,27 +246,29 @@ static void IOSNotifyPowerButtonCallback(Core::System& system, u64 userdata, s64
std::static_pointer_cast<IOS::HLE::STMEventHookDevice>(stm)->PowerButton();
}

void ResetButton_Tap()
void ProcessorInterfaceManager::ResetButton_Tap()
{
if (!Core::IsRunning())
return;

auto& system = Core::System::GetInstance();
auto& core_timing = system.GetCoreTiming();
core_timing.ScheduleEvent(0, toggleResetButton, true, CoreTiming::FromThread::ANY);
core_timing.ScheduleEvent(0, iosNotifyResetButton, 0, CoreTiming::FromThread::ANY);
core_timing.ScheduleEvent(SystemTimers::GetTicksPerSecond() / 2, toggleResetButton, false,
core_timing.ScheduleEvent(0, m_event_type_toggle_reset_button, true, CoreTiming::FromThread::ANY);
core_timing.ScheduleEvent(0, m_event_type_ios_notify_reset_button, 0,
CoreTiming::FromThread::ANY);
core_timing.ScheduleEvent(SystemTimers::GetTicksPerSecond() / 2, m_event_type_toggle_reset_button,
false, CoreTiming::FromThread::ANY);
}

void PowerButton_Tap()
void ProcessorInterfaceManager::PowerButton_Tap()
{
if (!Core::IsRunning())
return;

auto& system = Core::System::GetInstance();
auto& core_timing = system.GetCoreTiming();
core_timing.ScheduleEvent(0, iosNotifyPowerButton, 0, CoreTiming::FromThread::ANY);
core_timing.ScheduleEvent(0, m_event_type_ios_notify_power_button, 0,
CoreTiming::FromThread::ANY);
}

} // namespace ProcessorInterface

0 comments on commit b6b46d8

Please sign in to comment.