aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/hle/service/apt/apt.cpp
diff options
context:
space:
mode:
authorGravatar Subv <subv2112@gmail.com>2015-05-25 23:30:20 -0500
committerGravatar Subv <subv2112@gmail.com>2015-07-11 21:47:22 -0500
commit2a6ebadf66051362cdcf07d722f7e2d3cee14c82 (patch)
treef016b2ee81df95aabccc426762c42073d645803c /src/core/hle/service/apt/apt.cpp
parentb0d72e3de1ec2350716300c86bc02930893e9e23 (diff)
HLE/APT: Initial HLE support for applets.
Currently only the SWKBD is emulated, and there's currently no way to ask the user for input, so it always returns "Subv" as the text.
Diffstat (limited to 'src/core/hle/service/apt/apt.cpp')
-rw-r--r--src/core/hle/service/apt/apt.cpp139
1 files changed, 105 insertions, 34 deletions
diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp
index b454a270..0c3889e8 100644
--- a/src/core/hle/service/apt/apt.cpp
+++ b/src/core/hle/service/apt/apt.cpp
@@ -6,6 +6,7 @@
#include "common/file_util.h"
#include "common/logging/log.h"
+#include "core/hle/applets/applet.h"
#include "core/hle/service/service.h"
#include "core/hle/service/apt/apt.h"
#include "core/hle/service/apt/apt_a.h"
@@ -34,12 +35,21 @@ static Kernel::SharedPtr<Kernel::SharedMemory> shared_font_mem;
static Kernel::SharedPtr<Kernel::Mutex> lock;
static Kernel::SharedPtr<Kernel::Event> notification_event; ///< APT notification event
-static Kernel::SharedPtr<Kernel::Event> start_event; ///< APT start event
+static Kernel::SharedPtr<Kernel::Event> parameter_event; ///< APT parameter event
static std::vector<u8> shared_font;
static u32 cpu_percent; ///< CPU time available to the running application
+/// Parameter data to be returned in the next call to Glance/ReceiveParameter
+static MessageParameter next_parameter;
+
+void SendParameter(MessageParameter const& parameter) {
+ next_parameter = parameter;
+ // Signal the event to let the application know that a new parameter is ready to be read
+ parameter_event->Signal();
+}
+
void Initialize(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
u32 app_id = cmd_buff[1];
@@ -47,18 +57,18 @@ void Initialize(Service::Interface* self) {
cmd_buff[2] = IPC::MoveHandleDesc(2);
cmd_buff[3] = Kernel::g_handle_table.Create(notification_event).MoveFrom();
- cmd_buff[4] = Kernel::g_handle_table.Create(start_event).MoveFrom();
+ cmd_buff[4] = Kernel::g_handle_table.Create(parameter_event).MoveFrom();
// TODO(bunnei): Check if these events are cleared every time Initialize is called.
notification_event->Clear();
- start_event->Clear();
+ parameter_event->Clear();
ASSERT_MSG((nullptr != lock), "Cannot initialize without lock");
lock->Release();
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
- LOG_TRACE(Service_APT, "called app_id=0x%08X, flags=0x%08X", app_id, flags);
+ LOG_WARNING(Service_APT, "called app_id=0x%08X, flags=0x%08X", app_id, flags);
}
void GetSharedFont(Service::Interface* self) {
@@ -85,9 +95,7 @@ void GetSharedFont(Service::Interface* self) {
void NotifyToWait(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
u32 app_id = cmd_buff[1];
- // TODO(Subv): Verify this, it seems to get SWKBD and Home Menu further.
- start_event->Signal();
-
+
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
LOG_WARNING(Service_APT, "(STUBBED) app_id=%u", app_id);
}
@@ -112,6 +120,7 @@ void Enable(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
u32 unk = cmd_buff[1]; // TODO(bunnei): What is this field used for?
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ parameter_event->Signal(); // Let the application know that it has been started
LOG_WARNING(Service_APT, "(STUBBED) called unk=0x%08X", unk);
}
@@ -121,8 +130,8 @@ void GetAppletManInfo(Service::Interface* self) {
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
cmd_buff[2] = 0;
cmd_buff[3] = 0;
- cmd_buff[4] = static_cast<u32>(AppID::HomeMenu); // Home menu AppID
- cmd_buff[5] = static_cast<u32>(AppID::Application); // TODO(purpasmart96): Do this correctly
+ cmd_buff[4] = static_cast<u32>(AppletId::HomeMenu); // Home menu AppID
+ cmd_buff[5] = static_cast<u32>(AppletId::Application); // TODO(purpasmart96): Do this correctly
LOG_WARNING(Service_APT, "(STUBBED) called unk=0x%08X", unk);
}
@@ -131,7 +140,13 @@ void IsRegistered(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
u32 app_id = cmd_buff[1];
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
- cmd_buff[2] = 1; // Set to registered
+ /// TODO(Subv): It is currently unknown what this value (0x400) means,
+ /// but i believe it is used as a global "LibraryApplet" id, to verify if there's
+ /// any LibApplet currently running. This is not verified.
+ if (app_id != 0x400)
+ cmd_buff[2] = 1; // Set to registered
+ else
+ cmd_buff[2] = 0; // Set to not registered
LOG_WARNING(Service_APT, "(STUBBED) called app_id=0x%08X", app_id);
}
@@ -145,50 +160,81 @@ void InquireNotification(Service::Interface* self) {
void SendParameter(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
- u32 src_app_id = cmd_buff[1];
- u32 dst_app_id = cmd_buff[2];
- u32 signal_type = cmd_buff[3];
- u32 buffer_size = cmd_buff[4];
- u32 value = cmd_buff[5];
- u32 handle = cmd_buff[6];
- u32 size = cmd_buff[7];
- u32 in_param_buffer_ptr = cmd_buff[8];
+ u32 src_app_id = cmd_buff[1];
+ u32 dst_app_id = cmd_buff[2];
+ u32 signal_type = cmd_buff[3];
+ u32 buffer_size = cmd_buff[4];
+ u32 value = cmd_buff[5];
+ u32 handle = cmd_buff[6];
+ u32 size = cmd_buff[7];
+ u32 buffer = cmd_buff[8];
+
+ std::shared_ptr<HLE::Applets::Applet> dest_applet = HLE::Applets::Applet::Get(static_cast<AppletId>(dst_app_id));
+
+ if (dest_applet == nullptr) {
+ LOG_ERROR(Service_APT, "Unknown applet id=0x%08X", dst_app_id);
+ return;
+ }
- cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ MessageParameter param;
+ param.buffer_size = buffer_size;
+ param.destination_id = dst_app_id;
+ param.sender_id = src_app_id;
+ param.object = Kernel::g_handle_table.GetGeneric(handle);
+ param.signal = signal_type;
+ param.data = Memory::GetPointer(buffer);
+
+ cmd_buff[1] = dest_applet->ReceiveParameter(param).raw;
LOG_WARNING(Service_APT, "(STUBBED) called src_app_id=0x%08X, dst_app_id=0x%08X, signal_type=0x%08X,"
"buffer_size=0x%08X, value=0x%08X, handle=0x%08X, size=0x%08X, in_param_buffer_ptr=0x%08X",
- src_app_id, dst_app_id, signal_type, buffer_size, value, handle, size, in_param_buffer_ptr);
+ src_app_id, dst_app_id, signal_type, buffer_size, value, handle, size, buffer);
}
void ReceiveParameter(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
u32 app_id = cmd_buff[1];
u32 buffer_size = cmd_buff[2];
+ VAddr buffer = cmd_buff[0x104 >> 2];
+
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
- cmd_buff[2] = 0;
- cmd_buff[3] = static_cast<u32>(SignalType::AppJustStarted); // Signal type
- cmd_buff[4] = 0x10; // Parameter buffer size (16)
- cmd_buff[5] = 0;
+ cmd_buff[2] = next_parameter.sender_id;
+ cmd_buff[3] = next_parameter.signal; // Signal type
+ cmd_buff[4] = next_parameter.buffer_size; // Parameter buffer size
+ cmd_buff[5] = 0x10;
cmd_buff[6] = 0;
- cmd_buff[7] = 0;
- LOG_WARNING(Service_APT, "(STUBBED) called app_id=0x%08X, buffer_size=0x%08X", app_id, buffer_size);
+ if (next_parameter.object != nullptr)
+ cmd_buff[6] = Kernel::g_handle_table.Create(next_parameter.object).MoveFrom();
+ cmd_buff[7] = (next_parameter.buffer_size << 14) | 2;
+ cmd_buff[8] = buffer;
+
+ if (next_parameter.data)
+ memcpy(Memory::GetPointer(buffer), next_parameter.data, std::min(buffer_size, next_parameter.buffer_size));
+
+ LOG_WARNING(Service_APT, "called app_id=0x%08X, buffer_size=0x%08X", app_id, buffer_size);
}
void GlanceParameter(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
u32 app_id = cmd_buff[1];
u32 buffer_size = cmd_buff[2];
+ VAddr buffer = cmd_buff[0x104 >> 2];
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
- cmd_buff[2] = 0;
- cmd_buff[3] = static_cast<u32>(SignalType::AppJustStarted); // Signal type
- cmd_buff[4] = 0x10; // Parameter buffer size (16)
- cmd_buff[5] = 0;
+ cmd_buff[2] = next_parameter.sender_id;
+ cmd_buff[3] = next_parameter.signal; // Signal type
+ cmd_buff[4] = next_parameter.buffer_size; // Parameter buffer size
+ cmd_buff[5] = 0x10;
cmd_buff[6] = 0;
- cmd_buff[7] = 0;
+ if (next_parameter.object != nullptr)
+ cmd_buff[6] = Kernel::g_handle_table.Create(next_parameter.object).MoveFrom();
+ cmd_buff[7] = (next_parameter.buffer_size << 14) | 2;
+ cmd_buff[8] = buffer;
- LOG_WARNING(Service_APT, "(STUBBED) called app_id=0x%08X, buffer_size=0x%08X", app_id, buffer_size);
+ if (next_parameter.data)
+ memcpy(Memory::GetPointer(buffer), next_parameter.data, std::min(buffer_size, next_parameter.buffer_size));
+
+ LOG_WARNING(Service_APT, "called app_id=0x%08X, buffer_size=0x%08X", app_id, buffer_size);
}
void CancelParameter(Service::Interface* self) {
@@ -281,6 +327,28 @@ void GetAppCpuTimeLimit(Service::Interface* self) {
LOG_WARNING(Service_APT, "(STUBBED) called value=%u", value);
}
+void PrepareToStartLibraryApplet(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ cmd_buff[1] = HLE::Applets::Applet::Create(static_cast<AppletId>(cmd_buff[1])).raw;
+}
+
+void StartLibraryApplet(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ std::shared_ptr<HLE::Applets::Applet> applet = HLE::Applets::Applet::Get(static_cast<AppletId>(cmd_buff[1]));
+
+ if (applet == nullptr) {
+ cmd_buff[1] = -1; // TODO(Subv): Find the right error code
+ return;
+ }
+
+ AppletStartupParameter parameter;
+ parameter.buffer_size = cmd_buff[2];
+ parameter.object = Kernel::g_handle_table.GetGeneric(cmd_buff[4]);
+ parameter.data = Memory::GetPointer(cmd_buff[6]);
+
+ cmd_buff[1] = applet->Start(parameter).raw;
+}
+
void Init() {
AddService(new APT_A_Interface);
AddService(new APT_S_Interface);
@@ -318,7 +386,10 @@ void Init() {
// TODO(bunnei): Check if these are created in Initialize or on APT process startup.
notification_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "APT_U:Notification");
- start_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "APT_U:Start");
+ parameter_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "APT_U:Start");
+
+ next_parameter.signal = static_cast<u32>(SignalType::AppJustStarted);
+ next_parameter.destination_id = 0x300;
}
void Shutdown() {
@@ -326,7 +397,7 @@ void Shutdown() {
shared_font_mem = nullptr;
lock = nullptr;
notification_event = nullptr;
- start_event = nullptr;
+ parameter_event = nullptr;
}
} // namespace APT