diff options
Diffstat (limited to 'src/core')
88 files changed, 475 insertions, 284 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 861b711c7..edf5fcc44 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -250,6 +250,7 @@ set(HEADERS tracer/citrace.h memory.h memory_setup.h + mmio.h settings.h system.h ) diff --git a/src/core/arm/disassembler/arm_disasm.cpp b/src/core/arm/disassembler/arm_disasm.cpp index 76408e9fa..5ad1f1c29 100644 --- a/src/core/arm/disassembler/arm_disasm.cpp +++ b/src/core/arm/disassembler/arm_disasm.cpp @@ -738,23 +738,23 @@ std::string ARM_Disasm::DisassembleMemHalf(u32 insn) if (is_immed) { if (is_pre) { if (offset == 0) { - return Common::StringFromFormat("%s%sh\tr%d, [r%d]", opname, cond_to_str(cond), rd, rn); + return Common::StringFromFormat("%s%s%s\tr%d, [r%d]", opname, cond_to_str(cond), width, rd, rn); } else { - return Common::StringFromFormat("%s%sh\tr%d, [r%d, #%s%u]%s", - opname, cond_to_str(cond), rd, rn, minus, offset, bang); + return Common::StringFromFormat("%s%s%s\tr%d, [r%d, #%s%u]%s", + opname, cond_to_str(cond), width, rd, rn, minus, offset, bang); } } else { - return Common::StringFromFormat("%s%sh\tr%d, [r%d], #%s%u", - opname, cond_to_str(cond), rd, rn, minus, offset); + return Common::StringFromFormat("%s%s%s\tr%d, [r%d], #%s%u", + opname, cond_to_str(cond), width, rd, rn, minus, offset); } } if (is_pre) { - return Common::StringFromFormat("%s%sh\tr%d, [r%d, %sr%d]%s", - opname, cond_to_str(cond), rd, rn, minus, rm, bang); + return Common::StringFromFormat("%s%s%s\tr%d, [r%d, %sr%d]%s", + opname, cond_to_str(cond), width, rd, rn, minus, rm, bang); } else { - return Common::StringFromFormat("%s%sh\tr%d, [r%d], %sr%d", - opname, cond_to_str(cond), rd, rn, minus, rm); + return Common::StringFromFormat("%s%s%s\tr%d, [r%d], %sr%d", + opname, cond_to_str(cond), width, rd, rn, minus, rm); } } diff --git a/src/core/file_sys/archive_backend.cpp b/src/core/file_sys/archive_backend.cpp index 3f81447df..97adf0e12 100644 --- a/src/core/file_sys/archive_backend.cpp +++ b/src/core/file_sys/archive_backend.cpp @@ -43,7 +43,7 @@ Path::Path(LowPathType type, u32 size, u32 pointer) : type(type) { } } -const std::string Path::DebugStr() const { +std::string Path::DebugStr() const { switch (GetType()) { case Invalid: default: @@ -66,7 +66,7 @@ const std::string Path::DebugStr() const { } } -const std::string Path::AsString() const { +std::string Path::AsString() const { switch (GetType()) { case Char: return string; @@ -83,7 +83,7 @@ const std::string Path::AsString() const { } } -const std::u16string Path::AsU16Str() const { +std::u16string Path::AsU16Str() const { switch (GetType()) { case Char: return Common::UTF8ToUTF16(string); @@ -99,7 +99,7 @@ const std::u16string Path::AsU16Str() const { } } -const std::vector<u8> Path::AsBinary() const { +std::vector<u8> Path::AsBinary() const { switch (GetType()) { case Binary: return binary; diff --git a/src/core/file_sys/archive_backend.h b/src/core/file_sys/archive_backend.h index e7a59a1ed..601e95d8c 100644 --- a/src/core/file_sys/archive_backend.h +++ b/src/core/file_sys/archive_backend.h @@ -49,11 +49,11 @@ public: * Gets the string representation of the path for debugging * @return String representation of the path for debugging */ - const std::string DebugStr() const; + std::string DebugStr() const; - const std::string AsString() const; - const std::u16string AsU16Str() const; - const std::vector<u8> AsBinary() const; + std::string AsString() const; + std::u16string AsU16Str() const; + std::vector<u8> AsBinary() const; private: LowPathType type; diff --git a/src/core/hle/kernel/memory.cpp b/src/core/hle/kernel/memory.cpp index 0cfb43fc7..862643448 100644 --- a/src/core/hle/kernel/memory.cpp +++ b/src/core/hle/kernel/memory.cpp @@ -7,6 +7,8 @@ #include <utility> #include <vector> +#include "audio_core/audio_core.h" + #include "common/common_types.h" #include "common/logging/log.h" @@ -107,7 +109,6 @@ struct MemoryArea { static MemoryArea memory_areas[] = { {SHARED_MEMORY_VADDR, SHARED_MEMORY_SIZE, "Shared Memory"}, // Shared memory {VRAM_VADDR, VRAM_SIZE, "VRAM"}, // Video memory (VRAM) - {DSP_RAM_VADDR, DSP_RAM_SIZE, "DSP RAM"}, // DSP memory {TLS_AREA_VADDR, TLS_AREA_SIZE, "TLS Area"}, // TLS memory }; @@ -133,6 +134,8 @@ void InitLegacyAddressSpace(Kernel::VMManager& address_space) { auto shared_page_vma = address_space.MapBackingMemory(SHARED_PAGE_VADDR, (u8*)&SharedPage::shared_page, SHARED_PAGE_SIZE, MemoryState::Shared).MoveFrom(); address_space.Reprotect(shared_page_vma, VMAPermission::Read); + + AudioCore::AddAddressSpace(address_space); } } // namespace diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index d148efde2..16eb972fb 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -35,7 +35,7 @@ SharedPtr<Process> Process::Create(SharedPtr<CodeSet> code_set) { process->codeset = std::move(code_set); process->flags.raw = 0; - process->flags.memory_region = MemoryRegion::APPLICATION; + process->flags.memory_region.Assign(MemoryRegion::APPLICATION); Memory::InitLegacyAddressSpace(process->vm_manager); return process; diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp index 2610acf76..1e289f38a 100644 --- a/src/core/hle/kernel/vm_manager.cpp +++ b/src/core/hle/kernel/vm_manager.cpp @@ -8,6 +8,7 @@ #include "core/hle/kernel/vm_manager.h" #include "core/memory_setup.h" +#include "core/mmio.h" namespace Kernel { @@ -104,7 +105,7 @@ ResultVal<VMManager::VMAHandle> VMManager::MapBackingMemory(VAddr target, u8 * m return MakeResult<VMAHandle>(MergeAdjacent(vma_handle)); } -ResultVal<VMManager::VMAHandle> VMManager::MapMMIO(VAddr target, PAddr paddr, u32 size, MemoryState state) { +ResultVal<VMManager::VMAHandle> VMManager::MapMMIO(VAddr target, PAddr paddr, u32 size, MemoryState state, Memory::MMIORegionPointer mmio_handler) { // This is the appropriately sized VMA that will turn into our allocation. CASCADE_RESULT(VMAIter vma_handle, CarveVMA(target, size)); VirtualMemoryArea& final_vma = vma_handle->second; @@ -114,6 +115,7 @@ ResultVal<VMManager::VMAHandle> VMManager::MapMMIO(VAddr target, PAddr paddr, u3 final_vma.permissions = VMAPermission::ReadWrite; final_vma.meminfo_state = state; final_vma.paddr = paddr; + final_vma.mmio_handler = mmio_handler; UpdatePageTableForVMA(final_vma); return MakeResult<VMAHandle>(MergeAdjacent(vma_handle)); @@ -330,8 +332,7 @@ void VMManager::UpdatePageTableForVMA(const VirtualMemoryArea& vma) { Memory::MapMemoryRegion(vma.base, vma.size, vma.backing_memory); break; case VMAType::MMIO: - // TODO(yuriks): Add support for MMIO handlers. - Memory::MapIoRegion(vma.base, vma.size); + Memory::MapIoRegion(vma.base, vma.size, vma.mmio_handler); break; } } diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index 4e95f1f0c..91d40655b 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h @@ -11,6 +11,7 @@ #include "common/common_types.h" #include "core/hle/result.h" +#include "core/mmio.h" namespace Kernel { @@ -92,6 +93,7 @@ struct VirtualMemoryArea { // Settings for type = MMIO /// Physical address of the register area this VMA maps to. PAddr paddr = 0; + Memory::MMIORegionPointer mmio_handler = nullptr; /// Tests if this area can be merged to the right with `next`. bool CanBeMergedWith(const VirtualMemoryArea& next) const; @@ -168,8 +170,9 @@ public: * @param paddr The physical address where the registers are present. * @param size Size of the mapping. * @param state MemoryState tag to attach to the VMA. + * @param mmio_handler The handler that will implement read and write for this MMIO region. */ - ResultVal<VMAHandle> MapMMIO(VAddr target, PAddr paddr, u32 size, MemoryState state); + ResultVal<VMAHandle> MapMMIO(VAddr target, PAddr paddr, u32 size, MemoryState state, Memory::MMIORegionPointer mmio_handler); /// Unmaps a range of addresses, splitting VMAs as necessary. ResultCode UnmapRange(VAddr target, u32 size); diff --git a/src/core/hle/result.h b/src/core/hle/result.h index ea3abb5f6..0fce5988b 100644 --- a/src/core/hle/result.h +++ b/src/core/hle/result.h @@ -193,10 +193,10 @@ union ResultCode { explicit ResultCode(u32 raw) : raw(raw) {} ResultCode(ErrorDescription description_, ErrorModule module_, ErrorSummary summary_, ErrorLevel level_) : raw(0) { - description = description_; - module = module_; - summary = summary_; - level = level_; + description.Assign(description_); + module.Assign(module_); + summary.Assign(summary_); + level.Assign(level_); } ResultCode& operator=(const ResultCode& o) { raw = o.raw; return *this; } diff --git a/src/core/hle/service/ac_u.cpp b/src/core/hle/service/ac_u.cpp index f8aab6bc7..c48259e13 100644 --- a/src/core/hle/service/ac_u.cpp +++ b/src/core/hle/service/ac_u.cpp @@ -3,7 +3,6 @@ // Refer to the license.txt file included. #include "common/logging/log.h" -#include "core/hle/hle.h" #include "core/hle/service/ac_u.h" //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/act_u.cpp b/src/core/hle/service/act_u.cpp index bbe8e1625..b23d17fba 100644 --- a/src/core/hle/service/act_u.cpp +++ b/src/core/hle/service/act_u.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" #include "core/hle/service/act_u.h" //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 7ae4859a7..06be9940e 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -10,10 +10,6 @@ #include "core/hle/service/am/am_net.h" #include "core/hle/service/am/am_sys.h" -#include "core/hle/hle.h" -#include "core/hle/kernel/event.h" -#include "core/hle/kernel/shared_memory.h" - namespace Service { namespace AM { diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index 0b78f5393..15e63bc7b 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -4,10 +4,10 @@ #pragma once -#include "core/hle/kernel/kernel.h" -#include "core/hle/service/service.h" - namespace Service { + +class Interface; + namespace AM { /** diff --git a/src/core/hle/service/am/am_app.cpp b/src/core/hle/service/am/am_app.cpp index f40a87cb4..16c76a1eb 100644 --- a/src/core/hle/service/am/am_app.cpp +++ b/src/core/hle/service/am/am_app.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" #include "core/hle/service/am/am.h" #include "core/hle/service/am/am_app.h" diff --git a/src/core/hle/service/am/am_net.cpp b/src/core/hle/service/am/am_net.cpp index 7515a4e6e..065e04118 100644 --- a/src/core/hle/service/am/am_net.cpp +++ b/src/core/hle/service/am/am_net.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" #include "core/hle/service/am/am.h" #include "core/hle/service/am/am_net.h" diff --git a/src/core/hle/service/am/am_sys.cpp b/src/core/hle/service/am/am_sys.cpp index 715b7b55d..e38812297 100644 --- a/src/core/hle/service/am/am_sys.cpp +++ b/src/core/hle/service/am/am_sys.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" #include "core/hle/service/am/am.h" #include "core/hle/service/am/am_sys.h" diff --git a/src/core/hle/service/am/am_u.cpp b/src/core/hle/service/am/am_u.cpp index b1e1ea5e4..c0392b754 100644 --- a/src/core/hle/service/am/am_u.cpp +++ b/src/core/hle/service/am/am_u.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" #include "core/hle/service/am/am.h" #include "core/hle/service/am/am_u.h" diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp index ba66569b4..69255e2ef 100644 --- a/src/core/hle/service/apt/apt.cpp +++ b/src/core/hle/service/apt/apt.cpp @@ -13,12 +13,10 @@ #include "core/hle/service/apt/apt_s.h" #include "core/hle/service/apt/apt_u.h" -#include "core/hle/hle.h" #include "core/hle/kernel/event.h" #include "core/hle/kernel/mutex.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/shared_memory.h" -#include "core/hle/kernel/thread.h" namespace Service { namespace APT { diff --git a/src/core/hle/service/apt/apt_a.cpp b/src/core/hle/service/apt/apt_a.cpp index 22800c56f..0c6a77305 100644 --- a/src/core/hle/service/apt/apt_a.cpp +++ b/src/core/hle/service/apt/apt_a.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" #include "core/hle/service/apt/apt.h" #include "core/hle/service/apt/apt_a.h" diff --git a/src/core/hle/service/apt/apt_s.cpp b/src/core/hle/service/apt/apt_s.cpp index e5fd9165c..7f6e81a63 100644 --- a/src/core/hle/service/apt/apt_s.cpp +++ b/src/core/hle/service/apt/apt_s.cpp @@ -2,8 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. - -#include "core/hle/hle.h" #include "core/hle/service/apt/apt.h" #include "core/hle/service/apt/apt_s.h" diff --git a/src/core/hle/service/apt/apt_u.cpp b/src/core/hle/service/apt/apt_u.cpp index aba627f54..209a0055b 100644 --- a/src/core/hle/service/apt/apt_u.cpp +++ b/src/core/hle/service/apt/apt_u.cpp @@ -2,9 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. - -#include "common/file_util.h" - #include "core/hle/service/apt/apt.h" #include "core/hle/service/apt/apt_u.h" diff --git a/src/core/hle/service/boss/boss.cpp b/src/core/hle/service/boss/boss.cpp index d38140f19..419ec976e 100644 --- a/src/core/hle/service/boss/boss.cpp +++ b/src/core/hle/service/boss/boss.cpp @@ -7,10 +7,6 @@ #include "core/hle/service/boss/boss_p.h" #include "core/hle/service/boss/boss_u.h" -#include "core/hle/kernel/event.h" -#include "core/hle/kernel/shared_memory.h" -#include "core/hle/hle.h" - namespace Service { namespace BOSS { diff --git a/src/core/hle/service/boss/boss.h b/src/core/hle/service/boss/boss.h index a6942ada6..d3b5d7101 100644 --- a/src/core/hle/service/boss/boss.h +++ b/src/core/hle/service/boss/boss.h @@ -4,9 +4,6 @@ #pragma once -#include "core/hle/kernel/kernel.h" -#include "core/hle/service/service.h" - namespace Service { namespace BOSS { diff --git a/src/core/hle/service/boss/boss_p.cpp b/src/core/hle/service/boss/boss_p.cpp index 089f5f186..c498abe4e 100644 --- a/src/core/hle/service/boss/boss_p.cpp +++ b/src/core/hle/service/boss/boss_p.cpp @@ -2,8 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" -#include "core/hle/service/boss/boss.h" #include "core/hle/service/boss/boss_p.h" namespace Service { diff --git a/src/core/hle/service/boss/boss_u.cpp b/src/core/hle/service/boss/boss_u.cpp index 9f17711bb..d59babe71 100644 --- a/src/core/hle/service/boss/boss_u.cpp +++ b/src/core/hle/service/boss/boss_u.cpp @@ -2,8 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" -#include "core/hle/service/boss/boss.h" #include "core/hle/service/boss/boss_u.h" namespace Service { diff --git a/src/core/hle/service/cam/cam.cpp b/src/core/hle/service/cam/cam.cpp index 4f34b699b..360bcfca4 100644 --- a/src/core/hle/service/cam/cam.cpp +++ b/src/core/hle/service/cam/cam.cpp @@ -11,10 +11,6 @@ #include "core/hle/service/cam/cam_s.h" #include "core/hle/service/cam/cam_u.h" -#include "core/hle/kernel/event.h" -#include "core/hle/kernel/shared_memory.h" -#include "core/hle/hle.h" - namespace Service { namespace CAM { diff --git a/src/core/hle/service/cam/cam.h b/src/core/hle/service/cam/cam.h index e9abdcb1f..23d0c9c59 100644 --- a/src/core/hle/service/cam/cam.h +++ b/src/core/hle/service/cam/cam.h @@ -4,8 +4,7 @@ #pragma once -#include "core/hle/kernel/kernel.h" -#include "core/hle/service/service.h" +#include "common/common_types.h" namespace Service { namespace CAM { diff --git a/src/core/hle/service/cam/cam_c.cpp b/src/core/hle/service/cam/cam_c.cpp index d35adcb9f..8fa7abc85 100644 --- a/src/core/hle/service/cam/cam_c.cpp +++ b/src/core/hle/service/cam/cam_c.cpp @@ -2,8 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" -#include "core/hle/service/cam/cam.h" #include "core/hle/service/cam/cam_c.h" namespace Service { diff --git a/src/core/hle/service/cam/cam_q.cpp b/src/core/hle/service/cam/cam_q.cpp index c2760a102..d3ba91e9d 100644 --- a/src/core/hle/service/cam/cam_q.cpp +++ b/src/core/hle/service/cam/cam_q.cpp @@ -2,8 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" -#include "core/hle/service/cam/cam.h" #include "core/hle/service/cam/cam_q.h" namespace Service { diff --git a/src/core/hle/service/cam/cam_s.cpp b/src/core/hle/service/cam/cam_s.cpp index aefbf7df4..2a13984d8 100644 --- a/src/core/hle/service/cam/cam_s.cpp +++ b/src/core/hle/service/cam/cam_s.cpp @@ -2,8 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" -#include "core/hle/service/cam/cam.h" #include "core/hle/service/cam/cam_s.h" namespace Service { diff --git a/src/core/hle/service/cam/cam_u.cpp b/src/core/hle/service/cam/cam_u.cpp index 1c292ea23..9d59c55fb 100644 --- a/src/core/hle/service/cam/cam_u.cpp +++ b/src/core/hle/service/cam/cam_u.cpp @@ -2,8 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" -#include "core/hle/service/cam/cam.h" #include "core/hle/service/cam/cam_u.h" namespace Service { diff --git a/src/core/hle/service/cecd/cecd.cpp b/src/core/hle/service/cecd/cecd.cpp index db0e52b79..6d79ce9b4 100644 --- a/src/core/hle/service/cecd/cecd.cpp +++ b/src/core/hle/service/cecd/cecd.cpp @@ -9,10 +9,6 @@ #include "core/hle/service/cecd/cecd_s.h" #include "core/hle/service/cecd/cecd_u.h" -#include "core/hle/kernel/event.h" -#include "core/hle/kernel/shared_memory.h" -#include "core/hle/hle.h" - namespace Service { namespace CECD { diff --git a/src/core/hle/service/cecd/cecd.h b/src/core/hle/service/cecd/cecd.h index 32fd2045d..9e158521b 100644 --- a/src/core/hle/service/cecd/cecd.h +++ b/src/core/hle/service/cecd/cecd.h @@ -4,9 +4,6 @@ #pragma once -#include "core/hle/kernel/kernel.h" -#include "core/hle/service/service.h" - namespace Service { namespace CECD { diff --git a/src/core/hle/service/cecd/cecd_s.cpp b/src/core/hle/service/cecd/cecd_s.cpp index 72d7e8d44..bfd821c07 100644 --- a/src/core/hle/service/cecd/cecd_s.cpp +++ b/src/core/hle/service/cecd/cecd_s.cpp @@ -2,8 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" -#include "core/hle/service/cecd/cecd.h" #include "core/hle/service/cecd/cecd_s.h" namespace Service { diff --git a/src/core/hle/service/cecd/cecd_u.cpp b/src/core/hle/service/cecd/cecd_u.cpp index 0a23bafbc..9b720a738 100644 --- a/src/core/hle/service/cecd/cecd_u.cpp +++ b/src/core/hle/service/cecd/cecd_u.cpp @@ -2,18 +2,17 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" -#include "core/hle/service/cecd/cecd.h" #include "core/hle/service/cecd/cecd_u.h" namespace Service { namespace CECD { -// Empty arrays are illegal -- commented out until an entry is added. -//const Interface::FunctionInfo FunctionTable[] = { }; +static const Interface::FunctionInfo FunctionTable[] = { + { 0x00120104, nullptr, "ReadSavedData" }, +}; CECD_U_Interface::CECD_U_Interface() { - //Register(FunctionTable); + Register(FunctionTable); } } // namespace CECD diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp index 56986a49e..4c82a58e4 100644 --- a/src/core/hle/service/cfg/cfg.cpp +++ b/src/core/hle/service/cfg/cfg.cpp @@ -4,13 +4,15 @@ #include <algorithm> +#include "common/file_util.h" #include "common/logging/log.h" #include "common/string_util.h" -#include "common/file_util.h" +#include "common/swap.h" #include "core/file_sys/archive_systemsavedata.h" #include "core/file_sys/file_backend.h" #include "core/settings.h" +#include "core/hle/result.h" #include "core/hle/service/cfg/cfg.h" #include "core/hle/service/cfg/cfg_i.h" #include "core/hle/service/cfg/cfg_s.h" @@ -292,8 +294,8 @@ ResultCode DeleteConfigNANDSaveFile() { ResultCode UpdateConfigNANDSavegame() { FileSys::Mode mode = {}; - mode.write_flag = 1; - mode.create_flag = 1; + mode.write_flag.Assign(1); + mode.create_flag.Assign(1); FileSys::Path path("config"); @@ -333,6 +335,18 @@ ResultCode FormatConfig() { res = CreateConfigInfoBlk(0x000A0000, sizeof(CONSOLE_USERNAME_BLOCK), 0xE, &CONSOLE_USERNAME_BLOCK); if (!res.IsSuccess()) return res; + // 0x000A0000 - Profile username + struct { + u16_le username[10]; + u8 unused[4]; + u32_le wordfilter_version; // Unused by Citra + } profile_username = {}; + + std::u16string username_string = Common::UTF8ToUTF16("Citra"); + std::copy(username_string.cbegin(), username_string.cend(), profile_username.username); + res = CreateConfigInfoBlk(0x000A0000, sizeof(profile_username), 0xE, &profile_username); + if (!res.IsSuccess()) return res; + // 0x000A0001 - Profile birthday const u8 profile_birthday[2] = {3, 25}; // March 25th, 2014 res = CreateConfigInfoBlk(0x000A0001, sizeof(profile_birthday), 0xE, profile_birthday); @@ -343,9 +357,10 @@ ResultCode FormatConfig() { res = CreateConfigInfoBlk(0x000B0000, sizeof(COUNTRY_INFO), 0xE, &COUNTRY_INFO); if (!res.IsSuccess()) return res; - char16_t country_name_buffer[16][0x40] = {}; + u16_le country_name_buffer[16][0x40] = {}; + std::u16string region_name = Common::UTF8ToUTF16("Gensokyo"); for (size_t i = 0; i < 16; ++i) { - Common::UTF8ToUTF16("Gensokyo").copy(country_name_buffer[i], 0x40); + std::copy(region_name.cbegin(), region_name.cend(), country_name_buffer[i]); } // 0x000B0001 - Localized names for the profile Country res = CreateConfigInfoBlk(0x000B0001, sizeof(country_name_buffer), 0xE, country_name_buffer); @@ -404,7 +419,7 @@ void Init() { FileSys::Path config_path("config"); FileSys::Mode open_mode = {}; - open_mode.read_flag = 1; + open_mode.read_flag.Assign(1); auto config_result = Service::FS::OpenFileFromArchive(*archive_result, config_path, open_mode); diff --git a/src/core/hle/service/cfg/cfg.h b/src/core/hle/service/cfg/cfg.h index fc2a16a04..606ab99cf 100644 --- a/src/core/hle/service/cfg/cfg.h +++ b/src/core/hle/service/cfg/cfg.h @@ -5,10 +5,15 @@ #pragma once #include <array> -#include "core/hle/result.h" -#include "core/hle/service/service.h" + +#include "common/common_types.h" + +union ResultCode; namespace Service { + +class Interface; + namespace CFG { enum SystemModel { diff --git a/src/core/hle/service/cfg/cfg_i.cpp b/src/core/hle/service/cfg/cfg_i.cpp index 5aeadc084..0559a07b2 100644 --- a/src/core/hle/service/cfg/cfg_i.cpp +++ b/src/core/hle/service/cfg/cfg_i.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" #include "core/hle/service/cfg/cfg.h" #include "core/hle/service/cfg/cfg_i.h" diff --git a/src/core/hle/service/cfg/cfg_s.cpp b/src/core/hle/service/cfg/cfg_s.cpp index a329514a6..b03d290e5 100644 --- a/src/core/hle/service/cfg/cfg_s.cpp +++ b/src/core/hle/service/cfg/cfg_s.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" #include "core/hle/service/cfg/cfg.h" #include "core/hle/service/cfg/cfg_s.h" diff --git a/src/core/hle/service/cfg/cfg_u.cpp b/src/core/hle/service/cfg/cfg_u.cpp index 18939750b..89ae96c9e 100644 --- a/src/core/hle/service/cfg/cfg_u.cpp +++ b/src/core/hle/service/cfg/cfg_u.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" #include "core/hle/service/cfg/cfg.h" #include "core/hle/service/cfg/cfg_u.h" diff --git a/src/core/hle/service/dsp_dsp.cpp b/src/core/hle/service/dsp_dsp.cpp index d6b8d1318..15d3274ec 100644 --- a/src/core/hle/service/dsp_dsp.cpp +++ b/src/core/hle/service/dsp_dsp.cpp @@ -2,9 +2,10 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "audio_core/hle/pipe.h" + #include "common/logging/log.h" -#include "core/hle/hle.h" #include "core/hle/kernel/event.h" #include "core/hle/service/dsp_dsp.h" @@ -15,17 +16,30 @@ namespace DSP_DSP { static u32 read_pipe_count; static Kernel::SharedPtr<Kernel::Event> semaphore_event; -static Kernel::SharedPtr<Kernel::Event> interrupt_event; -void SignalInterrupt() { - // TODO(bunnei): This is just a stub, it does not do anything other than signal to the emulated - // application that a DSP interrupt occurred, without specifying which one. Since we do not - // emulate the DSP yet (and how it works is largely unknown), this is a work around to get games - // that check the DSP interrupt signal event to run. We should figure out the different types of - // DSP interrupts, and trigger them at the appropriate times. +struct PairHash { + template <typename T, typename U> + std::size_t operator()(const std::pair<T, U> &x) const { + // TODO(yuriks): Replace with better hash combining function. + return std::hash<T>()(x.first) ^ std::hash<U>()(x.second); + } +}; + +/// Map of (audio interrupt number, channel number) to Kernel::Events. See: RegisterInterruptEvents +static std::unordered_map<std::pair<u32, u32>, Kernel::SharedPtr<Kernel::Event>, PairHash> interrupt_events; + +// DSP Interrupts: +// Interrupt #2 occurs every frame tick. Userland programs normally have a thread that's waiting +// for an interrupt event. Immediately after this interrupt event, userland normally updates the +// state in the next region and increments the relevant frame counter by two. +void SignalAllInterrupts() { + // HACK: The other interrupts have currently unknown purpose, we trigger them each tick in any case. + for (auto& interrupt_event : interrupt_events) + interrupt_event.second->Signal(); +} - if (interrupt_event != 0) - interrupt_event->Signal(); +void SignalInterrupt(u32 interrupt, u32 channel) { + interrupt_events[std::make_pair(interrupt, channel)]->Signal(); } /** @@ -44,7 +58,7 @@ static void ConvertProcessAddressFromDspDram(Service::Interface* self) { cmd_buff[1] = 0; // No error cmd_buff[2] = (addr << 1) + (Memory::DSP_RAM_VADDR + 0x40000); - LOG_WARNING(Service_DSP, "(STUBBED) called with address 0x%08X", addr); + LOG_TRACE(Service_DSP, "addr=0x%08X", addr); } /** @@ -122,8 +136,8 @@ static void FlushDataCache(Service::Interface* self) { /** * DSP_DSP::RegisterInterruptEvents service function * Inputs: - * 1 : Parameter 0 (purpose unknown) - * 2 : Parameter 1 (purpose unknown) + * 1 : Interrupt Number + * 2 : Channel Number * 4 : Interrupt event handle * Outputs: * 1 : Result of function, 0 on success, otherwise error code @@ -131,22 +145,24 @@ static void FlushDataCache(Service::Interface* self) { static void RegisterInterruptEvents(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); - u32 param0 = cmd_buff[1]; - u32 param1 = cmd_buff[2]; + u32 interrupt = cmd_buff[1]; + u32 channel = cmd_buff[2]; u32 event_handle = cmd_buff[4]; - auto evt = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[4]); - if (evt != nullptr) { - interrupt_event = evt; - cmd_buff[1] = 0; // No error + if (event_handle) { + auto evt = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[4]); + if (evt) { + interrupt_events[std::make_pair(interrupt, channel)] = evt; + cmd_buff[1] = RESULT_SUCCESS.raw; + LOG_WARNING(Service_DSP, "Registered interrupt=%u, channel=%u, event_handle=0x%08X", interrupt, channel, event_handle); + } else { + cmd_buff[1] = -1; + LOG_ERROR(Service_DSP, "Invalid event handle! interrupt=%u, channel=%u, event_handle=0x%08X", interrupt, channel, event_handle); + } } else { - LOG_ERROR(Service_DSP, "called with invalid handle=%08X", cmd_buff[4]); - - // TODO(yuriks): An error should be returned from SendSyncRequest, not in the cmdbuf - cmd_buff[1] = -1; + interrupt_events.erase(std::make_pair(interrupt, channel)); + LOG_WARNING(Service_DSP, "Unregistered interrupt=%u, channel=%u, event_handle=0x%08X", interrupt, channel, event_handle); } - - LOG_WARNING(Service_DSP, "(STUBBED) called param0=%u, param1=%u, event_handle=0x%08X", param0, param1, event_handle); } /** @@ -159,8 +175,6 @@ static void RegisterInterruptEvents(Service::Interface* self) { static void SetSemaphore(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); - SignalInterrupt(); - cmd_buff[1] = 0; // No error LOG_WARNING(Service_DSP, "(STUBBED) called"); @@ -169,9 +183,9 @@ static void SetSemaphore(Service::Interface* self) { /** * DSP_DSP::WriteProcessPipe service function * Inputs: - * 1 : Number + * 1 : Channel * 2 : Size - * 3 : (size <<14) | 0x402 + * 3 : (size << 14) | 0x402 * 4 : Buffer * Outputs: * 0 : Return header @@ -180,21 +194,42 @@ static void SetSemaphore(Service::Interface* self) { static void WriteProcessPipe(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); - u32 number = cmd_buff[1]; + u32 channel = cmd_buff[1]; u32 size = cmd_buff[2]; - u32 new_size = cmd_buff[3]; u32 buffer = cmd_buff[4]; + if (IPC::StaticBufferDesc(size, 1) != cmd_buff[3]) { + LOG_ERROR(Service_DSP, "IPC static buffer descriptor failed validation (0x%X). channel=%u, size=0x%X, buffer=0x%08X", cmd_buff[3], channel, size, buffer); + cmd_buff[1] = -1; // TODO + return; + } + + if (!Memory::GetPointer(buffer)) { + LOG_ERROR(Service_DSP, "Invalid Buffer: channel=%u, size=0x%X, buffer=0x%08X", channel, size, buffer); + cmd_buff[1] = -1; // TODO + return; + } + + std::vector<u8> message(size); + + for (size_t i = 0; i < size; i++) { + message[i] = Memory::Read8(buffer + i); + } + + DSP::HLE::PipeWrite(channel, message); + cmd_buff[1] = RESULT_SUCCESS.raw; // No error - LOG_WARNING(Service_DSP, "(STUBBED) called number=%u, size=0x%X, new_size=0x%X, buffer=0x%08X", - number, size, new_size, buffer); + LOG_TRACE(Service_DSP, "channel=%u, size=0x%X, buffer=0x%08X", channel, size, buffer); } /** * DSP_DSP::ReadPipeIfPossible service function + * A pipe is a means of communication between the ARM11 and DSP that occurs on + * hardware by writing to/reading from the DSP registers at 0x10203000. + * Pipes are used for initialisation. See also DSP::HLE::PipeRead. * Inputs: - * 1 : Unknown + * 1 : Pipe Number * 2 : Unknown * 3 : Size in bytes of read (observed only lower half word used) * 0x41 : Virtual address to read from DSP pipe to in memory @@ -205,35 +240,25 @@ static void WriteProcessPipe(Service::Interface* self) { static void ReadPipeIfPossible(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); - u32 unk1 = cmd_buff[1]; + u32 pipe = cmd_buff[1]; u32 unk2 = cmd_buff[2]; u32 size = cmd_buff[3] & 0xFFFF;// Lower 16 bits are size VAddr addr = cmd_buff[0x41]; - // Canned DSP responses that games expect. These were taken from HW by 3dmoo team. - // TODO: Remove this hack :) - static const std::array<u16, 16> canned_read_pipe = {{ - 0x000F, 0xBFFF, 0x9E8E, 0x8680, 0xA78E, 0x9430, 0x8400, 0x8540, - 0x948E, 0x8710, 0x8410, 0xA90E, 0xAA0E, 0xAACE, 0xAC4E, 0xAC58 - }}; + if (!Memory::GetPointer(addr)) { + LOG_ERROR(Service_DSP, "Invalid addr: pipe=0x%08X, unk2=0x%08X, size=0x%X, buffer=0x%08X", pipe, unk2, size, addr); + cmd_buff[1] = -1; // TODO + return; + } - u32 initial_size = read_pipe_count; + std::vector<u8> response = DSP::HLE::PipeRead(pipe, size); - for (unsigned offset = 0; offset < size; offset += sizeof(u16)) { - if (read_pipe_count < canned_read_pipe.size()) { - Memory::Write16(addr + offset, canned_read_pipe[read_pipe_count]); - read_pipe_count++; - } else { - LOG_ERROR(Service_DSP, "canned read pipe log exceeded!"); - break; - } - } + Memory::WriteBlock(addr, response.data(), response.size()); cmd_buff[1] = 0; // No error - cmd_buff[2] = (read_pipe_count - initial_size) * sizeof(u16); + cmd_buff[2] = (u32)response.size(); - LOG_WARNING(Service_DSP, "(STUBBED) called unk1=0x%08X, unk2=0x%08X, size=0x%X, buffer=0x%08X", - unk1, unk2, size, addr); + LOG_TRACE(Service_DSP, "pipe=0x%08X, unk2=0x%08X, size=0x%X, buffer=0x%08X", pipe, unk2, size, addr); } /** @@ -312,7 +337,6 @@ const Interface::FunctionInfo FunctionTable[] = { Interface::Interface() { semaphore_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "DSP_DSP::semaphore_event"); - interrupt_event = nullptr; read_pipe_count = 0; Register(FunctionTable); @@ -320,7 +344,7 @@ Interface::Interface() { Interface::~Interface() { semaphore_event = nullptr; - interrupt_event = nullptr; + interrupt_events.clear(); } } // namespace diff --git a/src/core/hle/service/dsp_dsp.h b/src/core/hle/service/dsp_dsp.h index b6f611db5..32b89e9bb 100644 --- a/src/core/hle/service/dsp_dsp.h +++ b/src/core/hle/service/dsp_dsp.h @@ -23,7 +23,15 @@ public: } }; -/// Signals that a DSP interrupt has occurred to userland code -void SignalInterrupt(); +/// Signal all audio related interrupts. +void SignalAllInterrupts(); + +/** + * Signal a specific audio related interrupt based on interrupt id and channel id. + * @param interrupt_id The interrupt id + * @param channel_id The channel id + * The significance of various values of interrupt_id and channel_id is not yet known. + */ +void SignalInterrupt(u32 interrupt_id, u32 channel_id); } // namespace diff --git a/src/core/hle/service/err_f.cpp b/src/core/hle/service/err_f.cpp index e8c06c1cf..5f9cf6e94 100644 --- a/src/core/hle/service/err_f.cpp +++ b/src/core/hle/service/err_f.cpp @@ -2,9 +2,10 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/bit_field.h" +#include "common/common_types.h" #include "common/logging/log.h" -#include "core/hle/hle.h" #include "core/hle/service/err_f.h" //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/frd/frd.cpp b/src/core/hle/service/frd/frd.cpp index 2911ab402..c13ffd9d2 100644 --- a/src/core/hle/service/frd/frd.cpp +++ b/src/core/hle/service/frd/frd.cpp @@ -7,10 +7,6 @@ #include "core/hle/service/frd/frd_a.h" #include "core/hle/service/frd/frd_u.h" -#include "core/hle/kernel/event.h" -#include "core/hle/kernel/shared_memory.h" -#include "core/hle/hle.h" - namespace Service { namespace FRD { diff --git a/src/core/hle/service/frd/frd.h b/src/core/hle/service/frd/frd.h index 41f7a2f6b..f9f88b444 100644 --- a/src/core/hle/service/frd/frd.h +++ b/src/core/hle/service/frd/frd.h @@ -4,9 +4,6 @@ #pragma once -#include "core/hle/kernel/kernel.h" -#include "core/hle/service/service.h" - namespace Service { namespace FRD { diff --git a/src/core/hle/service/frd/frd_a.cpp b/src/core/hle/service/frd/frd_a.cpp index 1c438a337..818d610f3 100644 --- a/src/core/hle/service/frd/frd_a.cpp +++ b/src/core/hle/service/frd/frd_a.cpp @@ -2,8 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" -#include "core/hle/service/frd/frd.h" #include "core/hle/service/frd/frd_a.h" namespace Service { diff --git a/src/core/hle/service/frd/frd_u.cpp b/src/core/hle/service/frd/frd_u.cpp index 9e70ec901..2c6885377 100644 --- a/src/core/hle/service/frd/frd_u.cpp +++ b/src/core/hle/service/frd/frd_u.cpp @@ -2,8 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" -#include "core/hle/service/frd/frd.h" #include "core/hle/service/frd/frd_u.h" namespace Service { diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp index 98b11c798..5838b6d71 100644 --- a/src/core/hle/service/gsp_gpu.cpp +++ b/src/core/hle/service/gsp_gpu.cpp @@ -347,7 +347,7 @@ void SignalInterrupt(InterruptId interrupt_id) { FrameBufferUpdate* info = GetFrameBufferInfo(thread_id, screen_id); if (info->is_dirty) { SetBufferSwap(screen_id, info->framebuffer_info[info->index]); - info->is_dirty = false; + info->is_dirty.Assign(false); } } } @@ -499,7 +499,7 @@ static void SetLcdForceBlack(Service::Interface* self) { // Since data is already zeroed, there is no need to explicitly set // the color to black (all zero). - data.is_enabled = enable_black; + data.is_enabled.Assign(enable_black); LCD::Write(HW::VADDR_LCD + 4 * LCD_REG_INDEX(color_fill_top), data.raw); // Top LCD LCD::Write(HW::VADDR_LCD + 4 * LCD_REG_INDEX(color_fill_bottom), data.raw); // Bottom LCD @@ -521,7 +521,7 @@ static void TriggerCmdReqQueue(Service::Interface* self) { ExecuteCommand(command_buffer->commands[i], thread_id); // Indicates that command has completed - command_buffer->number_commands = command_buffer->number_commands - 1; + command_buffer->number_commands.Assign(command_buffer->number_commands - 1); } } diff --git a/src/core/hle/service/gsp_lcd.cpp b/src/core/hle/service/gsp_lcd.cpp index 59ee9b73c..7ad7f081f 100644 --- a/src/core/hle/service/gsp_lcd.cpp +++ b/src/core/hle/service/gsp_lcd.cpp @@ -2,8 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/bit_field.h" - #include "core/hle/service/gsp_lcd.h" //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 2e1e5c3e9..11d7e69a1 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -13,7 +13,6 @@ #include "core/core_timing.h" #include "core/hle/kernel/event.h" #include "core/hle/kernel/shared_memory.h" -#include "core/hle/hle.h" #include "video_core/video_core.h" @@ -106,7 +105,7 @@ void Update() { bool pressed = false; std::tie(touch_entry->x, touch_entry->y, pressed) = VideoCore::g_emu_window->GetTouchState(); - touch_entry->valid = pressed ? 1 : 0; + touch_entry->valid.Assign(pressed ? 1 : 0); // TODO(bunnei): We're not doing anything with offset 0xA8 + 0x18 of HID SharedMemory, which // supposedly is "Touch-screen entry, which contains the raw coordinate data prior to being diff --git a/src/core/hle/service/hid/hid_spvr.cpp b/src/core/hle/service/hid/hid_spvr.cpp index 532931ae0..c50f597eb 100644 --- a/src/core/hle/service/hid/hid_spvr.cpp +++ b/src/core/hle/service/hid/hid_spvr.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" #include "core/hle/service/hid/hid.h" #include "core/hle/service/hid/hid_spvr.h" diff --git a/src/core/hle/service/hid/hid_user.cpp b/src/core/hle/service/hid/hid_user.cpp index e103881b1..bbdde2abb 100644 --- a/src/core/hle/service/hid/hid_user.cpp +++ b/src/core/hle/service/hid/hid_user.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" #include "core/hle/service/hid/hid.h" #include "core/hle/service/hid/hid_user.h" diff --git a/src/core/hle/service/http_c.cpp b/src/core/hle/service/http_c.cpp index 43d8a3b85..79009053e 100644 --- a/src/core/hle/service/http_c.cpp +++ b/src/core/hle/service/http_c.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" #include "core/hle/service/http_c.h" //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/ir/ir.cpp b/src/core/hle/service/ir/ir.cpp index adfbb258d..c2121cb2e 100644 --- a/src/core/hle/service/ir/ir.cpp +++ b/src/core/hle/service/ir/ir.cpp @@ -2,21 +2,22 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "core/hle/kernel/event.h" +#include "core/hle/kernel/shared_memory.h" + #include "core/hle/service/service.h" #include "core/hle/service/ir/ir.h" #include "core/hle/service/ir/ir_rst.h" #include "core/hle/service/ir/ir_u.h" #include "core/hle/service/ir/ir_user.h" -#include "core/hle/hle.h" -#include "core/hle/kernel/event.h" -#include "core/hle/kernel/shared_memory.h" - namespace Service { namespace IR { static Kernel::SharedPtr<Kernel::Event> handle_event; +static Kernel::SharedPtr<Kernel::Event> conn_status_event; static Kernel::SharedPtr<Kernel::SharedMemory> shared_memory; +static Kernel::SharedPtr<Kernel::SharedMemory> transfer_shared_memory; void GetHandles(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); @@ -27,6 +28,64 @@ void GetHandles(Service::Interface* self) { cmd_buff[4] = Kernel::g_handle_table.Create(Service::IR::handle_event).MoveFrom(); } +void InitializeIrNopShared(Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + u32 transfer_buff_size = cmd_buff[1]; + u32 recv_buff_size = cmd_buff[2]; + u32 unk1 = cmd_buff[3]; + u32 send_buff_size = cmd_buff[4]; + u32 unk2 = cmd_buff[5]; + u8 baud_rate = cmd_buff[6] & 0xFF; + Handle handle = cmd_buff[8]; + + if(Kernel::g_handle_table.IsValid(handle)) { + transfer_shared_memory = Kernel::g_handle_table.Get<Kernel::SharedMemory>(handle); + transfer_shared_memory->name = "IR:TransferSharedMemory"; + } + + cmd_buff[1] = RESULT_SUCCESS.raw; + + LOG_WARNING(Service_IR, "(STUBBED) called, transfer_buff_size=%d, recv_buff_size=%d, " + "unk1=%d, send_buff_size=%d, unk2=%d, baud_rate=%u, handle=0x%08X", + transfer_buff_size, recv_buff_size, unk1, send_buff_size, unk2, baud_rate, handle); +} + +void RequireConnection(Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + conn_status_event->Signal(); + + cmd_buff[1] = RESULT_SUCCESS.raw; + + LOG_WARNING(Service_IR, "(STUBBED) called"); +} + +void Disconnect(Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + cmd_buff[1] = RESULT_SUCCESS.raw; + + LOG_WARNING(Service_IR, "(STUBBED) called"); +} + +void GetConnectionStatusEvent(Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + cmd_buff[1] = RESULT_SUCCESS.raw; + cmd_buff[3] = Kernel::g_handle_table.Create(Service::IR::conn_status_event).MoveFrom(); + + LOG_WARNING(Service_IR, "(STUBBED) called"); +} + +void FinalizeIrNop(Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + cmd_buff[1] = RESULT_SUCCESS.raw; + + LOG_WARNING(Service_IR, "(STUBBED) called"); +} + void Init() { using namespace Kernel; @@ -36,15 +95,19 @@ void Init() { using Kernel::MemoryPermission; shared_memory = SharedMemory::Create(0x1000, Kernel::MemoryPermission::ReadWrite, - Kernel::MemoryPermission::ReadWrite, "IR:SharedMemory"); + Kernel::MemoryPermission::ReadWrite, "IR:SharedMemory"); + transfer_shared_memory = nullptr; // Create event handle(s) handle_event = Event::Create(RESETTYPE_ONESHOT, "IR:HandleEvent"); + conn_status_event = Event::Create(RESETTYPE_ONESHOT, "IR:ConnectionStatusEvent"); } void Shutdown() { + transfer_shared_memory = nullptr; shared_memory = nullptr; handle_event = nullptr; + conn_status_event = nullptr; } } // namespace IR diff --git a/src/core/hle/service/ir/ir.h b/src/core/hle/service/ir/ir.h index c16d963e7..72d44ce60 100644 --- a/src/core/hle/service/ir/ir.h +++ b/src/core/hle/service/ir/ir.h @@ -4,10 +4,10 @@ #pragma once -#include "core/hle/kernel/kernel.h" -#include "core/hle/service/service.h" - namespace Service { + +class Interface; + namespace IR { /** @@ -20,6 +20,53 @@ namespace IR { */ void GetHandles(Interface* self); +/** + * IR::InitializeIrNopShared service function + * Inputs: + * 1 : Size of transfer buffer + * 2 : Recv buffer size + * 3 : unknown + * 4 : Send buffer size + * 5 : unknown + * 6 : BaudRate (u8) + * 7 : 0 + * 8 : Handle of transfer shared memory + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +void InitializeIrNopShared(Interface* self); + +/** + * IR::FinalizeIrNop service function + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +void FinalizeIrNop(Interface* self); + +/** + * IR::GetConnectionStatusEvent service function + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Connection Status Event handle + */ +void GetConnectionStatusEvent(Interface* self); + +/** + * IR::Disconnect service function + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +void Disconnect(Interface* self); + +/** + * IR::RequireConnection service function + * Inputs: + * 1 : unknown (u8), looks like always 1 + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +void RequireConnection(Interface* self); + /// Initialize IR service void Init(); diff --git a/src/core/hle/service/ir/ir_rst.cpp b/src/core/hle/service/ir/ir_rst.cpp index 96ae63420..c0300f109 100644 --- a/src/core/hle/service/ir/ir_rst.cpp +++ b/src/core/hle/service/ir/ir_rst.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" #include "core/hle/service/ir/ir.h" #include "core/hle/service/ir/ir_rst.h" diff --git a/src/core/hle/service/ir/ir_u.cpp b/src/core/hle/service/ir/ir_u.cpp index 1b1e3078b..96f76cb83 100644 --- a/src/core/hle/service/ir/ir_u.cpp +++ b/src/core/hle/service/ir/ir_u.cpp @@ -2,8 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" -#include "core/hle/service/ir/ir.h" #include "core/hle/service/ir/ir_u.h" namespace Service { diff --git a/src/core/hle/service/ir/ir_user.cpp b/src/core/hle/service/ir/ir_user.cpp index 8e3ff140f..06a601029 100644 --- a/src/core/hle/service/ir/ir_user.cpp +++ b/src/core/hle/service/ir/ir_user.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" #include "core/hle/service/ir/ir.h" #include "core/hle/service/ir/ir_user.h" @@ -10,20 +9,32 @@ namespace Service { namespace IR { const Interface::FunctionInfo FunctionTable[] = { - {0x00010182, nullptr, "InitializeIrNop"}, - {0x00020000, nullptr, "FinalizeIrNop"}, - {0x00030000, nullptr, "ClearReceiveBuffer"}, - {0x00040000, nullptr, "ClearSendBuffer"}, - {0x00060040, nullptr, "RequireConnection"}, - {0x00090000, nullptr, "Disconnect"}, - {0x000A0000, nullptr, "GetReceiveEvent"}, - {0x000B0000, nullptr, "GetSendEvent"}, - {0x000C0000, nullptr, "GetConnectionStatusEvent"}, - {0x000D0042, nullptr, "SendIrNop"}, - {0x000E0042, nullptr, "SendIrNopLarge"}, - {0x00180182, nullptr, "InitializeIrNopShared"}, - {0x00190040, nullptr, "ReleaseReceivedData"}, - {0x001A0040, nullptr, "SetOwnMachineId"}, + {0x00010182, nullptr, "InitializeIrNop"}, + {0x00020000, FinalizeIrNop, "FinalizeIrNop"}, + {0x00030000, nullptr, "ClearReceiveBuffer"}, + {0x00040000, nullptr, "ClearSendBuffer"}, + {0x000500C0, nullptr, "WaitConnection"}, + {0x00060040, RequireConnection, "RequireConnection"}, + {0x000702C0, nullptr, "AutoConnection"}, + {0x00080000, nullptr, "AnyConnection"}, + {0x00090000, Disconnect, "Disconnect"}, + {0x000A0000, nullptr, "GetReceiveEvent"}, + {0x000B0000, nullptr, "GetSendEvent"}, + {0x000C0000, GetConnectionStatusEvent, "GetConnectionStatusEvent"}, + {0x000D0042, nullptr, "SendIrNop"}, + {0x000E0042, nullptr, "SendIrNopLarge"}, + {0x000F0040, nullptr, "ReceiveIrnop"}, + {0x00100042, nullptr, "ReceiveIrnopLarge"}, + {0x00110040, nullptr, "GetLatestReceiveErrorResult"}, + {0x00120040, nullptr, "GetLatestSendErrorResult"}, + {0x00130000, nullptr, "GetConnectionStatus"}, + {0x00140000, nullptr, "GetTryingToConnectStatus"}, + {0x00150000, nullptr, "GetReceiveSizeFreeAndUsed"}, + {0x00160000, nullptr, "GetSendSizeFreeAndUsed"}, + {0x00170000, nullptr, "GetConnectionRole"}, + {0x00180182, InitializeIrNopShared, "InitializeIrNopShared"}, + {0x00190040, nullptr, "ReleaseReceivedData"}, + {0x001A0040, nullptr, "SetOwnMachineId"}, }; IR_User_Interface::IR_User_Interface() { diff --git a/src/core/hle/service/ldr_ro.cpp b/src/core/hle/service/ldr_ro.cpp index f84ce4d72..ecec2ce32 100644 --- a/src/core/hle/service/ldr_ro.cpp +++ b/src/core/hle/service/ldr_ro.cpp @@ -2,9 +2,9 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/common_types.h" #include "common/logging/log.h" -#include "core/hle/hle.h" #include "core/hle/service/ldr_ro.h" //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/mic_u.cpp b/src/core/hle/service/mic_u.cpp index 1f27e9c1f..f792bc9cd 100644 --- a/src/core/hle/service/mic_u.cpp +++ b/src/core/hle/service/mic_u.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" #include "core/hle/service/mic_u.h" //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/ndm_u.cpp b/src/core/hle/service/ndm_u.cpp index ad247fd1f..8fdf1ef90 100644 --- a/src/core/hle/service/ndm_u.cpp +++ b/src/core/hle/service/ndm_u.cpp @@ -2,8 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" -#include "ndm_u.h" +#include "core/hle/service/ndm_u.h" //////////////////////////////////////////////////////////////////////////////////////////////////// // Namespace NDM_U diff --git a/src/core/hle/service/news/news.cpp b/src/core/hle/service/news/news.cpp index 63cbd3850..b3f500694 100644 --- a/src/core/hle/service/news/news.cpp +++ b/src/core/hle/service/news/news.cpp @@ -9,10 +9,6 @@ #include "core/hle/service/news/news_s.h" #include "core/hle/service/news/news_u.h" -#include "core/hle/hle.h" -#include "core/hle/kernel/event.h" -#include "core/hle/kernel/shared_memory.h" - namespace Service { namespace NEWS { diff --git a/src/core/hle/service/news/news.h b/src/core/hle/service/news/news.h index b31ade255..46a3ffcb5 100644 --- a/src/core/hle/service/news/news.h +++ b/src/core/hle/service/news/news.h @@ -4,9 +4,6 @@ #pragma once -#include "core/hle/kernel/kernel.h" -#include "core/hle/service/service.h" - namespace Service { namespace NEWS { diff --git a/src/core/hle/service/news/news_s.cpp b/src/core/hle/service/news/news_s.cpp index 5b8db3288..39b5a50f8 100644 --- a/src/core/hle/service/news/news_s.cpp +++ b/src/core/hle/service/news/news_s.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" #include "core/hle/service/news/news.h" #include "core/hle/service/news/news_s.h" diff --git a/src/core/hle/service/news/news_u.cpp b/src/core/hle/service/news/news_u.cpp index 81f45a244..6b75cc24e 100644 --- a/src/core/hle/service/news/news_u.cpp +++ b/src/core/hle/service/news/news_u.cpp @@ -2,8 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" -#include "core/hle/service/news/news.h" #include "core/hle/service/news/news_u.h" namespace Service { diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp index 73b0ee52a..ed42464ce 100644 --- a/src/core/hle/service/nim/nim.cpp +++ b/src/core/hle/service/nim/nim.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/common_types.h" #include "common/logging/log.h" #include "core/hle/service/service.h" @@ -10,10 +11,6 @@ #include "core/hle/service/nim/nim_s.h" #include "core/hle/service/nim/nim_u.h" -#include "core/hle/kernel/event.h" -#include "core/hle/kernel/shared_memory.h" -#include "core/hle/hle.h" - namespace Service { namespace NIM { diff --git a/src/core/hle/service/nim/nim.h b/src/core/hle/service/nim/nim.h index f7635c747..c3106f18b 100644 --- a/src/core/hle/service/nim/nim.h +++ b/src/core/hle/service/nim/nim.h @@ -4,10 +4,10 @@ #pragma once -#include "core/hle/kernel/kernel.h" -#include "core/hle/service/service.h" - namespace Service { + +class Interface; + namespace NIM { /** diff --git a/src/core/hle/service/nim/nim_aoc.cpp b/src/core/hle/service/nim/nim_aoc.cpp index e6b1b6145..4a4818d57 100644 --- a/src/core/hle/service/nim/nim_aoc.cpp +++ b/src/core/hle/service/nim/nim_aoc.cpp @@ -2,8 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" -#include "core/hle/service/nim/nim.h" #include "core/hle/service/nim/nim_aoc.h" namespace Service { diff --git a/src/core/hle/service/nim/nim_s.cpp b/src/core/hle/service/nim/nim_s.cpp index 1172770ac..dcaa0255a 100644 --- a/src/core/hle/service/nim/nim_s.cpp +++ b/src/core/hle/service/nim/nim_s.cpp @@ -2,8 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" -#include "core/hle/service/nim/nim.h" #include "core/hle/service/nim/nim_s.h" namespace Service { diff --git a/src/core/hle/service/nim/nim_u.cpp b/src/core/hle/service/nim/nim_u.cpp index 066570a85..eae45ebc0 100644 --- a/src/core/hle/service/nim/nim_u.cpp +++ b/src/core/hle/service/nim/nim_u.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" #include "core/hle/service/nim/nim.h" #include "core/hle/service/nim/nim_u.h" diff --git a/src/core/hle/service/ns_s.cpp b/src/core/hle/service/ns_s.cpp index 99e8e0880..072918d62 100644 --- a/src/core/hle/service/ns_s.cpp +++ b/src/core/hle/service/ns_s.cpp @@ -2,8 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. - -#include "core/hle/hle.h" #include "core/hle/service/ns_s.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -14,14 +12,19 @@ namespace NS_S { const Interface::FunctionInfo FunctionTable[] = { {0x000100C0, nullptr, "LaunchFIRM"}, {0x000200C0, nullptr, "LaunchTitle"}, + {0x00030000, nullptr, "TerminateApplication"}, + {0x00040040, nullptr, "TerminateProcess"}, {0x000500C0, nullptr, "LaunchApplicationFIRM"}, {0x00060042, nullptr, "SetFIRMParams4A0"}, {0x00070042, nullptr, "CardUpdateInitialize"}, - {0x000D0140, nullptr, "SetFIRMParams4B0"}, + {0x00080000, nullptr, "CardUpdateShutdown"}, + {0x000D0140, nullptr, "SetTWLBannerHMAC"}, {0x000E0000, nullptr, "ShutdownAsync"}, {0x00100180, nullptr, "RebootSystem"}, + {0x00110100, nullptr, "TerminateTitle"}, + {0x001200C0, nullptr, "SetApplicationCpuTimeLimit"}, {0x00150140, nullptr, "LaunchApplication"}, - {0x00160000, nullptr, "HardRebootSystem"}, + {0x00160000, nullptr, "RebootSystemClean"}, }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/nwm_uds.cpp b/src/core/hle/service/nwm_uds.cpp index adca64a3a..dc80984b2 100644 --- a/src/core/hle/service/nwm_uds.cpp +++ b/src/core/hle/service/nwm_uds.cpp @@ -2,9 +2,9 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/common_types.h" #include "common/logging/log.h" -#include "core/hle/hle.h" #include "core/hle/kernel/event.h" #include "core/hle/service/nwm_uds.h" diff --git a/src/core/hle/service/pm_app.cpp b/src/core/hle/service/pm_app.cpp index 48646ed72..05d01bc48 100644 --- a/src/core/hle/service/pm_app.cpp +++ b/src/core/hle/service/pm_app.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" #include "core/hle/service/pm_app.h" //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/ptm/ptm.cpp b/src/core/hle/service/ptm/ptm.cpp index 22c1093ff..6bdee4d9e 100644 --- a/src/core/hle/service/ptm/ptm.cpp +++ b/src/core/hle/service/ptm/ptm.cpp @@ -110,8 +110,8 @@ void Init() { FileSys::Path gamecoin_path("gamecoin.dat"); FileSys::Mode open_mode = {}; - open_mode.write_flag = 1; - open_mode.create_flag = 1; + open_mode.write_flag.Assign(1); + open_mode.create_flag.Assign(1); // Open the file and write the default gamecoin information auto gamecoin_result = Service::FS::OpenFileFromArchive(*archive_result, gamecoin_path, open_mode); if (gamecoin_result.Succeeded()) { diff --git a/src/core/hle/service/ptm/ptm.h b/src/core/hle/service/ptm/ptm.h index f2e76441f..4cf7383d1 100644 --- a/src/core/hle/service/ptm/ptm.h +++ b/src/core/hle/service/ptm/ptm.h @@ -4,11 +4,12 @@ #pragma once -#include <array> -#include "core/hle/service/service.h" -#include "core/hle/result.h" +#include "common/common_types.h" namespace Service { + +class Interface; + namespace PTM { /// Charge levels used by PTM functions diff --git a/src/core/hle/service/ptm/ptm_play.cpp b/src/core/hle/service/ptm/ptm_play.cpp index 7bb990193..ca5dd0403 100644 --- a/src/core/hle/service/ptm/ptm_play.cpp +++ b/src/core/hle/service/ptm/ptm_play.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" #include "core/hle/service/ptm/ptm_play.h" namespace Service { diff --git a/src/core/hle/service/ptm/ptm_sysm.cpp b/src/core/hle/service/ptm/ptm_sysm.cpp index 3ecfab05c..fe76dd108 100644 --- a/src/core/hle/service/ptm/ptm_sysm.cpp +++ b/src/core/hle/service/ptm/ptm_sysm.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/hle.h" #include "core/hle/service/ptm/ptm.h" #include "core/hle/service/ptm/ptm_sysm.h" diff --git a/src/core/hle/service/ptm/ptm_u.cpp b/src/core/hle/service/ptm/ptm_u.cpp index 09dc38c3e..17e764866 100644 --- a/src/core/hle/service/ptm/ptm_u.cpp +++ b/src/core/hle/service/ptm/ptm_u.cpp @@ -2,9 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/logging/log.h" - -#include "core/hle/hle.h" #include "core/hle/service/ptm/ptm.h" #include "core/hle/service/ptm/ptm_u.h" diff --git a/src/core/hle/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp index 822b093f4..e603bf794 100644 --- a/src/core/hle/service/soc_u.cpp +++ b/src/core/hle/service/soc_u.cpp @@ -178,17 +178,17 @@ struct CTRPollFD { static Events TranslateTo3DS(u32 input_event) { Events ev = {}; if (input_event & POLLIN) - ev.pollin = 1; + ev.pollin.Assign(1); if (input_event & POLLPRI) - ev.pollpri = 1; + ev.pollpri.Assign(1); if (input_event & POLLHUP) - ev.pollhup = 1; + ev.pollhup.Assign(1); if (input_event & POLLERR) - ev.pollerr = 1; + ev.pollerr.Assign(1); if (input_event & POLLOUT) - ev.pollout = 1; + ev.pollout.Assign(1); if (input_event & POLLNVAL) - ev.pollnval = 1; + ev.pollnval.Assign(1); return ev; } diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp index 3b8c7c0e4..41fc3437b 100644 --- a/src/core/hle/service/srv.cpp +++ b/src/core/hle/service/srv.cpp @@ -2,9 +2,9 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/common_types.h" #include "common/logging/log.h" -#include "core/hle/hle.h" #include "core/hle/service/srv.h" #include "core/hle/kernel/event.h" diff --git a/src/core/hle/service/ssl_c.cpp b/src/core/hle/service/ssl_c.cpp index 9ecb72c77..fc7a4e6d3 100644 --- a/src/core/hle/service/ssl_c.cpp +++ b/src/core/hle/service/ssl_c.cpp @@ -4,7 +4,7 @@ #include <random> -#include "core/hle/hle.h" +#include "common/common_types.h" #include "core/hle/service/ssl_c.h" //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/y2r_u.cpp b/src/core/hle/service/y2r_u.cpp index 69d0bf4a3..bbead9344 100644 --- a/src/core/hle/service/y2r_u.cpp +++ b/src/core/hle/service/y2r_u.cpp @@ -4,15 +4,15 @@ #include <cstring> +#include "common/common_types.h" #include "common/logging/log.h" -#include "core/hle/hle.h" #include "core/hle/kernel/event.h" +#include "core/hle/kernel/kernel.h" #include "core/hle/service/y2r_u.h" #include "core/hw/y2r.h" #include "video_core/renderer_base.h" -#include "video_core/utils.h" #include "video_core/video_core.h" //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp index 4bd3a632d..5312baa83 100644 --- a/src/core/hw/gpu.cpp +++ b/src/core/hw/gpu.cpp @@ -17,7 +17,6 @@ #include "core/core_timing.h" #include "core/hle/service/gsp_gpu.h" -#include "core/hle/service/dsp_dsp.h" #include "core/hle/service/hid/hid.h" #include "core/hw/hw.h" @@ -146,8 +145,8 @@ inline void Write(u32 addr, const T data) { // Reset "trigger" flag and set the "finish" flag // NOTE: This was confirmed to happen on hardware even if "address_start" is zero. - config.trigger = 0; - config.finished = 1; + config.trigger.Assign(0); + config.finished.Assign(1); } break; } @@ -414,11 +413,6 @@ static void VBlankCallback(u64 userdata, int cycles_late) { GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PDC0); GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PDC1); - // TODO(bunnei): Fake a DSP interrupt on each frame. This does not belong here, but - // until we can emulate DSP interrupts, this is probably the only reasonable place to do - // this. Certain games expect this to be periodically signaled. - DSP_DSP::SignalInterrupt(); - // Check for user input updates Service::HID::Update(); @@ -444,16 +438,16 @@ void Init() { framebuffer_sub.address_left1 = 0x1848F000; framebuffer_sub.address_left2 = 0x184C7800; - framebuffer_top.width = 240; - framebuffer_top.height = 400; + framebuffer_top.width.Assign(240); + framebuffer_top.height.Assign(400); framebuffer_top.stride = 3 * 240; - framebuffer_top.color_format = Regs::PixelFormat::RGB8; + framebuffer_top.color_format.Assign(Regs::PixelFormat::RGB8); framebuffer_top.active_fb = 0; - framebuffer_sub.width = 240; - framebuffer_sub.height = 320; + framebuffer_sub.width.Assign(240); + framebuffer_sub.height.Assign(320); framebuffer_sub.stride = 3 * 240; - framebuffer_sub.color_format = Regs::PixelFormat::RGB8; + framebuffer_sub.color_format.Assign(Regs::PixelFormat::RGB8); framebuffer_sub.active_fb = 0; last_skip_frame = false; diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index 5d7264f12..69df94324 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp @@ -250,7 +250,7 @@ const char *ElfReader::GetSectionName(int section) const { return nullptr; int name_offset = sections[section].sh_name; - const char* ptr = (char*)GetSectionDataPtr(header->e_shstrndx); + const char* ptr = reinterpret_cast<const char*>(GetSectionDataPtr(header->e_shstrndx)); if (ptr) return ptr + name_offset; @@ -347,10 +347,10 @@ bool ElfReader::LoadSymbols() { SectionID sec = GetSectionByName(".symtab"); if (sec != -1) { int stringSection = sections[sec].sh_link; - const char *stringBase = (const char *)GetSectionDataPtr(stringSection); + const char *stringBase = reinterpret_cast<const char*>(GetSectionDataPtr(stringSection)); //We have a symbol table! - Elf32_Sym* symtab = (Elf32_Sym *)(GetSectionDataPtr(sec)); + const Elf32_Sym* symtab = reinterpret_cast<const Elf32_Sym*>(GetSectionDataPtr(sec)); unsigned int numSymbols = sections[sec].sh_size / sizeof(Elf32_Sym); for (unsigned sym = 0; sym < numSymbols; sym++) { int size = symtab[sym].st_size; diff --git a/src/core/memory.cpp b/src/core/memory.cpp index fc79c3ee9..4753c63a7 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -13,6 +13,7 @@ #include "core/hle/kernel/process.h" #include "core/memory.h" #include "core/memory_setup.h" +#include "core/mmio.h" namespace Memory { @@ -25,6 +26,12 @@ enum class PageType { Special, }; +struct SpecialRegion { + VAddr base; + u32 size; + MMIORegionPointer handler; +}; + /** * A (reasonably) fast way of allowing switchable and remappable process address spaces. It loosely * mimics the way a real CPU page table works, but instead is optimized for minimal decoding and @@ -41,8 +48,13 @@ struct PageTable { std::array<u8*, NUM_ENTRIES> pointers; /** + * Contains MMIO handlers that back memory regions whose entries in the `attribute` array is of type `Special`. + */ + std::vector<SpecialRegion> special_regions; + + /** * Array of fine grained page attributes. If it is set to any value other than `Memory`, then - * the corresponding entry in `pointer` MUST be set to null. + * the corresponding entry in `pointers` MUST be set to null. */ std::array<PageType, NUM_ENTRIES> attributes; }; @@ -80,10 +92,12 @@ void MapMemoryRegion(VAddr base, u32 size, u8* target) { MapPages(base / PAGE_SIZE, size / PAGE_SIZE, target, PageType::Memory); } -void MapIoRegion(VAddr base, u32 size) { +void MapIoRegion(VAddr base, u32 size, MMIORegionPointer mmio_handler) { ASSERT_MSG((size & PAGE_MASK) == 0, "non-page aligned size: %08X", size); ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: %08X", base); MapPages(base / PAGE_SIZE, size / PAGE_SIZE, nullptr, PageType::Special); + + current_page_table->special_regions.emplace_back(SpecialRegion{base, size, mmio_handler}); } void UnmapRegion(VAddr base, u32 size) { @@ -92,6 +106,22 @@ void UnmapRegion(VAddr base, u32 size) { MapPages(base / PAGE_SIZE, size / PAGE_SIZE, nullptr, PageType::Unmapped); } +/** + * This function should only be called for virtual addreses with attribute `PageType::Special`. + */ +static MMIORegionPointer GetMMIOHandler(VAddr vaddr) { + for (const auto& region : current_page_table->special_regions) { + if (vaddr >= region.base && vaddr < (region.base + region.size)) { + return region.handler; + } + } + ASSERT_MSG(false, "Mapped IO page without a handler @ %08X", vaddr); + return nullptr; // Should never happen +} + +template<typename T> +T ReadMMIO(MMIORegionPointer mmio_handler, VAddr addr); + template <typename T> T Read(const VAddr vaddr) { const u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; @@ -108,14 +138,17 @@ T Read(const VAddr vaddr) { return 0; case PageType::Memory: ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr); + break; case PageType::Special: - LOG_ERROR(HW_Memory, "I/O reads aren't implemented yet @ %08X", vaddr); - return 0; + return ReadMMIO<T>(GetMMIOHandler(vaddr), vaddr); default: UNREACHABLE(); } } +template<typename T> +void WriteMMIO(MMIORegionPointer mmio_handler, VAddr addr, const T data); + template <typename T> void Write(const VAddr vaddr, const T data) { u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; @@ -131,9 +164,10 @@ void Write(const VAddr vaddr, const T data) { return; case PageType::Memory: ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr); + break; case PageType::Special: - LOG_ERROR(HW_Memory, "I/O writes aren't implemented yet @ %08X", vaddr); - return; + WriteMMIO<T>(GetMMIOHandler(vaddr), vaddr, data); + break; default: UNREACHABLE(); } @@ -191,6 +225,46 @@ void WriteBlock(const VAddr addr, const u8* data, const size_t size) { } } +template<> +u8 ReadMMIO<u8>(MMIORegionPointer mmio_handler, VAddr addr) { + return mmio_handler->Read8(addr); +} + +template<> +u16 ReadMMIO<u16>(MMIORegionPointer mmio_handler, VAddr addr) { + return mmio_handler->Read16(addr); +} + +template<> +u32 ReadMMIO<u32>(MMIORegionPointer mmio_handler, VAddr addr) { + return mmio_handler->Read32(addr); +} + +template<> +u64 ReadMMIO<u64>(MMIORegionPointer mmio_handler, VAddr addr) { + return mmio_handler->Read64(addr); +} + +template<> +void WriteMMIO<u8>(MMIORegionPointer mmio_handler, VAddr addr, const u8 data) { + mmio_handler->Write8(addr, data); +} + +template<> +void WriteMMIO<u16>(MMIORegionPointer mmio_handler, VAddr addr, const u16 data) { + mmio_handler->Write16(addr, data); +} + +template<> +void WriteMMIO<u32>(MMIORegionPointer mmio_handler, VAddr addr, const u32 data) { + mmio_handler->Write32(addr, data); +} + +template<> +void WriteMMIO<u64>(MMIORegionPointer mmio_handler, VAddr addr, const u64 data) { + mmio_handler->Write64(addr, data); +} + PAddr VirtualToPhysicalAddress(const VAddr addr) { if (addr == 0) { return 0; diff --git a/src/core/memory_setup.h b/src/core/memory_setup.h index 84ff30120..05f70a1fe 100644 --- a/src/core/memory_setup.h +++ b/src/core/memory_setup.h @@ -23,10 +23,11 @@ void MapMemoryRegion(VAddr base, u32 size, u8* target); /** * Maps a region of the emulated process address space as a IO region. - * @note Currently this can only be used to mark a region as being IO, since actual memory-mapped - * IO isn't yet supported. + * @param base The address to start mapping at. Must be page-aligned. + * @param size The amount of bytes to map. Must be page-aligned. + * @param mmio_handler The handler that backs the mapping. */ -void MapIoRegion(VAddr base, u32 size); +void MapIoRegion(VAddr base, u32 size, MMIORegionPointer mmio_handler); void UnmapRegion(VAddr base, u32 size); diff --git a/src/core/mmio.h b/src/core/mmio.h new file mode 100644 index 000000000..06b555e98 --- /dev/null +++ b/src/core/mmio.h @@ -0,0 +1,34 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <memory> + +#include "common/common_types.h" + +namespace Memory { + +/** + * Represents a device with memory mapped IO. + * A device may be mapped to multiple regions of memory. + */ +class MMIORegion { +public: + virtual ~MMIORegion() = default; + + virtual u8 Read8(VAddr addr) = 0; + virtual u16 Read16(VAddr addr) = 0; + virtual u32 Read32(VAddr addr) = 0; + virtual u64 Read64(VAddr addr) = 0; + + virtual void Write8(VAddr addr, u8 data) = 0; + virtual void Write16(VAddr addr, u16 data) = 0; + virtual void Write32(VAddr addr, u32 data) = 0; + virtual void Write64(VAddr addr, u64 data) = 0; +}; + +using MMIORegionPointer = std::shared_ptr<MMIORegion>; + +}; diff --git a/src/core/system.cpp b/src/core/system.cpp index 7e9c56538..b62ebf69e 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -2,9 +2,12 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "audio_core/audio_core.h" + #include "core/core.h" #include "core/core_timing.h" #include "core/system.h" +#include "core/gdbstub/gdbstub.h" #include "core/hw/hw.h" #include "core/hle/hle.h" #include "core/hle/kernel/kernel.h" @@ -12,8 +15,6 @@ #include "video_core/video_core.h" -#include "core/gdbstub/gdbstub.h" - namespace System { void Init(EmuWindow* emu_window) { @@ -24,11 +25,13 @@ void Init(EmuWindow* emu_window) { Kernel::Init(); HLE::Init(); VideoCore::Init(emu_window); + AudioCore::Init(); GDBStub::Init(); } void Shutdown() { GDBStub::Shutdown(); + AudioCore::Shutdown(); VideoCore::Shutdown(); HLE::Shutdown(); Kernel::Shutdown(); |