diff options
| author | 2017-10-04 15:01:58 -0500 | |
|---|---|---|
| committer | 2017-10-04 15:01:58 -0500 | |
| commit | 84c344b9b14e28b9384b37bd73521de01ae7815c (patch) | |
| tree | 7e40cc6386af4067e891778020165115b0e2b2a2 /src | |
| parent | Merge pull request #2985 from huwpascoe/pica_reg (diff) | |
| parent | HLE/APT: Always set up the APT parameter when starting a library applet. (diff) | |
| download | yuzu-84c344b9b14e28b9384b37bd73521de01ae7815c.tar.gz yuzu-84c344b9b14e28b9384b37bd73521de01ae7815c.tar.xz yuzu-84c344b9b14e28b9384b37bd73521de01ae7815c.zip | |
Merge pull request #2953 from Subv/applet_launch
HLE/APT: Always set up the APT parameter when starting a library applet.
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/service/apt/apt.cpp | 73 | ||||
| -rw-r--r-- | src/core/hle/service/apt/apt_s.cpp | 4 |
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 2f7362748..59ea9823d 100644 --- a/src/core/hle/service/apt/apt.cpp +++ b/src/core/hle/service/apt/apt.cpp | |||
| @@ -171,7 +171,11 @@ void SendParameter(const MessageParameter& parameter) { | |||
| 171 | next_parameter = parameter; | 171 | next_parameter = parameter; |
| 172 | // Signal the event to let the receiver know that a new parameter is ready to be read | 172 | // Signal the event to let the receiver know that a new parameter is ready to be read |
| 173 | auto* const slot_data = GetAppletSlotData(static_cast<AppletId>(parameter.destination_id)); | 173 | auto* const slot_data = GetAppletSlotData(static_cast<AppletId>(parameter.destination_id)); |
| 174 | ASSERT(slot_data); | 174 | if (slot_data == nullptr) { |
| 175 | LOG_DEBUG(Service_APT, "No applet was registered with the id %03X", | ||
| 176 | parameter.destination_id); | ||
| 177 | return; | ||
| 178 | } | ||
| 175 | 179 | ||
| 176 | slot_data->parameter_event->Signal(); | 180 | slot_data->parameter_event->Signal(); |
| 177 | } | 181 | } |
| @@ -505,9 +509,6 @@ void SendParameter(Service::Interface* self) { | |||
| 505 | size_t size; | 509 | size_t size; |
| 506 | VAddr buffer = rp.PopStaticBuffer(&size); | 510 | VAddr buffer = rp.PopStaticBuffer(&size); |
| 507 | 511 | ||
| 508 | std::shared_ptr<HLE::Applets::Applet> dest_applet = | ||
| 509 | HLE::Applets::Applet::Get(static_cast<AppletId>(dst_app_id)); | ||
| 510 | |||
| 511 | LOG_DEBUG(Service_APT, | 512 | LOG_DEBUG(Service_APT, |
| 512 | "called src_app_id=0x%08X, dst_app_id=0x%08X, signal_type=0x%08X," | 513 | "called src_app_id=0x%08X, dst_app_id=0x%08X, signal_type=0x%08X," |
| 513 | "buffer_size=0x%08X, handle=0x%08X, size=0x%08zX, in_param_buffer_ptr=0x%08X", | 514 | "buffer_size=0x%08X, handle=0x%08X, size=0x%08zX, in_param_buffer_ptr=0x%08X", |
| @@ -522,12 +523,6 @@ void SendParameter(Service::Interface* self) { | |||
| 522 | return; | 523 | return; |
| 523 | } | 524 | } |
| 524 | 525 | ||
| 525 | if (dest_applet == nullptr) { | ||
| 526 | LOG_ERROR(Service_APT, "Unknown applet id=0x%08X", dst_app_id); | ||
| 527 | rb.Push<u32>(-1); // TODO(Subv): Find the right error code | ||
| 528 | return; | ||
| 529 | } | ||
| 530 | |||
| 531 | MessageParameter param; | 526 | MessageParameter param; |
| 532 | param.destination_id = dst_app_id; | 527 | param.destination_id = dst_app_id; |
| 533 | param.sender_id = src_app_id; | 528 | param.sender_id = src_app_id; |
| @@ -536,7 +531,14 @@ void SendParameter(Service::Interface* self) { | |||
| 536 | param.buffer.resize(buffer_size); | 531 | param.buffer.resize(buffer_size); |
| 537 | Memory::ReadBlock(buffer, param.buffer.data(), param.buffer.size()); | 532 | Memory::ReadBlock(buffer, param.buffer.data(), param.buffer.size()); |
| 538 | 533 | ||
| 539 | rb.Push(dest_applet->ReceiveParameter(param)); | 534 | SendParameter(param); |
| 535 | |||
| 536 | // If the applet is running in HLE mode, use the HLE interface to communicate with it. | ||
| 537 | if (auto dest_applet = HLE::Applets::Applet::Get(static_cast<AppletId>(dst_app_id))) { | ||
| 538 | rb.Push(dest_applet->ReceiveParameter(param)); | ||
| 539 | } else { | ||
| 540 | rb.Push(RESULT_SUCCESS); | ||
| 541 | } | ||
| 540 | } | 542 | } |
| 541 | 543 | ||
| 542 | void ReceiveParameter(Service::Interface* self) { | 544 | void ReceiveParameter(Service::Interface* self) { |
| @@ -765,7 +767,12 @@ void PrepareToStartLibraryApplet(Service::Interface* self) { | |||
| 765 | IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x18, 1, 0); // 0x180040 | 767 | IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x18, 1, 0); // 0x180040 |
| 766 | AppletId applet_id = static_cast<AppletId>(rp.Pop<u32>()); | 768 | AppletId applet_id = static_cast<AppletId>(rp.Pop<u32>()); |
| 767 | 769 | ||
| 770 | LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id); | ||
| 771 | |||
| 768 | 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 | |||
| 769 | auto applet = HLE::Applets::Applet::Get(applet_id); | 776 | auto applet = HLE::Applets::Applet::Get(applet_id); |
| 770 | if (applet) { | 777 | if (applet) { |
| 771 | 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); |
| @@ -773,7 +780,6 @@ void PrepareToStartLibraryApplet(Service::Interface* self) { | |||
| 773 | } else { | 780 | } else { |
| 774 | rb.Push(HLE::Applets::Applet::Create(applet_id)); | 781 | rb.Push(HLE::Applets::Applet::Create(applet_id)); |
| 775 | } | 782 | } |
| 776 | LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id); | ||
| 777 | } | 783 | } |
| 778 | 784 | ||
| 779 | void PrepareToStartNewestHomeMenu(Service::Interface* self) { | 785 | void PrepareToStartNewestHomeMenu(Service::Interface* self) { |
| @@ -794,7 +800,12 @@ void PreloadLibraryApplet(Service::Interface* self) { | |||
| 794 | IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x16, 1, 0); // 0x160040 | 800 | IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x16, 1, 0); // 0x160040 |
| 795 | AppletId applet_id = static_cast<AppletId>(rp.Pop<u32>()); | 801 | AppletId applet_id = static_cast<AppletId>(rp.Pop<u32>()); |
| 796 | 802 | ||
| 803 | LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id); | ||
| 804 | |||
| 797 | IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | 805 | IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); |
| 806 | |||
| 807 | // TODO(Subv): Launch the requested applet application. | ||
| 808 | |||
| 798 | auto applet = HLE::Applets::Applet::Get(applet_id); | 809 | auto applet = HLE::Applets::Applet::Get(applet_id); |
| 799 | if (applet) { | 810 | if (applet) { |
| 800 | LOG_WARNING(Service_APT, "applet has already been started id=%08X", applet_id); | 811 | LOG_WARNING(Service_APT, "applet has already been started id=%08X", applet_id); |
| @@ -802,34 +813,40 @@ void PreloadLibraryApplet(Service::Interface* self) { | |||
| 802 | } else { | 813 | } else { |
| 803 | rb.Push(HLE::Applets::Applet::Create(applet_id)); | 814 | rb.Push(HLE::Applets::Applet::Create(applet_id)); |
| 804 | } | 815 | } |
| 805 | LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id); | ||
| 806 | } | 816 | } |
| 807 | 817 | ||
| 808 | void StartLibraryApplet(Service::Interface* self) { | 818 | void StartLibraryApplet(Service::Interface* self) { |
| 809 | IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x1E, 2, 4); // 0x1E0084 | 819 | IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x1E, 2, 4); // 0x1E0084 |
| 810 | AppletId applet_id = static_cast<AppletId>(rp.Pop<u32>()); | 820 | AppletId applet_id = static_cast<AppletId>(rp.Pop<u32>()); |
| 811 | std::shared_ptr<HLE::Applets::Applet> applet = HLE::Applets::Applet::Get(applet_id); | ||
| 812 | |||
| 813 | LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id); | ||
| 814 | |||
| 815 | if (applet == nullptr) { | ||
| 816 | LOG_ERROR(Service_APT, "unknown applet id=%08X", applet_id); | ||
| 817 | IPC::RequestBuilder rb = rp.MakeBuilder(1, 0, false); | ||
| 818 | rb.Push<u32>(-1); // TODO(Subv): Find the right error code | ||
| 819 | return; | ||
| 820 | } | ||
| 821 | 821 | ||
| 822 | size_t buffer_size = rp.Pop<u32>(); | 822 | size_t buffer_size = rp.Pop<u32>(); |
| 823 | Kernel::Handle handle = rp.PopHandle(); | 823 | Kernel::Handle handle = rp.PopHandle(); |
| 824 | VAddr buffer_addr = rp.PopStaticBuffer(); | 824 | VAddr buffer_addr = rp.PopStaticBuffer(); |
| 825 | 825 | ||
| 826 | AppletStartupParameter parameter; | 826 | LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id); |
| 827 | parameter.object = Kernel::g_handle_table.GetGeneric(handle); | ||
| 828 | parameter.buffer.resize(buffer_size); | ||
| 829 | Memory::ReadBlock(buffer_addr, parameter.buffer.data(), parameter.buffer.size()); | ||
| 830 | 827 | ||
| 831 | IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | 828 | IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); |
| 832 | rb.Push(applet->Start(parameter)); | 829 | |
| 830 | // Send the Wakeup signal to the applet | ||
| 831 | MessageParameter param; | ||
| 832 | param.destination_id = static_cast<u32>(applet_id); | ||
| 833 | param.sender_id = static_cast<u32>(AppletId::Application); | ||
| 834 | param.object = Kernel::g_handle_table.GetGeneric(handle); | ||
| 835 | param.signal = static_cast<u32>(SignalType::Wakeup); | ||
| 836 | param.buffer.resize(buffer_size); | ||
| 837 | Memory::ReadBlock(buffer_addr, param.buffer.data(), param.buffer.size()); | ||
| 838 | SendParameter(param); | ||
| 839 | |||
| 840 | // In case the applet is being HLEd, attempt to communicate with it. | ||
| 841 | if (auto applet = HLE::Applets::Applet::Get(applet_id)) { | ||
| 842 | AppletStartupParameter parameter; | ||
| 843 | parameter.object = Kernel::g_handle_table.GetGeneric(handle); | ||
| 844 | parameter.buffer.resize(buffer_size); | ||
| 845 | Memory::ReadBlock(buffer_addr, parameter.buffer.data(), parameter.buffer.size()); | ||
| 846 | rb.Push(applet->Start(parameter)); | ||
| 847 | } else { | ||
| 848 | rb.Push(RESULT_SUCCESS); | ||
| 849 | } | ||
| 833 | } | 850 | } |
| 834 | 851 | ||
| 835 | void CancelLibraryApplet(Service::Interface* self) { | 852 | void 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 fe1d21fff..bb78ee7d7 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, IsRegistered, "IsRegistered"}, | 20 | {0x00090040, IsRegistered, "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"}, |