From 6a26b0ce8aa8ac96f9b593848c42b93fd982e91d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 5 Aug 2018 02:03:12 -0700 Subject: [PATCH] HW: Initial HSP implementation with ARAM expansion --- Source/Core/Common/Logging/Log.h | 1 + Source/Core/Common/Logging/LogManager.cpp | 1 + Source/Core/Core/CMakeLists.txt | 8 +++ Source/Core/Core/Config/MainSettings.cpp | 4 ++ Source/Core/Core/Config/MainSettings.h | 7 ++ Source/Core/Core/HW/DSP.cpp | 22 +++--- Source/Core/Core/HW/HSP/HSP.cpp | 68 +++++++++++++++++++ Source/Core/Core/HW/HSP/HSP.h | 28 ++++++++ Source/Core/Core/HW/HSP/HSP_Device.cpp | 38 +++++++++++ Source/Core/Core/HW/HSP/HSP_Device.h | 40 +++++++++++ .../Core/HW/HSP/HSP_DeviceARAMExpansion.cpp | 48 +++++++++++++ .../Core/HW/HSP/HSP_DeviceARAMExpansion.h | 26 +++++++ Source/Core/Core/HW/HSP/HSP_DeviceNull.cpp | 25 +++++++ Source/Core/Core/HW/HSP/HSP_DeviceNull.h | 19 ++++++ Source/Core/Core/HW/HW.cpp | 7 +- Source/Core/Core/State.cpp | 2 +- Source/Core/DolphinLib.props | 8 +++ 17 files changed, 340 insertions(+), 12 deletions(-) create mode 100644 Source/Core/Core/HW/HSP/HSP.cpp create mode 100644 Source/Core/Core/HW/HSP/HSP.h create mode 100644 Source/Core/Core/HW/HSP/HSP_Device.cpp create mode 100644 Source/Core/Core/HW/HSP/HSP_Device.h create mode 100644 Source/Core/Core/HW/HSP/HSP_DeviceARAMExpansion.cpp create mode 100644 Source/Core/Core/HW/HSP/HSP_DeviceARAMExpansion.h create mode 100644 Source/Core/Core/HW/HSP/HSP_DeviceNull.cpp create mode 100644 Source/Core/Core/HW/HSP/HSP_DeviceNull.h diff --git a/Source/Core/Common/Logging/Log.h b/Source/Core/Common/Logging/Log.h index 5a0d2c6e24..86a705e1ea 100644 --- a/Source/Core/Common/Logging/Log.h +++ b/Source/Core/Common/Logging/Log.h @@ -34,6 +34,7 @@ enum class LogType : int GDB_STUB, GPFIFO, HOST_GPU, + HSP, IOS, IOS_DI, IOS_ES, diff --git a/Source/Core/Common/Logging/LogManager.cpp b/Source/Core/Common/Logging/LogManager.cpp index ab795d372a..04078fc06c 100644 --- a/Source/Core/Common/Logging/LogManager.cpp +++ b/Source/Core/Common/Logging/LogManager.cpp @@ -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"}; diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt index 4063e01562..5f81f3036c 100644 --- a/Source/Core/Core/CMakeLists.txt +++ b/Source/Core/Core/CMakeLists.txt @@ -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 diff --git a/Source/Core/Core/Config/MainSettings.cpp b/Source/Core/Core/Config/MainSettings.cpp index 4b4b91f43e..0c749345c7 100644 --- a/Source/Core/Core/Config/MainSettings.cpp +++ b/Source/Core/Core/Config/MainSettings.cpp @@ -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 MAIN_MEM1_SIZE{{System::Main, "Core", "MEM1Size"}, Memory::MEM1_ const Info MAIN_MEM2_SIZE{{System::Main, "Core", "MEM2Size"}, Memory::MEM2_SIZE_RETAIL}; const Info MAIN_GFX_BACKEND{{System::Main, "Core", "GFXBackend"}, VideoBackendBase::GetDefaultBackendName()}; +const Info MAIN_HSP_DEVICE{{System::Main, "Core", "HSPDevice"}, + HSP::HSPDeviceType::None}; +const Info MAIN_ARAM_EXPANSION_SIZE{{System::Main, "Core", "ARAMExpansionSize"}, 0x400000}; const Info MAIN_GPU_DETERMINISM_MODE{{System::Main, "Core", "GPUDeterminismMode"}, "auto"}; diff --git a/Source/Core/Core/Config/MainSettings.h b/Source/Core/Core/Config/MainSettings.h index 63b89cbadb..4ed43a79da 100644 --- a/Source/Core/Core/Config/MainSettings.h +++ b/Source/Core/Core/Config/MainSettings.h @@ -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 MAIN_MEM1_SIZE; extern const Info MAIN_MEM2_SIZE; // Should really be part of System::GFX, but again, we're stuck with past mistakes. extern const Info MAIN_GFX_BACKEND; +extern const Info MAIN_HSP_DEVICE; +extern const Info MAIN_ARAM_EXPANSION_SIZE; enum class GPUDeterminismMode { diff --git a/Source/Core/Core/HW/DSP.cpp b/Source/Core/Core/HW/DSP.cpp index e2801339e8..5edc5314a5 100644 --- a/Source/Core/Core/HW/DSP.cpp +++ b/Source/Core/Core/HW/DSP.cpp @@ -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; + } } } } diff --git a/Source/Core/Core/HW/HSP/HSP.cpp b/Source/Core/Core/HW/HSP/HSP.cpp new file mode 100644 index 0000000000..562ff662a3 --- /dev/null +++ b/Source/Core/Core/HW/HSP/HSP.cpp @@ -0,0 +1,68 @@ +// Copyright 2022 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "Core/HW/HSP/HSP.h" + +#include + +#include "Common/ChunkFile.h" +#include "Core/Config/MainSettings.h" +#include "Core/HW/HSP/HSP_Device.h" + +namespace HSP +{ +static std::unique_ptr 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 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 diff --git a/Source/Core/Core/HW/HSP/HSP.h b/Source/Core/Core/HW/HSP/HSP.h new file mode 100644 index 0000000000..1e8f4f772d --- /dev/null +++ b/Source/Core/Core/HW/HSP/HSP.h @@ -0,0 +1,28 @@ +// Copyright 2022 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +#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 device); +void AddDevice(HSPDeviceType device); +} // namespace HSP diff --git a/Source/Core/Core/HW/HSP/HSP_Device.cpp b/Source/Core/Core/HW/HSP/HSP_Device.cpp new file mode 100644 index 0000000000..069fca3753 --- /dev/null +++ b/Source/Core/Core/HW/HSP/HSP_Device.cpp @@ -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 + +#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 HSPDevice_Create(const HSPDeviceType device) +{ + switch (device) + { + case HSPDeviceType::ARAMExpansion: + return std::make_unique(device); + case HSPDeviceType::None: + default: + return std::make_unique(device); + } +} +} // namespace HSP diff --git a/Source/Core/Core/HW/HSP/HSP_Device.h b/Source/Core/Core/HW/HSP/HSP_Device.h new file mode 100644 index 0000000000..b9caa21df8 --- /dev/null +++ b/Source/Core/Core/HW/HSP/HSP_Device.h @@ -0,0 +1,40 @@ +// Copyright 2022 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +#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 HSPDevice_Create(HSPDeviceType device); + +} // namespace HSP diff --git a/Source/Core/Core/HW/HSP/HSP_DeviceARAMExpansion.cpp b/Source/Core/Core/HW/HSP/HSP_DeviceARAMExpansion.cpp new file mode 100644 index 0000000000..18d6244c30 --- /dev/null +++ b/Source/Core/Core/HW/HSP/HSP_DeviceARAMExpansion.cpp @@ -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 + +#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(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 diff --git a/Source/Core/Core/HW/HSP/HSP_DeviceARAMExpansion.h b/Source/Core/Core/HW/HSP/HSP_DeviceARAMExpansion.h new file mode 100644 index 0000000000..8efa766286 --- /dev/null +++ b/Source/Core/Core/HW/HSP/HSP_DeviceARAMExpansion.h @@ -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 diff --git a/Source/Core/Core/HW/HSP/HSP_DeviceNull.cpp b/Source/Core/Core/HW/HSP/HSP_DeviceNull.cpp new file mode 100644 index 0000000000..669f857124 --- /dev/null +++ b/Source/Core/Core/HW/HSP/HSP_DeviceNull.cpp @@ -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 + +#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 diff --git a/Source/Core/Core/HW/HSP/HSP_DeviceNull.h b/Source/Core/Core/HW/HSP/HSP_DeviceNull.h new file mode 100644 index 0000000000..afadddd475 --- /dev/null +++ b/Source/Core/Core/HW/HSP/HSP_DeviceNull.h @@ -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 diff --git a/Source/Core/Core/HW/HW.cpp b/Source/Core/Core/HW/HW.cpp index b927e65d29..9b9251c201 100644 --- a/Source/Core/Core/HW/HW.cpp +++ b/Source/Core/Core/HW/HW.cpp @@ -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) { diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp index 35887bcd48..4b79a76d71 100644 --- a/Source/Core/Core/State.cpp +++ b/Source/Core/Core/State.cpp @@ -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, diff --git a/Source/Core/DolphinLib.props b/Source/Core/DolphinLib.props index d4cdb0af4b..ea6c9705dc 100644 --- a/Source/Core/DolphinLib.props +++ b/Source/Core/DolphinLib.props @@ -279,6 +279,10 @@ + + + + @@ -873,6 +877,10 @@ + + + +