HW: Initial HSP implementation with ARAM expansion

This commit is contained in:
Vicki Pfau 2018-08-05 02:03:12 -07:00
parent 0f2540a0d1
commit 6a26b0ce8a
17 changed files with 340 additions and 12 deletions

View File

@ -34,6 +34,7 @@ enum class LogType : int
GDB_STUB,
GPFIFO,
HOST_GPU,
HSP,
IOS,
IOS_DI,
IOS_ES,

View File

@ -119,6 +119,7 @@ LogManager::LogManager()
m_log[LogType::GDB_STUB] = {"GDB_STUB", "GDB Stub"};
m_log[LogType::GPFIFO] = {"GP", "GatherPipe FIFO"};
m_log[LogType::HOST_GPU] = {"Host GPU", "Host GPU"};
m_log[LogType::HSP] = {"HSP", "High-Speed Port (HSP)"};
m_log[LogType::IOS] = {"IOS", "IOS"};
m_log[LogType::IOS_DI] = {"IOS_DI", "IOS - Drive Interface"};
m_log[LogType::IOS_ES] = {"IOS_ES", "IOS - ETicket Services"};

View File

@ -220,6 +220,14 @@ add_library(core
HW/GCPadEmu.h
HW/GPFifo.cpp
HW/GPFifo.h
HW/HSP/HSP.cpp
HW/HSP/HSP.h
HW/HSP/HSP_Device.cpp
HW/HSP/HSP_Device.h
HW/HSP/HSP_DeviceARAMExpansion.cpp
HW/HSP/HSP_DeviceARAMExpansion.h
HW/HSP/HSP_DeviceNull.cpp
HW/HSP/HSP_DeviceNull.h
HW/HW.cpp
HW/HW.h
HW/Memmap.cpp

View File

@ -19,6 +19,7 @@
#include "Core/Config/DefaultLocale.h"
#include "Core/HW/EXI/EXI.h"
#include "Core/HW/EXI/EXI_Device.h"
#include "Core/HW/HSP/HSP_Device.h"
#include "Core/HW/Memmap.h"
#include "Core/HW/SI/SI_Device.h"
#include "Core/PowerPC/PowerPC.h"
@ -179,6 +180,9 @@ const Info<u32> MAIN_MEM1_SIZE{{System::Main, "Core", "MEM1Size"}, Memory::MEM1_
const Info<u32> MAIN_MEM2_SIZE{{System::Main, "Core", "MEM2Size"}, Memory::MEM2_SIZE_RETAIL};
const Info<std::string> MAIN_GFX_BACKEND{{System::Main, "Core", "GFXBackend"},
VideoBackendBase::GetDefaultBackendName()};
const Info<HSP::HSPDeviceType> MAIN_HSP_DEVICE{{System::Main, "Core", "HSPDevice"},
HSP::HSPDeviceType::None};
const Info<u32> MAIN_ARAM_EXPANSION_SIZE{{System::Main, "Core", "ARAMExpansionSize"}, 0x400000};
const Info<std::string> MAIN_GPU_DETERMINISM_MODE{{System::Main, "Core", "GPUDeterminismMode"},
"auto"};

View File

@ -42,6 +42,11 @@ namespace SerialInterface
enum SIDevices : int;
}
namespace HSP
{
enum class HSPDeviceType : int;
}
namespace Config
{
// Main.Core
@ -110,6 +115,8 @@ extern const Info<u32> MAIN_MEM1_SIZE;
extern const Info<u32> MAIN_MEM2_SIZE;
// Should really be part of System::GFX, but again, we're stuck with past mistakes.
extern const Info<std::string> MAIN_GFX_BACKEND;
extern const Info<HSP::HSPDeviceType> MAIN_HSP_DEVICE;
extern const Info<u32> MAIN_ARAM_EXPANSION_SIZE;
enum class GPUDeterminismMode
{

View File

@ -33,6 +33,7 @@
#include "Core/CoreTiming.h"
#include "Core/DSPEmulator.h"
#include "Core/HW/HSP/HSP.h"
#include "Core/HW/MMIO.h"
#include "Core/HW/Memmap.h"
#include "Core/HW/ProcessorInterface.h"
@ -543,13 +544,11 @@ static void Do_ARAM_DMA()
s_arDMA.Cnt.count -= 8;
}
}
else
else if (!s_ARAM.wii_mode)
{
// Assuming no external ARAM installed; returns zeros on out of bounds reads (verified on real
// HW)
while (s_arDMA.Cnt.count)
{
Memory::Write_U64(0, s_arDMA.MMAddr);
Memory::Write_U64(HSP::Read(s_arDMA.ARAddr), s_arDMA.MMAddr);
s_arDMA.MMAddr += 8;
s_arDMA.ARAddr += 8;
s_arDMA.Cnt.count -= 8;
@ -596,13 +595,16 @@ static void Do_ARAM_DMA()
s_arDMA.Cnt.count -= 8;
}
}
else
else if (!s_ARAM.wii_mode)
{
// Assuming no external ARAM installed; writes nothing to ARAM when out of bounds (verified on
// real HW)
s_arDMA.MMAddr += s_arDMA.Cnt.count;
s_arDMA.ARAddr += s_arDMA.Cnt.count;
s_arDMA.Cnt.count = 0;
while (s_arDMA.Cnt.count)
{
HSP::Write(s_arDMA.ARAddr, Memory::Read_U64(s_arDMA.MMAddr));
s_arDMA.MMAddr += 8;
s_arDMA.ARAddr += 8;
s_arDMA.Cnt.count -= 8;
}
}
}
}

