summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Sebastian Valle2017-09-30 10:47:42 -0500
committerGravatar GitHub2017-09-30 10:47:42 -0500
commit7056b9c46ac0265c4daff1d4908e6f6f78553ceb (patch)
tree964b177eb54edda4ac0065f9444c427ebef2eaff
parentMerge pull request #2967 from Subv/thread_wakeup_callbacks (diff)
parentHLE/APT: Always return an error from PrepareToStartNewestHomeMenu so that the... (diff)
downloadyuzu-7056b9c46ac0265c4daff1d4908e6f6f78553ceb.tar.gz
yuzu-7056b9c46ac0265c4daff1d4908e6f6f78553ceb.tar.xz
yuzu-7056b9c46ac0265c4daff1d4908e6f6f78553ceb.zip
Merge pull request #2946 from Subv/home_menu_apt
Implement PrepareToStartNewestHomeMenu and fixed an APT regression.
-rw-r--r--src/core/hle/service/apt/apt.cpp39
-rw-r--r--src/core/hle/service/apt/apt.h10
-rw-r--r--src/core/hle/service/apt/apt_s.cpp4
3 files changed, 45 insertions, 8 deletions
diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp
index 4c6156345..2f7362748 100644
--- a/src/core/hle/service/apt/apt.cpp
+++ b/src/core/hle/service/apt/apt.cpp
@@ -65,6 +65,7 @@ union AppletAttributes {
65 u32 raw; 65 u32 raw;
66 66
67 BitField<0, 3, u32> applet_pos; 67 BitField<0, 3, u32> applet_pos;
68 BitField<29, 1, u32> is_home_menu;
68 69
69 AppletAttributes() : raw(0) {} 70 AppletAttributes() : raw(0) {}
70 AppletAttributes(u32 attributes) : raw(attributes) {} 71 AppletAttributes(u32 attributes) : raw(attributes) {}
@@ -158,6 +159,11 @@ static AppletSlotData* GetAppletSlotData(AppletAttributes attributes) {
158 if (slot == AppletSlot::Error) 159 if (slot == AppletSlot::Error)
159 return nullptr; 160 return nullptr;
160 161
162 // The Home Menu is a system applet, however, it has its own applet slot so that it can run
163 // concurrently with other system applets.
164 if (slot == AppletSlot::SystemApplet && attributes.is_home_menu)
165 return &applet_slots[static_cast<size_t>(AppletSlot::HomeMenu)];
166
161 return &applet_slots[static_cast<size_t>(slot)]; 167 return &applet_slots[static_cast<size_t>(slot)];
162} 168}
163 169
@@ -197,6 +203,19 @@ void Initialize(Service::Interface* self) {
197 rb.Push(RESULT_SUCCESS); 203 rb.Push(RESULT_SUCCESS);
198 rb.PushCopyHandles(Kernel::g_handle_table.Create(slot_data->notification_event).Unwrap(), 204 rb.PushCopyHandles(Kernel::g_handle_table.Create(slot_data->notification_event).Unwrap(),
199 Kernel::g_handle_table.Create(slot_data->parameter_event).Unwrap()); 205 Kernel::g_handle_table.Create(slot_data->parameter_event).Unwrap());
206
207 if (slot_data->applet_id == AppletId::Application ||
208 slot_data->applet_id == AppletId::HomeMenu) {
209 // Initialize the APT parameter to wake up the application.
210 next_parameter.emplace();
211 next_parameter->signal = static_cast<u32>(SignalType::Wakeup);
212 next_parameter->sender_id = static_cast<u32>(AppletId::None);
213 next_parameter->destination_id = app_id;
214 // Not signaling the parameter event will cause the application (or Home Menu) to hang
215 // during startup. In the real console, it is usually the Kernel and Home Menu who cause NS
216 // to signal the HomeMenu and Application parameter events, respectively.
217 slot_data->parameter_event->Signal();
218 }
200} 219}
201 220
202static u32 DecompressLZ11(const u8* in, u8* out) { 221static u32 DecompressLZ11(const u8* in, u8* out) {
@@ -757,6 +776,20 @@ void PrepareToStartLibraryApplet(Service::Interface* self) {
757 LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id); 776 LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id);
758} 777}
759 778
779void PrepareToStartNewestHomeMenu(Service::Interface* self) {
780 IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x1A, 0, 0); // 0x1A0000
781 IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
782
783 // TODO(Subv): This command can only be called by a System Applet (return 0xC8A0CC04 otherwise).
784
785 // This command must return an error when called, otherwise the Home Menu will try to reboot the
786 // system.
787 rb.Push(ResultCode(ErrorDescription::AlreadyExists, ErrorModule::Applet,
788 ErrorSummary::InvalidState, ErrorLevel::Status));
789
790 LOG_DEBUG(Service_APT, "called");
791}
792
760void PreloadLibraryApplet(Service::Interface* self) { 793void PreloadLibraryApplet(Service::Interface* self) {
761 IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x16, 1, 0); // 0x160040 794 IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x16, 1, 0); // 0x160040
762 AppletId applet_id = static_cast<AppletId>(rp.Pop<u32>()); 795 AppletId applet_id = static_cast<AppletId>(rp.Pop<u32>());
@@ -1041,12 +1074,6 @@ void Init() {
1041 slot_data.parameter_event = 1074 slot_data.parameter_event =
1042 Kernel::Event::Create(Kernel::ResetType::OneShot, "APT:Parameter"); 1075 Kernel::Event::Create(Kernel::ResetType::OneShot, "APT:Parameter");
1043 } 1076 }
1044
1045 // Initialize the parameter to wake up the application.
1046 next_parameter.emplace();
1047 next_parameter->signal = static_cast<u32>(SignalType::Wakeup);
1048 next_parameter->destination_id = static_cast<u32>(AppletId::Application);
1049 applet_slots[static_cast<size_t>(AppletSlot::Application)].parameter_event->Signal();
1050} 1077}
1051 1078
1052void Shutdown() { 1079void Shutdown() {
diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h
index 96b28b438..7b79e1f3e 100644
--- a/src/core/hle/service/apt/apt.h
+++ b/src/core/hle/service/apt/apt.h
@@ -420,6 +420,16 @@ void GetAppCpuTimeLimit(Service::Interface* self);
420void PrepareToStartLibraryApplet(Service::Interface* self); 420void PrepareToStartLibraryApplet(Service::Interface* self);
421 421
422/** 422/**
423 * APT::PrepareToStartNewestHomeMenu service function
424 * Inputs:
425 * 0 : Command header [0x001A0000]
426 * Outputs:
427 * 0 : Return header
428 * 1 : Result of function
429 */
430void PrepareToStartNewestHomeMenu(Service::Interface* self);
431
432/**
423 * APT::PreloadLibraryApplet service function 433 * APT::PreloadLibraryApplet service function
424 * Inputs: 434 * Inputs:
425 * 0 : Command header [0x00160040] 435 * 0 : Command header [0x00160040]
diff --git a/src/core/hle/service/apt/apt_s.cpp b/src/core/hle/service/apt/apt_s.cpp
index ec5668d05..fe1d21fff 100644
--- a/src/core/hle/service/apt/apt_s.cpp
+++ b/src/core/hle/service/apt/apt_s.cpp
@@ -17,7 +17,7 @@ const Interface::FunctionInfo FunctionTable[] = {
17 {0x00060040, GetAppletInfo, "GetAppletInfo"}, 17 {0x00060040, GetAppletInfo, "GetAppletInfo"},
18 {0x00070000, nullptr, "GetLastSignaledAppletId"}, 18 {0x00070000, nullptr, "GetLastSignaledAppletId"},
19 {0x00080000, nullptr, "CountRegisteredApplet"}, 19 {0x00080000, nullptr, "CountRegisteredApplet"},
20 {0x00090040, nullptr, "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, nullptr, "SendParameter"},
@@ -34,7 +34,7 @@ const Interface::FunctionInfo FunctionTable[] = {
34 {0x00170040, nullptr, "FinishPreloadingLibraryApplet"}, 34 {0x00170040, nullptr, "FinishPreloadingLibraryApplet"},
35 {0x00180040, PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"}, 35 {0x00180040, PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"},
36 {0x00190040, nullptr, "PrepareToStartSystemApplet"}, 36 {0x00190040, nullptr, "PrepareToStartSystemApplet"},
37 {0x001A0000, nullptr, "PrepareToStartNewestHomeMenu"}, 37 {0x001A0000, PrepareToStartNewestHomeMenu, "PrepareToStartNewestHomeMenu"},
38 {0x001B00C4, nullptr, "StartApplication"}, 38 {0x001B00C4, nullptr, "StartApplication"},
39 {0x001C0000, nullptr, "WakeupApplication"}, 39 {0x001C0000, nullptr, "WakeupApplication"},
40 {0x001D0000, nullptr, "CancelApplication"}, 40 {0x001D0000, nullptr, "CancelApplication"},