Stratosphere: Add debugging to loader, it can now be talked to on console successfully.

This commit is contained in:
Michael Scire 2018-04-18 16:24:40 -06:00
parent 8ba3894c3a
commit 7fed8a4428
7 changed files with 46 additions and 16 deletions

View file

@ -18,6 +18,13 @@ class IWaitable {
return this->parent_waitable != NULL;
}
void set_parent(IWaitable *p) {
if (has_parent()) {
/* TODO: Panic? */
}
this->parent_waitable = p;
}
IWaitable *get_parent() {
return this->parent_waitable;
}

View file

@ -1,4 +1,5 @@
#include <switch.h>
#include <cstdio>
#include "ldr_debug_monitor.hpp"
#include "ldr_launch_queue.hpp"
@ -6,6 +7,8 @@ Result DebugMonitorService::dispatch(IpcParsedCommand *r, IpcCommand *out_c, u32
Result rc = 0xF601;
fprintf(stderr, "TLS: %p\n", armGetTls());
/* TODO: Prepare SFCO. */
switch ((DebugMonitorServiceCmd)cmd_id) {
@ -17,8 +20,8 @@ Result DebugMonitorService::dispatch(IpcParsedCommand *r, IpcCommand *out_c, u32
rc = add_title_to_launch_queue(((u64 *)in_rawdata)[0], (const char *)r->Statics[0], r->StaticSizes[0]);
*out_raw_data_count = 0;
*out_raw_data_count = 4;
break;
case Dmnt_Cmd_ClearLaunchQueue:
if (r->HasPid || r->NumHandles != 0 || r->NumBuffers != 0 || r->NumStatics != 0) {
@ -26,7 +29,7 @@ Result DebugMonitorService::dispatch(IpcParsedCommand *r, IpcCommand *out_c, u32
}
rc = clear_launch_queue();
*out_raw_data_count = 0;
*out_raw_data_count = 4;
break;
case Dmnt_Cmd_GetNsoInfo:

View file

@ -1,6 +1,6 @@
#include <switch.h>
#include <algorithm>
#include <cstdio>
#include "ldr_launch_queue.hpp"
@ -18,6 +18,10 @@ namespace LaunchQueue {
g_launch_queue[idx].tid = tid;
g_launch_queue[idx].arg_size = arg_size;
fprintf(stderr, "TID: %016llx, args: %p, size: %016llx\n", tid, args, arg_size);
fprintf(stderr, "Args: %s\n", args);
std::copy(args, args + arg_size, g_launch_queue[idx].args);
return 0x0;
}

View file

@ -33,12 +33,14 @@ void __libnx_initheap(void)
int main(int argc, char **argv)
{
consoleDebugInit(debugDevice_SVC);
/* TODO: What's a good timeout value to use here? */
WaitableManager *server_manager = new WaitableManager(U64_MAX);
/* Add services to manager. */
server_manager->add_waitable(new ServiceServer<ShellService>("ldr:shel", 3));
server_manager->add_waitable(new ServiceServer<DebugMonitorService>("ldr:dmnt", 2));
server_manager->add_waitable(new ServiceServer<ShellService>("dbg:shel", 3));
server_manager->add_waitable(new ServiceServer<DebugMonitorService>("dbg:dmnt", 2));
/* Loop forever, servicing our services. */
server_manager->process();

View file

@ -19,7 +19,7 @@ class ServiceServer : public IWaitable {
ServiceSession<T> **sessions;
public:
ServiceServer(const char *service_name, unsigned int max_s) {
ServiceServer(const char *service_name, unsigned int max_s) : max_sessions(max_s) {
if (R_FAILED(smRegisterService(&this->port_handle, service_name, false, this->max_sessions))) {
/* TODO: Panic. */
}
@ -91,8 +91,12 @@ class ServiceServer : public IWaitable {
/* If this server's port was signaled, accept a new session. */
Handle session_h;
svcAcceptSession(&session_h, this->port_handle);
fprintf(stderr, "Accept %08X -> %08X\n", this->port_handle, session_h);
fprintf(stderr, "Sessions: %08X/%08X\n", this->num_sessions, this->max_sessions);
if (this->num_sessions >= this->max_sessions) {
fprintf(stderr, "Closing because of max sessions...\n");
svcCloseHandle(session_h);
return 0x10601;
}
@ -105,6 +109,7 @@ class ServiceServer : public IWaitable {
}
this->sessions[i] = new ServiceSession<T>(this, session_h, 0);
this->sessions[i]->set_parent(this);
this->num_sessions++;
return 0;
}

View file

@ -1,6 +1,7 @@
#pragma once
#include <switch.h>
#include <type_traits>
#include <cstdio>
#include "iserviceobject.hpp"
#include "iwaitable.hpp"
@ -70,6 +71,8 @@ class ServiceSession : public IWaitable {
IpcParsedCommand r;
IpcCommand c;
fprintf(stderr, "Doing ServiceSession parse...\n");
ipcInitialize(&c);
retval = ipcParse(&r);
@ -81,17 +84,21 @@ class ServiceSession : public IWaitable {
out_words += extra_rawdata_count;
}
struct {
u64 magic;
u64 retval;
} *raw;
if (retval != 0xF601) {
struct {
u64 magic;
u64 retval;
} *raw;
raw = (decltype(raw))ipcPrepareHeader(&c, out_words);
raw = (decltype(raw))ipcPrepareHeader(&c, out_words);
raw->magic = SFCO_MAGIC;
raw->retval = retval;
rc = svcReplyAndReceive(&handle_index, &this->server_handle, 1, this->server_handle, 0);
raw->magic = SFCO_MAGIC;
raw->retval = retval;
rc = svcReplyAndReceive(&handle_index, &this->server_handle, 1, this->server_handle, 0);
} else {
rc = retval;
}
}
return rc;

View file

@ -1,6 +1,7 @@
#include <switch.h>
#include <algorithm>
#include <cstdio>
#include "waitablemanager.hpp"
@ -44,6 +45,7 @@ void WaitableManager::process() {
if (R_SUCCEEDED(rc)) {
/* Handle a signaled waitable. */
/* TODO: What timeout should be passed here? */
rc = signalables[handle_index]->handle_signaled(0);
for (int i = 0; i < handle_index; i++) {