View File

@ -0,0 +1,68 @@
// Copyright 2022 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "Core/HW/HSP/HSP.h"
#include <memory>
#include "Common/ChunkFile.h"
#include "Core/Config/MainSettings.h"
#include "Core/HW/HSP/HSP_Device.h"
namespace HSP
{
static std::unique_ptr<IHSPDevice> s_device;
void Init()
{
AddDevice(Config::Get(Config::MAIN_HSP_DEVICE));
}
void Shutdown()
{
RemoveDevice();
}
u64 Read(u32 address)
{
DEBUG_LOG_FMT(HSP, "HSP read from 0x{:08x}", address);
if (s_device)
return s_device->Read(address);
return 0;
}
void Write(u32 address, u64 value)
{
DEBUG_LOG_FMT(HSP, "HSP write to 0x{:08x}: 0x{:016x}", address, value);
if (s_device)
s_device->Write(address, value);
}
void DoState(PointerWrap& p)
{
HSPDeviceType type = s_device->GetDeviceType();
p.Do(type);
// If the type doesn't match, switch to the right device type
if (type != s_device->GetDeviceType())
AddDevice(type);
s_device->DoState(p);
}
void AddDevice(std::unique_ptr<IHSPDevice> device)
{
// Set the new one
s_device = std::move(device);
}
void AddDevice(const HSPDeviceType device)
{
AddDevice(HSPDevice_Create(device));
}
void RemoveDevice()
{
s_device.reset();
}
} // namespace HSP

View File

@ -0,0 +1,28 @@
// Copyright 2022 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <memory>
#include "Common/CommonTypes.h"
class PointerWrap;
namespace HSP
{
class IHSPDevice;
enum class HSPDeviceType : int;
void Init();
void Shutdown();
u64 Read(u32 address);
void Write(u32 address, u64 value);
void DoState(PointerWrap& p);
void RemoveDevice();
void AddDevice(std::unique_ptr<IHSPDevice> device);
void AddDevice(HSPDeviceType device);
} // namespace HSP

View File

