mirror of
https://github.com/citra-emu/citra.git
synced 2024-12-18 18:00:07 +00:00
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.
This commit is contained in:
parent
a7758b0b36
commit
e27ae04696
@ -165,7 +165,11 @@ void SendParameter(const MessageParameter& parameter) {
|
|||||||
next_parameter = parameter;
|
next_parameter = parameter;
|
||||||
// Signal the event to let the receiver know that a new parameter is ready to be read
|
// Signal the event to let the receiver know that a new parameter is ready to be read
|
||||||
auto* const slot_data = GetAppletSlotData(static_cast<AppletId>(parameter.destination_id));
|
auto* const slot_data = GetAppletSlotData(static_cast<AppletId>(parameter.destination_id));
|
||||||
ASSERT(slot_data);
|
if (slot_data == nullptr) {
|
||||||
|
LOG_DEBUG(Service_APT, "No applet was registered with the id %03X",
|
||||||
|
parameter.destination_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
slot_data->parameter_event->Signal();
|
slot_data->parameter_event->Signal();
|
||||||
}
|
}
|
||||||
@ -486,9 +490,6 @@ void SendParameter(Service::Interface* self) {
|
|||||||
size_t size;
|
size_t size;
|
||||||
VAddr buffer = rp.PopStaticBuffer(&size);
|
VAddr buffer = rp.PopStaticBuffer(&size);
|
||||||
|
|
||||||
std::shared_ptr<HLE::Applets::Applet> dest_applet =
|
|
||||||
HLE::Applets::Applet::Get(static_cast<AppletId>(dst_app_id));
|
|
||||||
|
|
||||||
LOG_DEBUG(Service_APT,
|
LOG_DEBUG(Service_APT,
|
||||||
"called src_app_id=0x%08X, dst_app_id=0x%08X, signal_type=0x%08X,"
|
"called src_app_id=0x%08X, dst_app_id=0x%08X, signal_type=0x%08X,"
|
||||||
"buffer_size=0x%08X, handle=0x%08X, size=0x%08zX, in_param_buffer_ptr=0x%08X",
|
"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) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dest_applet == nullptr) {
|
|
||||||
LOG_ERROR(Service_APT, "Unknown applet id=0x%08X", dst_app_id);
|
|
||||||
rb.Push<u32>(-1); // TODO(Subv): Find the right error code
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageParameter param;
|
MessageParameter param;
|
||||||
param.destination_id = dst_app_id;
|
param.destination_id = dst_app_id;
|
||||||
param.sender_id = src_app_id;
|
param.sender_id = src_app_id;
|
||||||
@ -517,7 +512,14 @@ void SendParameter(Service::Interface* self) {
|
|||||||
param.buffer.resize(buffer_size);
|
param.buffer.resize(buffer_size);
|
||||||
Memory::ReadBlock(buffer, param.buffer.data(), param.buffer.size());
|
Memory::ReadBlock(buffer, param.buffer.data(), param.buffer.size());
|
||||||
|
|
||||||
rb.Push(dest_applet->ReceiveParameter(param));
|
SendParameter(param);
|
||||||
|
|
||||||
|
// If the applet is running in HLE mode, use the HLE interface to communicate with it.
|
||||||
|
if (auto dest_applet = HLE::Applets::Applet::Get(static_cast<AppletId>(dst_app_id))) {
|
||||||
|
rb.Push(dest_applet->ReceiveParameter(param));
|
||||||
|
} else {
|
||||||
|
rb.Push(RESULT_SUCCESS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReceiveParameter(Service::Interface* self) {
|
void ReceiveParameter(Service::Interface* self) {
|
||||||
@ -746,7 +748,12 @@ void PrepareToStartLibraryApplet(Service::Interface* self) {
|
|||||||
IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x18, 1, 0); // 0x180040
|
IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x18, 1, 0); // 0x180040
|
||||||
AppletId applet_id = static_cast<AppletId>(rp.Pop<u32>());
|
AppletId applet_id = static_cast<AppletId>(rp.Pop<u32>());
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id);
|
||||||
|
|
||||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||||
|
|
||||||
|
// TODO(Subv): Launch the requested applet application.
|
||||||
|
|
||||||
auto applet = HLE::Applets::Applet::Get(applet_id);
|
auto applet = HLE::Applets::Applet::Get(applet_id);
|
||||||
if (applet) {
|
if (applet) {
|
||||||
LOG_WARNING(Service_APT, "applet has already been started id=%08X", applet_id);
|
LOG_WARNING(Service_APT, "applet has already been started id=%08X", applet_id);
|
||||||
@ -754,14 +761,18 @@ void PrepareToStartLibraryApplet(Service::Interface* self) {
|
|||||||
} else {
|
} else {
|
||||||
rb.Push(HLE::Applets::Applet::Create(applet_id));
|
rb.Push(HLE::Applets::Applet::Create(applet_id));
|
||||||
}
|
}
|
||||||
LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreloadLibraryApplet(Service::Interface* self) {
|
void PreloadLibraryApplet(Service::Interface* self) {
|
||||||
IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x16, 1, 0); // 0x160040
|
IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x16, 1, 0); // 0x160040
|
||||||
AppletId applet_id = static_cast<AppletId>(rp.Pop<u32>());
|
AppletId applet_id = static_cast<AppletId>(rp.Pop<u32>());
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id);
|
||||||
|
|
||||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||||
|
|
||||||
|
// TODO(Subv): Launch the requested applet application.
|
||||||
|
|
||||||
auto applet = HLE::Applets::Applet::Get(applet_id);
|
auto applet = HLE::Applets::Applet::Get(applet_id);
|
||||||
if (applet) {
|
if (applet) {
|
||||||
LOG_WARNING(Service_APT, "applet has already been started id=%08X", applet_id);
|
LOG_WARNING(Service_APT, "applet has already been started id=%08X", applet_id);
|
||||||
@ -769,34 +780,40 @@ void PreloadLibraryApplet(Service::Interface* self) {
|
|||||||
} else {
|
} else {
|
||||||
rb.Push(HLE::Applets::Applet::Create(applet_id));
|
rb.Push(HLE::Applets::Applet::Create(applet_id));
|
||||||
}
|
}
|
||||||
LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartLibraryApplet(Service::Interface* self) {
|
void StartLibraryApplet(Service::Interface* self) {
|
||||||
IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x1E, 2, 4); // 0x1E0084
|
IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x1E, 2, 4); // 0x1E0084
|
||||||
AppletId applet_id = static_cast<AppletId>(rp.Pop<u32>());
|
AppletId applet_id = static_cast<AppletId>(rp.Pop<u32>());
|
||||||
std::shared_ptr<HLE::Applets::Applet> applet = HLE::Applets::Applet::Get(applet_id);
|
|
||||||
|
|
||||||
LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id);
|
|
||||||
|
|
||||||
if (applet == nullptr) {
|
|
||||||
LOG_ERROR(Service_APT, "unknown applet id=%08X", applet_id);
|
|
||||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0, false);
|
|
||||||
rb.Push<u32>(-1); // TODO(Subv): Find the right error code
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t buffer_size = rp.Pop<u32>();
|
size_t buffer_size = rp.Pop<u32>();
|
||||||
Kernel::Handle handle = rp.PopHandle();
|
Kernel::Handle handle = rp.PopHandle();
|
||||||
VAddr buffer_addr = rp.PopStaticBuffer();
|
VAddr buffer_addr = rp.PopStaticBuffer();
|
||||||
|
|
||||||
AppletStartupParameter parameter;
|
LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id);
|
||||||
parameter.object = Kernel::g_handle_table.GetGeneric(handle);
|
|
||||||
parameter.buffer.resize(buffer_size);
|
|
||||||
Memory::ReadBlock(buffer_addr, parameter.buffer.data(), parameter.buffer.size());
|
|
||||||
|
|
||||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||||
rb.Push(applet->Start(parameter));
|
|
||||||
|
// Send the Wakeup signal to the applet
|
||||||
|
MessageParameter param;
|
||||||
|
param.destination_id = static_cast<u32>(applet_id);
|
||||||
|
param.sender_id = static_cast<u32>(AppletId::Application);
|
||||||
|
param.object = Kernel::g_handle_table.GetGeneric(handle);
|
||||||
|
param.signal = static_cast<u32>(SignalType::Wakeup);
|
||||||
|
param.buffer.resize(buffer_size);
|
||||||
|
Memory::ReadBlock(buffer_addr, param.buffer.data(), param.buffer.size());
|
||||||
|
SendParameter(param);
|
||||||
|
|
||||||
|
// In case the applet is being HLEd, attempt to communicate with it.
|
||||||
|
if (auto applet = HLE::Applets::Applet::Get(applet_id)) {
|
||||||
|
AppletStartupParameter parameter;
|
||||||
|
parameter.object = Kernel::g_handle_table.GetGeneric(handle);
|
||||||
|
parameter.buffer.resize(buffer_size);
|
||||||
|
Memory::ReadBlock(buffer_addr, parameter.buffer.data(), parameter.buffer.size());
|
||||||
|
rb.Push(applet->Start(parameter));
|
||||||
|
} else {
|
||||||
|
rb.Push(RESULT_SUCCESS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CancelLibraryApplet(Service::Interface* self) {
|
void CancelLibraryApplet(Service::Interface* self) {
|
||||||
|
@ -20,7 +20,7 @@ const Interface::FunctionInfo FunctionTable[] = {
|
|||||||
{0x00090040, nullptr, "IsRegistered"},
|
{0x00090040, nullptr, "IsRegistered"},
|
||||||
{0x000A0040, nullptr, "GetAttribute"},
|
{0x000A0040, nullptr, "GetAttribute"},
|
||||||
{0x000B0040, InquireNotification, "InquireNotification"},
|
{0x000B0040, InquireNotification, "InquireNotification"},
|
||||||
{0x000C0104, nullptr, "SendParameter"},
|
{0x000C0104, SendParameter, "SendParameter"},
|
||||||
{0x000D0080, ReceiveParameter, "ReceiveParameter"},
|
{0x000D0080, ReceiveParameter, "ReceiveParameter"},
|
||||||
{0x000E0080, GlanceParameter, "GlanceParameter"},
|
{0x000E0080, GlanceParameter, "GlanceParameter"},
|
||||||
{0x000F0100, nullptr, "CancelParameter"},
|
{0x000F0100, nullptr, "CancelParameter"},
|
||||||
@ -38,7 +38,7 @@ const Interface::FunctionInfo FunctionTable[] = {
|
|||||||
{0x001B00C4, nullptr, "StartApplication"},
|
{0x001B00C4, nullptr, "StartApplication"},
|
||||||
{0x001C0000, nullptr, "WakeupApplication"},
|
{0x001C0000, nullptr, "WakeupApplication"},
|
||||||
{0x001D0000, nullptr, "CancelApplication"},
|
{0x001D0000, nullptr, "CancelApplication"},
|
||||||
{0x001E0084, nullptr, "StartLibraryApplet"},
|
{0x001E0084, StartLibraryApplet, "StartLibraryApplet"},
|
||||||
{0x001F0084, nullptr, "StartSystemApplet"},
|
{0x001F0084, nullptr, "StartSystemApplet"},
|
||||||
{0x00200044, nullptr, "StartNewestHomeMenu"},
|
{0x00200044, nullptr, "StartNewestHomeMenu"},
|
||||||
{0x00210000, nullptr, "OrderToCloseApplication"},
|
{0x00210000, nullptr, "OrderToCloseApplication"},
|
||||||
|
Loading…
Reference in New Issue
Block a user