IPC Episode 1 - Prologue

This commit is contained in:
Ryan Teal 2019-07-09 22:35:51 +01:00
parent 1e057cb5f9
commit 4cd7c985f0
No known key found for this signature in database
GPG Key ID: 8DBEE0F12C7E2D23
5 changed files with 115 additions and 2 deletions

View File

@ -12,6 +12,7 @@ add_library(lightswitch SHARED
${source_DIR}/core/arm/cpu.cpp
${source_DIR}/core/arm/memory.cpp
${source_DIR}/core/hos/kernel/ipc.cpp
${source_DIR}/core/hos/kernel/kernel.cpp
${source_DIR}/core/hos/kernel/svc.cpp
${source_DIR}/core/hos/loaders/nro.cpp

View File

@ -0,0 +1,49 @@
#include <syslog.h>
#include <cstdlib>
#include "ipc.h"
namespace core::kernel
{
IpcRequest::IpcRequest(uint8_t* tlsPtr)
{
for(int i = 0; i < 32; i++)
syslog(LOG_DEBUG, "%02x\t%02x %02x %02x %02x %02x %02x %02x %02x", i*8, tlsPtr[0+(i*8)], tlsPtr[1+(i*8)], tlsPtr[2+(i*8)], tlsPtr[3+(i*8)], tlsPtr[4+(i*8)], tlsPtr[5+(i*8)], tlsPtr[6+(i*8)], tlsPtr[7+(i*8)]);
syslog(LOG_DEBUG, "-----------------------");
uint32_t word1 = ((uint32_t*)tlsPtr)[1];
type = *(uint16_t*)tlsPtr;
xCount = tlsPtr[2] & 0xF0 >> 4;
aCount = tlsPtr[2] & 0x0F;
bCount = tlsPtr[3] & 0xF0 >> 4;
wCount = tlsPtr[3] & 0x0F;
dataSize = word1 & 0x3FF;
dataPos = 8;
if(tlsPtr[2] || tlsPtr[3])
{
syslog(LOG_ERR, "IPC - X/A/B/W descriptors");
exit(0);
}
syslog(LOG_DEBUG, "Enable handle descriptor: %s", word1 >> 31 ? "yes" : "no");
if(word1 >> 31)
{
syslog(LOG_ERR, "IPC - Handle descriptor");
exit(0);
}
// Align to 16 bytes
if((dataPos % 16) != 0)
dataPos += 16 - (dataPos % 16);
dataPtr = &tlsPtr[dataPos+16];
syslog(LOG_DEBUG, "Type: %x", type);
syslog(LOG_DEBUG, "X descriptors: 0x%x", xCount);
syslog(LOG_DEBUG, "A descriptors: 0x%x", aCount);
syslog(LOG_DEBUG, "B descriptors: 0x%x", bCount);
syslog(LOG_DEBUG, "W descriptors: 0x%x", wCount);
syslog(LOG_DEBUG, "Raw data size: 0x%x", word1 & 0x3FF);
syslog(LOG_DEBUG, "Data offset=%x, Data size=%x", dataPos, dataSize);
syslog(LOG_DEBUG, "Payload CmdId=%i", *((uint32_t*)&tlsPtr[dataPos+8]));
syslog(LOG_DEBUG, "Setting dataPtr to %08x", dataPos+16);
}
}

View File

@ -0,0 +1,31 @@
#pragma once
#include <cstdint>
namespace core::kernel
{
class IpcRequest
{
public:
IpcRequest(uint8_t* tlsPtr);
template<typename T>
T GetValue()
{
dataPos += sizeof(T);
return *reinterpret_cast<T*>(&dataPtr[dataPos-sizeof(T)]);
}
uint16_t type, xCount, aCount, bCount, wCount;
uint32_t dataSize;
private:
uint8_t* dataPtr;
uint32_t dataPos;
};
class IpcResponse
{
public:
IpcResponse() {}
};
}

View File

@ -2,6 +2,8 @@
#include <cstdint>
#include <memory>
#define SM_HANDLE 0xd000 // sm: is hardcoded for now
namespace core::kernel
{
class KObject

View File

@ -4,10 +4,40 @@
#include <utility>
#include "core/arm/cpu.h"
#include "core/arm/memory.h"
#include "kernel.h"
#include "ipc.h"
#include "svc.h"
using namespace core::cpu;
namespace core::kernel {
static uint32_t ConnectToNamedPort()
{
std::string port(8, '\0');
memory::Read((void*)port.data(), GetRegister(UC_ARM64_REG_X1), 8);
if(std::strcmp(port.c_str(), "sm:") == 0)
SetRegister(UC_ARM64_REG_W1, SM_HANDLE);
else
{
syslog(LOG_ERR, "svcConnectToNamedPort tried connecting to invalid port '%s'", port.c_str());
exit(0);
}
return 0;
}
static uint32_t SendSyncRequest()
{
syslog(LOG_INFO, "svcSendSyncRequest called for handle 0x%x, dumping TLS:", GetRegister(UC_ARM64_REG_X0));
uint8_t tls[0x100];
memory::Read(&tls, 0x2000000, 0x100);
core::kernel::IpcRequest* r = new core::kernel::IpcRequest(tls);
exit(0);
return 0;
}
static uint32_t OutputDebugString()
{
std::string debug(GetRegister(UC_ARM64_REG_X1), '\0');
@ -71,9 +101,9 @@ namespace core::kernel {
{0x1c, nullptr},
{0x1d, nullptr},
{0x1e, nullptr},
{0x1f, nullptr},
{0x1f, ConnectToNamedPort},
{0x20, nullptr},
{0x21, nullptr},
{0x21, SendSyncRequest},
{0x22, nullptr},
{0x23, nullptr},
{0x24, nullptr},