@ -0,0 +1,38 @@
// Copyright 2022 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "Core/HW/HSP/HSP_Device.h"
#include <memory>
#include "Core/HW/HSP/HSP_DeviceARAMExpansion.h"
#include "Core/HW/HSP/HSP_DeviceNull.h"
namespace HSP
{
IHSPDevice::IHSPDevice(HSPDeviceType device_type) : m_device_type(device_type)
{
}
HSPDeviceType IHSPDevice::GetDeviceType() const
{
return m_device_type;
}
void IHSPDevice::DoState(PointerWrap& p)
{
}
// F A C T O R Y
std::unique_ptr<IHSPDevice> HSPDevice_Create(const HSPDeviceType device)
{
switch (device)
{
case HSPDeviceType::ARAMExpansion:
return std::make_unique<CHSPDevice_ARAMExpansion>(device);
case HSPDeviceType::None:
default:
return std::make_unique<CHSPDevice_Null>(device);
}
}
} // namespace HSP

View File

@ -0,0 +1,40 @@
// Copyright 2022 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <memory>
#include "Common/CommonTypes.h"
class PointerWrap;
namespace HSP
{
enum class HSPDeviceType : int
{
None,
ARAMExpansion,
};
class IHSPDevice
{
public:
explicit IHSPDevice(HSPDeviceType device_type);
virtual ~IHSPDevice() = default;
HSPDeviceType GetDeviceType() const;
virtual void Write(u32 address, u64 value) = 0;
virtual u64 Read(u32 address) = 0;
// Savestate support
virtual void DoState(PointerWrap& p);
protected:
HSPDeviceType m_device_type;
};
std::unique_ptr<IHSPDevice> HSPDevice_Create(HSPDeviceType device);
} // namespace HSP

View File

@ -0,0 +1,48 @@
// Copyright 2022 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "Core/HW/HSP/HSP_DeviceARAMExpansion.h"
#include <cstring>
#include "Common/ChunkFile.h"
#include "Common/MathUtil.h"
#include "Common/MemoryUtil.h"
#include "Common/Swap.h"
#include "Core/Config/MainSettings.h"
namespace HSP
{
CHSPDevice_ARAMExpansion::CHSPDevice_ARAMExpansion(HSPDeviceType device) : IHSPDevice(device)
{
m_size = MathUtil::NextPowerOf2(Config::Get(Config::MAIN_ARAM_EXPANSION_SIZE));
m_mask = m_size - 1;
m_ptr = static_cast<u8*>(Common::AllocateMemoryPages(m_size));
}
CHSPDevice_ARAMExpansion::~CHSPDevice_ARAMExpansion()
{
Common::FreeMemoryPages(m_ptr, m_size);
m_ptr = nullptr;
}
u64 CHSPDevice_ARAMExpansion::Read(u32 address)
{
u64 value;
std::memcpy(&value, &m_ptr[address & m_mask], sizeof(value));
return Common::swap64(value);
}
void CHSPDevice_ARAMExpansion::Write(u32 address, u64 value)
{
value = Common::swap64(value);
std::memcpy(&value, &m_ptr[address & m_mask], sizeof(value));
}
void CHSPDevice_ARAMExpansion::DoState(PointerWrap& p)
{
p.DoArray(m_ptr, m_size);
}
} // namespace HSP

View File

@ -0,0 +1,26 @@
// Copyright 2022 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "Core/HW/HSP/HSP_Device.h"
namespace HSP
{
class CHSPDevice_ARAMExpansion : public IHSPDevice
{
public:
explicit CHSPDevice_ARAMExpansion(HSPDeviceType device);
~CHSPDevice_ARAMExpansion() override;
void Write(u32 address, u64 value) override;
u64 Read(u32 address) override;
void DoState(PointerWrap&) override;
private:
u32 m_size;
u32 m_mask;
u8* m_ptr = nullptr;
};
} // namespace HSP

View File

@ -0,0 +1,25 @@
// Copyright 2022 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "Core/HW/HSP/HSP_DeviceNull.h"
#include <cstring>
#include "Core/HW/HSP/HSP.h"
namespace HSP
{
CHSPDevice_Null::CHSPDevice_Null(HSPDeviceType device) : IHSPDevice(device)
{
}
u64 CHSPDevice_Null::Read(u32 address)
{
return 0;
}
void CHSPDevice_Null::Write(u32 address, u64 value)
{
}
} // namespace HSP

