Skip to content
Permalink
Browse files
Merge pull request #8067 from endrift/hsp
Preliminary HSP support
  • Loading branch information
JMC47 committed May 22, 2022
2 parents f27027d + 6a26b0c commit 3a33574
Show file tree
Hide file tree
Showing 17 changed files with 340 additions and 12 deletions.
@@ -34,6 +34,7 @@ enum class LogType : int
GDB_STUB,
GPFIFO,
HOST_GPU,
HSP,
IOS,
IOS_DI,
IOS_ES,
@@ -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"};
@@ -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
@@ -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"};
@@ -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
{
@@ -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;
}
}
}
}
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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

0 comments on commit 3a33574

Please sign in to comment.