summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Subv2017-09-24 19:09:13 -0500
committerGravatar Subv2017-09-25 23:47:50 -0500
commite27ae046960e20144892cf8252d8a672a48b0123 (patch)
treea9bebb5f7732ff29ef12f1eb00dede038b18ccdd /src
parentMerge pull request #2928 from huwpascoe/master (diff)
downloadyuzu-e27ae046960e20144892cf8252d8a672a48b0123.tar.gz
yuzu-e27ae046960e20144892cf8252d8a672a48b0123.tar.xz
yuzu-e27ae046960e20144892cf8252d8a672a48b0123.zip
HLE/APT: Always set up the APT parameter when starting a library applet.
Only use the HLE interface if an HLE applet with the desired id was started. This commit reorganizes the APT code surrounding parameter creation and delivery to make it easier to support LLE applets in the future. As future work, the HLE applet interface can be reworked to utilize the same facilities as the LLE interface.
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/apt/apt.cpp73
-rw-r--r--src/core/hle/service/apt/apt_s.cpp4
2 files changed, 47 insertions, 30 deletions
diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp
index 8c0ba73f2..c36775473 100644
--- a/src/core/hle/service/apt/apt.cpp
+++ b/src/core/hle/service/apt/apt.cpp
@@ -165,7 +165,11 @@ void SendParameter(const MessageParameter& parameter) {
165 next_parameter = parameter; 165 next_parameter = parameter;
166 // Signal the event to let the receiver know that a new parameter is ready to be read 166 // Signal the event to let the receiver know that a new parameter is ready to be read
167 auto* const slot_data = GetAppletSlotData(static_cast<AppletId>(parameter.destination_id)); 167 auto* const slot_data = GetAppletSlotData(static_cast<AppletId>(parameter.destination_id));
168 ASSERT(slot_data); 168 if (slot_data == nullptr) {
169 LOG_DEBUG(Service_APT, "No applet was registered with the id %03X",
170 parameter.destination_id);
171 return;
172 }
169 173
170 slot_data->parameter_event->Signal(); 174 slot_data->parameter_event->Signal();
171} 175}
@@ -486,9 +490,6 @@ void SendParameter(Service::Interface* self) {
486 size_t size; 490 size_t size;
487 VAddr buffer = rp.PopStaticBuffer(&size); 491 VAddr buffer = rp.PopStaticBuffer(&size);
488 492
489 std::shared_ptr<HLE::Applets::Applet> dest_applet =
490 HLE::Applets::Applet::Get(static_cast<AppletId>(dst_app_id));
491
492 LOG_DEBUG(Service_APT, 493 LOG_DEBUG(Service_APT,
493 "called src_app_id=0x%08X, dst_app_id=0x%08X, signal_type=0x%08X," 494 "called src_app_id=0x%08X, dst_app_id=0x%08X, signal_type=0x%08X,"
494 "buffer_size=0x%08X, handle=0x%08X, size=0x%08zX, in_param_buffer_ptr=0x%08X", 495 "buffer_size=0x%08X, handle=0x%08X, size=0x%08zX, in_param_buffer_ptr=0x%08X",
@@ -503,12 +504,6 @@ void SendParameter(Service::Interface* self) {
503 return; 504 return;
504 } 505 }
505 506
506 if (dest_applet == nullptr) {
507 LOG_ERROR(Service_APT, "Unknown applet id=0x%08X", dst_app_id);
508 rb.Push<u32>(-1); // TODO(Subv): Find the right error code
509 return;
510 }
511
512 MessageParameter param; 507 MessageParameter param;
513 param.destination_id = dst_app_id; 508 param.destination_id = dst_app_id;
514 param.sender_id = src_app_id; 509 param.sender_id = src_app_id;
@@ -517,7 +512,14 @@ void SendParameter(Service::Interface* self) {
517 param.buffer.resize(buffer_size); 512 param.buffer.resize(buffer_size);
518 Memory::ReadBlock(buffer, param.buffer.data(), param.buffer.size()); 513 Memory::ReadBlock(buffer, param.buffer.data(), param.buffer.size());
519 514
520 rb.Push(dest_applet->ReceiveParameter(param)); 515 SendParameter(param);
516
517 // If the applet is running in HLE mode, use the HLE interface to communicate with it.
518 if (auto dest_applet = HLE::Applets::Applet::Get(static_cast<AppletId>(dst_app_id))) {
519 rb.Push(dest_applet->ReceiveParameter(param));
520 } else {
521 rb.Push(RESULT_SUCCESS);
522 }
521} 523}
522 524
523void ReceiveParameter(Service::Interface* self) { 525void ReceiveParameter(Service::Interface* self) {
@@ -746,7 +748,12 @@ void PrepareToStartLibraryApplet(Service::Interface* self) {
746 IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x18, 1, 0); // 0x180040 748 IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x18, 1, 0); // 0x180040
747 AppletId applet_id = static_cast<AppletId>(rp.Pop<u32>()); 749 AppletId applet_id = static_cast<AppletId>(rp.Pop<u32>());
748 750
751 LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id);
752
749 IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); 753 IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
754
755 // TODO(Subv): Launch the requested applet application.
756
750 auto applet = HLE::Applets::Applet::Get(applet_id); 757 auto applet = HLE::Applets::Applet::Get(applet_id);
751 if (applet) { 758 if (applet) {
752 LOG_WARNING(Service_APT, "applet has already been started id=%08X", applet_id); 759 LOG_WARNING(Service_APT, "applet has already been started id=%08X", applet_id);
@@ -754,14 +761,18 @@ void PrepareToStartLibraryApplet(Service::Interface* self) {
754 } else { 761 } else {
755 rb.Push(HLE::Applets::Applet::Create(applet_id)); 762 rb.Push(HLE::Applets::Applet::Create(applet_id));
756 } 763 }
757 LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id);
758} 764}
759 765
760void PreloadLibraryApplet(Service::Interface* self) { 766void PreloadLibraryApplet(Service::Interface* self) {
761 IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x16, 1, 0); // 0x160040 767 IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x16, 1, 0); // 0x160040
762 AppletId applet_id = static_cast<AppletId>(rp.Pop<u32>()); 768 AppletId applet_id = static_cast<AppletId>(rp.Pop<u32>());
763 769
770 LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id);
771
764 IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); 772 IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
773
774 // TODO(Subv): Launch the requested applet application.
775
765 auto applet = HLE::Applets::Applet::Get(applet_id); 776 auto applet = HLE::Applets::Applet::Get(applet_id);
766 if (applet) { 777 if (applet) {
767 LOG_WARNING(Service_APT, "applet has already been started id=%08X", applet_id); 778 LOG_WARNING(Service_APT, "applet has already been started id=%08X", applet_id);
@@ -769,34 +780,40 @@ void PreloadLibraryApplet(Service::Interface* self) {
769 } else { 780 } else {
770 rb.Push(HLE::Applets::Applet::Create(applet_id)); 781 rb.Push(HLE::Applets::Applet::Create(applet_id));
771 } 782 }
772 LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id);
773} 783}
774 784
775void StartLibraryApplet(Service::Interface* self) { 785void StartLibraryApplet(Service::Interface* self) {
776 IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x1E, 2, 4); // 0x1E0084 786 IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x1E, 2, 4); // 0x1E0084
777 AppletId applet_id = static_cast<AppletId>(rp.Pop<u32>()); 787 AppletId applet_id = static_cast<AppletId>(rp.Pop<u32>());
778 std::shared_ptr<HLE::Applets::Applet> applet = HLE::Applets::Applet::Get(applet_id);
779
780 LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id);
781
782 if (applet == nullptr) {
783 LOG_ERROR(Service_APT, "unknown applet id=%08X", applet_id);
784 IPC::RequestBuilder rb = rp.MakeBuilder(1, 0, false);
785 rb.Push<u32>(-1); // TODO(Subv): Find the right error code
786 return;
787 }
788 788
789 size_t buffer_size = rp.Pop<u32>(); 789 size_t buffer_size = rp.Pop<u32>();
790 Kernel::Handle handle = rp.PopHandle(); 790 Kernel::Handle handle = rp.PopHandle();
791 VAddr buffer_addr = rp.PopStaticBuffer(); 791 VAddr buffer_addr = rp.PopStaticBuffer();
792 792
793 AppletStartupParameter parameter; 793 LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id);
794 parameter.object = Kernel::g_handle_table.GetGeneric(handle);
795 parameter.buffer.resize(buffer_size);
796 Memory::ReadBlock(buffer_addr, parameter.buffer.data(), parameter.buffer.size());
797 794
798 IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); 795 IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
799 rb.Push(applet->Start(parameter)); 796
797 // Send the Wakeup signal to the applet
798 MessageParameter param;
799 param.destination_id = static_cast<u32>(applet_id);
800 param.sender_id = static_cast<u32>(AppletId::Application);
801 param.object = Kernel::g_handle_table.GetGeneric(handle);
802 param.signal = static_cast<u32>(SignalType::Wakeup);
803 param.buffer.resize(buffer_size);
804 Memory::ReadBlock(buffer_addr, param.buffer.data(), param.buffer.size());
805 SendParameter(param);
806
807 // In case the applet is being HLEd, attempt to communicate with it.
808 if (auto applet = HLE::Applets::Applet::Get(applet_id)) {
809 AppletStartupParameter parameter;
810 parameter.object = Kernel::g_handle_table.GetGeneric(handle);
811 parameter.buffer.resize(buffer_size);
812 Memory::ReadBlock(buffer_addr, parameter.buffer.data(), parameter.buffer.size());
813 rb.Push(applet->Start(parameter));
814 } else {
815 rb.Push(RESULT_SUCCESS);
816 }
800} 817}
801 818
802void CancelLibraryApplet(Service::Interface* self) { 819void CancelLibraryApplet(Service::Interface* self) {
diff --git a/src/core/hle/service/apt/apt_s.cpp b/src/core/hle/service/apt/apt_s.cpp
index ec5668d05..cf74c2a36 100644
--- a/src/core/hle/service/apt/apt_s.cpp
+++ b/src/core/hle/service/apt/apt_s.cpp
@@ -20,7 +20,7 @@ const Interface::FunctionInfo FunctionTable[] = {
20 {0x00090040, nullptr, "IsRegistered"}, 20 {0x00090040, nullptr, "IsRegistered"},
21 {0x000A0040, nullptr, "GetAttribute"}, 21 {0x000A0040, nullptr, "GetAttribute"},
22 {0x000B0040, InquireNotification, "InquireNotification"}, 22 {0x000B0040, InquireNotification, "InquireNotification"},
23 {0x000C0104, nullptr, "SendParameter"}, 23 {0x000C0104, SendParameter, "SendParameter"},
24 {0x000D0080, ReceiveParameter, "ReceiveParameter"}, 24 {0x000D0080, ReceiveParameter, "ReceiveParameter"},
25 {0x000E0080, GlanceParameter, "GlanceParameter"}, 25 {0x000E0080, GlanceParameter, "GlanceParameter"},
26 {0x000F0100, nullptr, "CancelParameter"}, 26 {0x000F0100, nullptr, "CancelParameter"},
@@ -38,7 +38,7 @@ const Interface::FunctionInfo FunctionTable[] = {
38 {0x001B00C4, nullptr, "StartApplication"}, 38 {0x001B00C4, nullptr, "StartApplication"},
39 {0x001C0000, nullptr, "WakeupApplication"}, 39 {0x001C0000, nullptr, "WakeupApplication"},
40 {0x001D0000, nullptr, "CancelApplication"}, 40 {0x001D0000, nullptr, "CancelApplication"},
41 {0x001E0084, nullptr, "StartLibraryApplet"}, 41 {0x001E0084, StartLibraryApplet, "StartLibraryApplet"},
42 {0x001F0084, nullptr, "StartSystemApplet"}, 42 {0x001F0084, nullptr, "StartSystemApplet"},
43 {0x00200044, nullptr, "StartNewestHomeMenu"}, 43 {0x00200044, nullptr, "StartNewestHomeMenu"},
44 {0x00210000, nullptr, "OrderToCloseApplication"}, 44 {0x00210000, nullptr, "OrderToCloseApplication"},