View File

@ -0,0 +1,19 @@
// Copyright 2022 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "Common/CommonTypes.h"
#include "Core/HW/HSP/HSP_Device.h"
namespace HSP
{
class CHSPDevice_Null : public IHSPDevice
{
public:
explicit CHSPDevice_Null(HSPDeviceType device);
void Write(u32 address, u64 value) override;
u64 Read(u32 address) override;
};
} // namespace HSP

View File

@ -17,6 +17,7 @@
#include "Core/HW/DVD/DVDInterface.h"
#include "Core/HW/EXI/EXI.h"
#include "Core/HW/GPFifo.h"
#include "Core/HW/HSP/HSP.h"
#include "Core/HW/Memmap.h"
#include "Core/HW/ProcessorInterface.h"
#include "Core/HW/SI/SI.h"
@ -41,7 +42,8 @@ void Init()
SerialInterface::Init();
ProcessorInterface::Init();
ExpansionInterface::Init(); // Needs to be initialized before Memory
Memory::Init(); // Needs to be initialized before AddressSpace
HSP::Init();
Memory::Init(); // Needs to be initialized before AddressSpace
AddressSpace::Init();
DSP::Init(Config::Get(Config::MAIN_DSP_HLE));
DVDInterface::Init();
@ -68,6 +70,7 @@ void Shutdown()
DSP::Shutdown();
AddressSpace::Shutdown();
Memory::Shutdown();
HSP::Shutdown();
ExpansionInterface::Shutdown();
SerialInterface::Shutdown();
AudioInterface::Shutdown();
@ -96,6 +99,8 @@ void DoState(PointerWrap& p)
p.DoMarker("ExpansionInterface");
AudioInterface::DoState(p);
p.DoMarker("AudioInterface");
HSP::DoState(p);
p.DoMarker("HSP");
if (SConfig::GetInstance().bWii)
{

View File

@ -74,7 +74,7 @@ static std::recursive_mutex g_save_thread_mutex;
static std::thread g_save_thread;
// Don't forget to increase this after doing changes on the savestate system
constexpr u32 STATE_VERSION = 140; // Last changed in PR 10591
constexpr u32 STATE_VERSION = 141; // Last changed in PR 8067
// Maps savestate versions to Dolphin versions.
// Versions after 42 don't need to be added to this list,

View File

@ -279,6 +279,10 @@
<ClInclude Include="Core\HW\GCPad.h" />
<ClInclude Include="Core\HW\GCPadEmu.h" />
<ClInclude Include="Core\HW\GPFifo.h" />
<ClInclude Include="Core\HW\HSP\HSP.h" />
<ClInclude Include="Core\HW\HSP\HSP_Device.h" />
<ClInclude Include="Core\HW\HSP\HSP_DeviceARAMExpansion.h" />
<ClInclude Include="Core\HW\HSP\HSP_DeviceNull.h" />
<ClInclude Include="Core\HW\HW.h" />
<ClInclude Include="Core\HW\Memmap.h" />
<ClInclude Include="Core\HW\MemoryInterface.h" />
@ -873,6 +877,10 @@
<ClCompile Include="Core\HW\GCPad.cpp" />
<ClCompile Include="Core\HW\GCPadEmu.cpp" />
<ClCompile Include="Core\HW\GPFifo.cpp" />
<ClCompile Include="Core\HW\HSP\HSP.cpp" />
<ClCompile Include="Core\HW\HSP\HSP_Device.cpp" />
<ClCompile Include="Core\HW\HSP\HSP_DeviceARAMExpansion.cpp" />
<ClCompile Include="Core\HW\HSP\HSP_DeviceNull.cpp" />
<ClCompile Include="Core\HW\HW.cpp" />
<ClCompile Include="Core\HW\Memmap.cpp" />
<ClCompile Include="Core\HW\MemoryInterface.cpp" />