summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/logging/backend.cpp2
-rw-r--r--src/common/logging/log.h2
-rw-r--r--src/common/threadsafe_queue.h32
-rw-r--r--src/core/CMakeLists.txt10
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic.cpp16
-rw-r--r--src/core/hle/service/am/am.cpp6
-rw-r--r--src/core/hle/service/am/idle.cpp24
-rw-r--r--src/core/hle/service/am/idle.h16
-rw-r--r--src/core/hle/service/am/omm.cpp42
-rw-r--r--src/core/hle/service/am/omm.h16
-rw-r--r--src/core/hle/service/am/spsm.cpp30
-rw-r--r--src/core/hle/service/am/spsm.h16
-rw-r--r--src/core/hle/service/audio/audout_u.cpp2
-rw-r--r--src/core/hle/service/fgm/fgm.cpp75
-rw-r--r--src/core/hle/service/fgm/fgm.h15
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp14
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp9
-rw-r--r--src/core/hle/service/pcie/pcie.cpp64
-rw-r--r--src/core/hle/service/pcie/pcie.h15
-rw-r--r--src/core/hle/service/service.cpp4
-rw-r--r--src/video_core/macro_interpreter.cpp4
-rw-r--r--src/video_core/macro_interpreter.h4
22 files changed, 398 insertions, 20 deletions
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index 55de535c0..d86c40d26 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -171,6 +171,7 @@ void FileBackend::Write(const Entry& entry) {
SUB(Service, BCAT) \
SUB(Service, BTM) \
SUB(Service, Fatal) \
+ SUB(Service, FGM) \
SUB(Service, Friend) \
SUB(Service, FS) \
SUB(Service, HID) \
@@ -185,6 +186,7 @@ void FileBackend::Write(const Entry& entry) {
SUB(Service, NIFM) \
SUB(Service, NS) \
SUB(Service, NVDRV) \
+ SUB(Service, PCIE) \
SUB(Service, PCTL) \
SUB(Service, PREPO) \
SUB(Service, SET) \
diff --git a/src/common/logging/log.h b/src/common/logging/log.h
index e8d98de99..140cd8e47 100644
--- a/src/common/logging/log.h
+++ b/src/common/logging/log.h
@@ -58,6 +58,7 @@ enum class Class : ClassType {
Service_BCAT, ///< The BCAT service
Service_BTM, ///< The BTM service
Service_Fatal, ///< The Fatal service
+ Service_FGM, ///< The FGM service
Service_Friend, ///< The friend service
Service_FS, ///< The FS (Filesystem) service
Service_HID, ///< The HID (Human interface device) service
@@ -72,6 +73,7 @@ enum class Class : ClassType {
Service_NIFM, ///< The NIFM (Network interface) service
Service_NS, ///< The NS services
Service_NVDRV, ///< The NVDRV (Nvidia driver) service
+ Service_PCIE, ///< The PCIe service
Service_PCTL, ///< The PCTL (Parental control) service
Service_PREPO, ///< The PREPO (Play report) service
Service_SET, ///< The SET (Settings) service
diff --git a/src/common/threadsafe_queue.h b/src/common/threadsafe_queue.h
index a0c731e8c..edf13bc49 100644
--- a/src/common/threadsafe_queue.h
+++ b/src/common/threadsafe_queue.h
@@ -33,9 +33,11 @@ public:
bool Empty() const {
return !read_ptr->next.load();
}
+
T& Front() const {
return read_ptr->current;
}
+
template <typename Arg>
void Push(Arg&& t) {
// create the element, add it to the queue
@@ -108,15 +110,41 @@ private:
// single reader, multiple writer queue
template <typename T, bool NeedSize = true>
-class MPSCQueue : public SPSCQueue<T, NeedSize> {
+class MPSCQueue {
public:
+ u32 Size() const {
+ return spsc_queue.Size();
+ }
+
+ bool Empty() const {
+ return spsc_queue.Empty();
+ }
+
+ T& Front() const {
+ return spsc_queue.Front();
+ }
+
template <typename Arg>
void Push(Arg&& t) {
std::lock_guard<std::mutex> lock(write_lock);
- SPSCQueue<T, NeedSize>::Push(t);
+ spsc_queue.Push(t);
+ }
+
+ void Pop() {
+ return spsc_queue.Pop();
+ }
+
+ bool Pop(T& t) {
+ return spsc_queue.Pop(t);
+ }
+
+ // not thread-safe
+ void Clear() {
+ spsc_queue.Clear();
}
private:
+ SPSCQueue<T, NeedSize> spsc_queue;
std::mutex write_lock;
};
} // namespace Common
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 3386c2231..3e13fc25b 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -114,6 +114,12 @@ add_library(core STATIC
hle/service/am/applet_ae.h
hle/service/am/applet_oe.cpp
hle/service/am/applet_oe.h
+ hle/service/am/idle.cpp
+ hle/service/am/idle.h
+ hle/service/am/omm.cpp
+ hle/service/am/omm.h
+ hle/service/am/spsm.cpp
+ hle/service/am/spsm.h
hle/service/aoc/aoc_u.cpp
hle/service/aoc/aoc_u.h
hle/service/apm/apm.cpp
@@ -160,6 +166,8 @@ add_library(core STATIC
hle/service/filesystem/filesystem.h
hle/service/filesystem/fsp_srv.cpp
hle/service/filesystem/fsp_srv.h
+ hle/service/fgm/fgm.cpp
+ hle/service/fgm/fgm.h
hle/service/friend/friend.cpp
hle/service/friend/friend.h
hle/service/friend/interface.cpp
@@ -225,6 +233,8 @@ add_library(core STATIC
hle/service/nvflinger/buffer_queue.h
hle/service/nvflinger/nvflinger.cpp
hle/service/nvflinger/nvflinger.h
+ hle/service/pcie/pcie.cpp
+ hle/service/pcie/pcie.h
hle/service/pctl/module.cpp
hle/service/pctl/module.h
hle/service/pctl/pctl.cpp
diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp
index da7acbb46..ceb3f7683 100644
--- a/src/core/arm/dynarmic/arm_dynarmic.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic.cpp
@@ -139,14 +139,12 @@ void ARM_Dynarmic::Step() {
}
ARM_Dynarmic::ARM_Dynarmic(std::shared_ptr<ExclusiveMonitor> exclusive_monitor, size_t core_index)
- : cb(std::make_unique<ARM_Dynarmic_Callbacks>(*this)),
- jit(MakeJit()), exclusive_monitor{std::dynamic_pointer_cast<DynarmicExclusiveMonitor>(
- exclusive_monitor)},
- core_index{core_index} {
- ARM_Interface::ThreadContext ctx;
+ : cb(std::make_unique<ARM_Dynarmic_Callbacks>(*this)), core_index{core_index},
+ exclusive_monitor{std::dynamic_pointer_cast<DynarmicExclusiveMonitor>(exclusive_monitor)} {
+ ThreadContext ctx;
inner_unicorn.SaveContext(ctx);
- LoadContext(ctx);
PageTableChanged();
+ LoadContext(ctx);
}
ARM_Dynarmic::~ARM_Dynarmic() = default;
@@ -205,7 +203,7 @@ u64 ARM_Dynarmic::GetTlsAddress() const {
return cb->tpidrro_el0;
}
-void ARM_Dynarmic::SetTlsAddress(u64 address) {
+void ARM_Dynarmic::SetTlsAddress(VAddr address) {
cb->tpidrro_el0 = address;
}
@@ -217,7 +215,7 @@ void ARM_Dynarmic::SetTPIDR_EL0(u64 value) {
cb->tpidr_el0 = value;
}
-void ARM_Dynarmic::SaveContext(ARM_Interface::ThreadContext& ctx) {
+void ARM_Dynarmic::SaveContext(ThreadContext& ctx) {
ctx.cpu_registers = jit->GetRegisters();
ctx.sp = jit->GetSP();
ctx.pc = jit->GetPC();
@@ -226,7 +224,7 @@ void ARM_Dynarmic::SaveContext(ARM_Interface::ThreadContext& ctx) {
ctx.fpscr = jit->GetFpcr();
}
-void ARM_Dynarmic::LoadContext(const ARM_Interface::ThreadContext& ctx) {
+void ARM_Dynarmic::LoadContext(const ThreadContext& ctx) {
jit->SetRegisters(ctx.cpu_registers);
jit->SetSP(ctx.sp);
jit->SetPC(ctx.pc);
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 97ef07bf9..94d2a973d 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -11,6 +11,9 @@
#include "core/hle/service/am/am.h"
#include "core/hle/service/am/applet_ae.h"
#include "core/hle/service/am/applet_oe.h"
+#include "core/hle/service/am/idle.h"
+#include "core/hle/service/am/omm.h"
+#include "core/hle/service/am/spsm.h"
#include "core/hle/service/apm/apm.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/nvflinger/nvflinger.h"
@@ -689,6 +692,9 @@ void InstallInterfaces(SM::ServiceManager& service_manager,
std::shared_ptr<NVFlinger::NVFlinger> nvflinger) {
std::make_shared<AppletAE>(nvflinger)->InstallAsService(service_manager);
std::make_shared<AppletOE>(nvflinger)->InstallAsService(service_manager);
+ std::make_shared<IdleSys>()->InstallAsService(service_manager);
+ std::make_shared<OMM>()->InstallAsService(service_manager);
+ std::make_shared<SPSM>()->InstallAsService(service_manager);
}
IHomeMenuFunctions::IHomeMenuFunctions() : ServiceFramework("IHomeMenuFunctions") {
diff --git a/src/core/hle/service/am/idle.cpp b/src/core/hle/service/am/idle.cpp
new file mode 100644
index 000000000..af46e9494
--- /dev/null
+++ b/src/core/hle/service/am/idle.cpp
@@ -0,0 +1,24 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/hle/service/am/idle.h"
+
+namespace Service::AM {
+
+IdleSys::IdleSys() : ServiceFramework{"idle:sys"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "GetAutoPowerDownEvent"},
+ {1, nullptr, "Unknown1"},
+ {2, nullptr, "Unknown2"},
+ {3, nullptr, "Unknown3"},
+ {4, nullptr, "Unknown4"},
+ {5, nullptr, "Unknown5"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+}
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/idle.h b/src/core/hle/service/am/idle.h
new file mode 100644
index 000000000..1eb68d2c9
--- /dev/null
+++ b/src/core/hle/service/am/idle.h
@@ -0,0 +1,16 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+namespace Service::AM {
+
+class IdleSys final : public ServiceFramework<IdleSys> {
+public:
+ explicit IdleSys();
+};
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/omm.cpp b/src/core/hle/service/am/omm.cpp
new file mode 100644
index 000000000..447fe8669
--- /dev/null
+++ b/src/core/hle/service/am/omm.cpp
@@ -0,0 +1,42 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/hle/service/am/omm.h"
+
+namespace Service::AM {
+
+OMM::OMM() : ServiceFramework{"omm"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "GetOperationMode"},
+ {1, nullptr, "GetOperationModeChangeEvent"},
+ {2, nullptr, "EnableAudioVisual"},
+ {3, nullptr, "DisableAudioVisual"},
+ {4, nullptr, "EnterSleepAndWait"},
+ {5, nullptr, "GetCradleStatus"},
+ {6, nullptr, "FadeInDisplay"},
+ {7, nullptr, "FadeOutDisplay"},
+ {8, nullptr, "Unknown1"},
+ {9, nullptr, "Unknown2"},
+ {10, nullptr, "Unknown3"},
+ {11, nullptr, "Unknown4"},
+ {12, nullptr, "Unknown5"},
+ {13, nullptr, "Unknown6"},
+ {14, nullptr, "Unknown7"},
+ {15, nullptr, "Unknown8"},
+ {16, nullptr, "Unknown9"},
+ {17, nullptr, "Unknown10"},
+ {18, nullptr, "Unknown11"},
+ {19, nullptr, "Unknown12"},
+ {20, nullptr, "Unknown13"},
+ {21, nullptr, "Unknown14"},
+ {22, nullptr, "Unknown15"},
+ {23, nullptr, "Unknown16"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+}
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/omm.h b/src/core/hle/service/am/omm.h
new file mode 100644
index 000000000..49e5d331c
--- /dev/null
+++ b/src/core/hle/service/am/omm.h
@@ -0,0 +1,16 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+namespace Service::AM {
+
+class OMM final : public ServiceFramework<OMM> {
+public:
+ explicit OMM();
+};
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/spsm.cpp b/src/core/hle/service/am/spsm.cpp
new file mode 100644
index 000000000..a05d433d0
--- /dev/null
+++ b/src/core/hle/service/am/spsm.cpp
@@ -0,0 +1,30 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/hle/service/am/spsm.h"
+
+namespace Service::AM {
+
+SPSM::SPSM() : ServiceFramework{"spsm"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "GetState"},
+ {1, nullptr, "SleepSystemAndWaitAwake"},
+ {2, nullptr, "Unknown1"},
+ {3, nullptr, "Unknown2"},
+ {4, nullptr, "GetNotificationMessageEventHandle"},
+ {5, nullptr, "Unknown3"},
+ {6, nullptr, "Unknown4"},
+ {7, nullptr, "Unknown5"},
+ {8, nullptr, "AnalyzePerformanceLogForLastSleepWakeSequence"},
+ {9, nullptr, "ChangeHomeButtonLongPressingTime"},
+ {10, nullptr, "Unknown6"},
+ {11, nullptr, "Unknown7"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+}
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/spsm.h b/src/core/hle/service/am/spsm.h
new file mode 100644
index 000000000..57dde62e1
--- /dev/null
+++ b/src/core/hle/service/am/spsm.h
@@ -0,0 +1,16 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+namespace Service::AM {
+
+class SPSM final : public ServiceFramework<SPSM> {
+public:
+ explicit SPSM();
+};
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp
index ab37c2a69..b317027b6 100644
--- a/src/core/hle/service/audio/audout_u.cpp
+++ b/src/core/hle/service/audio/audout_u.cpp
@@ -194,7 +194,7 @@ void AudOutU::OpenAudioOutImpl(Kernel::HLERequestContext& ctx) {
// TODO(bunnei): Support more than one IAudioOut interface. When we add this, ListAudioOutsImpl
// will likely need to be updated as well.
ASSERT_MSG(!audio_out_interface, "Unimplemented");
- audio_out_interface = std::make_shared<IAudioOut>(std::move(params), *audio_core);
+ audio_out_interface = std::make_shared<IAudioOut>(params, *audio_core);
IPC::ResponseBuilder rb{ctx, 6, 0, 1};
rb.Push(RESULT_SUCCESS);
diff --git a/src/core/hle/service/fgm/fgm.cpp b/src/core/hle/service/fgm/fgm.cpp
new file mode 100644
index 000000000..566fbf924
--- /dev/null
+++ b/src/core/hle/service/fgm/fgm.cpp
@@ -0,0 +1,75 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <memory>
+
+#include "core/hle/ipc_helpers.h"
+#include "core/hle/kernel/hle_ipc.h"
+#include "core/hle/service/fgm/fgm.h"
+#include "core/hle/service/service.h"
+#include "core/hle/service/sm/sm.h"
+
+namespace Service::FGM {
+
+class IRequest final : public ServiceFramework<IRequest> {
+public:
+ explicit IRequest() : ServiceFramework{"IRequest"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Initialize"},
+ {1, nullptr, "Set"},
+ {2, nullptr, "Get"},
+ {3, nullptr, "Cancel"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class FGM final : public ServiceFramework<FGM> {
+public:
+ explicit FGM(const char* name) : ServiceFramework{name} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, &FGM::Initialize, "Initialize"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+
+private:
+ void Initialize(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<IRequest>();
+
+ LOG_DEBUG(Service_FGM, "called");
+ }
+};
+
+class FGM_DBG final : public ServiceFramework<FGM_DBG> {
+public:
+ explicit FGM_DBG() : ServiceFramework{"fgm:dbg"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Initialize"},
+ {1, nullptr, "Read"},
+ {2, nullptr, "Cancel"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+void InstallInterfaces(SM::ServiceManager& sm) {
+ std::make_shared<FGM>("fgm")->InstallAsService(sm);
+ std::make_shared<FGM>("fgm:0")->InstallAsService(sm);
+ std::make_shared<FGM>("fgm:9")->InstallAsService(sm);
+ std::make_shared<FGM_DBG>()->InstallAsService(sm);
+}
+
+} // namespace Service::FGM
diff --git a/src/core/hle/service/fgm/fgm.h b/src/core/hle/service/fgm/fgm.h
new file mode 100644
index 000000000..e59691264
--- /dev/null
+++ b/src/core/hle/service/fgm/fgm.h
@@ -0,0 +1,15 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+namespace Service::SM {
+class ServiceManager;
+}
+
+namespace Service::FGM {
+
+void InstallInterfaces(SM::ServiceManager& sm);
+
+} // namespace Service::FGM
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
index 44e062f50..010072a5b 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
@@ -97,7 +97,9 @@ u32 nvhost_ctrl_gpu::GetTPCMasks(const std::vector<u8>& input, std::vector<u8>&
u32 nvhost_ctrl_gpu::GetActiveSlotMask(const std::vector<u8>& input, std::vector<u8>& output) {
LOG_DEBUG(Service_NVDRV, "called");
IoctlActiveSlotMask params{};
- std::memcpy(&params, input.data(), input.size());
+ if (input.size() > 0) {
+ std::memcpy(&params, input.data(), input.size());
+ }
params.slot = 0x07;
params.mask = 0x01;
std::memcpy(output.data(), &params, output.size());
@@ -107,7 +109,9 @@ u32 nvhost_ctrl_gpu::GetActiveSlotMask(const std::vector<u8>& input, std::vector
u32 nvhost_ctrl_gpu::ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u8>& output) {
LOG_DEBUG(Service_NVDRV, "called");
IoctlZcullGetCtxSize params{};
- std::memcpy(&params, input.data(), input.size());
+ if (input.size() > 0) {
+ std::memcpy(&params, input.data(), input.size());
+ }
params.size = 0x1;
std::memcpy(output.data(), &params, output.size());
return 0;
@@ -116,7 +120,11 @@ u32 nvhost_ctrl_gpu::ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u
u32 nvhost_ctrl_gpu::ZCullGetInfo(const std::vector<u8>& input, std::vector<u8>& output) {
LOG_DEBUG(Service_NVDRV, "called");
IoctlNvgpuGpuZcullGetInfoArgs params{};
- std::memcpy(&params, input.data(), input.size());
+
+ if (input.size() > 0) {
+ std::memcpy(&params, input.data(), input.size());
+ }
+
params.width_align_pixels = 0x20;
params.height_align_pixels = 0x20;
params.pixel_squares_by_aliquots = 0x400;
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
index 126782573..5a1123ad2 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
@@ -132,9 +132,12 @@ u32 nvhost_gpu::SubmitGPFIFO(const std::vector<u8>& input, std::vector<u8>& outp
LOG_WARNING(Service_NVDRV, "(STUBBED) called, gpfifo={:X}, num_entries={:X}, flags={:X}",
params.address, params.num_entries, params.flags);
- auto entries = std::vector<IoctlGpfifoEntry>();
- entries.resize(params.num_entries);
- std::memcpy(&entries[0], &input.data()[sizeof(IoctlSubmitGpfifo)],
+ ASSERT_MSG(input.size() ==
+ sizeof(IoctlSubmitGpfifo) + params.num_entries * sizeof(IoctlGpfifoEntry),
+ "Incorrect input size");
+
+ std::vector<IoctlGpfifoEntry> entries(params.num_entries);
+ std::memcpy(entries.data(), &input[sizeof(IoctlSubmitGpfifo)],
params.num_entries * sizeof(IoctlGpfifoEntry));
for (auto entry : entries) {
Tegra::GPUVAddr va_addr = entry.Address();
diff --git a/src/core/hle/service/pcie/pcie.cpp b/src/core/hle/service/pcie/pcie.cpp
new file mode 100644
index 000000000..39cf05eba
--- /dev/null
+++ b/src/core/hle/service/pcie/pcie.cpp
@@ -0,0 +1,64 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <memory>
+
+#include "core/hle/service/pcie/pcie.h"
+#include "core/hle/service/service.h"
+#include "core/hle/service/sm/sm.h"
+
+namespace Service::PCIe {
+
+class ISession final : public ServiceFramework<ISession> {
+public:
+ explicit ISession() : ServiceFramework{"ISession"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "QueryFunctions"},
+ {1, nullptr, "AcquireFunction"},
+ {2, nullptr, "ReleaseFunction"},
+ {3, nullptr, "GetFunctionState"},
+ {4, nullptr, "GetBarProfile"},
+ {5, nullptr, "ReadConfig"},
+ {6, nullptr, "WriteConfig"},
+ {7, nullptr, "ReadBarRegion"},
+ {8, nullptr, "WriteBarRegion"},
+ {9, nullptr, "FindCapability"},
+ {10, nullptr, "FindExtendedCapability"},
+ {11, nullptr, "MapDma"},
+ {12, nullptr, "UnmapDma"},
+ {13, nullptr, "UnmapDmaBusAddress"},
+ {14, nullptr, "GetDmaBusAddress"},
+ {15, nullptr, "GetDmaBusAddressRange"},
+ {16, nullptr, "SetDmaEnable"},
+ {17, nullptr, "AcquireIrq"},
+ {18, nullptr, "ReleaseIrq"},
+ {19, nullptr, "SetIrqEnable"},
+ {20, nullptr, "SetAspmEnable"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class PCIe final : public ServiceFramework<PCIe> {
+public:
+ explicit PCIe() : ServiceFramework{"pcie"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "RegisterClassDriver"},
+ {1, nullptr, "QueryFunctionsUnregistered"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+void InstallInterfaces(SM::ServiceManager& sm) {
+ std::make_shared<PCIe>()->InstallAsService(sm);
+}
+
+} // namespace Service::PCIe
diff --git a/src/core/hle/service/pcie/pcie.h b/src/core/hle/service/pcie/pcie.h
new file mode 100644
index 000000000..59c22ca45
--- /dev/null
+++ b/src/core/hle/service/pcie/pcie.h
@@ -0,0 +1,15 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+namespace Service::SM {
+class ServiceManager;
+}
+
+namespace Service::PCIe {
+
+void InstallInterfaces(SM::ServiceManager& sm);
+
+} // namespace Service::PCIe
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 3cad64837..fccc4c461 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -27,6 +27,7 @@
#include "core/hle/service/es/es.h"
#include "core/hle/service/eupld/eupld.h"
#include "core/hle/service/fatal/fatal.h"
+#include "core/hle/service/fgm/fgm.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/friend/friend.h"
#include "core/hle/service/grc/grc.h"
@@ -44,6 +45,7 @@
#include "core/hle/service/nim/nim.h"
#include "core/hle/service/ns/ns.h"
#include "core/hle/service/nvdrv/nvdrv.h"
+#include "core/hle/service/pcie/pcie.h"
#include "core/hle/service/pctl/pctl.h"
#include "core/hle/service/pm/pm.h"
#include "core/hle/service/prepo/prepo.h"
@@ -208,6 +210,7 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm) {
ES::InstallInterfaces(*sm);
EUPLD::InstallInterfaces(*sm);
Fatal::InstallInterfaces(*sm);
+ FGM::InstallInterfaces(*sm);
FileSystem::InstallInterfaces(*sm);
Friend::InstallInterfaces(*sm);
GRC::InstallInterfaces(*sm);
@@ -225,6 +228,7 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm) {
NIM::InstallInterfaces(*sm);
NS::InstallInterfaces(*sm);
Nvidia::InstallInterfaces(*sm);
+ PCIe::InstallInterfaces(*sm);
PCTL::InstallInterfaces(*sm);
PlayReport::InstallInterfaces(*sm);
PM::InstallInterfaces(*sm);
diff --git a/src/video_core/macro_interpreter.cpp b/src/video_core/macro_interpreter.cpp
index 44ece01c1..377bd66ab 100644
--- a/src/video_core/macro_interpreter.cpp
+++ b/src/video_core/macro_interpreter.cpp
@@ -102,11 +102,11 @@ bool MacroInterpreter::Step(const std::vector<u32>& code, bool is_delay_slot) {
if (taken) {
// Ignore the delay slot if the branch has the annul bit.
if (opcode.branch_annul) {
- pc = base_address + (opcode.immediate << 2);
+ pc = base_address + opcode.GetBranchTarget();
return true;
}
- delayed_pc = base_address + (opcode.immediate << 2);
+ delayed_pc = base_address + opcode.GetBranchTarget();
// Execute one more instruction due to the delay slot.
return Step(code, true);
}
diff --git a/src/video_core/macro_interpreter.h b/src/video_core/macro_interpreter.h
index a71e359d8..7d836b816 100644
--- a/src/video_core/macro_interpreter.h
+++ b/src/video_core/macro_interpreter.h
@@ -91,6 +91,10 @@ private:
u32 GetBitfieldMask() const {
return (1 << bf_size) - 1;
}
+
+ s32 GetBranchTarget() const {
+ return static_cast<s32>(immediate * sizeof(u32));
+ }
};
union MethodAddress {